Upgrade ECharts to v5, add support for ECharts gauge & chart widget (#814)
Add a oh-chart widget to add charts to layout pages; change oh-chart-page to use it. Add a oh-data-series component with the ability to add gauges representing a single value. Upgrade ECharts to v5.0.1. Also-by: Yannick Schaus <github@schaus.net> Signed-off-by: Boris Krivonog <boris.krivonog@inova.si>pull/853/head
parent
ece12a1ed5
commit
379cbbe0c5
|
@ -12,13 +12,12 @@
|
|||
"cronstrue": "^1.100.0",
|
||||
"dayjs": "^1.9.6",
|
||||
"dom7": "^2.1.5",
|
||||
"echarts": "^4.9.0",
|
||||
"echarts": "^5.0.1",
|
||||
"event-source-polyfill": "^1.0.22",
|
||||
"expression-eval": "^2.1.0",
|
||||
"framework7": "^5.7.12",
|
||||
"framework7-icons": "^3.0.1",
|
||||
"framework7-vue": "^5.7.12",
|
||||
"global-prefix": "^3.0.0",
|
||||
"later-again": "^0.1.1",
|
||||
"leaflet": "^1.7.1",
|
||||
"leaflet-providers": "^1.11.0",
|
||||
|
@ -26,7 +25,6 @@
|
|||
"nearley": "^2.19.6",
|
||||
"pkce-challenge": "^2.1.0",
|
||||
"qrcode": "^1.0.0",
|
||||
"resolve-dir": "^1.0.1",
|
||||
"sprintf-js": "^1.1.2",
|
||||
"template7": "^1.4.2",
|
||||
"tern": "^0.23.0",
|
||||
|
@ -74,6 +72,7 @@
|
|||
"eslint-loader": "^2.2.1",
|
||||
"eslint-plugin-vue": "^5.2.3",
|
||||
"file-loader": "^3.0.1",
|
||||
"global-prefix": "^3.0.0",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"jest": "^24.9.0",
|
||||
"jest-serializer-vue": "^2.0.2",
|
||||
|
@ -85,6 +84,7 @@
|
|||
"ora": "^3.4.0",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"resolve-dir": "^1.0.1",
|
||||
"rimraf": "^2.7.1",
|
||||
"standard": "^12.0.1",
|
||||
"strip-ansi": "=3.0.1",
|
||||
|
@ -7620,13 +7620,19 @@
|
|||
}
|
||||
},
|
||||
"node_modules/echarts": {
|
||||
"version": "4.9.0",
|
||||
"resolved": "https://registry.npmjs.org/echarts/-/echarts-4.9.0.tgz",
|
||||
"integrity": "sha512-+ugizgtJ+KmsJyyDPxaw2Br5FqzuBnyOWwcxPKO6y0gc5caYcfnEUIlNStx02necw8jmKmTafmpHhGo4XDtEIA==",
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.0.1.tgz",
|
||||
"integrity": "sha512-JYn22Dolt2esY2jEzUsw1OxbobuW67oGjIoTjZO3rW89SWkfJ4kbrmC2OW9JjsBrD1rdkmaWBuZZ2HgmThyxJw==",
|
||||
"dependencies": {
|
||||
"zrender": "4.3.2"
|
||||
"tslib": "2.0.3",
|
||||
"zrender": "5.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/echarts/node_modules/tslib": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
|
||||
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
|
||||
},
|
||||
"node_modules/editorconfig": {
|
||||
"version": "0.15.3",
|
||||
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
|
||||
|
@ -8565,6 +8571,7 @@
|
|||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
|
||||
"integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"homedir-polyfill": "^1.0.1"
|
||||
},
|
||||
|
@ -10283,6 +10290,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
|
||||
"integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ini": "^1.3.5",
|
||||
"kind-of": "^6.0.2",
|
||||
|
@ -10599,6 +10607,7 @@
|
|||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
||||
"integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"parse-passwd": "^1.0.0"
|
||||
},
|
||||
|
@ -11023,6 +11032,7 @@
|
|||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
|
@ -11561,6 +11571,7 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
|
||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
@ -11594,7 +11605,8 @@
|
|||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/isobject": {
|
||||
"version": "3.0.1",
|
||||
|
@ -12587,6 +12599,7 @@
|
|||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
|
||||
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
@ -14681,6 +14694,7 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
|
||||
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
@ -17257,6 +17271,7 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
|
||||
"integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"expand-tilde": "2.0.2",
|
||||
"global-modules": "1.0.0"
|
||||
|
@ -17269,6 +17284,7 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
|
||||
"integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"global-prefix": "1.0.2",
|
||||
"is-windows": "1.0.2",
|
||||
|
@ -21494,6 +21510,7 @@
|
|||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"isexe": "2.0.0"
|
||||
},
|
||||
|
@ -21890,9 +21907,17 @@
|
|||
}
|
||||
},
|
||||
"node_modules/zrender": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/zrender/-/zrender-4.3.2.tgz",
|
||||
"integrity": "sha512-bIusJLS8c4DkIcdiK+s13HiQ/zjQQVgpNohtd8d94Y2DnJqgM1yjh/jpDb8DoL6hd7r8Awagw8e3qK/oLaWr3g=="
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.0.3.tgz",
|
||||
"integrity": "sha512-TVcN2IMdo7je3GEq/E4CER4AGBe/n50/izILdupppyHf/hVHuiXCRliqdu8+32Z1OmGg6RfKt5qQlkX+bOtU0g==",
|
||||
"dependencies": {
|
||||
"tslib": "2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/zrender/node_modules/tslib": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
|
||||
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -28839,11 +28864,19 @@
|
|||
}
|
||||
},
|
||||
"echarts": {
|
||||
"version": "4.9.0",
|
||||
"resolved": "https://registry.npmjs.org/echarts/-/echarts-4.9.0.tgz",
|
||||
"integrity": "sha512-+ugizgtJ+KmsJyyDPxaw2Br5FqzuBnyOWwcxPKO6y0gc5caYcfnEUIlNStx02necw8jmKmTafmpHhGo4XDtEIA==",
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.0.1.tgz",
|
||||
"integrity": "sha512-JYn22Dolt2esY2jEzUsw1OxbobuW67oGjIoTjZO3rW89SWkfJ4kbrmC2OW9JjsBrD1rdkmaWBuZZ2HgmThyxJw==",
|
||||
"requires": {
|
||||
"zrender": "4.3.2"
|
||||
"tslib": "2.0.3",
|
||||
"zrender": "5.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
|
||||
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"editorconfig": {
|
||||
|
@ -29622,6 +29655,7 @@
|
|||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
|
||||
"integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"homedir-polyfill": "^1.0.1"
|
||||
}
|
||||
|
@ -31060,6 +31094,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
|
||||
"integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ini": "^1.3.5",
|
||||
"kind-of": "^6.0.2",
|
||||
|
@ -31312,6 +31347,7 @@
|
|||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
||||
"integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"parse-passwd": "^1.0.0"
|
||||
}
|
||||
|
@ -31677,7 +31713,8 @@
|
|||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"dev": true
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "6.5.2",
|
||||
|
@ -32098,7 +32135,8 @@
|
|||
"is-windows": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
|
||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
|
||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
|
||||
"dev": true
|
||||
},
|
||||
"is-wsl": {
|
||||
"version": "1.1.0",
|
||||
|
@ -32123,7 +32161,8 @@
|
|||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||
"dev": true
|
||||
},
|
||||
"isobject": {
|
||||
"version": "3.0.1",
|
||||
|
@ -32941,7 +32980,8 @@
|
|||
"kind-of": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
|
||||
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
|
||||
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
|
||||
"dev": true
|
||||
},
|
||||
"kleur": {
|
||||
"version": "3.0.3",
|
||||
|
@ -34671,7 +34711,8 @@
|
|||
"parse-passwd": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
|
||||
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY="
|
||||
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
|
||||
"dev": true
|
||||
},
|
||||
"parse5": {
|
||||
"version": "4.0.0",
|
||||
|
@ -36763,6 +36804,7 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
|
||||
"integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"expand-tilde": "2.0.2",
|
||||
"global-modules": "1.0.0"
|
||||
|
@ -36772,6 +36814,7 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
|
||||
"integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"global-prefix": "1.0.2",
|
||||
"is-windows": "1.0.2",
|
||||
|
@ -40365,6 +40408,7 @@
|
|||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isexe": "2.0.0"
|
||||
}
|
||||
|
@ -40725,9 +40769,19 @@
|
|||
}
|
||||
},
|
||||
"zrender": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/zrender/-/zrender-4.3.2.tgz",
|
||||
"integrity": "sha512-bIusJLS8c4DkIcdiK+s13HiQ/zjQQVgpNohtd8d94Y2DnJqgM1yjh/jpDb8DoL6hd7r8Awagw8e3qK/oLaWr3g=="
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.0.3.tgz",
|
||||
"integrity": "sha512-TVcN2IMdo7je3GEq/E4CER4AGBe/n50/izILdupppyHf/hVHuiXCRliqdu8+32Z1OmGg6RfKt5qQlkX+bOtU0g==",
|
||||
"requires": {
|
||||
"tslib": "2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
|
||||
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
"cronstrue": "^1.100.0",
|
||||
"dayjs": "^1.9.6",
|
||||
"dom7": "^2.1.5",
|
||||
"echarts": "^4.9.0",
|
||||
"echarts": "^5.0.1",
|
||||
"event-source-polyfill": "^1.0.22",
|
||||
"expression-eval": "^2.1.0",
|
||||
"framework7": "^5.7.12",
|
||||
|
|
|
@ -375,6 +375,17 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
'oh-data-series': {
|
||||
label: 'Data Series',
|
||||
docLink: 'https://echarts.apache.org/en/option.html#series',
|
||||
props: {
|
||||
parameterGroups: [],
|
||||
parameters: [
|
||||
seriesTypeParameter('gauge')
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
'oh-time-series': {
|
||||
label: 'Time Series',
|
||||
docLink: 'https://echarts.apache.org/en/option.html#series',
|
||||
|
|
|
@ -1,33 +1,7 @@
|
|||
// definitions for the chart page & widgets
|
||||
|
||||
import { WidgetDefinition, po } from '../helpers'
|
||||
import { WidgetDefinition } from '../helpers'
|
||||
|
||||
import ChartParameters from '../system/chart'
|
||||
export const OhChartPageDefinition = () => new WidgetDefinition('oh-chart-page', 'Chart Page', 'Visualize historical series')
|
||||
.params([
|
||||
po('chartType', 'Chart Type', 'Define a fixed period for the chart, aligned at the beginning of the period, e.g. January 1st at midnight for a year chart. If not set (or set to dynamic), the length of the period will be configurable but certain combinations like aggregated series might not work', [
|
||||
{ value: '', label: 'Dynamic period' },
|
||||
{ value: 'day', label: 'Day' },
|
||||
{ value: 'isoWeek', label: 'Week (starting on Monday)' },
|
||||
{ value: 'week', label: 'Week (starting on Sunday)' },
|
||||
{ value: 'month', label: 'Month' },
|
||||
{ value: 'year', label: 'Year' }
|
||||
]).r(),
|
||||
po('period', 'Initial Period', 'The initial period for the chart', [
|
||||
{ value: 'h', label: 'h' },
|
||||
{ value: '2h', label: '2h' },
|
||||
{ value: '4h', label: '4h' },
|
||||
{ value: '12h', label: '12h' },
|
||||
{ value: 'D', label: 'D' },
|
||||
{ value: '2D', label: '2D' },
|
||||
{ value: '3D', label: '3D' },
|
||||
{ value: 'W', label: 'W' },
|
||||
{ value: '2W', label: '2W' },
|
||||
{ value: 'M', label: 'M' },
|
||||
{ value: '2M', label: '2M' },
|
||||
{ value: '4M', label: '4M' },
|
||||
{ value: '6M', label: '6M' },
|
||||
{ value: 'Y', label: 'Y' }
|
||||
]).v((value, configuration, configDescription, parameters) => {
|
||||
return !configuration.chartType
|
||||
})
|
||||
])
|
||||
.params(ChartParameters())
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
import { po } from '../helpers'
|
||||
|
||||
export default () => [
|
||||
po('chartType', 'Chart Type', 'Define a fixed period for the chart, aligned at the beginning of the period, e.g. January 1st at midnight for a year chart. If not set (or set to dynamic), the length of the period will be configurable but certain combinations like aggregated series might not work', [
|
||||
{ value: '', label: 'Dynamic period' },
|
||||
{ value: 'day', label: 'Day' },
|
||||
{ value: 'isoWeek', label: 'Week (starting on Monday)' },
|
||||
{ value: 'week', label: 'Week (starting on Sunday)' },
|
||||
{ value: 'month', label: 'Month' },
|
||||
{ value: 'year', label: 'Year' }
|
||||
]).r(),
|
||||
po('period', 'Initial Period', 'The initial period for the chart', [
|
||||
{ value: 'h', label: 'h' },
|
||||
{ value: '2h', label: '2h' },
|
||||
{ value: '4h', label: '4h' },
|
||||
{ value: '12h', label: '12h' },
|
||||
{ value: 'D', label: 'D' },
|
||||
{ value: '2D', label: '2D' },
|
||||
{ value: '3D', label: '3D' },
|
||||
{ value: 'W', label: 'W' },
|
||||
{ value: '2W', label: '2W' },
|
||||
{ value: 'M', label: 'M' },
|
||||
{ value: '2M', label: '2M' },
|
||||
{ value: '4M', label: '4M' },
|
||||
{ value: '6M', label: '6M' },
|
||||
{ value: 'Y', label: 'Y' }
|
||||
]).v((value, configuration, configDescription, parameters) => {
|
||||
return !configuration.chartType
|
||||
})
|
||||
]
|
|
@ -9,6 +9,10 @@ export const OhButtonDefinition = () => new WidgetDefinition('oh-button', 'Butto
|
|||
.paramGroup(actionGroup(), actionParams())
|
||||
.params([...ButtonParameters(), VariableParameter, ClearVariableParameter])
|
||||
|
||||
import ChartParameters from './chart'
|
||||
export const OhChartDefinition = () => new WidgetDefinition('oh-chart', 'Chart', 'Visualize series of data')
|
||||
.params(ChartParameters())
|
||||
|
||||
import ColorpickerParameters from './colorpicker'
|
||||
export const OhColorpickerDefinition = () => new WidgetDefinition('oh-colorpicker', 'Colorpicker', 'Control to pick a color')
|
||||
.params(ColorpickerParameters())
|
||||
|
|
|
@ -23,7 +23,7 @@ function getWidgetDefinitions (cm) {
|
|||
switch (componentType) {
|
||||
case 'chart':
|
||||
return [
|
||||
OhChartPageDefinition,
|
||||
OhChartPageDefinition(),
|
||||
...Object.keys(ChartWidgetsDefinitions).map((name) => {
|
||||
return Object.assign({}, ChartWidgetsDefinitions[name], { name })
|
||||
})
|
||||
|
@ -39,7 +39,10 @@ function getWidgetDefinitions (cm) {
|
|||
return [
|
||||
...(componentType === 'home') ? [OhLocationCardParameters(), OhEquipmentCardParameters(), OhPropertyCardParameters()] : [],
|
||||
...ohComponents.map((c) => c.widget()).sort((c1, c2) => c1.name.localeCompare(c2.name)),
|
||||
...f7Components.sort((c1, c2) => c1.name.localeCompare(c2.name))
|
||||
...f7Components.sort((c1, c2) => c1.name.localeCompare(c2.name)),
|
||||
...Object.keys(ChartWidgetsDefinitions).map((name) => {
|
||||
return Object.assign({}, ChartWidgetsDefinitions[name], { name })
|
||||
})
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ export default {
|
|||
confine: true,
|
||||
position: [10, 10]
|
||||
},
|
||||
backgroundColor: (this.$f7.data.themeOptions.dark === 'dark') ? '#121212' : undefined,
|
||||
series: this.series
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +94,7 @@ export default {
|
|||
}
|
||||
}
|
||||
return this.$oh.api.get('/rest/things').then((data) => {
|
||||
let zWaveNodes = data.filter((t) => t.properties && t.properties.zwave_nodeid)
|
||||
let zWaveNodes = data.filter((t) => t.properties && t.properties.zwave_nodeid && t.properties.zwave_neighbours)
|
||||
|
||||
zWaveNodes.forEach((t) => {
|
||||
let nodeid = t.properties.zwave_nodeid
|
||||
|
|
|
@ -9,6 +9,7 @@ import OhCalendarAxis from './axis/oh-calendar-axis'
|
|||
import OhCategoryAxis from './axis/oh-category-axis'
|
||||
|
||||
// Series components
|
||||
import OhDataSeries from './series/oh-data-series'
|
||||
import OhTimeSeries from './series/oh-time-series'
|
||||
import OhAggregateSeries from './series/oh-aggregate-series'
|
||||
import OhCalendarSeries from './series/oh-calendar-series'
|
||||
|
@ -29,6 +30,7 @@ const axisComponents = {
|
|||
}
|
||||
|
||||
const seriesComponents = {
|
||||
'oh-data-series': OhDataSeries,
|
||||
'oh-time-series': OhTimeSeries,
|
||||
'oh-aggregate-series': OhAggregateSeries,
|
||||
'oh-calendar-series': OhCalendarSeries
|
||||
|
@ -36,8 +38,9 @@ const seriesComponents = {
|
|||
|
||||
export default {
|
||||
data () {
|
||||
const chartType = this.context.component.config.chartType
|
||||
const period = this.context.component.config.period || 'D'
|
||||
const config = this.context.component.config || {}
|
||||
const chartType = config.chartType
|
||||
const period = config.period || 'D'
|
||||
let endTime = (chartType) ? this.addOrSubtractPeriod(dayjs().startOf(chartType), 1) : dayjs()
|
||||
return {
|
||||
items: {},
|
||||
|
@ -51,7 +54,11 @@ export default {
|
|||
return this.addOrSubtractPeriod(this.endTime, -1)
|
||||
},
|
||||
options () {
|
||||
if (!this.config) return {}
|
||||
const chartConfig = this.config.options || {}
|
||||
if (!chartConfig.backgroundColor && this.$f7.data.themeOptions.dark === 'dark') {
|
||||
chartConfig.backgroundColor = '#121212'
|
||||
}
|
||||
return {
|
||||
...chartConfig,
|
||||
grid: this.grid,
|
||||
|
@ -121,7 +128,13 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
getSeriesPromises (component) {
|
||||
const getter = (data) => seriesComponents[component.component].get(component, data.map((d) => d[1]), this.startTime, this.endTime, this)
|
||||
|
||||
const neededItems = seriesComponents[component.component].neededItems(component).filter(i => !!i)
|
||||
if (neededItems.length === 0) {
|
||||
return Promise.resolve(getter([]))
|
||||
}
|
||||
|
||||
const itemPromises = neededItems.map((neededItem) => {
|
||||
if (this.items[neededItem]) return Promise.resolve(this.items[neededItem])
|
||||
return this.$oh.api.get(`/rest/items/${neededItem}`).then((item) => {
|
||||
|
@ -147,9 +160,7 @@ export default {
|
|||
return Promise.all([itemPromises[neededItem], this.$oh.api.get(url, query)])
|
||||
})
|
||||
|
||||
return Promise.all(combinedPromises).then((data) => {
|
||||
return seriesComponents[component.component].get(component, data.map((d) => d[1]), this.startTime, this.endTime, this)
|
||||
})
|
||||
return Promise.all(combinedPromises).then(getter)
|
||||
},
|
||||
setPeriod (period) {
|
||||
this.period = period
|
||||
|
@ -167,6 +178,7 @@ export default {
|
|||
this.endTime = this.addOrSubtractPeriod(this.endTime, 1)
|
||||
},
|
||||
addOrSubtractPeriod (day, direction) {
|
||||
if (!this.context.component.config) return
|
||||
const fn = (direction < 0) ? day.subtract : day.add
|
||||
const chartType = this.context.component.config.chartType
|
||||
for (let i = 0; i < Math.abs(direction); i++) {
|
||||
|
|
|
@ -1,31 +1,13 @@
|
|||
<template>
|
||||
<div>
|
||||
<chart
|
||||
ref="chart"
|
||||
v-if="ready"
|
||||
:options="options"
|
||||
class="oh-chart-page-chart"
|
||||
:class="{ 'with-tabbar': context.tab, 'with-toolbar': context.analyzer }"
|
||||
:theme="$f7.data.themeOptions.dark === 'dark' ? 'dark' : undefined" autoresize></chart>
|
||||
<f7-menu class="padding float-right">
|
||||
<f7-menu-item @click="earlierPeriod()" icon-f7="chevron_left" />
|
||||
<f7-menu-item v-if="context.component.config.chartType" :text="fixedPeriodLabel" type="text" @click="pickFixedStartDate">
|
||||
<input ref="calendarInput" type="text" style="width: 40px; height: 0; visibility: hidden">
|
||||
</f7-menu-item>
|
||||
<f7-menu-item v-else dropdown :text="period">
|
||||
<f7-menu-dropdown right>
|
||||
<f7-menu-dropdown-item v-for="p in ['h', '2h', '4h', '12h', 'D', '2D', '3D', 'W', '2W', 'M', '2M', '4M', '6M', 'Y']"
|
||||
:key="p" @click="setPeriod(p)" href="#" :text="p"></f7-menu-dropdown-item>
|
||||
</f7-menu-dropdown>
|
||||
</f7-menu-item>
|
||||
<f7-menu-item @click="laterPeriod()" icon-f7="chevron_right" />
|
||||
</f7-menu>
|
||||
</div>
|
||||
<oh-chart
|
||||
class="oh-chart-page-chart"
|
||||
:class="{ 'with-tabbar': context.tab, 'with-toolbar': context.analyzer }"
|
||||
:context="this.context" />
|
||||
</template>
|
||||
|
||||
<style lang="stylus">
|
||||
.oh-chart-page-chart
|
||||
position absolute
|
||||
position absolute !important
|
||||
background-color white
|
||||
overflow-x hidden
|
||||
top calc(var(--f7-safe-area-top) + var(--f7-navbar-height))
|
||||
|
@ -35,97 +17,20 @@
|
|||
height calc(100% - var(--f7-safe-area-top) - var(--f7-safe-area-bottom) - var(--f7-navbar-height) - var(--f7-tabbar-labels-height)) !important
|
||||
&.with-toolbar
|
||||
height calc(100% - var(--f7-safe-area-top) - var(--f7-safe-area-bottom) - var(--f7-navbar-height) - var(--f7-toolbar-height)) !important
|
||||
&.with-sheet
|
||||
&.sheet-opened
|
||||
height calc(100% - var(--f7-safe-area-top) - var(--f7-safe-area-bottom) - var(--f7-navbar-height) - var(--f7-sheet-height)) !important
|
||||
.echarts
|
||||
width calc(100% - 20px)
|
||||
height 100%
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import mixin from '../widget-mixin'
|
||||
import chart from './chart-mixin'
|
||||
|
||||
import dayjs from 'dayjs'
|
||||
import LocalizedFormat from 'dayjs/plugin/localizedFormat'
|
||||
dayjs.extend(LocalizedFormat)
|
||||
|
||||
// import echarts from 'echarts/lib/echarts'
|
||||
import 'echarts/lib/chart/line'
|
||||
import 'echarts/lib/chart/bar'
|
||||
import 'echarts/lib/chart/heatmap'
|
||||
import 'echarts/lib/chart/scatter'
|
||||
import 'echarts/lib/component/title'
|
||||
import 'echarts/lib/component/legend'
|
||||
import 'echarts/lib/component/legendScroll'
|
||||
import 'echarts/lib/component/toolbox'
|
||||
import 'echarts/lib/component/tooltip'
|
||||
import 'echarts/lib/component/dataZoom'
|
||||
import 'echarts/lib/component/markLine'
|
||||
import 'echarts/lib/component/markPoint'
|
||||
import 'echarts/lib/component/markArea'
|
||||
import 'echarts/lib/component/visualMap'
|
||||
import 'echarts/lib/component/calendar'
|
||||
|
||||
import ECharts from 'vue-echarts/components/ECharts'
|
||||
import OhChart from '../system/oh-chart.vue'
|
||||
import { OhChartPageDefinition } from '@/assets/definitions/widgets/chart/page'
|
||||
|
||||
export default {
|
||||
mixins: [mixin, chart],
|
||||
mixins: [mixin],
|
||||
components: {
|
||||
'chart': ECharts
|
||||
OhChart
|
||||
},
|
||||
widget: OhChartPageDefinition,
|
||||
computed: {
|
||||
fixedPeriodLabel () {
|
||||
const startTime = this.startTime
|
||||
if (!this.startTime) return ''
|
||||
switch (this.context.component.config.chartType) {
|
||||
case 'hour':
|
||||
return startTime.format('lll')
|
||||
case 'day':
|
||||
return startTime.format('ll')
|
||||
case 'week':
|
||||
case 'isoWeek':
|
||||
return startTime.format('ll')
|
||||
case 'month':
|
||||
return startTime.format('MMM YYYY')
|
||||
case 'year':
|
||||
return startTime.format('YYYY')
|
||||
default:
|
||||
return startTime.format('ll')
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
ready: false,
|
||||
calendarPicker: null
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.ready = true
|
||||
},
|
||||
beforeDestroy () {
|
||||
if (this.calendarPicker) this.calendarPicker.destroy()
|
||||
},
|
||||
methods: {
|
||||
pickFixedStartDate (evt) {
|
||||
const self = this
|
||||
const value = this.startTime.toDate()
|
||||
this.calendarPicker = this.$f7.calendar.create({
|
||||
inputEl: this.$refs.calendarInput,
|
||||
value: [value],
|
||||
on: {
|
||||
change (calendar, value) {
|
||||
if (value.length < 1) return
|
||||
if (dayjs(value[0]).isSame(self.startTime)) return
|
||||
self.setDate(value[0])
|
||||
}
|
||||
}
|
||||
})
|
||||
this.calendarPicker.open()
|
||||
}
|
||||
}
|
||||
widget: OhChartPageDefinition
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import Framework7 from 'framework7'
|
||||
|
||||
export default {
|
||||
neededItems () {
|
||||
return []
|
||||
},
|
||||
get (component, points, startTime, endTime, chart) {
|
||||
if (!component.config || typeof component.config !== 'object') return {}
|
||||
|
||||
if (!component.dataSeriesId) {
|
||||
component.dataSeriesId = Framework7.utils.id()
|
||||
}
|
||||
|
||||
let series = chart.evaluateExpression(component.dataSeriesId, component.config)
|
||||
|
||||
if (series.data && Array.isArray(series.data)) {
|
||||
series.data = series.data.map((v, index) => {
|
||||
const item = chart.evaluateExpression(component.dataSeriesId + 'data.' + index, v)
|
||||
return Number.isNaN(item.value) ? {} : item
|
||||
})
|
||||
}
|
||||
|
||||
if (series.axisLine && series.axisLine.lineStyle && series.axisLine.lineStyle.color && Array.isArray(series.axisLine.lineStyle.color)) {
|
||||
series.axisLine.lineStyle.color = series.axisLine.lineStyle.color.map((v, index) => {
|
||||
if (!Array.isArray(v)) return v
|
||||
return v.map((s, subindex) => chart.evaluateExpression(component.dataSeriesId + 'axisLine.lineStyle.color.' + index + '.' + subindex, s))
|
||||
})
|
||||
}
|
||||
|
||||
return series
|
||||
}
|
||||
}
|
|
@ -19,3 +19,4 @@ export { default as OhSwiperSlide } from './oh-swiper-slide.vue'
|
|||
export { default as OhTrend } from './oh-trend.vue'
|
||||
export { default as OhWebframe } from './oh-webframe.vue'
|
||||
export { default as OhRepeater } from './oh-repeater.vue'
|
||||
export { default as OhChart } from './oh-chart.vue'
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
<template>
|
||||
<div class="oh-chart-container" v-bind:style="{ height: activeHeight }">
|
||||
<chart
|
||||
ref="chart"
|
||||
v-if="ready"
|
||||
:options="options"
|
||||
class="oh-chart"
|
||||
:class="{ 'with-tabbar': context.tab, 'with-toolbar': context.analyzer }"
|
||||
:theme="$f7.data.themeOptions.dark === 'dark' ? 'dark' : undefined" autoresize></chart>
|
||||
<f7-menu class="padding float-right" v-if="periodVisible">
|
||||
<f7-menu-item @click="earlierPeriod()" icon-f7="chevron_left" />
|
||||
<f7-menu-item v-if="context.component.config.chartType" :text="fixedPeriodLabel" type="text" @click="pickFixedStartDate">
|
||||
<input ref="calendarInput" type="text" style="width: 40px; height: 0; visibility: hidden">
|
||||
</f7-menu-item>
|
||||
<f7-menu-item v-else dropdown :text="period">
|
||||
<f7-menu-dropdown right>
|
||||
<f7-menu-dropdown-item v-for="p in ['h', '2h', '4h', '12h', 'D', '2D', '3D', 'W', '2W', 'M', '2M', '4M', '6M', 'Y']"
|
||||
:key="p" @click="setPeriod(p)" href="#" :text="p"></f7-menu-dropdown-item>
|
||||
</f7-menu-dropdown>
|
||||
</f7-menu-item>
|
||||
<f7-menu-item @click="laterPeriod()" icon-f7="chevron_right" />
|
||||
</f7-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="stylus">
|
||||
.oh-chart-container
|
||||
position relative
|
||||
.oh-chart
|
||||
position absolute
|
||||
width 100%
|
||||
height 100%
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import mixin from '../widget-mixin'
|
||||
import chart from '../chart/chart-mixin'
|
||||
|
||||
import dayjs from 'dayjs'
|
||||
import LocalizedFormat from 'dayjs/plugin/localizedFormat'
|
||||
dayjs.extend(LocalizedFormat)
|
||||
|
||||
// import echarts from 'echarts/lib/echarts'
|
||||
import 'echarts/lib/chart/line'
|
||||
import 'echarts/lib/chart/bar'
|
||||
import 'echarts/lib/chart/gauge'
|
||||
import 'echarts/lib/chart/heatmap'
|
||||
import 'echarts/lib/chart/scatter'
|
||||
import 'echarts/lib/component/title'
|
||||
import 'echarts/lib/component/legend'
|
||||
import 'echarts/lib/component/legendScroll'
|
||||
import 'echarts/lib/component/toolbox'
|
||||
import 'echarts/lib/component/tooltip'
|
||||
import 'echarts/lib/component/dataZoom'
|
||||
import 'echarts/lib/component/markLine'
|
||||
import 'echarts/lib/component/markPoint'
|
||||
import 'echarts/lib/component/markArea'
|
||||
import 'echarts/lib/component/visualMap'
|
||||
import 'echarts/lib/component/calendar'
|
||||
|
||||
import ECharts from 'vue-echarts/components/ECharts'
|
||||
|
||||
export default {
|
||||
mixins: [mixin, chart],
|
||||
components: {
|
||||
'chart': ECharts
|
||||
},
|
||||
computed: {
|
||||
activeHeight () {
|
||||
const config = this.config || {}
|
||||
return config.height || '300px'
|
||||
},
|
||||
periodVisible () {
|
||||
if (!this.config || this.config.periodVisible === undefined) {
|
||||
if (this.context.component.slots && this.context.component.slots.series && Array.isArray(this.context.component.slots.series) && this.context.component.slots.series.length) {
|
||||
return this.context.component.slots.series[0].component !== 'oh-data-series'
|
||||
}
|
||||
return true
|
||||
}
|
||||
return this.config.periodVisible
|
||||
},
|
||||
fixedPeriodLabel () {
|
||||
const startTime = this.startTime
|
||||
if (!this.startTime) return ''
|
||||
switch (this.context.component.config.chartType) {
|
||||
case 'hour':
|
||||
return startTime.format('lll')
|
||||
case 'day':
|
||||
return startTime.format('ll')
|
||||
case 'week':
|
||||
case 'isoWeek':
|
||||
return startTime.format('ll')
|
||||
case 'month':
|
||||
return startTime.format('MMM YYYY')
|
||||
case 'year':
|
||||
return startTime.format('YYYY')
|
||||
default:
|
||||
return startTime.format('ll')
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
ready: false,
|
||||
calendarPicker: null
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.ready = true
|
||||
},
|
||||
beforeDestroy () {
|
||||
if (this.calendarPicker) this.calendarPicker.destroy()
|
||||
},
|
||||
methods: {
|
||||
pickFixedStartDate (evt) {
|
||||
const self = this
|
||||
const value = this.startTime.toDate()
|
||||
this.calendarPicker = this.$f7.calendar.create({
|
||||
inputEl: this.$refs.calendarInput,
|
||||
value: [value],
|
||||
on: {
|
||||
change (calendar, value) {
|
||||
if (value.length < 1) return
|
||||
if (dayjs(value[0]).isSame(self.startTime)) return
|
||||
self.setDate(value[0])
|
||||
}
|
||||
}
|
||||
})
|
||||
this.calendarPicker.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,16 @@
|
|||
<template>
|
||||
<oh-chart-component :context="this.context" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../widget-mixin'
|
||||
import { OhChartDefinition } from '@/assets/definitions/widgets/system'
|
||||
|
||||
export default {
|
||||
mixins: [mixin],
|
||||
components: {
|
||||
'oh-chart-component': () => import(/* webpackChunkName: "oh-chart-component" */ './oh-chart-component.vue')
|
||||
},
|
||||
widget: OhChartDefinition
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue