blob: b7d1be83a8e00ef34eac2e8dfa749b8a9e82100f [file] [log] [blame]
Matteo Scandolobe9b13d2016-01-21 11:21:03 -08001(function () {
2 'use strict';
3
4 angular.module('xos.serviceTopology')
5 .directive('serviceCanvas', function(){
6 return {
7 restrict: 'E',
8 scope: {},
9 bindToController: true,
10 controllerAs: 'vm',
11 templateUrl: 'templates/topology_canvas.tpl.html',
Matteo Scandolo68236262016-01-21 15:38:06 -080012 controller: function($element, $window, d3, serviceTopologyConfig, ServiceRelation, Slice, Instances){
Matteo Scandolobe9b13d2016-01-21 11:21:03 -080013
14 // count the mas depth of an object
15 const depthOf = (obj) => {
16 var depth = 0;
17 if (obj.children) {
18 obj.children.forEach(function (d) {
19 var tmpDepth = depthOf(d);
20 if (tmpDepth > depth) {
21 depth = tmpDepth
22 }
23 })
24 }
25 return 1 + depth
26 };
27
Matteo Scandolobe9b13d2016-01-21 11:21:03 -080028 const width = $window.innerWidth - serviceTopologyConfig.widthMargin;
29 const height = $window.innerHeight - serviceTopologyConfig.heightMargin;
30
31 const tree = d3.layout.tree()
32 .size([height, width]);
33
34 const diagonal = d3.svg.diagonal()
35 .projection(d => [d.y, d.x]);
36
37 const svg = d3.select($element[0])
38 .append('svg')
39 .style('width', `${$window.innerWidth}px`)
40 .style('height', `${$window.innerHeight}px`)
41 .append('g')
42 .attr("transform", "translate(" + serviceTopologyConfig.widthMargin+ "," + serviceTopologyConfig.heightMargin + ")");;
43
Matteo Scandolo85aad312016-01-21 14:23:28 -080044 //const resizeCanvas = () => {
45 // var targetSize = svg.node().getBoundingClientRect();
46 //
47 // d3.select(self.frameElement)
48 // .attr('width', `${targetSize.width}px`)
49 // .attr('height', `${targetSize.height}px`)
50 //};
Matteo Scandolobe9b13d2016-01-21 11:21:03 -080051 //d3.select(window)
52 // .on('load', () => {
53 // resizeCanvas();
54 // });
55 //d3.select(window)
56 // .on('resize', () => {
57 // resizeCanvas();
58 // update(root);
59 // });
Matteo Scandolo85aad312016-01-21 14:23:28 -080060 var root;
Matteo Scandolobe9b13d2016-01-21 11:21:03 -080061 var i = 0;
62 var duration = 750;
63
Matteo Scandolo85aad312016-01-21 14:23:28 -080064 const draw = (tree) => {
65 root = tree;
66 root.x0 = $window.innerHeight / 2;
67 root.y0 = 0;
68
69 update(root);
70 };
Matteo Scandolobe9b13d2016-01-21 11:21:03 -080071
72 function update(source) {
73
74 const maxDepth = depthOf(source);
75
76 // Compute the new tree layout.
77 var nodes = tree.nodes(root).reverse(),
78 links = tree.links(nodes);
79
80 // Normalize for fixed-depth.
81 nodes.forEach(function(d) {
Matteo Scandolo53a02262016-01-21 16:02:57 -080082 // position the child node horizontally
Matteo Scandolobe9b13d2016-01-21 11:21:03 -080083 d.y = d.depth * (($window.innerWidth - (serviceTopologyConfig.widthMargin * 2)) / maxDepth);
84 console.log(d.x);
85 });
86
87 // Update the nodes…
88 var node = svg.selectAll('g.node')
89 .data(nodes, function(d) { return d.id || (d.id = ++i); });
90
91 // Enter any new nodes at the parent's previous position.
92 var nodeEnter = node.enter().append('g')
93 .attr('class', 'node')
94 .attr('transform', function(d) {
95 // this is the starting position
96 return 'translate(' + source.y0 + ',' + source.x0 + ')';
Matteo Scandolo53a02262016-01-21 16:02:57 -080097 });
Matteo Scandolobe9b13d2016-01-21 11:21:03 -080098
99 nodeEnter.append('circle')
100 .attr('r', 1e-6)
Matteo Scandolo53a02262016-01-21 16:02:57 -0800101 .style('fill', function(d) { return d._children ? 'lightsteelblue' : '#fff'; })
102 .on('click', click);
Matteo Scandolobe9b13d2016-01-21 11:21:03 -0800103
104 nodeEnter.append('text')
105 .attr('x', function(d) { return d.children || d._children ? -13 : 13; })
Matteo Scandolo68236262016-01-21 15:38:06 -0800106 .attr('transform', function(d) {
107 if((d.children || d._children) && d.parent || d._parent){
108 return 'rotate(30)';
109 }
110 return;
111 })
Matteo Scandolobe9b13d2016-01-21 11:21:03 -0800112 .attr('dy', '.35em')
113 .attr('text-anchor', function(d) { return d.children || d._children ? 'end' : 'start'; })
114 .text(function(d) { return d.name; })
115 .style('fill-opacity', 1e-6);
116
117 // Transition nodes to their new position.
118 var nodeUpdate = node.transition()
119 .duration(duration)
120 .attr('transform', function(d) {
121 return 'translate(' + d.y + ',' + d.x + ')';
122 });
123
124 nodeUpdate.select('circle')
125 .attr('r', 10)
126 .style('fill', function(d) { return d._children ? 'lightsteelblue' : '#fff'; });
127
128 nodeUpdate.select('text')
129 .style('fill-opacity', 1);
130
131 // Transition exiting nodes to the parent's new position.
132 var nodeExit = node.exit().transition()
133 .duration(duration)
134 .attr('transform', function(d) { return 'translate(' + source.y + ',' + source.x + ')'; })
135 .remove();
136
137 nodeExit.select('circle')
138 .attr('r', 1e-6);
139
140 nodeExit.select('text')
141 .style('fill-opacity', 1e-6);
142
143 // Update the links…
144 var link = svg.selectAll('path.link')
145 .data(links, function(d) { return d.target.id; });
146
147 // Enter any new links at the parent's previous position.
148 link.enter().insert('path', 'g')
149 .attr('class', 'link')
150 .attr('d', function(d) {
151 var o = {x: source.x0, y: source.y0};
152 return diagonal({source: o, target: o});
153 });
154
155 // Transition links to their new position.
156 link.transition()
157 .duration(duration)
158 .attr('d', diagonal);
159
160 // Transition exiting nodes to the parent's new position.
161 link.exit().transition()
162 .duration(duration)
163 .attr('d', function(d) {
164 var o = {x: source.x, y: source.y};
165 return diagonal({source: o, target: o});
166 })
167 .remove();
168
169 // Stash the old positions for transition.
170 nodes.forEach(function(d) {
171 d.x0 = d.x;
172 d.y0 = d.y;
173 });
174 }
Matteo Scandolo85aad312016-01-21 14:23:28 -0800175
Matteo Scandolo53a02262016-01-21 16:02:57 -0800176 this.instances = [];
177 this.slices = [];
178
179 var _this = this;
180 const click = function(d) {
181
182 d3.select(this).attr('r', 30);
183
184 _this.selectedService = {
Matteo Scandolo68236262016-01-21 15:38:06 -0800185 id: d.id,
186 name: d.name
187 };
188 Slice.query({service: d.id}).$promise
189 .then(slices => {
Matteo Scandolo53a02262016-01-21 16:02:57 -0800190 _this.instances = [];
191 _this.slices = slices;
Matteo Scandolo68236262016-01-21 15:38:06 -0800192 })
193 };
194
Matteo Scandolo85aad312016-01-21 14:23:28 -0800195 ServiceRelation.get()
196 .then((tree) => {
197 console.log(tree);
198 draw(tree);
199 });
Matteo Scandolo68236262016-01-21 15:38:06 -0800200
201 this.getInstances = (slice) => {
202 Instances.query({slice: slice.id}).$promise
203 .then((instances) => {
204 this.selectedSlice = slice;
205 this.instances = instances;
206 })
207 };
Matteo Scandolobe9b13d2016-01-21 11:21:03 -0800208 }
209 }
210 });
211
212}());