所以我有一张图表绘制了流量与日期和汇率与日期的关系。我试图遮蔽两条线之间的区域。但是,我想根据哪条线越高,将它涂成不同的颜色。以下工作没有最后一项要求:
var area = d3.svg.area()
.x0(function(d) { return x(d3.time.format("%m/%d/%Y").parse(d.original.date)); })
.x1(function(d) { return x(d3.time.format("%m/%d/%Y").parse(d.original.date)); })
.y0(function(d) { return y(parseInt(d.original.traffic)); })
.y1(function(d) { return y(parseInt(d.original.rate)); })
但是,添加最后一个要求,我尝试使用defined():
.defined(function(d){ return parseInt(d.original.traffic) >= parseInt(d.original.rate); })
现在这种情况大多有效,除非线条交叉。如何在BETWEEN点之下的一条线下遮挡区域?它基于点的着色,我希望它基于线条着色。如果我没有在线的一侧连续两个点,我根本不会有任何阴影。
答案 0 :(得分:15)
由于您在交叉点没有数据点,因此最简单的解决方案可能是获取每行上下的区域,并使用clipPath
来裁剪差异。
我假设您正在使用d3.svg.line
绘制区域所基于的线条。这样我们就可以在以后的区域重复使用.x()
和.y()
访问器功能:
var trafficLine = d3.svg.line()
.x(function(d) { return x(d3.time.format("%m/%d/%Y").parse(d.original.date)); })
.y(function(d) { return y(parseInt(d.original.traffic)); });
var rateLine = d3.svg.line()
.x(trafficLine.x()) // reuse the traffic line's x
.y(function(d) { return y(parseInt(d.original.rate)); })
您可以创建单独的区域功能来计算两条线上方和下方的区域。每行下方的区域将用于绘制实际路径,上面的区域将用作剪切路径。现在我们可以重新使用行中的访问器:
var areaAboveTrafficLine = d3.svg.area()
.x(trafficLine.x())
.y0(trafficLine.y())
.y1(0);
var areaBelowTrafficLine = d3.svg.area()
.x(trafficLine.x())
.y0(trafficLine.y())
.y1(height);
var areaAboveRateLine = d3.svg.area()
.x(rateLine.x())
.y0(rateLine.y())
.y1(0);
var areaBelowRateLine = d3.svg.area()
.x(rateLine.x())
.y0(rateLine.y())
.y1(height);
...其中height
是图表的高度,假设0
是图表顶部的y坐标,否则相应地调整这些值。
现在您可以使用上面的区域函数来创建这样的剪切路径:
var defs = svg.append('defs');
defs.append('clipPath')
.attr('id', 'clip-traffic')
.append('path')
.datum(YOUR_DATASET)
.attr('d', areaAboveTrafficLine);
defs.append('clipPath')
.attr('id', 'clip-rate')
.append('path')
.datum(YOUR_DATASET)
.attr('d', areaAboveRateLine);
id
属性是必需的,因为我们需要在实际剪切路径时引用这些定义。
最后,使用area-below函数绘制svg的路径。这里要记住的重要一点是,对于下面的每个区域,我们需要剪切到上面的对面区域,因此将根据#clip-traffic
剪切速率区域,反之亦然:
// TRAFFIC IS ABOVE RATE
svg.append('path')
.datum(YOUR_DATASET)
.attr('d', areaBelowTrafficLine)
.attr('clip-path', 'url(#clip-rate)')
// RATE IS ABOVE TRAFFIC
svg.append('path')
.datum(YOUR_DATASET)
.attr('d', areaBelowRateLine)
.attr('clip-path', 'url(#clip-traffic)')
之后,您只需要为这两个区域提供不同的填充颜色或任何您想要做的事情,以便将它们彼此区分开来。希望有所帮助!