title: D3.js Grouped bar chart with JSON data
body: <p>I am new to <code>d3.js</code>. I want to map <code>JSON</code> data in grouped bar chart as shown in fig as example <a href="https://i.stack.imgur.com/9BLVz.png" rel="nofollow noreferrer">https://i.stack.imgur.com/9BLVz.png</a>  .I know there is something wrong with my x scaling. According to my chart x should show the months and on y axis hours.It's giving me 6 bars but for some reason bars are getting overlapped on each other.Could anyone please help me out here.</p>
  
  <p>JSON data coming from MariaDB as an object.</p>
  
  <pre><code>[
      {"name":"jhon","hours":"9","months":"August"},
      {"name":"jack","hours":"8","months":"August"},
      {"name":"jhon","hours":"7","months":"July"},
      {"name":"jack","hours":"6","months":"July"},
      {"name":"jhon","hours":"4","months":"June"},
      {"name":"jack","hours":"5","months":"June"}
  ] 
  </code></pre>
  
  <p>Code</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;meta charset="utf-8"&gt;
  &lt;style&gt;
      .bar {
        fill: steelblue;
        stroke:black
      }
  
      .bar:hover {
        fill: brown;
      }
  
      .axis--x path {
        display: none;
      }
  
  &lt;/style&gt;
  
  &lt;svg width="500" height="500"&gt;&lt;/svg&gt;
  &lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;
  &lt;script&gt;
      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 + ")");
  
      d3.json("http://localhost:8888/index.php?r=emp/gethours", function(d) {
  
      var ydomain=d3.extent(d,function(d){return d.hours;});
  
      x.domain(d.map(function(d,i) {return d.months}));
  
      y.domain(ydomain);
  
      g.selectAll(".bar")
          .data(d)
          .enter().append("rect")
          .attr("x", function(d,i) { return x(d.months) })
          .attr("y", function(d) {return y(d.hours); })
          .attr("width", 40)
          .attr("height", function(d) { return height - y(d.hours); })
      });
  
  &lt;/script&gt;
  </code></pre>
  
  <p>After suggestion my modify data and code is </p>
  
  <p>Bar graph generate for this is  <a href="https://i.stack.imgur.com/VowEA.png" rel="nofollow noreferrer">https://i.stack.imgur.com/VowEA.png</a></p>
  
  <pre><code>[{"name":"jhon","hours":"8","months":"June","emp_id":"1"},{"name":"jack","hours":"6","months":"June","emp_id":"2"},{"name":"jhon","hours":"6","months":"July","emp_id":"1"},{"name":"jack","hours":"7","months":"July","emp_id":"2"},{"name":"jhon","hours":"8","months":"August","emp_id":"1"},{"name":"jack","hours":"9","months":"August","emp_id":"2"}]
  
  &lt;style&gt;
  
  .bar {
    fill: steelblue;
    stroke:black
  }
  
  .bar:hover {
    fill: brown;
  }
  
  .axis--x path {
    display: none;
  }
  
  &lt;/style&gt;
  &lt;svg width="500" height="500"&gt;&lt;/svg&gt;
  &lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;
  &lt;script&gt;
  
      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 z = d3.scaleOrdinal()
      .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
  
      d3.json("http://localhost:8888/index.php?r=emp/gethours", function(d) {
  
  
                          var ymaxdomain=d3.max(d,function(d){return parseInt(d.hours);});
                          var x1domain=d3.extent(d,function(d){return parseInt(d.emp_id);});
  
  
                          x.domain(d.map(function(d) {return d.months}));
                          y.domain([0,ymaxdomain]);
  
                          var x1=d3.scaleBand().rangeRound([0, x.bandwidth()]);
                          x1.domain(x1domain);
  
                           g.selectAll(".bar")
                          .data(d)
                          .enter().append("rect")
                          .attr("x", function(d,i) {console.log(d,i); return (x(d.months)+x1(parseInt(d.emp_id))); })
  
                          .attr("y", function(d) {return y(d.hours); })
                          .attr("width",x1.bandwidth())
                          .attr("height", function(d) { return height - y(parseInt(d.hours)); })
                          .attr("fill", function(d,i) { return z(d.emp_id); });
  
  
  
                           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("Hours");
  
  
  
  
  
  });
  
  &lt;/script&gt;
  </code></pre>