如何创建具有负值的柱形图?

时间:2013-03-25 16:44:00

标签: javascript d3.js

我试图将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)); });

1 个答案:

答案 0 :(得分: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)); });
    
  3. 请参阅更新的小提琴:http://jsfiddle.net/pYZn8/5/