如何在带有 scaleTime 的条形图中使用 x 和宽度?

IT技术 javascript d3.js data-visualization
2021-03-09 14:31:09

我这里有一个代码笔 - https://codepen.io/anon/pen/xpaYYw?editors=0010

它是一个简单的测试图,但日期将被格式化为这样。

我在 x 轴上有日期,在 y 上有数量

如何使用 x 比例来设置条形的宽度和 x 位置。

    layers.selectAll('rect')
      .data(data)
      .enter()
      .append('rect')

      .attr('height', function(d, i) {
        return height - y(d.one);
      })

      .attr('y', function(d, i) {
        return y(d.one);
      })

      .attr('width', function(d, i) {
        return 50;
      })

      .attr('x', function(d, i) {
        return 80*i;
      })

      .style('fill', (d, i) => {
        return colors[i];
      });
1个回答

你的问题与编程、JavaScript 或 D3 无关……问题是一个基本的 dataviz 概念(这就是为什么我添加了 在您的问题中标记):

你试图做的是不正确的!你应该不会有时间刻度使用吧。时间尺度用于时间序列(其中我们使用点,或由线连接的点)。

如果您在 x 轴上使用带有时间的条形,您将面临以下问题:

  1. 定位栏:栏的左边距将始终位于您设置的日期。整个酒吧将那个日期之后躺着
  2. 设置条形的宽度:在实际条形图中,x 轴使用分类变量,宽度没有意义。但在时间尺度上,宽度代表时间

但是,为了便于说明,让我们创建这个带有时间刻度的条形图(尽管这是一个错误的选择)......这是如何做到的:

首先,及时设置条形的“宽度” 假设每个条形将有 10 天的宽度:

.attr("width", function(d){
    return x(d3.timeDay.offset(d.date, 10)) - x(d.date)
})

然后,将x条形图位置设置为当前日期减去其宽度的一半(即,在我们的示例中小于 5 天):

.attr('x', function(d, i) {
    return x(d3.timeDay.offset(d.date, -5));
})

最后,不要忘记在时间尺度上创建一个“填充”:

var x = d3.scaleTime()
  .domain([d3.min(data, function(d) {
    return d3.timeDay.offset(d.date, -10);
  }), d3.max(data, function(d) {
    return d3.timeDay.offset(d.date, 10);
  })])
  .range([0, width]);

这是带有这些更改的代码:

在这种情况下,您可以使用乐队音阶,只需传递字符串。
2021-05-02 14:31:09
虽然我理解将 scaleTime 与条形图一起使用的担忧以及引入的挑战,但我认为这不一定是 ttmt 所说的“错误”。事实上,有时它是非常合适的。例如,纽约时报在他们的 COVID 图表中有几个很好的例子,其中他们将条形作为原始数据,并在 7 天平均值的条形顶部添加一条线。有一个 scaleTime 比例尺来允许放大和缩小以便为 x 刻度提供适合这种情况的适当日期标签是很好的。但是,是的,对于大多数条形图, scaleLinear 或 scaleBand 更好。
2021-05-14 14:31:09
Gerardo,谢谢你的帮助。我明白你现在关于不使用 scaleTime 的意思。我不在乎这些日期之间的时间或数据。它只会显示当月的数据。我会更好地使用 ascaleLinear作为 x 轴上的日期,因为它们只是一个时刻,它们可能只是几个月。我只需要将数据中的时间戳转换为可读日期
2021-05-16 14:31:09