【问题标题】:How do I color line segments between specific points in a d3 line plot?如何在 d3 线图中的特定点之间为线段着色?
【发布时间】:2014-06-26 23:50:48
【问题描述】:

我有一个简单的时间线图与动态更新的数据值。也就是说,我会定期添加一个新的数据值,一旦达到“最大值”,我就会在添加新值时开始从数据集中删除一个数据值。线图是“动画的”,它的工作原理是在线的右端出现一个新点,而最旧的点从左边消失。根据新数据的某些属性(正在绘制的值和其他一些关联值),我需要更改连接最新数据值和一定数量的先前绘制数据值的线段的外观。

例如,假设数据值是一个简单的“对象”,由 { Time, DataValueToPlot, FlagValue } 组成。正如我所说,我目前正在将每个数据对象的“DataValueToPlot”绘制在 X 时间轴上。假设最后绘制的 3 个值是 (1PM,10)、(2PM,20) 和 (3PM,30)(尽管实际时间并不统一)。我们已经绘制了 10、20 和 30。现在 (4PM,15) 的新值到达并且 15 值被添加到线图中,但是这个新值有一个关联的 FlagValue 指示前面的三个线段是比如说,用大笔画宽度绘制的红色。这如何实现?

明确地说,我并不是要求在任何数据值超过或低于指定值时绘制彩色线段,而是我需要能够更改所选线段的外观。

======================== 回复@jshanley 感谢您的示例代码。我看到它可以让我将适当的颜色与“线”(段)相关联,但我无法让它工作。我最初使用了将数据数组与 svg 路径绑定的常见模式,其中我使用 line 函数来描述如何绘制数据点,例如:

lineFcn = d3.svg.line()
        .x(function(d) { return(d.Time); })
        .y(function(d) { return(d.DataValueToPlot); })
        .interpolate("linear");
var svgContainer = d3.select("body").append("svg")
                                    .attr("width",500)
                                    .attr("height",500);
var lineGraph = svgContainer.append("path")
                            .attr("d", lineFcn(lineData))
                            .attr("stroke","black")
                            .attr("stroke-width",1)
                            .attr("fill","none");

这种方法的问题是我无法将您的建议应用于它,因为您将笔画属性与每个“线”(段)相关联,但在上面的代码中我们没有任何此类元素。我试图重写代码,以便我不使用带有 svg line() 辅助函数的 svg 路径,而只是创建一个单独的“线段”的集合。这意味着在您的“输入”代码块中,我们扩展了 selection.enter().append('line') 以添加 X1,Y1 和 X2,Y2 坐标,但这就是问题所在。我找不到任何可以让我定义这些值的方法。

我试图将您的建议扩展到以下内容:

selection.enter().append('line')
        .attr("x1",function(d,i) { return(d[i-1].Time); })
        .attr("y1",function(d,i) { return(d[i-1].DataValueToPlot)); })
        .attr("x2",function(d,i) { return(d].Time); })
        .attr("y2",function(d,i) { return(d].DataValueToPlot)); })

但对“d[i-1]”的引用会触发错误。

1) 访问器函数是否有某种方法可以引用“先前”数据值? 2) 您能否扩展您之前的代码示例,向我展示如何在您设置笔画属性的位置实际绘制每个线段?

谢谢!

【问题讨论】:

    标签: d3.js colors


    【解决方案1】:

    假设您使用标准的 Enter、Update、Exit 模式described here,您可以在更新部分插入一些分支逻辑,并根据 FlagValue 是否出现切换颜色或其他样式。

    function update(data) {
    
      // reset the flag
      var flagged = false;
    
      var selection = svg.selectAll('line')
        .data(data);
    
      // ENTER
      selection.enter().append('line')
        // adding the attribute is superfluous
        //  but it gives us a callback in which
        //  we can set `flagged` to `true`
        .attr('data-flagged', function(d) {
           if (d.FlagValue === true) {
             flagged = true;
             return true;
           } else {
             return false;
           }
        });
    
      // ENTER + UPDATE
      // set the stroke based on whether `flagged` is true
      selection.attr('stroke', function(d) {
        if (flagged) {
          // could also add more conditional
          //  logic here to change only certain lines
          //  for example
          // if (d.time < someTimeVar) { return 'blue'; }
          return 'red';
        } else {
          return 'green';
        }
      });
    
      // EXIT
      selection.exit().remove();
    
    }    
    

    【讨论】:

    • 我刚刚得知我无法输入详细回复作为评论,我不得不编辑我的原始帖子以回复您的建议。你能告诉我我应该如何对回复提供详细的回复吗?但也请看我的回复。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    • 2018-11-13
    • 2019-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多