From 5c73aa4b94eea29d2cea03a5be623a3093d1d0f9 Mon Sep 17 00:00:00 2001 From: Daniel Lando Date: Thu, 2 Jan 2020 11:52:15 +0100 Subject: [PATCH] feat: Mesh graph showing node neighbors --- package-lock.json | 39 +++++++ package.json | 1 + src/App.vue | 20 +++- src/assets/css/my-mesh.css | 19 ++++ src/assets/css/my-progress.css | 24 +++++ src/components/ControlPanel.vue | 20 +--- src/components/Mesh.vue | 184 ++++++++++++++++++++++++++++++++ src/main.js | 2 + src/router/index.js | 7 ++ 9 files changed, 299 insertions(+), 17 deletions(-) create mode 100644 src/assets/css/my-mesh.css create mode 100644 src/components/Mesh.vue diff --git a/package-lock.json b/package-lock.json index e666a635531..bb6042a7447 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2990,6 +2990,37 @@ "es5-ext": "^0.10.9" } }, + "d3-collection": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", + "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" + }, + "d3-dispatch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz", + "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA==" + }, + "d3-force": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.2.1.tgz", + "integrity": "sha512-HHvehyaiUlVo5CxBJ0yF/xny4xoaxFxDnBXNvNcfW9adORGZfyNF1dj6DGLKyk4Yh3brP/1h3rnDzdIAwL08zg==", + "requires": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-quadtree": "1", + "d3-timer": "1" + } + }, + "d3-quadtree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz", + "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA==" + }, + "d3-timer": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz", + "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==" + }, "date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", @@ -12120,6 +12151,14 @@ "resolved": "https://registry.npmjs.org/vue/-/vue-2.5.22.tgz", "integrity": "sha512-pxY3ZHlXNJMFQbkjEgGVMaMMkSV1ONpz+4qB55kZuJzyJOhn6MSy/YZdzhdnumegNzVTL/Dn3Pp4UrVBYt1j/g==" }, + "vue-d3-network": { + "version": "0.1.28", + "resolved": "https://registry.npmjs.org/vue-d3-network/-/vue-d3-network-0.1.28.tgz", + "integrity": "sha512-36Id0gT/fMEK0i+rV7ikAbqXdB0wDHK9cBOlXDjLK2FYBB8yAExN82dYsmTF4GPiGx59hsQV/MvgWmercRjDww==", + "requires": { + "d3-force": "^1.0.6" + } + }, "vue-eslint-parser": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz", diff --git a/package.json b/package.json index bc1315a8a18..8166725ab08 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "tail": "^2.0.2", "uniqid": "^4.1.1", "vue": "^2.5.2", + "vue-d3-network": "^0.1.28", "vue-router": "^3.0.1", "vuetify": "^1.0.1", "vuex": "^3.0.1" diff --git a/src/App.vue b/src/App.vue index 97f7b12e00b..3f6254bfdd8 100644 --- a/src/App.vue +++ b/src/App.vue @@ -57,6 +57,8 @@ @export="exportConfiguration" @showSnackbar="showSnackbar" :socket="socket" + :socketEvents="socketEvents" + :socketActions="socketActions" /> @@ -162,8 +164,24 @@ export default { version: process.env.VERSION, pages: [ { icon: 'widgets', title: 'Control Panel', path: '/' }, - { icon: 'settings', title: 'Settings', path: '/settings' } + { icon: 'settings', title: 'Settings', path: '/settings' }, + { icon: 'share', title: 'Network graph', path: '/mesh' } ], + socketEvents: { + init: 'INIT', + controller: 'CONTROLLER_CMD', + driver: 'DRIVER_READY', + nodeRemoved: 'NODE_REMOVED', + nodeUpdated: 'NODE_UPDATED', + valueUpdated: 'VALUE_UPDATED', + api: 'API_RETURN', + debug: 'DEBUG' + }, + socketActions: { + init: 'INITED', + hass: 'HASS_API', + zwave: 'ZWAVE_API' + }, status: '', statusColor: '', drawer: false, diff --git a/src/assets/css/my-mesh.css b/src/assets/css/my-mesh.css new file mode 100644 index 00000000000..a4917525a92 --- /dev/null +++ b/src/assets/css/my-mesh.css @@ -0,0 +1,19 @@ +.node.controller { + stroke: purple; +} + +.node.sleep { + stroke: yellow; +} + +.node.alive { + stroke: green; +} + +.node.failed .node.removed { + stroke: black; +} + +.node.dead { + stroke: red; +} \ No newline at end of file diff --git a/src/assets/css/my-progress.css b/src/assets/css/my-progress.css index 2074ccf4513..2bd00bab850 100644 --- a/src/assets/css/my-progress.css +++ b/src/assets/css/my-progress.css @@ -1,3 +1,27 @@ #nprogress .spinner { right: 50% !important; } + +::-webkit-scrollbar { + height: 5px; + width: 4px; + background: transparent; + padding-right: 10; +} + +::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.05); + border-radius: 1ex; + -webkit-border-radius: 1ex; +} + +::-webkit-scrollbar-corner { + background: transparent; +} + +/* Hacky hack. Remove scrollbars for 320 width screens */ +@media screen and (max-width : 320px) { + body::-webkit-scrollbar { + display: none; + } +} diff --git a/src/components/ControlPanel.vue b/src/components/ControlPanel.vue index 699f2a72be7..41b5f013f85 100644 --- a/src/components/ControlPanel.vue +++ b/src/components/ControlPanel.vue @@ -457,7 +457,9 @@ const MAX_DEBUG_LINES = 300 export default { name: 'ControlPanel', props: { - socket: Object + socket: Object, + socketActions: Object, + socketEvents: Object }, components: { ValueID, @@ -545,21 +547,6 @@ export default { debugActive: false, selectedScene: null, cnt_status: 'Unknown', - socketEvents: { - init: 'INIT', - controller: 'CONTROLLER_CMD', - driver: 'DRIVER_READY', - nodeRemoved: 'NODE_REMOVED', - nodeUpdated: 'NODE_UPDATED', - valueUpdated: 'VALUE_UPDATED', - api: 'API_RETURN', - debug: 'DEBUG' - }, - socketActions: { - init: 'INITED', - hass: 'HASS_API', - zwave: 'ZWAVE_API' - }, newScene: '', scene_values: [], dialogValue: false, @@ -773,6 +760,7 @@ export default { self.apiRequest('setScenes', [scenes]) } else { self.showSnackbar('Imported file not valid') + console.log(err) } }) } diff --git a/src/components/Mesh.vue b/src/components/Mesh.vue new file mode 100644 index 00000000000..48f4b28b0ea --- /dev/null +++ b/src/components/Mesh.vue @@ -0,0 +1,184 @@ + + diff --git a/src/main.js b/src/main.js index 13f73dd85a3..16582b3ddeb 100644 --- a/src/main.js +++ b/src/main.js @@ -11,9 +11,11 @@ import Vuetify from 'vuetify' import 'vuetify/dist/vuetify.min.css' import 'axios-progress-bar/dist/nprogress.css' +import 'vue-d3-network/dist/vue-d3-network.css' // Custom assets CSS JS require('./assets/css/my-progress.css') +require('./assets/css/my-mesh.css') Vue.use(Vuetify) diff --git a/src/router/index.js b/src/router/index.js index f3980cf7608..0c48e8c7b94 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -2,6 +2,7 @@ import Vue from 'vue' import Router from 'vue-router' import ControlPanel from '@/components/ControlPanel' import Settings from '@/components/Settings' +import Mesh from '@/components/Mesh' Vue.use(Router) @@ -19,6 +20,12 @@ export default new Router({ name: 'Settings', component: Settings, props: true + }, + { + path: '/mesh', + name: 'Mesh', + component: Mesh, + props: true } ] })