2013-03-25 53 views
-2

我試圖從本質上將this水平條形圖轉換爲垂直條形圖,但無法弄清楚如何去做。我可以創建一個正常的柱形圖,但是一旦我嘗試將負值放入並計算y和高度,所有地獄都會崩潰。這裏是my fiddle。 (至少我能夠創建Y軸(我認爲)。)如何創建負值的柱狀圖?

我在這裏做錯了什麼?

var data = [{"letter":"A",'frequency':10},{"letter":"B","frequency":-5},{"letter":"C","frequency":7}]; 

var margin = {top: 20, right: 20, bottom: 30, left: 40}, width = 750 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; 
var x = d3.scale.ordinal().rangeRoundBands([0, width], .1); 
var y = d3.scale.linear().range([height, 0]); 
var xAxis = d3.svg.axis() 
      .scale(x) 
      .orient("bottom"); 
var yAxis = d3.svg.axis() 
      .scale(y) 
      .orient("left"); 

var svg = d3.select("body").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 x0 = Math.max(-d3.min(data), d3.max(data)); 
    x.domain(data.map(function(d) { return d.letter; })); 
    y.domain([d3.min(data, function(d) { return d.frequency; }), d3.max(data, function(d) { return d.frequency; })]); 

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

    svg.selectAll(".bar") 
     .data(data).enter().append("rect") 
     .attr("class", "bar") 
     .attr("x", function(d, i) { return x(d.letter); }) 
     .attr("y", function(d, i) { return x(Math.min(0, d.frequency));}) 
     .attr("width", x.rangeBand()) 
     .attr("height", function(d) { return Math.abs(x(d.frequency) - x(0)); }); 
+0

相關:http://stackoverflow.com/questions/15388481/d3- JS-直方圖與-正和負片ve-values – 2013-03-25 20:11:32

回答

1

看起來像有兩個問題在這裏:

  1. 錯別字:.attr("y", function(d, i) { return x(...);})現在應該.attr("y", function(d, i) { return y(...);})。對於height屬性中的比例也是如此。

  2. 從X軸的0基到Y軸的0基的變化。在X軸上有一個基於零的條形,條形的x屬性爲x(0)。在Y軸上有一個基於0的條形,條的y屬性是而不是y(0),但是y(value)(因爲條的「基」不再是矩形的前沿) - 所以在此代碼中需要使用Math.max(0, value)(這將給y(value)爲正值),而不是Math.min(0, value)

    svg.selectAll(".bar") 
        // ...snip... 
        .attr("y", function(d, i) { return y(Math.max(0, d.frequency));}) 
        .attr("height", function(d) { return Math.abs(y(d.frequency) - y(0)); }); 
    

見更新小提琴:http://jsfiddle.net/pYZn8/5/

+0

行var x0 = Math.max(-d3.min(data),d3.max(data));不再有貢獻,因爲數據不再是一個數字的數組,因此x0不再是一個數字。 – jing3142 2013-03-25 18:03:18

+0

謝謝! @ jing3142:你是對的。我不善於保持這一點。 – 2013-03-25 19:17:33