动态更改每个条形的高度 & 反转 SVG 元素

505 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的19天,点击查看活动详情

动态更改每个条形的高度

介绍

和动态设置 x 值一样,也可以把每个条形的高度设置成数组中数据点的值。

selection.attr("property", (d, i) => {

})

d 是数据点值,i 是数组中数据点的索引。

实操

改变 height 属性的回调函数,让它返回数据值乘以 3 的值。

注意: 记住,把所有数据点乘以相同的常数来对数据进行缩放(就像放大), 这有利于看清例子中条形数值之间的差异。

  1. 第一个 rectheight 应为 36
  2. 第二个 rectheight 应为 93
  3. 第三个 rectheight 应为 66
  4. 第四个 rectheight 应为 51
  5. 第五个 rectheight 应为 75
  6. 第六个 rectheight 应为 54
  7. 第七个 rectheight 应为 87
  8. 第八个 rectheight 应为 42
  9. 第九个 rectheight 应为 27
<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];

    const w = 500;
    const h = 100;

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

    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", (d, i) => i * 30)
       .attr("y", 0)
       .attr("width", 25)
       .attr("height", (d, i) => {
 
          return d*3

       });
  </script>
</body>

反转 SVG 元素

介绍

你可能已经注意到了常见的条形图像是把这个翻转或者颠倒过来。 这是因为 SVG 的 (x, y) 坐标有些特别。

在 SVG 中,坐标轴的原点在左上角。 x 坐标为 0 将图形放在 SVG 区域的左边缘, y 坐标为 0 将图形放在 SVG 区域的上边缘。 x 值增大矩形将向右移动, y 值增大矩形将向下移动。

为了使条形图向上,需要改变 y 坐标计算的方式。 这需要计算条形的高度和 SVG 区域的总高度。

SVG 区域的高度为 100。 如果在集合中一个数据点的值为 0,那么条形将从 SVG 区域的最底端开始(而不是顶端)。 为此,y 坐标的值应为 100。 如果数据点的值为 1,你将从 y 坐标为 100 开始来将这个条形设置在底端, 然后需要考虑该条形的高度为 1,所以最终的 y 坐标将是 99。

y 坐标为 y = heightOfSVG - heightOfBar 会将条形图向上放置。

实操

改变 y 属性的回调函数,让条形图向上放置。 height 的值是 3 倍 d 的值。

注意: 通常,关系是 y = h - m * d,其中 m 是缩放数据点的常数。

  1. 第一个 recty 值应该为 64
  2. 第二个 recty 值应该为 7
  3. 第三个 recty 值应该为 34
  4. 第四个 recty 值应该为 49
  5. 第五个 recty 值应该为 25
  6. 第六个 recty 值应该为 46
  7. 第七个 recty 值应该为 13
  8. 第八个 recty 值应该为 58
  9. 第九个 recty 值应该为 73
<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];

    const w = 500;
    const h = 100;

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

    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => {
    
          return h - (3 * d)

       })
       .attr("width", 25)
       .attr("height", (d, i) => 3 * d);
  </script>
</body>