g.selectAll(".nodes")
.data(y, function(j, i){
dataValues.push([
cfg.w/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)
*cfg.factor*Math.sin(i*cfg.radians/total)),
cfg.h/2*(1-(parseFloat(Math.max(j.value, 0))/cfg.maxValue)
*cfg.factor*Math.cos(i*cfg.radians/total))
]);
});
var chart = d3.select('#chart');
var width = 900, height = 600;
var padding = 60;
var radius = d3.min([width - padding, height - padding])/2;
var svg = chart.selectAll("svg")
.data([{}]).enter()
.append("svg")
.attr("height", height)
.attr("width", width);
var centerCoords = [width/2, height/2];
var radar = svg.append('g')
.attr('transform',"translate(" + centerCoords[0] + "," + centerCoords[1] + ")");
var angles = d3.range(0,360,45);
// [0, 45, 90, 135, 180, 225, 270, 315]
radar.append('circle')
.attr('cx',0)
.attr('cy',0)
.attr('r', radius);
radar.selectAll('line')
.data(angles).enter()
.append('line')
.attr('x0',0)
.attr('y0',0)
.attr('x1',function(d) { return Math.cos(d) * radius})
.attr('y1',function(d) { return Math.sin(d) * radius});
var angles = d3.range(0,360,45)
.map(function(a) { return a * Math.PI / 180});
// [0, 0.7853981633974483, 1.5707963267948966, 2.356194490192345,
// 3.141592653589793, 3.9269908169872414, 4.71238898038469,
// 5.497787143782138]
radar.selectAll('line')
.data(angles).enter()
.append('line')
.attr('x0',0)
.attr('y0',0)
.attr('x1',function(d) { return Math.cos(d) * radius})
.attr('y1',function(d) { return Math.sin(d) * radius});
var data = [
{attribute: 'Bulk Apperception', value: 14},
{attribute: 'Candor', value: 19},
{attribute: 'Vivacity', value: 17},
{attribute: 'Coordination', value: 10},
{attribute: 'Meekness', value: 2},
{attribute: 'Humility', value: 3},
{attribute: 'Cruelty', value: 1},
{attribute: 'Self-Preservation', value: 10},
{attribute: 'Patience', value: 3},
{attribute: 'Decisiveness', value: 14},
{attribute: 'Imagination', value: 13},
{attribute: 'Curiosity', value: 8},
{attribute: 'Aggression', value: 5},
{attribute: 'Loyalty', value: 16},
{attribute: 'Empathy', value: 9},
{attribute: 'Tenacity', value: 17},
{attribute: 'Courage', value: 15},
{attribute: 'Sensuality', value: 18},
{attribute: 'Charm', value: 18},
{attribute: 'Humor', value: 9}
]
var angleInRadians = (360 / data.length) * Math.PI / 180;
radar.selectAll('line.axis')
.data(data).enter()
.append('line')
.classed('axis',true)
.attr('x0',0)
.attr('y0',0)
.attr('x1',function(d,i) {
return Math.cos(angleInRadians * i) * radius
})
.attr('y1',function(d,i) {
return Math.sin(angleInRadians * i) * radius
})
var angle = d3.scaleLinear()
.domain([0, data.length])
.range([0, 2 * Math.PI])
radar.selectAll('line.axis')
.data(data).enter()
.append('line')
.classed('axis',true)
.attr('x0',0)
.attr('y0',0)
.attr('x1',function(d,i) {
return Math.cos(angle(i)) * radius
})
.attr('y1',function(d,i) {
return Math.sin(angle(i)) * radius
})
radar.selectAll('line.axis')
.data(data).enter()
.append('line')
.classed('axis',true)
.attr('x0',0)
.attr('y0',0)
.attr('x1',function(d,i) { return X(i)})
.attr('y1',function(d,i) { return Y(i)})
radar.selectAll('text.label')
.data(data).enter()
.append('text')
.classed('label',true)
.attr('x', function(d,i) { return X(i) })
.attr('y', function(d,i) { return Y(i) })
.text(function(d) {
return d.attribute.toUpperCase() + " [" + d.value +"]";
})
var labelAnchor = function(d, i) {
var topAngle = 0 - Math.PI/2;
var bottomAngle = 0 + Math.PI/2;
var the_angle = angle(i) - RADIAN_OFFSET;
var anchor = "";
if (the_angle == topAngle || the_angle == bottomAngle)
anchor = "middle"
else if(the_angle > topAngle && the_angle < bottomAngle)
anchor = "start"
else
anchor = "end"
return anchor;
}
radar.selectAll('text.label')
.data(data).enter()
.append('text')
.classed('label',true)
.attr('x', function(d,i) { return X(i, 20)})
.attr('y', function(d,i) { return Y(i, 20)})
.style("text-anchor", labelAnchor)
.text(function(d) {
return d.attribute.toUpperCase() + " [" + d.value +"]";
})
var measureScale = d3.scaleLinear()
.domain([0, 20])
.range([0, radius])
radar.selectAll('circle.ring')
.data(data).enter()
.append('circle')
.classed('ring',true)
.attr('cx',0)
.attr('cy',0)
.attr('r', function(d,i) {
return measureScale(i + 1);
})
radar.selectAll('polygon.area')
.data([data]).enter()
.append('polygon')
.classed('area',true)
.attr('points', function(d) {
return d.map(function(d,i) {
var rad = measureScale(d.value);
return [X(i, rad), Y(i, rad)];
}).join(' ');
})
radar.selectAll('circle.point')
.data(data).enter()
.append('circle')
.classed('point',true)
.attr('cx',function(d,i) {
return X(i,measureScale(d.value))})
.attr('cy',function(d,i) {
return Y(i,measureScale(d.value))})
.attr('r', 7)
var areas = radar.selectAll('polygon.area')
.data([data]).enter()
areas.append('polygon')
.classed('area',true)
.attr('points', function(d) {
return d.map(function() {
return [0,0]
}).join(' ')
})
.merge(areas)
.transition()
.duration(2500)
.attr('points', function(d) {
return d.map(function(d,i) {
var rad = measureScale(d.value);
return [X(i, rad), Y(i, rad)];
}).join(' ');
})
var points = radar.selectAll('circle.point')
.data(data).enter()
points.append('circle')
.classed('point',true)
.attr('r', 7)
.attr('cx',0)
.attr('cy',0)
.merge(points)
.transition()
.duration(2500)
.attr('cx',function(d,i) {
return X(i,measureScale(d.value))
})
.attr('cy',function(d,i) {
return Y(i,measureScale(d.value))
})
jsancha@carto.com
@jorgesancha
https://carto.com/jobs