blob: 5bf0dc89ebe0f18a96484c6a1c18ff9b836e40a2 [file] [log] [blame]
Matteo Scandolo9fe01af2016-02-09 16:01:49 -08001(function () {
2 'use strict';
3
4 const shapes = {
5 cloud: ' M 79.72 49.60 C 86.00 37.29 98.57 29.01 111.96 26.42 C 124.27 24.11 137.53 26.15 148.18 32.90 C 158.08 38.78 165.39 48.87 167.65 60.20 C 176.20 57.90 185.14 56.01 194.00 57.73 C 206.08 59.59 217.92 66.01 224.37 76.66 C 227.51 81.54 228.85 87.33 229.23 93.06 C 237.59 93.33 246.22 95.10 253.04 100.19 C 256.69 103.13 259.87 107.67 258.91 112.59 C 257.95 118.43 252.78 122.38 247.78 124.82 C 235.27 130.43 220.23 130.09 207.98 123.93 C 199.33 127.88 189.76 129.43 180.30 128.57 C 173.70 139.92 161.70 147.65 148.86 149.93 C 133.10 153.26 116.06 148.15 104.42 137.08 C 92.98 143.04 78.96 143.87 66.97 139.04 C 57.75 135.41 49.70 128.00 46.60 118.43 C 43.87 109.95 45.81 100.29 51.30 93.32 C 57.38 85.18 67.10 80.44 76.99 78.89 C 74.38 69.20 74.87 58.52 79.72 49.60 Z'
6 }
7
Matteo Scandolo170d3be2016-02-11 08:58:04 -08008 var computeNodeId = 0;
9 var instanceId = 0;
10
Matteo Scandolo9fe01af2016-02-09 16:01:49 -080011 angular.module('xos.serviceTopology')
Matteo Scandoload5b2282016-02-16 11:50:51 -080012 .service('NodeDrawer', function(d3, serviceTopologyConfig, Node, RackHelper){
Matteo Scandolo9fe01af2016-02-09 16:01:49 -080013 this.addNetworks = (nodes) => {
14 nodes.append('path')
15 .attr({
16 d: shapes.cloud,
17 transform: 'translate(-63, -52), scale(0.5)',
18 class: 'cloud'
19 });
20
21 nodes.append('text')
22 .attr({
23 'text-anchor': 'middle'
24 })
25 .text(d => d.name)
26 }
27
28 this.addRack = (nodes) => {
Matteo Scandolo170d3be2016-02-11 08:58:04 -080029
30 // NOTE is good to request data here? Probably not.
31
32 Node.queryWithInstances().$promise
33 .then((computeNodes) => {
Matteo Scandoload5b2282016-02-16 11:50:51 -080034 let [w, h] = RackHelper.getRackSize(computeNodes);
35
36 let rack = nodes
37 .append('g').
38 attr({
39 transform: d => `translate(${- (w / 2)}, ${- (h / 2)})`
40 });
41
42 rack
43 .append('rect')
44 .attr({
45 width: w,
46 height: h
47 });
48
49 nodes.append('text')
50 .attr({
51 'text-anchor': 'middle',
52 y: - (h / 2) - 10
53 })
54 .text(d => d.name);
55
56 this.drawComputeNodes(rack, computeNodes);
Matteo Scandolo170d3be2016-02-11 08:58:04 -080057 });
Matteo Scandolo170d3be2016-02-11 08:58:04 -080058 };
59
60 this.drawComputeNodes = (container, nodes) => {
Matteo Scandoload5b2282016-02-16 11:50:51 -080061
62
Matteo Scandolo170d3be2016-02-11 08:58:04 -080063 let elements = container.selectAll('.compute-nodes')
64 .data(nodes, d => {
65 if(!angular.isString(d.d3Id)){
66 d.d3Id = `compute-node-${++computeNodeId}`;
67 }
68 return d.d3Id;
69 });
70
71 var nodeContainer = elements.enter().append('g')
72 .attr({
Matteo Scandoload5b2282016-02-16 11:50:51 -080073 class: 'compute-node',
74 transform: (d) => `translate(${RackHelper.getComputeNodePosition(nodes, d.d3Id.replace('compute-node-', '') - 1)})`
Matteo Scandolo170d3be2016-02-11 08:58:04 -080075 });
76
77 nodeContainer.append('rect')
Matteo Scandoload5b2282016-02-16 11:50:51 -080078 .attr({
79 width: d => RackHelper.getComputeNodeSize(d.instances)[0],
80 height: d => RackHelper.getComputeNodeSize(d.instances)[1],
81 });
82
83 nodeContainer.append('text')
84 .attr({
85 'text-anchor': 'start',
86 y: 15, //FIXME
87 x: 10 //FIXME
88 })
89 .text(d => d.humanReadableName.split('.')[0]);
Matteo Scandolo170d3be2016-02-11 08:58:04 -080090
91 // if there are Compute Nodes
92 if(nodeContainer.length > 0){
93 angular.forEach(nodeContainer.data(), (computeNode) => {
94 this.drawInstances(nodeContainer, computeNode.instances);
95 });
96 }
97
98 };
99
Matteo Scandolo7030ceb2016-02-16 13:29:26 -0800100 // NOTE Stripping unuseful names to shorten labels.
101 // This is not elegant
102 const formatInstanceName = (name) => {
103 return name
104 .replace('app_', '')
105 .replace('service_', '')
106 .replace('ovs_', '')
107 .replace('mysite_', '')
108 .replace('_instance', '');
109 };
110
Matteo Scandolo170d3be2016-02-11 08:58:04 -0800111 this.drawInstances = (container, instances) => {
Matteo Scandolo170d3be2016-02-11 08:58:04 -0800112
113 let elements = container.selectAll('.instances')
114 .data(instances, d => angular.isString(d.d3Id) ? d.d3Id : d.d3Id = `instance-${++instanceId}`)
115
116 var instanceContainer = elements.enter().append('g')
117 .attr({
Matteo Scandoload5b2282016-02-16 11:50:51 -0800118 class: 'instance',
119 transform: d => `translate(${RackHelper.getInstancePosition(d.d3Id.replace('instance-', '') - 1)})`
Matteo Scandolo170d3be2016-02-11 08:58:04 -0800120 });
121
122 instanceContainer.append('rect')
Matteo Scandoload5b2282016-02-16 11:50:51 -0800123 .attr({
124 width: serviceTopologyConfig.instance.width,
125 height: serviceTopologyConfig.instance.height
126 });
127
128 instanceContainer.append('text')
129 .attr({
Matteo Scandolo7030ceb2016-02-16 13:29:26 -0800130 'text-anchor': 'middle',
131 y: 23, //FIXME
132 x: 40 //FIXME
Matteo Scandoload5b2282016-02-16 11:50:51 -0800133 })
Matteo Scandolo7030ceb2016-02-16 13:29:26 -0800134 .text(d => formatInstanceName(d.name));
135
136 instanceContainer
137 .on('click', d => {
138 console.log(d);
139 });
Matteo Scandolo170d3be2016-02-11 08:58:04 -0800140 };
Matteo Scandolo9fe01af2016-02-09 16:01:49 -0800141
142 this.addPhisical = (nodes) => {
143 nodes.append('rect')
144 .attr(serviceTopologyConfig.square);
145
146 nodes.append('text')
147 .attr({
148 'text-anchor': 'middle',
149 y: serviceTopologyConfig.square.y - 10
150 })
151 .text(d => d.name);
152 }
153
154 this.addDevice = (nodes) => {
155 nodes.append('circle')
156 .attr(serviceTopologyConfig.circle);
157
158 nodes.append('text')
159 .attr({
160 'text-anchor': 'end',
161 x: - serviceTopologyConfig.circle.r - 10,
162 y: serviceTopologyConfig.circle.r / 2
163 })
164 .text(d => d.name);
165 }
166 });
167})();