使用d3来遮挡两条线之间的区域
Using d3 to shade area between two lines
所以我有一张图表,绘制了流量与日期以及费率与日期的关系。我正在设法把两条线之间的区域遮蔽起来。然而,我想根据哪条线更高,给它涂上不同的颜色。以下工作没有最后的要求:
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); })
现在这基本上是有效的,除了线交叉的时候。如何在点之间的一条线下对区域进行着色?它基于点进行着色,我希望它基于线进行着色。如果我在直线的一侧没有两个连续的点,我就不会得到任何阴影。
由于交叉点处没有数据点,最简单的解决方案可能是获得每条线上方和下方的面积,并使用clipPath
s来裁剪差异。
我假设您使用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
属性是必要的,因为我们在实际剪裁路径时需要参考这些定义。
最后,使用下面的区域函数绘制svg的路径。这里需要记住的重要一点是,对于下面的每个区域,我们需要剪裁到上面的对面区域,因此Rate区域将基于#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)')
之后,你只需要给这两个区域不同的填充颜色,或者你想做的任何事情来区分它们。希望能有所帮助!
相关文章:
- 浏览器之间的文本区域更新方式不同
- 谷歌图表(Geochart)在世界和欧洲之间切换区域
- 两个折线图之间的 D3 区域
- 使用 D3 的两条线之间的阴影区域
- HTML 表单文件中的行号与文本区域中的行号之间的对应关系
- 如何在高图表的 2 点之间制作颜色填充区域
- 为坐标之间的区域添加背景色
- 单击按钮时,将光标放在文本区域中的 2 点之间
- 仅在按 Tab 按钮时在两个文本区域之间切换
- 如何使用纯javascript和css(无jquery)调暗整个屏幕,除了两个同心正方形之间的区域
- 移动可查看区域的高度(地址栏和导航栏之间)
- JavaScript图表库,用于处理两行之间的着色区域
- 在输入和输出区域之间具有不同的行高
- 显示/隐藏文本区域框+单击时在图像之间切换
- 如何在光标开始和文本区域结束之间获取文本
- 检查用户光标是否位于文本区域中的两个标记之间
- 在输入和文本区域之间切换,但前提是文本很长
- 使用d3来遮挡两条线之间的区域
- 有条件地填充d3中两行之间的区域
- 如何在HighChart中用多个yAxis填充两个系列之间的区域