2016-03-01 124 views
0

我想實現分組條形圖,但無法使其工作。我的數據結構如下:D3.js分組條形圖渲染X軸不正確

[{ 
    "Type": "Email", 
    "DataPoints": [{ 
     "xValue": 1, 
     "Value": 17 
    }, 
    { 
     "xValue": 2, 
     "Value": 59 
    }] 
}, 
{ 
    "Type": "Phone", 
    "DataPoints": [{ 
     "xValue": 1, 
     "Value": 1 
    }] 
}] 

我的代碼如下:

var margin = { top: 20, right: 0, bottom: 40, left: 50 }, 
    width = 960 - margin.left - margin.right, 
    height = 500 - margin.top - margin.bottom, 
    tooltipTextColour = "white"; 

if (data.length > 0) { 
    var x0 = d3.scale.ordinal() 
        .rangeRoundBands([0, width], .1); 

    var x1 = d3.scale.ordinal(); 

    var y = d3.scale.linear().range([height, 0]); 

    var xAxis = d3.svg.axis() 
         .scale(x0) 
         .orient("bottom"); 

    var yAxis = d3.svg.axis() 
         .scale(y) 
         .orient("left") 
         .tickFormat(d3.format(".2s")); 

    var svg = placeholder.append("svg") 
          .attr('width', width + margin.left + margin.right) 
          .attr('height', height + margin.top + margin.bottom) 
          .append('g') 
           .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); 

    var types = d3.entries(data); 

    x0.domain(types.map(function (d) { return d.Type; })); 
    x1.domain(types).rangeRoundBands([0, x0.rangeBand()]); 
    y.domain([0, d3.max(types, function (d) { return d3.max(d.value.DataPoints, function (d) { return d.Value; }); })]); 

    svg.append('g') 
     .attr('class', 'x axis') 
     .attr('transform', 'translate(0,' + height + ')') 
     .call(xAxis); 

    svg.append('g') 
     .attr('class', 'y axis') 
     .call(yAxis) 
     .append('text') 
      .attr("transform", "rotate(-90)") 
      .attr("y", 6) 
      .attr("dy", ".71em") 
      .style("text-anchor", "end") 
      .text("Complaints"); 

    var type = svg.selectAll(".type") 
        .data(data) 
        .enter() 
        .append('g') 
         .attr('class', 'type') 
         .attr('transform', function (d) { return 'translate(' + x0(d.Type) + ',0)'; }); 

    type.selectAll("rect") 
      .data(function (d) { return d.DataPoints; }) 
      .enter() 
      .append('rect') 
      .attr('width', x1.rangeBand()) 
      .attr('x', function (d) { return x1(d.xValue); }) 
      .attr('y', function (d) { return y(d.Value); }) 
      .attr('height', function (d) { return height - y(d.Value); }) 
      .style('fill', function (d, i) { return color(d.xValue); }); 
} 
else { 
    placeholder.append('p').text('No Data to Display').style('font-weight', 'bold'); 
} 

這將產生以下結果:

enter image description here

沒有任何人有任何想法,這是爲什麼?我認爲這是因爲它不是正確渲染x軸,但我無法解決原因。

任何幫助將不勝感激。

+0

放在一起搗鼓可能?我試過,但你的缺失變量,例如:placeholder :) – thatOneGuy

+0

@thisOneGuy我不知道如何創建一個小提琴和模擬所有適當的數據,因爲沒有任何經驗。但數據顯然是數據。佔位符只是d3.select在div上的結果,以便指定圖表的位置。這應該是它參數明智 – DaRoGa

+0

看起來像馬克有你的答案;) – thatOneGuy

回答

2

您沒有正確設置您的x0x1域。應該是這樣的:

// x0 is easy it's just the type 
    x0.domain(data.map(function(d) { 
    return d.Type 
    })); 
    // x1 is messy 
    // this reduces each DataPoints xValue into a single array 
    // and then creates a set from it to remove duplicates 
    x1.domain(
    d3.set(data.reduce(function(previousValue, currentValue) { 
     return previousValue.concat(currentValue.DataPoints.map(function(d) { 
     return d.xValue 
     })) 
    }, [])).values() 
).rangeRoundBands([0, x0.rangeBand()]); 

