Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitaku/f122242ed96503ce1fa9 to your computer and use it in GitHub Desktop.
Save nitaku/f122242ed96503ce1fa9 to your computer and use it in GitHub Desktop.
Pie vs. pie II
### 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)
# arc chart subplotting
radius_scale = d3.scale.linear()
.domain([0, max])
.range([0, RADIUS])
inner_radius_scale = d3.scale.linear()
.domain([0, max])
.range([RADIUS*0.4, RADIUS])
arc_generator = d3.svg.arc()
.innerRadius((d) -> inner_radius_scale(max-d.value))
.outerRadius((d) -> radius_scale(max))
.startAngle((d) -> d.angle - polar_layout.angle()/2)
.endAngle((d) -> d.angle + polar_layout.angle()/2)
pies = ur.selectAll('.arc')
.data(polar_data)
pies.enter().append('path')
.attr
class: 'arc'
d: arc_generator
fill: (count, klass) -> color(klass)
# 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)
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;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="Pie vs. pie II" />
<title>Pie vs. pie II</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, arc_generator, bl, br, color, data, height, inner_radius_scale, max, pie, pies, polar, polar_data, polar_layout, 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);
}
});
radius_scale = d3.scale.linear().domain([0, max]).range([0, RADIUS]);
inner_radius_scale = d3.scale.linear().domain([0, max]).range([RADIUS * 0.4, RADIUS]);
arc_generator = d3.svg.arc().innerRadius(function(d) {
return inner_radius_scale(max - d.value);
}).outerRadius(function(d) {
return radius_scale(max);
}).startAngle(function(d) {
return d.angle - polar_layout.angle() / 2;
}).endAngle(function(d) {
return d.angle + polar_layout.angle() / 2;
});
pies = ur.selectAll('.arc').data(polar_data);
pies.enter().append('path').attr({
"class": 'arc',
d: arc_generator,
fill: function(count, klass) {
return color(klass);
}
});
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