Last active
August 29, 2015 14:02
-
-
Save nitaku/70da709633904c6de9d9 to your computer and use it in GitHub Desktop.
Pie vs. pie
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### polar layout ### | |
polar = () -> | |
# defaults | |
#scale = d3.scale.linear | |
angle = null | |
self = (data) -> | |
angle = 2*Math.PI/data.length | |
data.forEach (d, i) -> | |
d.angle = if data.length > 2 then i * angle else (i-0.25) * angle | |
return data | |
self.angle = () -> | |
return angle | |
return self | |
### --- ### | |
rand2_6 = () -> 2 + Math.round(Math.random() * 6) | |
data = d3.range(rand2_6()).map (d) -> { category: "cat_#{d}", value: Math.random() } | |
console.log data | |
max = d3.max(data, (d) -> d.value) | |
width = 960 | |
height = 500 | |
side = Math.min(width,height) | |
RADIUS = side / 4 - 20 | |
polar_layout = polar() | |
polar_data = polar_layout(data) | |
console.log polar_data | |
svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height) | |
.append('g') | |
.attr | |
transform: "translate(#{width/2}, #{height/2})" | |
ul = svg.append("g") | |
.attr | |
transform: "translate(#{-side/4}, #{-side/4})" | |
ur = svg.append("g") | |
.attr | |
transform: "translate(#{+side/4}, #{-side/4})" | |
bl = svg.append("g") | |
.attr | |
transform: "translate(#{-side/4}, #{+side/4})" | |
br = svg.append("g") | |
.attr | |
transform: "translate(#{+side/4}, #{+side/4})" | |
color = d3.scale.ordinal() | |
.range(["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"]) | |
# pie chart | |
pie = d3.layout.pie() | |
.sort(null) | |
.value((d) -> d.value ) | |
arc_generator = d3.svg.arc() | |
.innerRadius(0) | |
.outerRadius(RADIUS) | |
ul.selectAll('.arc') | |
.data(pie(data)) | |
.enter().append('path') | |
.attr | |
class: 'arc' | |
d: arc_generator | |
fill: (d, i) -> color(i) | |
# radar chart | |
outer_polygon_generator = d3.svg.line() | |
.x((d) -> RADIUS*Math.cos(d.angle-Math.PI/2)) | |
.y((d) -> RADIUS*Math.sin(d.angle-Math.PI/2)) | |
ur.append("path") | |
.datum(polar_data) | |
.attr | |
class: 'outer_polygon' | |
d: (ds) -> outer_polygon_generator(ds) + 'z' | |
ur.selectAll(".radius") | |
.data(polar_data) | |
.enter().append("path") | |
.attr('class','radius') | |
.attr("d", (d) -> "M0 0 L#{RADIUS*Math.cos(d.angle-Math.PI/2)} #{RADIUS*Math.sin(d.angle-Math.PI/2)}") | |
polygon_generator = d3.svg.line() | |
.x((d) -> RADIUS/max*d.value*Math.cos(d.angle-Math.PI/2)) | |
.y((d) -> RADIUS/max*d.value*Math.sin(d.angle-Math.PI/2)) | |
ur.append('path') | |
.datum(polar_data) | |
.attr | |
class: 'polygon' | |
d: (ds) -> polygon_generator(ds) + 'z' | |
ur.selectAll(".dot") | |
.data(polar_data) | |
.enter().append("circle") | |
.attr('class','dot') | |
.attr | |
cx: (d) -> "#{RADIUS/max*d.value*Math.cos(d.angle-Math.PI/2)}" | |
cy: (d) -> "#{RADIUS/max*d.value*Math.sin(d.angle-Math.PI/2)}" | |
r: 4 | |
fill: (d, i) -> color(i) | |
# polar chart | |
radius_scale = d3.scale.linear() | |
.domain([0, max]) | |
.range([0, RADIUS]) | |
arc_generator = d3.svg.arc() | |
.innerRadius(0) | |
.outerRadius((d) -> radius_scale(d.value)) | |
.startAngle((d) -> d.angle - polar_layout.angle()/2) | |
.endAngle((d) -> d.angle + polar_layout.angle()/2) | |
bl.selectAll('.arc') | |
.data(polar_data) | |
.enter().append('path') | |
.attr | |
class: 'arc' | |
d: arc_generator | |
fill: (d, i) -> color(i) | |
# polar area chart | |
radius_scale = d3.scale.sqrt() | |
.domain([0, max]) | |
.range([0, RADIUS]) | |
arc_generator = d3.svg.arc() | |
.innerRadius(0) | |
.outerRadius((d) -> radius_scale(d.value)) | |
.startAngle((d) -> d.angle - polar_layout.angle()/2) | |
.endAngle((d) -> d.angle + polar_layout.angle()/2) | |
br.selectAll('.arc') | |
.data(polar_data) | |
.enter().append('path') | |
.attr | |
class: 'arc' | |
d: arc_generator | |
fill: (d, i) -> color(i) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
svg { | |
background-color: white; | |
} | |
.arc { | |
stroke-width: 1; | |
stroke: white; | |
stroke-linejoin: round; | |
} | |
.radius { | |
stroke: gray; | |
stroke-dasharray: 3 3; | |
} | |
.polygon { | |
fill: #DDD; | |
fill-opacity: 0.5; | |
stroke: gray; | |
} | |
.outer_polygon { | |
fill: none; | |
stroke: gray; | |
stroke-dasharray: 3 3; | |
} | |
.dot { | |
stroke: white; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="description" content="Pie vs. pie" /> | |
<title>Pie vs. pie</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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* polar layout | |
*/ | |
(function() { | |
var RADIUS, arc_generator, bl, br, color, data, height, max, outer_polygon_generator, pie, polar, polar_data, polar_layout, polygon_generator, radius_scale, rand2_6, side, svg, ul, ur, width; | |
polar = function() { | |
var angle, self; | |
angle = null; | |
self = function(data) { | |
angle = 2 * Math.PI / data.length; | |
data.forEach(function(d, i) { | |
return d.angle = data.length > 2 ? i * angle : (i - 0.25) * angle; | |
}); | |
return data; | |
}; | |
self.angle = function() { | |
return angle; | |
}; | |
return self; | |
}; | |
/* --- | |
*/ | |
rand2_6 = function() { | |
return 2 + Math.round(Math.random() * 6); | |
}; | |
data = d3.range(rand2_6()).map(function(d) { | |
return { | |
category: "cat_" + d, | |
value: Math.random() | |
}; | |
}); | |
console.log(data); | |
max = d3.max(data, function(d) { | |
return d.value; | |
}); | |
width = 960; | |
height = 500; | |
side = Math.min(width, height); | |
RADIUS = side / 4 - 20; | |
polar_layout = polar(); | |
polar_data = polar_layout(data); | |
console.log(polar_data); | |
svg = d3.select("body").append("svg").attr("width", width).attr("height", height).append('g').attr({ | |
transform: "translate(" + (width / 2) + ", " + (height / 2) + ")" | |
}); | |
ul = svg.append("g").attr({ | |
transform: "translate(" + (-side / 4) + ", " + (-side / 4) + ")" | |
}); | |
ur = svg.append("g").attr({ | |
transform: "translate(" + (+side / 4) + ", " + (-side / 4) + ")" | |
}); | |
bl = svg.append("g").attr({ | |
transform: "translate(" + (-side / 4) + ", " + (+side / 4) + ")" | |
}); | |
br = svg.append("g").attr({ | |
transform: "translate(" + (+side / 4) + ", " + (+side / 4) + ")" | |
}); | |
color = d3.scale.ordinal().range(["#1b9e77", "#d95f02", "#7570b3", "#e7298a", "#66a61e", "#e6ab02", "#a6761d", "#666666"]); | |
pie = d3.layout.pie().sort(null).value(function(d) { | |
return d.value; | |
}); | |
arc_generator = d3.svg.arc().innerRadius(0).outerRadius(RADIUS); | |
ul.selectAll('.arc').data(pie(data)).enter().append('path').attr({ | |
"class": 'arc', | |
d: arc_generator, | |
fill: function(d, i) { | |
return color(i); | |
} | |
}); | |
outer_polygon_generator = d3.svg.line().x(function(d) { | |
return RADIUS * Math.cos(d.angle - Math.PI / 2); | |
}).y(function(d) { | |
return RADIUS * Math.sin(d.angle - Math.PI / 2); | |
}); | |
ur.append("path").datum(polar_data).attr({ | |
"class": 'outer_polygon', | |
d: function(ds) { | |
return outer_polygon_generator(ds) + 'z'; | |
} | |
}); | |
ur.selectAll(".radius").data(polar_data).enter().append("path").attr('class', 'radius').attr("d", function(d) { | |
return "M0 0 L" + (RADIUS * Math.cos(d.angle - Math.PI / 2)) + " " + (RADIUS * Math.sin(d.angle - Math.PI / 2)); | |
}); | |
polygon_generator = d3.svg.line().x(function(d) { | |
return RADIUS / max * d.value * Math.cos(d.angle - Math.PI / 2); | |
}).y(function(d) { | |
return RADIUS / max * d.value * Math.sin(d.angle - Math.PI / 2); | |
}); | |
ur.append('path').datum(polar_data).attr({ | |
"class": 'polygon', | |
d: function(ds) { | |
return polygon_generator(ds) + 'z'; | |
} | |
}); | |
ur.selectAll(".dot").data(polar_data).enter().append("circle").attr('class', 'dot').attr({ | |
cx: function(d) { | |
return "" + (RADIUS / max * d.value * Math.cos(d.angle - Math.PI / 2)); | |
}, | |
cy: function(d) { | |
return "" + (RADIUS / max * d.value * Math.sin(d.angle - Math.PI / 2)); | |
}, | |
r: 4, | |
fill: function(d, i) { | |
return color(i); | |
} | |
}); | |
radius_scale = d3.scale.linear().domain([0, max]).range([0, RADIUS]); | |
arc_generator = d3.svg.arc().innerRadius(0).outerRadius(function(d) { | |
return radius_scale(d.value); | |
}).startAngle(function(d) { | |
return d.angle - polar_layout.angle() / 2; | |
}).endAngle(function(d) { | |
return d.angle + polar_layout.angle() / 2; | |
}); | |
bl.selectAll('.arc').data(polar_data).enter().append('path').attr({ | |
"class": 'arc', | |
d: arc_generator, | |
fill: function(d, i) { | |
return color(i); | |
} | |
}); | |
radius_scale = d3.scale.sqrt().domain([0, max]).range([0, RADIUS]); | |
arc_generator = d3.svg.arc().innerRadius(0).outerRadius(function(d) { | |
return radius_scale(d.value); | |
}).startAngle(function(d) { | |
return d.angle - polar_layout.angle() / 2; | |
}).endAngle(function(d) { | |
return d.angle + polar_layout.angle() / 2; | |
}); | |
br.selectAll('.arc').data(polar_data).enter().append('path').attr({ | |
"class": 'arc', | |
d: arc_generator, | |
fill: function(d, i) { | |
return color(i); | |
} | |
}); | |
}).call(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment