【问题标题】:Fill area between two lines填充两条线之间的区域
【发布时间】:2016-01-26 21:50:37
【问题描述】:

对于这样一个基本的问题,我们深表歉意。是否可以填充两行之间的区域?

例如,我有历史高/低温数据。我想在这两个时间序列之间创建一个阴影区域。

我尝试过像这样使用 lineChart 的区域功能:

return [
    {
        values: tsData.normal,
        key: 'Historical Normal',
        classed: 'dashed'
    },
    {
        area: true,
        values: tsData.hi,
        key: 'Historical Max',
        color: '#0000ff'
    },
    {
        area: true,
        values: tsData.low,
        key: 'Historical Min',
        color: '#ffffff',
        fillOpacity: 1
    }
];

这会导致这张图片:

请注意,历史最小值线下方的网格线被填充区域隐藏。这个解决方案有点笨拙和丑陋。有没有更直接的方法来做到这一点?

【问题讨论】:

    标签: nvd3.js


    【解决方案1】:

    我通过使用 d3 绘制区域实现了更好的解决方案。

    首先,我创建了一个合并 tsData.hi 和 tsData.low 的数组(我称为 areaData)。对于我推动的每个数据点,例如: {x: "x 值", y0:"tsData.hi 中的 y 值", y1:"tsData.low 中的 y 值"}

    然后我根据图表的比例定义了 x 和 y 比例:

    var x = chart.xScale();
    var y = chart.yScale();
    

    然后我添加了一个区域定义为

    var area = d3.svg.area()
        .x(function (d) { return x(d.x); })
        .y0(function (d) { return y(d.y0); })
        .y1(function (d) { return y(d.y1); });
    

    接下来我使用以下方法绘制区域:

    d3.select('.nv-linesWrap')
        .append("path")
        .datum(areaData)
        .attr("class", "area")
        .attr("d", area)
        .style("fill", "#AEC7E8")
        .style("opacity", .2);
    

    这实现了更好看的解决方案。因为 nvd3 会在调整窗口大小时更新图表。我将该区域的绘图包装在一个函数中。这样我就可以在调整窗口大小时调用该函数,同时删除先前绘制的区域,如下所示:

    var drawArea = function () {
        d3.select(".area").remove();
        d3.select('.nv-linesWrap')
            .append("path")
            .datum(areaData)
            .attr("class", "forecastArea")
            .attr("d", area)
            .style("fill", "#AEC7E8")
            .style("opacity", .2);
    }
    drawArea();
    
    nv.utils.windowResize(resize);
    
    function resize() {
        chart.update();
    
        drawArea();
    }
    

    我还禁止使用图例打开和关闭系列,因为我没有处理这种情况:

    chart.legend.updateState(false);
    

    结果:

    【讨论】: