Skip to content

Instantly share code, notes, and snippets.

@DarienLiang
Last active October 3, 2016 20:07
Show Gist options
  • Save DarienLiang/b2635cfff1cc0d90b3abda68ed4cfa66 to your computer and use it in GitHub Desktop.
Save DarienLiang/b2635cfff1cc0d90b3abda68ed4cfa66 to your computer and use it in GitHub Desktop.
test
license: mit
Fruit Count
Apple 12
Pear 4
Orange 13
Cherry 13
Blueberry 8
Banana 2
Peach 13
Lemon 5
Watermelon 15
Lime 24
Mango 16
Grape 10
Kiwi 8
Pineapple 15
Date 20
<!DOCTYPE html>
<meta charset="utf-8">
<style>
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var m = [50, 50, 50, 50],
w = 960 - m[1] - m[3],
h = 450 - m[0] - m[2];
var x,
y,
N = 15,
duration = 2000,
delay = 500,
radius = 50;
var rscale = d3.scale.linear()
.domain([0, N])
.range([0, radius]);
var barWidth = 65,
barPadding = 5;
// set color
// var color = d3.scale.category20();
var c_value = function(d){ return d.f_name; };
var color = function(key){
dict = {
Apple:"#ff6666",
Pear:"#ffed89",
Orange:"#ff9933",
Cherry:"#cc0000",
Blueberry:"#373EFF",
Banana:"#ffd21e",
Peach:"#FFBAE2",
Lemon:"#fff67a",
Watermelon:"#00994c",
Lime:"#ccff99",
Mango:"#ff7c19",
Grape:"#b266ff",
Kiwi:"#999900",
Pineapple:"#FFFF7A",
Date:"#994c00",
}
return dict[key];
}
var svg = d3.select("body").append("svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
var pie = d3.layout.pie()
.value(function(d) {
return d.count;
});
var arc = d3.svg.arc();
d3.csv("fruit.csv", function(error, data) {
data.forEach(function(d) {
d.fruit = d.Fruit;
d.count = +d.Count;
});
x = d3.scale.ordinal()
.domain(data.map(function(d) { return d.fruit; }))
.rangeRoundBands([0, w]);
y = d3.scale.linear()
.domain([d3.max(data.map(function(d) { return d.count; })), 0])
.range([0, h]);
// add pie
var g = svg.selectAll(".symbol")
.data(function() { return pie(data); })
.enter()
.append("g")
.attr("class", "symbol");
g.append("rect")
.style("fill", function(d) { return color(d.data.fruit); })
.attr({
x: function(d){ return x(d.data.fruit); },
y: function(d){ return y(d.data.count); },
width: function(d) { return rscale(d.data.count); },
height: function(d) { return rscale(d.data.count); },
rx: function(d){return 0.5*rscale(d.data.count); },
ry: function(d){return 0.5*rscale(d.data.count); },
})
.transition()
.duration(1500)
.delay(1000)
.attr({
width: x.rangeBand(),
height: function(d) { return h - y(d.data.count); },
rx: 0,
ry: 0
});
//draw bar chart first
g.append("path")
.style("fill", function(d) {
return color(d.data.fruit);
});
function scatterText(d) { return "translate(" + (x(d.data.fruit)+x.rangeBand()/3+10) + "," + (y(d.data.count)-10) + ")"; }
function barText(d) { return "translate(" + (x(d.data.fruit)+x.rangeBand()/3+10) + "," + (0.5*y(d.data.count)+0.5*h) + ")"; }
g.append("text")
.text(function(d) { return d.data.fruit; })
.attr({
fill: 'black', 'alignment-baseline': 'before-edge', 'text-anchor': 'middle',
transform: scatterText
})
.style('font', '12px Lucida Console')
.transition()
.duration(1500)
.delay(1000)
.attr("transform", barText);
//call the function after a period of time
setTimeout(toPie, 2500);
});
function toPie(){
var g = svg.selectAll(".symbol");
g.selectAll("rect").remove();
g.selectAll("path")
.transition()
.duration(duration)
.tween("arc", arcTween)
setTimeout(function() { return g.selectAll("text").remove(); }, 2000)
g.transition()
.duration(duration)
.delay(3000)
.attr("transform", explode);
//The idea here is to first draw an arc like a bar,
//then tween the bar-like arc to the donut arc.
//Thus, the fruit is find the initial bar size and position:
//The initial bar height is approximated by the length of
//outside arc: barHeight = init_OuterRadius * init_Angle.
//So we can get the startAngle shown in f;
//(Note that: the measure of angle in d3 starts from vertical y:
// y angle
// | /
// | /
// | /
// |o/
// |/
// )
function arcTween(d) {
var path = d3.select(this),
text = d3.select(this.parentNode).select("text"),
x0 = x(d.data.fruit),
y0 = h - y(d.data.count); //initial height
return function(t) {
var r = h / 2 / Math.min(1, t + 1e-3),
//a is stepping factor, starting from 1 to 0,
//as the timer t goes.
//A simper alternative: a = 1 - t;
a = Math.cos(t * Math.PI / 2),
xx = (-r + (a) * (x0 + x.rangeBand()) + (1-a)*(w + h)/2),
yy = ((a) * h + (1 - a) * h/2),
f = {
innerRadius: (r - x.rangeBand() / (2 - a)) * a,
outerRadius: r,
//endAngle:0,
startAngle: a * (Math.PI / 2 - y0 / r) + (1 - a) * d.startAngle,
endAngle: a * (Math.PI / 2) + (1 - a) * d.endAngle
};
path.attr("transform", "translate(" + xx + "," + yy + ")");
path.attr("d", arc(f));
text.attr("transform", "translate(" + arc.centroid(f) + ")translate(" + xx + "," + yy + ")rotate(" + ((f.startAngle + f.endAngle) / 2 + 3 * Math.PI / 2) * 180 / Math.PI + ")");
};
}
function explode(x, index) {
var offset = 600;
var angle = (x.startAngle + x.endAngle) / 2;
var xOff = Math.sin(angle) * offset;
var yOff = -Math.cos(angle) * offset;
return "translate("+xOff+", "+yOff+")";
}
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment