From 0eacea3d509fcc62a66701efd08866efcdab435f Mon Sep 17 00:00:00 2001 From: Mathis Neumann <mathis@simpletechs.net> Date: Mon, 25 Apr 2016 18:49:49 +0200 Subject: [PATCH] more node and change graph every several seconds to simulate socket updates --- app/components/architecture-visualisation.js | 45 ++++++- app/router.js | 1 + app/routes/architecture.js | 121 ++++++++++++++++++- app/styles/app.scss | 25 +--- app/styles/components/_architecture.scss | 49 ++++++-- app/templates/application.hbs | 5 +- 6 files changed, 204 insertions(+), 42 deletions(-) diff --git a/app/components/architecture-visualisation.js b/app/components/architecture-visualisation.js index 999db59..95031c2 100644 --- a/app/components/architecture-visualisation.js +++ b/app/components/architecture-visualisation.js @@ -4,6 +4,36 @@ import klay from 'npm:klayjs-d3'; import _ from 'npm:lodash'; export default Ember.Component.extend({ + init: function() { + this._super(); + const self = this; + const log = self.debug.bind(self); + this.interval = setInterval(function() { + const graph = self.get('graph'); + + log('update interval called', graph); + + if(!graph) { + return; // eventual consistent + } + const edges = graph.edges || []; + const index = Math.floor(Math.random()*edges.length); + if(Math.random() > 0.5) { + edges.splice(index, 1); + } else { // FIXME: does not render updates + const children = _.get(graph, 'children', []); + const randomNodeIndex = Math.floor(Math.random()*children.length); + const randomNodeId = children[randomNodeIndex].id; + graph.edges = _.set(edges, `${index}.target`, randomNodeId); + log(`updating random edge (${index}) to target a random node id ${randomNodeId}`, randomNodeIndex, edges); + } + self.set('graph', graph); + self.renderGraph(); + }, 1000); + }, + willDestroyElement() { + clearInterval(this.interval); + }, didInsertElement: function() { const log = this.debug.bind(this); const width = window.innerWidth; @@ -17,10 +47,11 @@ export default Ember.Component.extend({ .attr("width", width) .attr("height", height) .attr('class', 'architectureVisualisation') - // .call(zoom) + .call(zoom) .append("g"); - const root = svg.append("g"); + const root = svg.append('g').attr('class', 'root'); + this.svg = svg; this.layouter = klay.d3kgraph() .size([width, height]) .transformGroup(root) @@ -46,6 +77,9 @@ export default Ember.Component.extend({ .append('g') .attr('class', d => d.children? 'node compound' : 'node leaf'); + nodeData.exit() + .remove(); + const atoms = node.append('rect') .attr('width', 10) .attr('height', 10) @@ -63,6 +97,7 @@ export default Ember.Component.extend({ .attr('font-size', '4px'); + // FIXME does not handle updates (neither enter() nor exit()) const linkData = root.selectAll('.link') .data(links, p => p.id); const link = linkData.enter() @@ -70,6 +105,9 @@ export default Ember.Component.extend({ .attr('class', 'link') .attr('d', 'M0 0'); + linkData.exit() + .remove(); + // apply edge routes link.transition().attr('d', (d) => { let path = ''; @@ -88,6 +126,9 @@ export default Ember.Component.extend({ .attr('height', (d) => d.height); }; this.layouter.on('finish', onFinish); + this.renderGraph(); + }, + renderGraph() { this.layouter.kgraph(this.get('graph')); } }); diff --git a/app/router.js b/app/router.js index 42acc41..f6c0454 100644 --- a/app/router.js +++ b/app/router.js @@ -6,6 +6,7 @@ const Router = Ember.Router.extend({ }); Router.map(function() { + this.route('home', {path: '/'}); this.route('architecture', {path: '/architecture'}); }); diff --git a/app/routes/architecture.js b/app/routes/architecture.js index ac893ce..d78a1ba 100644 --- a/app/routes/architecture.js +++ b/app/routes/architecture.js @@ -5,12 +5,41 @@ export default Ember.Route.extend({ return { id: 'root', labels: [{text: 'My Architecture'}], + 'properties': { + 'direction': 'RIGHT', + 'spacing': 10 + }, children: [{ + id: 'VM_Profile', + children: [{ + id: 'VM_Profile>Database', + labels: [{text: 'Profile DB'}], + width: 20, + height: 20 + }] + }, + { id: 'VM_Big', children: [{ - id: 'VM_Big>Auth' + id: 'VM_Big>Auth', + width: 20, + height: 20 }, { - id: 'VM_Big>User' + id: 'VM_Big>User', + width: 20, + height: 20 + }, { + id: 'VM_Big>User2', + width: 20, + height: 20 + }, { + id: 'VM_Big>User3', + width: 20, + height: 20 + }, { + id: 'VM_Big>User4', + width: 20, + height: 20 }], edges: [{ id: 'VM_Big>Auth->VM_Big>User', @@ -23,28 +52,72 @@ export default Ember.Route.extend({ id: 'VM_1', children: [{ id: 'VM_1>Auth', - labels: [{text: "Auth 1"}] + labels: [{text: 'Auth 1'}], + width: 20, + height: 20 }] }, { id: 'VM_2', children: [{ id: 'VM_2>Auth', - labels: [{text: "Auth 2"}] + labels: [{text: 'Auth 2'}], + width: 20, + height: 20 }] }, { id: 'VM_3', children: [{ id: 'VM_3>User', - labels: [{text: "User 1"}] + labels: [{text: 'User 1'}], + width: 20, + height: 20 }] }, { id: 'VM_4', children: [{ id: 'VM_4>User', - labels: [{text: "User 2"}] + labels: [{text: 'User 2'}], + width: 20, + height: 20 + }] + }, + { + id: 'VM_5', + children: [{ + id: 'VM_5>User', + labels: [{text: 'User 2'}], + width: 20, + height: 20 + }] + }, + { + id: 'VM_6', + children: [{ + id: 'VM_6>User', + labels: [{text: 'User 2'}], + width: 20, + height: 20 + }] + }, + { + id: 'VM_7', + children: [{ + id: 'VM_7>User', + labels: [{text: 'User 2'}], + width: 20, + height: 20 + }] + }, + { + id: 'VM_8', + children: [{ + id: 'VM_8>User', + labels: [{text: 'User 2'}], + width: 20, + height: 20 }] }], edges: [{ @@ -55,6 +128,42 @@ export default Ember.Route.extend({ id: 'VM_2>Auth->VM_4>User', source: 'VM_2>Auth', target: 'VM_4>User', + }, { + id: 'VM_Big>User->VM_Profile>Database', + source: 'VM_Big>User', + target: 'VM_Profile>Database', + }, { + id: 'VM_2>Auth->VM_Profile>Database', + source: 'VM_2>Auth', + target: 'VM_Profile>Database', + }, { + id: 'VM_1>Auth->VM_Profile>Database', + source: 'VM_1>Auth', + target: 'VM_Profile>Database', + }, { + id: 'VM_3>User->VM_Profile>Database', + source: 'VM_3>User', + target: 'VM_Profile>Database', + }, { + id: 'VM_4>User->VM_Profile>Database', + source: 'VM_4>User', + target: 'VM_Profile>Database', + }, { + id: 'VM_5>User->VM_Profile>Database', + source: 'VM_5>User', + target: 'VM_Profile>Database', + }, { + id: 'VM_6>User->VM_Profile>Database', + source: 'VM_6>User', + target: 'VM_Profile>Database', + }, { + id: 'VM_7>User->VM_Profile>Database', + source: 'VM_7>User', + target: 'VM_Profile>Database', + }, { + id: 'VM_8>User->VM_Profile>Database', + source: 'VM_8>User', + target: 'VM_Profile>Database', }] }; } diff --git a/app/styles/app.scss b/app/styles/app.scss index 22c865c..1c11d30 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -1,29 +1,6 @@ -@import "components/_architecture"; - body { font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; } -g.leaf > rect { - stroke: #fff; - stroke-width: 1px; - opacity: .5; -} - -g.compound > rect { - opacity: 0.1; -} -.node { -} - -.link { - stroke: #999; - stroke-opacity: .6; - fill: none; -} +@import "components/_architecture"; -.port { - stroke: #000; - width: 1px; - opacity: .6; -} diff --git a/app/styles/components/_architecture.scss b/app/styles/components/_architecture.scss index e7d390a..4a98a5e 100644 --- a/app/styles/components/_architecture.scss +++ b/app/styles/components/_architecture.scss @@ -1,12 +1,43 @@ svg.architectureVisualisation { - g.compound > rect:hover { - stroke: white; - stroke-opacity: 1; - fill: red; - } - .link:hover { - stroke: #A000; - stroke-opacity: 1; - fill: black; + .root { + g.compound { + &:first-child rect { // hide root compound + opacity: 0; + } + + & > rect { + opacity: 0.1; + + &:hover { + stroke: white; + stroke-opacity: 1; + fill: red; + } + } + } + } + .link { + stroke: #999; + stroke-opacity: .6; + fill: none; + stroke-width: 2px; + + &:hover { + stroke: #A000; + stroke-opacity: 1; + } + } + g.leaf > rect { + stroke: #fff; + stroke-width: 1px; + opacity: .5; + } + + // .node {} + + .port { + stroke: #000; + width: 1px; + opacity: .6; } } \ No newline at end of file diff --git a/app/templates/application.hbs b/app/templates/application.hbs index 3f1cdac..c009e1f 100644 --- a/app/templates/application.hbs +++ b/app/templates/application.hbs @@ -1,4 +1,7 @@ <h2 id="title">Welcome to Ember</h2> -<h3>Go to {{#link-to 'architecture'}}Klay-based Architecture{{/link-to}}</h3> +<ul> + <li>Go to {{#link-to 'home'}}Home{{/link-to}}</li> + <li>Go to {{#link-to 'architecture'}}Klay-based Architecture{{/link-to}}</li> +</ul> {{outlet}} -- GitLab