使用d3遮蔽两条线之间的区域

And*_*rew 12 javascript linechart d3.js

所以我有一个图表绘制了流量与日期和费率与日期的关系.我试图遮蔽两条线之间的区域.但是,我想根据哪条线越高,将它涂成不同的颜色.以下工作没有最后一个要求:

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)); })
Run Code Online (Sandbox Code Playgroud)

但是,添加最后一个要求,我尝试使用defined():

.defined(function(d){ return parseInt(d.original.traffic) >= parseInt(d.original.rate); })
Run Code Online (Sandbox Code Playgroud)

现在这种情况大多有效,除非线条交叉.如何在BETWEEN点之下的一条线下遮挡区域?这是基于点的阴影,我希望它基于线条阴影.如果我在线的一侧没有两个连续的点,我根本没有任何阴影.

jsh*_*ley 16

由于交叉口处没有数据点,因此最简单的解决方案可能是获取每条线上下的区域,并使用clipPaths来裁剪差异.

我假设您正在使用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)); })
Run Code Online (Sandbox Code Playgroud)

您可以创建单独的区域函数来计算两条线上方和下方的区域.每行下方的区域将用于绘制实际路径,上面的区域将用作剪切路径.现在我们可以重新使用行中的访问器:

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);
Run Code Online (Sandbox Code Playgroud)

... 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);
Run Code Online (Sandbox Code Playgroud)

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)')
Run Code Online (Sandbox Code Playgroud)

之后,您只需要为两个区域提供不同的填充颜色或任何您想要做的事情,以区分它们.希望有所帮助!