+ .attr('cx', center())
+ .attr('cy', center())
+ .attr('r', getRadius(cycles, i));
+ });
+ }
+
+ function plotTexts(cycles) {
+ var increment;
+
+ increment = Math.round(center() / cycles.length);
+
+ cycles.forEach(function (cycle, i) {
+ svg.append('text')
+ .attr('class', 'line-text')
+ .attr('y', center() + 4)
+ .attr('x', center() - getRadius(cycles, i) + 10)
+ .text(cycle.name());
+
+ svg.append('text')
+ .attr('class', 'line-text')
+ .attr('y', center() + 4)
+ .attr('x', center() + getRadius(cycles, i) - 10)
+ .attr('text-anchor', 'end')
+ .text(cycle.name());
+ });
+ };
+
+ function triangle(x, y, cssClass, group) {
+ var tsize, top, left, right, bottom, points;
+
+ tsize = 13
+ top = y - tsize;
+ left = (x - tsize + 1);
+ right = (x + tsize + 1);
+ bottom = (y + tsize - tsize / 2.5);
+
+ points = x + 1 + ',' + top + ' ' + left + ',' + bottom + ' ' + right + ',' + bottom;
+
+ return (group || svg).append('polygon')
+ .attr('points', points)
+ .attr('class', cssClass)
+ .attr('stroke-width', 1.5);
+ }
+
+ function circle(x, y, cssClass, group) {
+ return (group || svg).append('circle')
+ .attr('cx', x)
+ .attr('cy', y)
+ .attr('class', cssClass)
+ .attr('stroke-width', 1.5)
+ .attr('r', 10);
+ }
+
+ function plotBlips(cycles, quadrant, adjustX, adjustY, cssClass) {
+ var blips;
+ blips = quadrant.blips();
+ cycles.forEach(function (cycle, i) {
+ var maxRadius, minRadius, cycleBlips;
+
+ maxRadius = getRadius(cycles, i);
+ minRadius = (i == cycles.length - 1) ? 0: getRadius(cycles, i + 1);
+
+ var cycleBlips = blips.filter(function (blip) {
+ return blip.cycle() == cycle;
+ });
+
+ cycleBlips.forEach(function (blip) {
+ var angleInRad, radius;
+
+ var split = blip.name().split('');
+ var sum = split.reduce(function (p, c) { return p + c.charCodeAt(0); }, 0);
+ chance = new Chance(sum * cycle.name().length * blip.number());
+
+ angleInRad = Math.PI * chance.integer({ min: 13, max: 85 }) / 180;
+ radius = chance.floating({ min: minRadius + 25, max: maxRadius - 10 });
+
+ var x = center() + radius * Math.cos(angleInRad) * adjustX;
+ var y = center() + radius * Math.sin(angleInRad) * adjustY;
+
+ var group = svg.append('g').attr('class', 'blip-group');
+
+ if (blip.isNew()) {
+ triangle(x, y, cssClass, group);
+ } else {
+ circle(x, y, cssClass, group);
+ }
+
+ texts.push(function () {
+ var name;
+
+ name = svg.append('text')
+ .attr('x', x + 15)
+ .attr('y', y + 4)
+ .attr('class', 'blip-name')
+ .attr('text-anchor', 'left')
+ .text(blip.name())
+
+ group
+ .on('mouseover', function () { name.style('display', 'block'); })
+ .on('mouseout', function () { name.style('display', 'none'); });
+ });
+
+ group.append('text')
+ .attr('x', x)
+ .attr('y', y + 4)
+ .attr('class', 'blip-text')
+ .attr('text-anchor', 'middle')
+ .text(blip.number())
+ .append("svg:title")
+ .text(blip.name() + ((toolTipDescription && blip.description())
+ ? ': ' + blip.description().replace(/(<([^>]+)>)/ig, '')
+ : '' ))
+ });