工作代碼:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> 
 

 
</head> 
 

 
<body> 
 
    <div id="placeholder"></div> 
 
    <script> 
 
    var placeholder = d3.select('#placeholder'); 
 

 
    var color = d3.scale.category10(); 
 

 
    var margin = { 
 
     top: 20, 
 
     right: 0, 
 
     bottom: 40, 
 
     left: 50 
 
     }, 
 
     width = 960 - margin.left - margin.right, 
 
     height = 500 - margin.top - margin.bottom, 
 
     tooltipTextColour = "white"; 
 

 
    var data = [{ 
 
     "Type": "Email", 
 
     "DataPoints": [{ 
 
     "xValue": 1, 
 
     "Value": 17 
 
     }, { 
 
     "xValue": 2, 
 
     "Value": 59 
 
     }] 
 
    }, { 
 
     "Type": "Phone", 
 
     "DataPoints": [{ 
 
     "xValue": 1, 
 
     "Value": 1 
 
     },{ 
 
     "xValue": 3, 
 
     "Value": 30 
 
     }] 
 
    }]; 
 

 
    if (data.length > 0) { 
 
     var x0 = d3.scale.ordinal() 
 
     .rangeRoundBands([0, width], .1); 
 

 
     var x1 = d3.scale.ordinal(); 
 

 
     var y = d3.scale.linear().range([height, 0]); 
 

 
     var xAxis = d3.svg.axis() 
 
     .scale(x0) 
 
     .orient("bottom"); 
 

 
     var yAxis = d3.svg.axis() 
 
     .scale(y) 
 
     .orient("left") 
 
     .tickFormat(d3.format(".2s")); 
 

 
     var svg = placeholder.append("svg") 
 
     .attr('width', width + margin.left + margin.right) 
 
     .attr('height', height + margin.top + margin.bottom) 
 
     .append('g') 
 
     .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); 
 

 
     x0.domain(data.map(function(d) { 
 
     return d.Type 
 
     })); 
 
     x1.domain(
 
     d3.set(data.reduce(function(previousValue, currentValue) { 
 
      return previousValue.concat(currentValue.DataPoints.map(function(d) { 
 
      return d.xValue 
 
      })) 
 
     }, [])).values() 
 
    ).rangeRoundBands([0, x0.rangeBand()]); 
 

 
     y.domain([0, d3.max(data, function(d) { 
 
     return d3.max(d.DataPoints, function(d) { 
 
      return d.Value; 
 
     }); 
 
     })]); 
 

 
     svg.append('g') 
 
     .attr('class', 'x axis') 
 
     .attr('transform', 'translate(0,' + height + ')') 
 
     .call(xAxis); 
 

 
     svg.append('g') 
 
     .attr('class', 'y axis') 
 
     .call(yAxis) 
 
     .append('text') 
 
     .attr("transform", "rotate(-90)") 
 
     .attr("y", 6) 
 
     .attr("dy", ".71em") 
 
     .style("text-anchor", "end") 
 
     .text("Complaints"); 
 

 
     var type = svg.selectAll(".type") 
 
     .data(data) 
 
     .enter() 
 
     .append('g') 
 
     .attr('class', 'type') 
 
     .attr('transform', function(d) { 
 
      return 'translate(' + x0(d.Type) + ',0)'; 
 
     }); 
 

 
     type.selectAll("rect") 
 
     .data(function(d) { 
 
      return d.DataPoints; 
 
     }) 
 
     .enter() 
 
     .append('rect') 
 
     .attr('width', x1.rangeBand()) 
 
     .attr('x', function(d) { 
 
      return x1(d.xValue); 
 
     }) 
 
     .attr('y', function(d) { 
 
      return y(d.Value); 
 
     }) 
 
     .attr('height', function(d) { 
 
      return height - y(d.Value); 
 
     }) 
 
     .style('fill', function(d, i) { 
 
      return color(d.xValue); 
 
     }); 
 
    } else { 
 
     placeholder.append('p').text('No Data to Display').style('font-weight', 'bold'); 
 
    } 
 
    </script> 
 
</body> 
 

 
</html>

+1

謝謝@Mark。當我在早上上班時,我會試試這個。它總是數據操作混淆了我:) Ur一個d3 pro。到目前爲止,我的所有問題都可以找到,所以毫無疑問,這將起作用謝謝!!! – DaRoGa

+0

@DaRoGa,不客氣。最近我被困在一些非常無聊的會議中,所以你的問題給了我閒置的大腦一些有趣的想法:) – Mark

+0

我試着爲你找到更多的問題! – DaRoGa