blob: 5141195602e2468446a418fe256360ae3b594fae [file] [log] [blame]
Paul Greysone15c4392013-04-09 15:05:31 -07001function createTopologyView() {
2
3 window.addEventListener('resize', function () {
4 // this is too slow. instead detect first resize event and hide the paths that have explicit matrix applied
5 // either that or is it possible to position the paths so they get the automatic transform as well?
6// updateTopology();
7 });
8
9 var svg = d3.select('#svg-container').append('svg:svg');
10
11 svg.append("svg:defs").append("svg:marker")
12 .attr("id", "arrow")
13 .attr("viewBox", "0 -5 10 10")
14 .attr("refX", -1)
15 .attr("markerWidth", 5)
16 .attr("markerHeight", 5)
17 .attr("orient", "auto")
18 .append("svg:path")
19 .attr("d", "M0,-3L10,0L0,3");
20
21 return svg.append('svg:svg').attr('id', 'viewBox').attr('viewBox', '0 0 1000 1000').attr('preserveAspectRatio', 'none').
22 attr('id', 'viewbox').append('svg:g').attr('transform', 'translate(500 500)');
23}
24
25var widths = {
26 edge: 6,
27 aggregation: 12,
28 core: 18
29}
30
31function createTopologyModel(model) {
32 var rings = [{
33 radius: 3,
34 width: widths.edge,
35 switches: model.edgeSwitches,
36 className: 'edge',
37 angles: []
38 }, {
39 radius: 2.25,
40 width: widths.aggregation,
41 switches: model.aggregationSwitches,
42 className: 'aggregation',
43 angles: []
44 }, {
45 radius: 0.75,
46 width: widths.core,
47 switches: model.coreSwitches,
48 className: 'core',
49 angles: []
50 }];
51
52
53 var aggRanges = {};
54
55 // arrange edge switches at equal increments
56 var k = 360 / rings[0].switches.length;
57 rings[0].switches.forEach(function (s, i) {
58 var angle = k * i;
59
60 rings[0].angles[i] = angle;
61
62 // record the angle for the agg switch layout
63 var dpid = s.dpid.split(':');
64 dpid[7] = '01'; // the last component of the agg switch is always '01'
65 var aggdpid = dpid.join(':');
66 var aggRange = aggRanges[aggdpid];
67 if (!aggRange) {
68 aggRange = aggRanges[aggdpid] = {};
69 aggRange.min = aggRange.max = angle;
70 } else {
71 aggRange.max = angle;
72 }
73 });
74
75 // arrange aggregation switches to "fan out" to edge switches
76 k = 360 / rings[1].switches.length;
77 rings[1].switches.forEach(function (s, i) {
78// rings[1].angles[i] = k * i;
79 var range = aggRanges[s.dpid];
80
81 rings[1].angles[i] = (range.min + range.max)/2;
82 });
83
84 // find the association between core switches and aggregation switches
85 var aggregationSwitchMap = {};
86 model.aggregationSwitches.forEach(function (s, i) {
87 aggregationSwitchMap[s.dpid] = i;
88 });
89
90 // put core switches next to linked aggregation switches
91 k = 360 / rings[2].switches.length;
92 rings[2].switches.forEach(function (s, i) {
93// rings[2].angles[i] = k * i;
94 var associatedAggregationSwitches = model.configuration.association[s.dpid];
95 // TODO: go between if there are multiple
96 var index = aggregationSwitchMap[associatedAggregationSwitches[0]];
97
98 rings[2].angles[i] = rings[1].angles[index];
99 });
100
101 // TODO: construct this form initially rather than converting. it works better because
102 // it allows binding by dpid
103 var testRings = [];
104 rings.forEach(function (ring) {
105 var testRing = [];
106 ring.switches.forEach(function (s, i) {
107 var testSwitch = {
108 dpid: s.dpid,
109 state: s.state,
110 radius: ring.radius,
111 width: ring.width,
112 className: ring.className,
113 angle: ring.angles[i],
114 controller: s.controller
115 };
116 testRing.push(testSwitch);
117 });
118
119
120 testRings.push(testRing);
121 });
122
123
124// return rings;
125 return testRings;
126}