【问题标题】:How can I make my upside-downed stacked graph right using d3.js?如何使用 d3.js 制作我的倒置堆叠图?
【发布时间】:2016-07-05 06:19:01
【问题描述】:

“Web 的交互式数据可视化”的第 11 章展示了如何使用 D3.js 库创建堆叠条形图。该示例生成了一个倒置图表,其中条形连接到 x 轴的顶部。

Upside-down

<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">
  var w = 500;
  var h = 300;

  var dataset = [[ { x: 0, y: 5 }, { x: 1, y: 4 }, { x: 2, y: 2 }, { x: 3, y: 7 }, { x: 4, y: 23 }],
    [ { x: 0, y: 10 }, { x: 1, y: 12 }, { x: 2, y: 19 }, { x: 3, y: 23 }, { x: 4, y: 17 } ],
    [ { x: 0, y: 22 }, { x: 1, y: 28 }, { x: 2, y: 32 }, { x: 3, y: 35 }, { x: 4, y: 43 } ]];

  var stack = d3.layout.stack();
  stack(dataset);

  var xScale = d3.scale.ordinal()
      .domain(d3.range(dataset[0].length)).rangeRoundBands([0, w], 0.05);

  var yScale = d3.scale.linear()
      .domain([0, d3.max(dataset, function(d) {
        return d3.max(d, function(d) { return d.y0 + d.y; });
      })])
      .range([0, h]);

  var colors = d3.scale.category10();

  var svg = d3.select("body").append("svg").attr("width", w).attr("height", h);

  var groups = svg.selectAll("g").data(dataset).enter().append("g")
      .style("fill", function(d, i) { return colors(i); });

  var rects = groups.selectAll("rect")
      .data(function(d) { return d; })
      .enter()
      .append("rect")
      .attr("x", function(d, i) { return xScale(i); })
      .attr("y", function(d) { return yScale(d.y0); })
      .attr("height", function(d) { return yScale(d.y); })
      .attr("width", xScale.rangeBand());
</script>

这是使堆叠条倒置的代码。

当我更改如下几个代码时:

1) 将 yScale .range 更改为:

.range([0, h]);

.range([h, 0]);

2) 将矩形 "y" .attr 从:

.attr("y", function(d) { return yScale(d.y0); })

.attr("y", function(d) { return yScale(d.y0) + yScale(d.y) - h; })

3) 将矩形“高度”.attr 从:

.attr("height", function(d) { return yScale(d.y); })

.attr("height", function(d) { return h - yScale(d.y); })

应用这些更改后,堆栈附加到底部并仍保持其相对大小。 right graph

问题是,我不明白第二步和第三步的意思。

为什么y 应该是yScale(d.y0) + yScale(d.y) - h

为什么height 应该是h - yScale(d.y)

如果将这些值修改为不同的值(如y(yScale(d.y0) + yScale(d.y))/10 左右),则不会显示所需的图形。

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    这种“反向数学”(正如 Scott Murray 在他的代码中所说)的原因是,在您的第一个代码中,倒置的代码中,SVG 坐标系和范围的 Y 坐标都从上到下增长(零位于顶部,最大值位于底部)。但是,当您在第二个代码中将范围反转为 ([h, 0]) 时,SVG 坐标系继续使 Y 坐标从上到下增长,尽管范围现在向上。

    在“倒置”代码中,栏的顶部实际上是它的底部,它的高度随着 SVG 系统一起下降。但在第二个代码中,“正常”图表,情况更复杂:条形的“底”不再是它的“y”属性,并且高度值向下添加像素,与倒置范围无关。 SVG 的坐标系统不会因为我们反转范围而自动反转。

    这很复杂,所以让我重新表述一下:在 SVG 坐标系中,“y”属性始终是矩形的顶部。在您的第一个代码中,矩形的顶部是条形的底部......但是,在您的第二个代码中,矩形的顶部是条形的顶部。令人困惑,我知道。

    让我们做一个简单的数学运算:想象一个高度为 100 像素的 SVG 和一个高度为 80 像素的条(y0: 0, y:80)。要绘制此条,“y”属性必须设置其顶部。如何计算它? yScale(d.y0) 给我们 100,yScale(d.y) 给我们 20。通过将它们相加,我们得到 120,减去 100(高度)给我们 20,即顶部的位置。为什么不直接使用d.y?它适用于第一个小节,但不适用于后续小节。

    现在是高度,它必须是 80 像素。 yScale(d.y) 给了我们 20,所以,100(高度)减去 20 给我们 80... 这适用于每个条形图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-27
      • 1970-01-01
      • 1970-01-01
      • 2017-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多