2017-04-20 61 views
0

我是d3.js的新成员。我想在分组条形图中绘制JSON数据,如图所示https://i.stack.imgur.com/9BLVz.png。我知道我的x缩放比例有问题。根据我的图表x应该显示月份和y轴的小时数。它给我6个小节,但由于某种原因,小节互相重叠。请任何人都可以帮我在这里。D3.js使用JSON数据分组条形图

来自MariaDB的JSON数据作为对象。

[ 
    {"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"} 
] 

代码

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 
    .bar { 
     fill: steelblue; 
     stroke:black 
    } 

    .bar:hover { 
     fill: brown; 
    } 

    .axis--x path { 
     display: none; 
    } 

</style> 

<svg width="500" height="500"></svg> 
<script src="https://d3js.org/d3.v4.min.js"></script> 
<script> 
    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); }) 
    }); 

</script> 

后建议我修改的数据和代码是

柱状图生成,这是https://i.stack.imgur.com/VowEA.png

[{"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"}] 

<style> 

.bar { 
    fill: steelblue; 
    stroke:black 
} 

.bar:hover { 
    fill: brown; 
} 

.axis--x path { 
    display: none; 
} 

</style> 
<svg width="500" height="500"></svg> 
<script src="https://d3js.org/d3.v4.min.js"></script> 
<script> 

    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"); 





}); 

</script> 

回答

2

JSON数据

[{"name":"jhon","hours":"8","months":"June","emp_id":"1"}, 
{"name":"jack","hours":"6","months":"June","emp_id":"2"}, 
{"name":"jim","hours":"7","months":"June","emp_id":"3"}, 
{"name":"tim","hours":"4","months":"June","emp_id":"4"}, 
{"name":"jhon","hours":"6","months":"July","emp_id":"1"}, 
{"name":"jack","hours":"7","months":"July","emp_id":"2"}, 
{"name":"jim","hours":"8","months":"July","emp_id":"3"}, 
{"name":"tim","hours":"6","months":"July","emp_id":"4"}, 
{"name":"jhon","hours":"8","months":"August","emp_id":"1"}, 
{"name":"jack","hours":"9","months":"August","emp_id":"2"}, 
{"name":"jim","hours":"7","months":"August","emp_id":"3"}, 
{"name":"tim","hours":"8","months":"August","emp_id":"4"}] 

,答案------- --------------------------------------------------

分组条形图图片https://i.stack.imgur.com/1ud5S.png

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 

.bar { 
    fill: steelblue; 
    stroke:black 
} 

.bar:hover { 
    fill: brown; 
} 

.axis--x path { 
    display: none; 
} 

</style> 
<svg width="600" height="600"></svg> 
<script src="https://d3js.org/d3.v4.min.js"></script> 
<script> 

    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 d.hours;}); 
         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.emp_id;})); 

         g.selectAll(".bar") 
         .data(d) 
         .enter().append("rect") 
         .attr("x", function(d,i) {return (x(d.months)+x1(d.emp_id)); }) 

         .attr("y", function(d) {return y(d.hours); }) 
         .attr("width",x1.bandwidth()) 
         .attr("height", function(d) { return height - y(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)) 
           .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"); 

}); 

</script> 
+0

感谢您的帮助Lary Ciminera。 –

0

https://bl.ocks.org/mbostock/3887051你需要第二个x轴为每个“组”移动您的矩形。 看看var x1;它的域名是.rangeRound([0, x0.bandwidth()]);

在你的代码

您可以做

var d = [ 
     {"name":"jhon","hours":"9","months":"August","group":0}, 
     {"name":"jack","hours":"8","months":"August","group":1}, 
     {"name":"jhon","hours":"7","months":"July","group":0}, 
     {"name":"jack","hours":"6","months":"July","group":1}, 
     {"name":"jhon","hours":"4","months":"June","group":0}, 
     {"name":"jack","hours":"5","months":"June","group":1} 
    ] 

x1.domain([0,1]) 
... 
.attr("x", function(d) { return x(d.months)+x1(d.group) }) 
+0

感谢解决方案Lary但是我不能修改我的JSON数据,因为它来自数据库连接查询。 –

+0

你总是可以在你的js中做一个d.forEach来“保存”你的数据,或者根据你的数据创建一个定义组值的函数,你可以在不修改你的数据的情况下实现它,你需要一个例子吗? –

+0

当然,先生,这将是真正的帮助full.Please根据我的数据,以便我可以很容易地把握它.. –

0

哦,我发现你的问题 变化

var ydomain=d3.extent(d,function(d){return d.hours;}); 

var ymaxdomain=d3.max(d,function(d){return d.hours;}); 
    y.domain([0,ymaxdomain]); 

在y轴上的最小值为4,而不是的0

编辑: 你也要做移动X1的范围的定义后定义x域:

x.domain(d.map(function(d,i) {return d.months})); 
// this should go after 
    var x1=d3.scaleBand().rangeRound([0, x.bandwidth()]); 
+0

谢谢你的帮助,但是x缩放的问题仍然是相同的。 。 –

+0

move var x1 = d3.scaleBand()。rangeRound([0,x.bandwidth()]);之后 x.domain(d.map(function(d,i){return d.months})); –

+0

我编辑了我的答案,以解决你的第二轴问题,x1取决于x带宽,这取决于x域,所以你之后做了。试试吧,它适用于我 –