-2

我试图从本质上将此水平条形图旋转为垂直条形图,但无法弄清楚如何做到这一点。我可以创建一个普通的柱形图,但是一旦我尝试输入负值并计算 y 和高度,所有的地狱都会崩溃。这是我的小提琴。(至少我能够创建 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)); });
4

1 回答 1

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/

于 2013-03-25T17:34:23.243 回答