10 tr
.graphing
.Radar = function (size
, radar
) {
13 fib
= new tr
.util
.Fib();
16 self
.svg = function () {
21 return Math
.round(size
/2);
24 function plotLines() {
30 .attr('stroke-width', 14);
37 .attr('stroke-width', 14);
40 function getRadius(cycles
, i
) {
41 var sequence
= fib
.sequence(cycles
.length
);
42 var total
= fib
.sum(cycles
.length
);
45 return center() - (center() * sum
/ total
);
48 function plotCircles(cycles
) {
51 cycles
.forEach(function (cycle
, i
) {
55 .attr('r', getRadius(cycles
, i
));
59 function plotTexts(cycles
) {
62 increment
= Math
.round(center() / cycles
.length
);
64 cycles
.forEach(function (cycle
, i
) {
66 .attr('class', 'line-text')
67 .attr('y', center() + 4)
68 .attr('x', center() - getRadius(cycles
, i
) + 10)
72 .attr('class', 'line-text')
73 .attr('y', center() + 4)
74 .attr('x', center() + getRadius(cycles
, i
) - 10)
75 .attr('text-anchor', 'end')
80 function triangle(x
, y
, cssClass
) {
81 var tsize
, top
, left
, right
, bottom
, points
;
85 left
= (x
- tsize
+ 1);
86 right
= (x
+ tsize
+ 1);
87 bottom
= (y
+ tsize
- tsize
/ 2.5);
89 points
= x
+ 1 + ',' + top
+ ' ' + left
+ ',' + bottom
+ ' ' + right
+ ',' + bottom
;
91 return svg
.append('polygon')
92 .attr('points', points
)
93 .attr('class', cssClass
)
94 .attr('stroke-width', 1.5);
97 function circle(x
, y
, cssClass
) {
101 .attr('class', cssClass
)
102 .attr('stroke-width', 1.5)
106 function plotBlips(cycles
, quadrant
, adjustX
, adjustY
, cssClass
) {
108 blips
= quadrant
.blips();
109 cycles
.forEach(function (cycle
, i
) {
110 var maxRadius
, minRadius
, cycleBlips
;
112 maxRadius
= getRadius(cycles
, i
);
113 minRadius
= (i
== cycles
.length
- 1) ? 0: getRadius(cycles
, i
+ 1);
115 var cycleBlips
= blips
.filter(function (blip
) {
116 return blip
.cycle() == cycle
;
119 cycleBlips
.forEach(function (blip
) {
120 var angleInRad
, radius
;
122 var split
= blip
.name().split('');
123 var sum
= split
.reduce(function (p
, c
) { return p
+ c
.charCodeAt(0); }, 0);
124 chance
= new Chance(sum
* cycle
.name().length
* blip
.number());
126 angleInRad
= Math
.PI
* chance
.integer({ min
: 13, max
: 85 }) / 180;
127 radius
= chance
.floating({ min
: minRadius
+ 25, max
: maxRadius
- 10 });
129 var x
= center() + radius
* Math
.cos(angleInRad
) * adjustX
;
130 var y
= center() + radius
* Math
.sin(angleInRad
) * adjustY
;
133 triangle(x
, y
, cssClass
);
135 circle(x
, y
, cssClass
);
141 .attr('class', 'blip-text')
142 .attr('text-anchor', 'middle')
148 function plotQuadrantNames(quadrants
) {
149 function plotName(name
, anchor
, x
, y
, cssClass
) {
153 .attr('class', cssClass
)
154 .attr('text-anchor', anchor
)
158 plotName(quadrants
.I
.name(), 'end', size
- 10, 10, 'first')
159 plotName(quadrants
.II
.name(), 'start', 10, 10, 'second')
160 plotName(quadrants
.III
.name(), 'start', 10, size
- 10, 'third')
161 plotName(quadrants
.IV
.name(), 'end', size
-10, size
- 10, 'fourth')
164 self
.init = function (selector
) {
165 svg
= d3
.select(selector
|| 'body').append("svg");
169 self
.plot = function () {
170 var cycles
, quadrants
;
172 cycles
= radar
.cycles().reverse();
173 quadrants
= radar
.quadrants();
175 svg
.attr('width', size
).attr('height', size
);
181 if (radar
.hasQuadrants()) {
182 plotQuadrantNames(quadrants
);
183 plotBlips(cycles
, quadrants
.I
, 1, -1, 'first');
184 plotBlips(cycles
, quadrants
.II
, -1, -1, 'second');
185 plotBlips(cycles
, quadrants
.III
, -1, 1, 'third');
186 plotBlips(cycles
, quadrants
.IV
, 1, 1, 'fourth');
193 tr
.graphing
.RefTable = function (radar
) {
195 var injectionElement
;
197 function blipsByCycle () {
198 // set up empty blip arrays for each cycle
201 .map(function (cycle
) {
203 order
: cycle
.order(),
207 .sort(function (a
, b
) {
208 if (a
.order
=== b
.order
) {
210 } else if (a
.order
< b
.order
) {
216 .forEach(function (cycle
) {
217 cycles
[cycle
.name
] = [];
220 // group blips by cycle
222 var quadrants
= radar
.quadrants();
223 Object
.keys(quadrants
).forEach(function (quadrant
) {
224 blips
= blips
.concat(quadrants
[quadrant
].blips());
227 blips
.forEach(function (blip
) {
228 cycles
[blip
.cycle().name()].push(blip
);
234 self
.init = function (selector
) {
235 injectionElement
= document
.querySelector(selector
|| 'body');
239 self
.render = function () {
240 var blips
= blipsByCycle();
242 var html
= '<table class="radar-ref-table">';
244 Object
.keys(blips
).forEach(function (cycle
) {
245 html
+= '<tr class="radar-ref-status-group"><td colspan="3">' + cycle
+ '</td></tr>';
247 blips
[cycle
].forEach(function (blip
) {
249 '<td>' + blip
.number() + '</td>' +
250 '<td>' + blip
.name() + '</td>' +
251 '<td>' + blip
.description() + '</td>' +
258 injectionElement
.innerHTML
= html
;
264 tr
.models
.Blip = function (name
, cycle
, isNew
, description
) {
270 self
.name = function () {
274 self
.description = function () {
275 return description
|| '';
278 self
.isNew = function () {
282 self
.cycle = function () {
286 self
.number = function () {
290 self
.setNumber = function (newNumber
) {
297 tr
.models
.Cycle = function (name
, order
) {
300 self
.name = function () {
304 self
.order = function () {
311 tr
.models
.Quadrant = function (name
) {
317 self
.name = function () {
321 self
.add = function (newBlips
) {
322 if (Array
.isArray(newBlips
)) {
323 blips
= blips
.concat(newBlips
);
325 blips
.push(newBlips
);
329 self
.blips = function () {
330 return blips
.slice(0);
336 tr
.models
.Radar = function() {
337 var self
, quadrants
, blipNumber
;
340 quadrants
= { I
: null, II
: null, III
: null, IV
: null };
343 function setNumbers(blips
) {
344 blips
.forEach(function (blip
) {
345 blip
.setNumber(++blipNumber
);
349 self
.setFirstQuadrant = function (quadrant
) {
350 quadrants
.I
= quadrant
;
351 setNumbers(quadrants
.I
.blips());
354 self
.setSecondQuadrant = function (quadrant
) {
355 quadrants
.II
= quadrant
;
356 setNumbers(quadrants
.II
.blips());
359 self
.setThirdQuadrant = function (quadrant
) {
360 quadrants
.III
= quadrant
;
361 setNumbers(quadrants
.III
.blips());
364 self
.setFourthQuadrant = function (quadrant
) {
365 quadrants
.IV
= quadrant
;
366 setNumbers(quadrants
.IV
.blips());
369 function allQuadrants() {
372 for (var p
in quadrants
) {
373 if (quadrants
.hasOwnProperty(p
) && quadrants
[p
] != null) {
374 all
.push(quadrants
[p
]);
381 function allBlips() {
382 return allQuadrants().reduce(function (blips
, quadrant
) {
383 return blips
.concat(quadrant
.blips());
387 self
.hasQuadrants = function () {
388 return !!quadrants
.I
|| !!quadrants
.II
|| !!quadrants
.III
|| !!quadrants
.IV
;
391 self
.cycles = function () {
392 var cycleHash
, cycleArray
;
397 allBlips().forEach(function (blip
) {
398 cycleHash
[blip
.cycle().name()] = blip
.cycle();
401 for (var p
in cycleHash
) {
402 if (cycleHash
.hasOwnProperty(p
)) {
403 cycleArray
.push(cycleHash
[p
]);
407 return cycleArray
.slice(0).sort(function (a
, b
) { return a
.order() - b
.order(); });
410 self
.quadrants = function () {
417 tr
.util
.Fib = function () {
420 self
.sequence = function (length
) {
423 for (var i
= 2; i
< length
; i
++) {
424 result
[i
] = result
[i
-2] + result
[i
-1];
430 self
.sum = function (length
) {
431 if (length
=== 0) { return 0; }
432 if (length
=== 1) { return 1; }
434 return self
.sequence(length
+ 1).reduce(function (previous
, current
) {
435 return previous
+ current
;