Revert "fixed fib sum, it was doing the sum for lenght + 1"
[tech-radar.git] / src / graphing / radar.js
1 tr.graphing.Radar = function (size, radar) {
2 var self, fib, svg;
3
4 fib = new tr.util.Fib();
5
6 self = {};
7 self.svg = function () {
8 return svg;
9 }
10
11 function center () {
12 return Math.round(size/2);
13 }
14
15 function plotLines() {
16 svg.append('line')
17 .attr('x1', center())
18 .attr('y1', 0)
19 .attr('x2', center())
20 .attr('y2', size)
21 .attr('stroke-width', 14);
22
23 svg.append('line')
24 .attr('x1', 0)
25 .attr('y1', center())
26 .attr('x2', size)
27 .attr('y2', center())
28 .attr('stroke-width', 14);
29 };
30
31 function getRadius(cycles, i) {
32 var sequence = fib.sequence(cycles.length);
33 var total = fib.sum(cycles.length);
34 var sum = fib.sum(i);
35
36 return center() - (center() * sum / total);
37 }
38
39 function plotCircles(cycles) {
40 var increment;
41
42 cycles.forEach(function (cycle, i) {
43 svg.append('circle')
44 .attr('cx', center())
45 .attr('cy', center())
46 .attr('r', getRadius(cycles, i));
47 });
48 }
49
50 function plotTexts(cycles) {
51 var increment;
52
53 increment = Math.round(center() / cycles.length);
54
55 cycles.forEach(function (cycle, i) {
56 svg.append('text')
57 .attr('class', 'line-text')
58 .attr('y', center() + 4)
59 .attr('x', center() - getRadius(cycles, i) + 10)
60 .text(cycle.name());
61
62 svg.append('text')
63 .attr('class', 'line-text')
64 .attr('y', center() + 4)
65 .attr('x', center() + getRadius(cycles, i) - 10)
66 .attr('text-anchor', 'end')
67 .text(cycle.name());
68 });
69 };
70
71 function triangle(x, y, cssClass) {
72 var tsize, top, left, right, bottom, points;
73
74 tsize = 13
75 top = y - tsize;
76 left = (x - tsize + 1);
77 right = (x + tsize + 1);
78 bottom = (y + tsize - tsize / 2.5);
79
80 points = x + 1 + ',' + top + ' ' + left + ',' + bottom + ' ' + right + ',' + bottom;
81
82 return svg.append('polygon')
83 .attr('points', points)
84 .attr('class', cssClass)
85 .attr('stroke-width', 1.5);
86 }
87
88 function circle(x, y, cssClass) {
89 svg.append('circle')
90 .attr('cx', x)
91 .attr('cy', y)
92 .attr('class', cssClass)
93 .attr('stroke-width', 1.5)
94 .attr('r', 10);
95 }
96
97 function plotBlips(cycles, quadrant, adjustX, adjustY, cssClass) {
98 var blips;
99 blips = quadrant.blips();
100 cycles.forEach(function (cycle, i) {
101 var maxRadius, minRadius, cycleBlips;
102
103 maxRadius = getRadius(cycles, i);
104 minRadius = (i == cycles.length - 1) ? 0: getRadius(cycles, i + 1);
105
106 var cycleBlips = blips.filter(function (blip) {
107 return blip.cycle() == cycle;
108 });
109
110 cycleBlips.forEach(function (blip) {
111 var angleInRad, radius;
112
113 var split = blip.name().split('');
114 var sum = split.reduce(function (p, c) { return p + c.charCodeAt(0); }, 0);
115 chance = new Chance(sum * cycle.name().length * blip.number());
116
117 angleInRad = Math.PI * chance.integer({ min: 13, max: 85 }) / 180;
118 radius = chance.floating({ min: minRadius + 25, max: maxRadius - 10 });
119
120 var x = center() + radius * Math.cos(angleInRad) * adjustX;
121 var y = center() + radius * Math.sin(angleInRad) * adjustY;
122
123 if (blip.isNew()) {
124 triangle(x, y, cssClass);
125 } else {
126 circle(x, y, cssClass);
127 }
128
129 svg.append('text')
130 .attr('x', x)
131 .attr('y', y + 4)
132 .attr('class', 'blip-text')
133 .attr('text-anchor', 'middle')
134 .text(blip.number())
135 });
136 });
137 };
138
139 function plotQuadrantNames(quadrants) {
140 function plotName(name, anchor, x, y, cssClass) {
141 svg.append('text')
142 .attr('x', x)
143 .attr('y', y)
144 .attr('class', cssClass)
145 .attr('text-anchor', anchor)
146 .text(name);
147 }
148
149 plotName(quadrants.I.name(), 'end', size - 10, 10, 'first')
150 plotName(quadrants.II.name(), 'start', 10, 10, 'second')
151 plotName(quadrants.III.name(), 'start', 10, size - 10, 'third')
152 plotName(quadrants.IV.name(), 'end', size -10, size - 10, 'fourth')
153 }
154
155 self.init = function (selector) {
156 svg = d3.select(selector || 'body').append("svg");
157 return self;
158 };
159
160 self.plot = function () {
161 var cycles, quadrants;
162
163 cycles = radar.cycles().reverse();
164 quadrants = radar.quadrants();
165
166 svg.attr('width', size).attr('height', size);
167
168 plotCircles(cycles);
169 plotLines();
170 plotTexts(cycles);
171
172 if (radar.hasQuadrants()) {
173 plotQuadrantNames(quadrants);
174 plotBlips(cycles, quadrants.I, 1, -1, 'first');
175 plotBlips(cycles, quadrants.II, -1, -1, 'second');
176 plotBlips(cycles, quadrants.III, -1, 1, 'third');
177 plotBlips(cycles, quadrants.IV, 1, 1, 'fourth');
178 }
179 };
180
181 return self;
182 };