2017-04-20 90 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域,所以你之後做了。試試吧,它適用於我 –