Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active August 29, 2015 14:02
Show Gist options
  • Save nitaku/af6f61a8de5888b8e035 to your computer and use it in GitHub Desktop.
Save nitaku/af6f61a8de5888b8e035 to your computer and use it in GitHub Desktop.
Radar chart
### polar layout ###
polar = () ->
# defaults
#scale = d3.scale.linear
self = (data) ->
data.forEach (d, i) ->
d.angle = i * 2*Math.PI/data.length
return data
return self
### --- ###
csv = '''
category,value
one,323
two,534
three,230
four,156
five,336
'''
data = d3.csv.parse csv
data.forEach (d) -> d.value = +d.value
max = d3.max(data, (d) -> d.value)
width = 960
height = 500
RADIUS = Math.min(width, height) / 2 - 40
polar_layout = polar()
polar_data = polar_layout(data)
svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr
transform: "translate(#{width/2}, #{height/2})"
polygon_generator = d3.svg.line()
.x((d) -> RADIUS/max*d.value*Math.cos(d.angle))
.y((d) -> RADIUS/max*d.value*Math.sin(d.angle))
svg.append("path")
.datum(polar_data)
.attr
class: 'polygon'
d: (ds) -> polygon_generator(ds) + 'z'
outer_polygon_generator = d3.svg.line()
.x((d) -> RADIUS*Math.cos(d.angle))
.y((d) -> RADIUS*Math.sin(d.angle))
svg.append("path")
.datum(polar_data)
.attr
class: 'outer_polygon'
d: (ds) -> outer_polygon_generator(ds) + 'z'
svg.selectAll(".radius")
.data(polar_data)
.enter().append("path")
.attr('class','radius')
.attr("d", (d) -> "M0 0 L#{RADIUS*Math.cos(d.angle)} #{RADIUS*Math.sin(d.angle)}")
svg.selectAll(".dot")
.data(polar_data)
.enter().append("circle")
.attr('class','dot')
.attr
cx: (d) -> "#{RADIUS/max*d.value*Math.cos(d.angle)}"
cy: (d) -> "#{RADIUS/max*d.value*Math.sin(d.angle)}"
r: 3
svg {
background-color: white;
}
.radius {
stroke: gray;
stroke-dasharray: 3 3;
}
.polygon {
fill: orange;
fill-opacity: 0.2;
stroke: orange;
}
.outer_polygon {
fill: none;
stroke: gray;
stroke-dasharray: 3 3;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="Radar chart" />
<title>Radar chart</title>
<link rel="stylesheet" href="index.css">
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<script src="index.js"></script>
</body>
</html>
/* polar layout
*/
(function() {
var RADIUS, csv, data, height, max, outer_polygon_generator, polar, polar_data, polar_layout, polygon_generator, svg, width;
polar = function() {
var self;
self = function(data) {
data.forEach(function(d, i) {
return d.angle = i * 2 * Math.PI / data.length;
});
return data;
};
return self;
};
/* ---
*/
csv = 'category,value\none,323\ntwo,534\nthree,230\nfour,156\nfive,336';
data = d3.csv.parse(csv);
data.forEach(function(d) {
return d.value = +d.value;
});
max = d3.max(data, function(d) {
return d.value;
});
width = 960;
height = 500;
RADIUS = Math.min(width, height) / 2 - 40;
polar_layout = polar();
polar_data = polar_layout(data);
svg = d3.select("body").append("svg").attr("width", width).attr("height", height).append("g").attr({
transform: "translate(" + (width / 2) + ", " + (height / 2) + ")"
});
polygon_generator = d3.svg.line().x(function(d) {
return RADIUS / max * d.value * Math.cos(d.angle);
}).y(function(d) {
return RADIUS / max * d.value * Math.sin(d.angle);
});
svg.append("path").datum(polar_data).attr({
"class": 'polygon',
d: function(ds) {
return polygon_generator(ds) + 'z';
}
});
outer_polygon_generator = d3.svg.line().x(function(d) {
return RADIUS * Math.cos(d.angle);
}).y(function(d) {
return RADIUS * Math.sin(d.angle);
});
svg.append("path").datum(polar_data).attr({
"class": 'outer_polygon',
d: function(ds) {
return outer_polygon_generator(ds) + 'z';
}
});
svg.selectAll(".radius").data(polar_data).enter().append("path").attr('class', 'radius').attr("d", function(d) {
return "M0 0 L" + (RADIUS * Math.cos(d.angle)) + " " + (RADIUS * Math.sin(d.angle));
});
svg.selectAll(".dot").data(polar_data).enter().append("circle").attr('class', 'dot').attr({
cx: function(d) {
return "" + (RADIUS / max * d.value * Math.cos(d.angle));
},
cy: function(d) {
return "" + (RADIUS / max * d.value * Math.sin(d.angle));
},
r: 3
});
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment