强制d3折线图忽略空值

ell*_*iot 6 javascript charts d3.js

我有一个包含空值的时间序列折线图,从而在我的行中留下了空白.我想要做的是选择让d3线生成器忽略空值并跨越间隙.

正如您在图像中看到的那样,蓝色系列有间隙.

正如您在图像中看到的那样,蓝色系列有间隙.

我的部分问题是我已经标准化了这种数据格式:

[
  {"x":1397102460000,"y0":11.4403,"y1":96.5},
  {"x":1397139660000,"y0":13.1913,"y1":96.5},
  {"x":1397522940000,"y1":96.5},
  ...
]
Run Code Online (Sandbox Code Playgroud)

因此,当一个系列具有特定时间戳的读数时,另一个系列具有空值.

最终,我可以尝试通过在绘制之前过滤我的数据来解决这个问题,但我希望有一个更聪明的解决方案,也许是在线生成器周围.

我的线生成器非常简单:

line = d3.line()
         .x(function(d) {
           return ~~_this.x(d[xKey]);
         })
         .y(function(d) {
           return ~~_this.y(d[yKey]);
         })
         .defined(function(d) {
           return d[yKey] || d[yKey] === 0;
         });
Run Code Online (Sandbox Code Playgroud)

如果我删除我的defined方法,行连接,但null y值被解释为0px而不是仅存在.

在此输入图像描述

有没有办法告诉线路生成器不要在空数据中包含一个点?

我还应该注意到我正在使用d3 v4.x.

Ger*_*ado 3

假设您希望直线从上一个有效点到下一个有效点作为一条直线,最好的想法是过滤您的数据,如评论中所建议的。

line.defined在行中创建间隙,这是预期的行为,也是此函数的用途。

因此,如果您不想过滤数据并且不想创建间隙(使用defined),则可以更改行生成器函数。这不是一个好主意,它是一个丑陋的代码,但它是可行的。

设置一个计数器:

var counter;
Run Code Online (Sandbox Code Playgroud)

如果该值有效 ( != null),则增加计数器。如果不是,请告诉行生成器保留最后一个有效值:

var line = d3.line()
    .x((d, i) => {
        if (data[i].y) {
            return xScale(d.x)
        } else {
            return xScale(data[counter].x)
        }
    })
    .y((d, i) => {
        if (d.y) {
            counter = i;
            return yScale(d.y)
        } else {
            return yScale(data[counter].y)
        }
    });
Run Code Online (Sandbox Code Playgroud)

在此演示中,该行从第五个数据点(最后一个有效值)跳转到第九个数据点(下一个有效值):

var counter;
Run Code Online (Sandbox Code Playgroud)
var line = d3.line()
    .x((d, i) => {
        if (data[i].y) {
            return xScale(d.x)
        } else {
            return xScale(data[counter].x)
        }
    })
    .y((d, i) => {
        if (d.y) {
            counter = i;
            return yScale(d.y)
        } else {
            return yScale(data[counter].y)
        }
    });
Run Code Online (Sandbox Code Playgroud)