我有一条d3.js折线图,有多行。用户可以更改与每一行关联的过滤器,这会更改绘制的值以及图表更新。
这一切都运行正常,但如果用户选择导致行没有匹配值的过滤器,我会在控制台中收到此错误:
Error: Invalid value for <path> attribute d="" d3.js:8481
attrNull d3.js:8481
(anonymous function) d3.js:8653
d3_class.forEach d3.js:275
start d3.js:8652
(anonymous function) d3.js:8646
d3_timer_mark d3.js:2085
d3_timer_step d3.js:2065
用户可见的内容很好 - 当图表更新时,线条(显然)不会被绘制。但是我想摆脱这个错误!这是输入/更新/删除行的代码:
var line = g.selectAll('path.line')
.data(function(d) { return d; },
function(d) { return d.id; });
line.enter().append('path')
.attr('class', 'line')
.attr('id', function(d) { return lineCSSID(d.id); })
.style('stroke', function(d) { return d.color; });
line.data(function(d) { return d; })
.transition()
.attr('d', function(d) { return chartLine(d.values); });
line.exit().remove();
调用return chartLine(d.values);
且d.values
为空数组时发生错误。我能做些什么会让它更优雅地失败?
如果它影响答案:用户可以再次更改该行的过滤器,如果这会导致匹配数据,则会重新绘制该行。
答案 0 :(得分:1)
在将数据添加到图表之前,我最后省略了没有数据的任何行。
例如,如果(在我的问题代码之前的某个地方)我有类似的东西,其中data
是一个对象数组,每个对象代表图表上的一行:
var svg = d3.select('.chart')
.selectAll('svg')
.data([data]);
然后在此之前我现在这样做:
data = data.filter(function(d){ return d.values.length > 0; });
这可确保任何没有数据点的行都不会传递给图表。
更新:我意识到如果 all 这些行的过滤器导致没有匹配的值,那么我在尝试计算{{1对于x轴。所以我现在有这样的事情:
domain
答案 1 :(得分:0)
您是否尝试添加一些条件,以便只有在d.values不是空数组时才会返回?
if(d.values.length > 0){
return chartLine(d.values);
}
答案 2 :(得分:0)
我迟到了,但考虑使用d3.line并声明使用line.defined定义数据的位置。这是一种用于容纳缺失数据的d3内置方法。
例如:
var line = d3.line()
.defined(function(d) { return d[hasData]; })
.x(function(d) { return x(d.x); })
.y(function(d) { return y(d.y); });
如果对象包含数据,function(d) { return d[hasData]; }
应返回truthy值,否则返回false。如果返回false,则d3将跳过呈现该特定数据元素。
如果您的数据是:
var data = [{name:"foo", value:1, hasData:true}, {name:"bar", value:0, hasData:false}]
d3.line
的上述设置将跳过第二个对象("bar"
)。此外,由于0
是假的,而且任何正int
或float
都是真实的,您只需使用function(d) { return d.value; }
。
迈克自己做了一个例子here。
干杯。