D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
ikbale
Full window
Github gist
grouped charts stocks
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { font-family: sans-serif; } form { position: absolute; left: 200px; top: 10px; } label { display: block; } .xAxis .domain { display: none; } </style> </head> <body> <script> var parseDate = d3.timeParse("%b %Y"); var formatTime = d3.timeFormat("%Y"); var margin = {top: 30, right: 30, bottom: 30, left: 40}, width = 960 - margin.left - margin.right, height = 500 - 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(["#98abc5", "#8a89a6", "#7b6888", "#6b486b"]); // read from stocks.csv d3.csv("stocks.csv", function(data) { var nest_by_year = d3.nest() .key(function(d) {return formatTime(parseDate(d.date)); }) .entries(data); //display year var Transitional_data = []; 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_data.push({ key: +KeyYear.key, values: nest_by_symbol }); }); var Final_data = Transitional_data.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(Final_data[0]).slice(1); console.log(keys) var SumData = []; Final_data.forEach(function(d){ SumData.push(d3.sum(keys, function(key) {return d[key]; })) }); x.domain(Final_data.map(function(d) {return d.year; })); x1.domain(keys).range([0, x.bandwidth()]); yBar.domain([0, d3.max(Final_data, function(d) {return d3.max(keys, function(key) {return d[key]; }); })]); yStack.domain([0, d3.max(SumData)]); var group = g .selectAll("g") .data(d3.stack().keys(keys)(Final_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()); 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", "#000") .attr("font-weight", "bold") .attr("text-anchor", "start") .text("Price"); d3.selectAll("input") .on("click", changed); function changed() { if (this.value === "grouped") GroupeIt(); else StackIt(); }; function GroupeIt() { rect .transition().duration(900) .attr("width", x1.bandwidth()) .transition().duration(1000) .attr("x", function(d) {return x(d.data.year) + x1(this.parentNode.__data__.key)}) .transition().duration(1000) .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(1000) .attr("y", function(d) {return yStack(d[1] - d[0]); }) .attr("height", function(d) {return yStack(d[0]) - yStack(d[1]); }) .transition().duration(1000) .attr("y", function(d) {return yStack(d[1]); }) .transition().duration(900) .attr("x", function(d) {return x(d.data.year); }) .attr("width", x.bandwidth()); 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> </body>
https://d3js.org/d3.v4.min.js