我想基于此example创建一个包含D3的多系列折线图。我的问题是,缺少一些值:
y x1 x2 x3
1 0.8 0.7
2 0.9 0.7
3 0.9 1.2 0.7
4 1.1 0.7
5 0.8 1.1 2.7
6 0.9 1.2 2.6
7 1.3 0.8
我想得到以下图表:
应该忽略在开始或结束时缺少的点数。我可以通过
实现这一目标d3.svg.line().defined(function (d) { return d.value; }
但如果一条线内缺少某些点,则不应该中断该线。使用上面的代码,绿线(x1)在y = 3处停止并在y = 5处继续。但是我希望将这些点连接起来。
如果不使用line().defined()
,则会处理所有缺失点,就好像它们的值为0
一样。
以下是代码,我曾经找到实现该功能的方法:
我认为在将数据传递给我的图表函数之前替换数据数组中的缺失点是没有办法的,因为我必须在图例和工具提示中显示值,我不能在这里显示计算值。因此,例如,如果我使用鼠标移动y = 4,则图例中应显示x1:-- x2:1.1 x3:0.8
(x1此处没有任何值)。此外,(实际)点应显示为圆圈。我也不想在内存中有两个数据表(一个包含真实的测量数据,另一个包含图表行的增强数据)。
答案 0 :(得分:3)
我可以解决它,但我不确定我是否可以通过转换以这种方式处理数据更新。我稍微更改了数据格式,现在分别绘制每一行:
var data = [
{
name: "x1",
color: "green",
data: [
[1, 0.8],
[2, 0.9],
[3, 0.9],
[5, 0.8],
[6, 0.9]
]
},
{
name: "x2",
color: "red",
data: [
[3, 1.2],
[4, 1.1],
[5, 1.1],
[6, 1.2],
[7, 1.3]
]
},
{
name: "x3",
color: "blue",
data: [
[1, 0.7],
[2, 0.7],
[3, 0.7],
[4, 0.7],
[5, 2.7],
[6, 2.6],
[7, 0.8]
]
},
];
var margin = [20, 20, 20, 20];
var w = 400 - margin[1] - margin[3];
var h = 300 - margin[0] - margin[2];
var x = d3.time.scale().range([0, w]);
var y = d3.scale.linear().range([h, 0]);
var lineFunction = d3.svg.line()
.x(function(d) { return x(d[0]); })
.y(function(d) { return y(d[1]); });
graph = d3.select('#line')
.append("svg:svg")
.attr("class", "line-graph")
.attr("width", w + margin[1] + margin[3])
.attr("height", h + margin[0] + margin[2])
.append("svg:g")
.attr("transform", "translate(" + margin[3] + "," + margin[0] + ")");
x.domain([
d3.min(data, function(c) { return d3.min(c.data, function(v) { return v[0]; }); }),
d3.max(data, function(c) { return d3.max(c.data, function(v) { return v[0]; }); })
]);
y.domain([
d3.min(data, function(c) { return d3.min(c.data, function(v) { return +v[1]; }); }),
d3.max(data, function(c) { return d3.max(c.data, function(v) { return +v[1]; }); })
]);
var linesGroup = graph
.append("svg:g")
.attr("class", "lines");
var linedata;
for (var i in data) {
linedata = data[i];
linesGroup
.append("path")
.attr("d", lineFunction(linedata.data))
.attr("class", "line")
.attr("fill", "none")
.attr("stroke", function(d, i) {
console.log(linedata.color);
return linedata.color;
});
};