D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
OussamaHOURIRA
Full window
Github gist
BarChartAnimation
Built with
blockbuilder.org
<!DOCTYPE html> <style> body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } form { position: absolute; left: 60px; top: 40px; } label { display: block; } .xAxis .domain { display: none; } </style> <body> <!--The buttons radio form--> <form> <label><input type="radio" name="mode" value="grouped"> Grouped</label> <label><input type="radio" name="mode" value="stacked"checked> Stacked</label> </form> <script src="https://d3js.org/d3.v4.min.js"></script> <script> // This work is a result of many reading and github projects,especially inspired from Mike Bostock’s work var parseDate = d3.timeParse("%b %Y"); var formatTime = d3.timeFormat("%Y"); var margin = {top: 30, right: 30, bottom: 30, left: 40}, width = 900 - margin.left - margin.right, height = 450 - margin.top - margin.bottom; var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom); var g = svg.append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var x = d3.scaleBand() .range([0, width]) .padding(0.4); var x1 = d3.scaleBand() .padding(0.1); var yBar = d3.scaleLinear() .range([height, 0]); var yStack = d3.scaleLinear() .range([height, 0]); var color = d3.scaleOrdinal() .range(["#00aaf9", "#00ff44", "#ede73f", "#696969"]); // Import Stock data and build the transitional informations d3.csv("stocks.csv", function(StockInfo) { var nest_by_year = d3.nest() .key(function(d) {return formatTime(parseDate(d.date)); }) .entries(StockInfo); var Transitional_Info = []; nest_by_year.forEach(function(KeyYear) { var nest_by_symbol = d3.nest() .key(function(d) {return d.symbol; }) .rollup(function(v) {return d3.mean(v,function(d) {return d.price; })}) .object(KeyYear.values); Transitional_Info.push({ key: +KeyYear.key, values: nest_by_symbol }); }); var Merged_data = Transitional_Info.map(function(d) { var merged = {year: d.key}; Object.keys(d.values).forEach(function(key) { merged[key] = d.values[key]; }); return merged; }); var keys = d3.keys(Merged_data[0]).slice(1); // Summing values grouped by key var Summing = []; Merged_data.forEach(function(d){ Summing.push(d3.sum(keys, function(key) {return d[key]; })) }); x.domain(Merged_data.map(function(d) {return d.year; })); x1.domain(keys).range([0, x.bandwidth()]); yBar.domain([0, d3.max(Merged_data, function(d) {return d3.max(keys, function(key) {return d[key]; }); })]); yStack.domain([0, d3.max(Summing)]); var group = g .selectAll("g") .data(d3.stack().keys(keys)(Merged_data)) .enter().append("g") .attr("fill", function(d) {return color(d.key); }); var rect = group.selectAll("rect") .data(function(d) {return d; }) .enter().append("rect") .attr("x", function(d) {return x(d.data.year); }) .attr("y", function(d) {return yStack(d[1]); }) .attr("height", function(d) {return yStack(d[0]) - yStack(d[1]); }) .attr("width", x.bandwidth()) .attr('stroke', '#000000') .attr('stroke-dasharray', '10,5') .attr('stroke-linecap', 'butt') .attr('stroke-width', '2'); g.append("g") .attr("class", "xAxis") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x).tickSize(0)); var yAxis = g.append("g") .call(d3.axisLeft(yStack)); yAxis.append("text") .attr("x", -35) .attr("y", -15) .attr("dy", "0.32em") .attr("fill", "#3d3d3d") .attr("font-weight", "bold") .attr("text-anchor", "start") .text("Pricing"); d3.selectAll("input") .on("change", changed); function changed() { if (this.value === "grouped") GroupeIt(); else StackIt(); }; function GroupeIt() { rect .transition().duration(1300) .attr("width", x1.bandwidth()) .transition().duration(1400) .attr("x", function(d) {return x(d.data.year) + x1(this.parentNode.__data__.key)}) .transition().duration(1400) .attr("y", function(d) {return yBar(d[1] - d[0]); }) .attr("height", function(d) {return yBar(0) - yBar(d[1]-d[0]); }); yAxis .transition() .call(d3.axisLeft(yBar)); }; function StackIt() { rect .transition().duration(1400) .attr("y", function(d) {return yStack(d[1] - d[0]); }) .attr("height", function(d) {return yStack(d[0]) - yStack(d[1]); }) .transition().duration(1400) .attr("y", function(d) {return yStack(d[1]); }) .transition().duration(1300) .attr("x", function(d) {return x(d.data.year); }) .attr("width", 50); yAxis .transition() .call(d3.axisLeft(yStack)); }; var legend = svg.selectAll(".legend") .data(color.domain().reverse()).enter().append("g") .attr("class", "legend") .attr("transform", function(d, i) {return "translate(0," + i * 20 + ")"; }); legend.append("path") .style("fill", function(d) {return color(d); }) .attr("d", d3.symbol().type(d3.symbolSquare).size(100) ) .attr("transform", "translate(" + width/2.5 + "," + 20 +")"); legend.append("text") .attr("x", width/2.5 + 15) .attr("y", 20) .attr("dy", ".35em") .style("text-anchor", "start") .text(function(d) {return d; }); }); </script>
https://d3js.org/d3.v4.min.js