简体   繁体   中英

Making a grouped bar chart using d3.js

I'm new to d3.js and I'm finding hard to create grouped bar chart but I tried something which appears to be not right. I want months in x-axis and count of group(mars and jupiter) in y-axis. something like dis Link .

 var svg = d3.select("svg"), margin = {top: 20, right: 20, bottom: 30, left: 40}, width = +svg.attr("width") - margin.left - margin.right, height = +svg.attr("height") - margin.top - margin.bottom; var x = d3.scaleBand().rangeRound([0, width]).padding(0.1), y = d3.scaleLinear().rangeRound([height, 0]); var g = svg.append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var data = [ {"Group":"Mars","count":10,"months":"June"}, {"Group":"Jupiter","count":50,"months":"June"}, {"Group":"Mars","count":70,"months":"July"}, {"Group":"Jupiter","count":60,"months":"July"}]; var ymaxdomain=d3.max(d,function(d){return d.count;}); x.domain(d.map(function(d) {return d.months})); y.domain([0,ymaxdomain]); var x1=d3.scaleBand().rangeRound([0, x.bandwidth()]); x1.domain(d.map(function(d) {return d.months;})); g.selectAll(".bar") .data(data) .enter().append("rect") .attr("x", function(d,i) {console.log(d,i); return (x(d.months))} .attr("y", function(d) {return y(d.count); }) .attr("width",x1.bandwidth()) .attr("height", function(d) { return height - y(d.count); }) g.append("g") .attr("class", "axis") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)); g.append("g") .attr("class", "axis") .call(d3.axisLeft(y).ticks(null, "s")) .append("text") .attr("x", 2) .attr("y", y(y.ticks().pop()) + 0.5) .attr("dy", "0.32em") .attr("fill", "#000") .attr("font-weight", "bold") .attr("text-anchor", "start") .text("count"); 
 <style> .bar { fill: steelblue; stroke:black } </style> 
 <!DOCTYPE html> <svg width="600" height="600"></svg> <body><script src="//d3js.org/d3.v4.min.js"></script></body> 

For creating a grouped bar chart, you have to set 2 scales for the x position:

var x = d3.scaleBand().rangeRound([0, width])
  .padding(0.1);

var x1 = d3.scaleBand()
  .rangeRound([0, x.bandwidth()])
  .padding(0.05);

Then, you append groups using the first scale...

var groups = g.selectAll(null)
  .data(data)
  .enter()
  .append("g")
  .attr("transform", function(d) {
    return "translate(" + x(d.months) + ",0)";
  })

... and, inside each group, you append the rects using the second scale.

Here is the demo:

 var svg = d3.select("svg"), margin = { top: 20, right: 20, bottom: 30, left: 40 }, width = +svg.attr("width") - margin.left - margin.right, height = +svg.attr("height") - margin.top - margin.bottom; var color = d3.scaleOrdinal(d3.schemeCategory10); var x = d3.scaleBand().rangeRound([0, width]) .padding(0.1), y = d3.scaleLinear().rangeRound([height, 0]); var g = svg.append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var data = [{ "Group": "Mars", "count": 10, "months": "June" }, { "Group": "Jupiter", "count": 50, "months": "June" }, { "Group": "Mars", "count": 70, "months": "July" }, { "Group": "Jupiter", "count": 60, "months": "July" }]; var ymaxdomain = d3.max(data, function(d) { return d.count; }); x.domain(data.map(function(d) { return d.months })); y.domain([0, ymaxdomain]); var x1 = d3.scaleBand() .rangeRound([0, x.bandwidth()]) .padding(0.05) .domain(data.map(function(d) { return d.Group; })); color.domain(data.map(function(d) { return d.Group; })); var groups = g.selectAll(null) .data(data) .enter() .append("g") .attr("transform", function(d) { return "translate(" + x(d.months) + ",0)"; }) var bars = groups.selectAll(null) .data(function(d) { return [d] }) .enter() .append("rect") .attr("x", function(d, i) { return x1(d.Group) }) .attr("y", function(d) { return y(d.count); }) .attr("width", x1.bandwidth()) .attr("height", function(d) { return height - y(d.count); }) .attr("fill", function(d) { return color(d.Group) }) g.append("g") .attr("class", "axis") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)); g.append("g") .attr("class", "axis") .call(d3.axisLeft(y).ticks(null, "s")) .append("text") .attr("x", 2) .attr("y", y(y.ticks().pop()) + 0.5) .attr("dy", "0.32em") .attr("fill", "#000") .attr("font-weight", "bold") .attr("text-anchor", "start") .text("count"); 
 .bar { fill: steelblue; stroke: black } 
 <svg width="600" height="600"></svg> <script src="//d3js.org/d3.v4.min.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM