【问题标题】:Is an NVD3 Line Plot with Markers Possible?带标记的 NVD3 线图是否可行?
【发布时间】:2012-11-23 20:29:20
【问题描述】:

我正在制作一个 NVD3 线图,如果我可以为每个数据点显示标记,而不仅仅是线本身,它将显着提高清晰度。不幸的是,我还没有找到一个简单的方法来使用 NVD3 做到这一点。我也考虑过使用散点图,但我不知道如何显示点之间的连接线。我考虑的第三个选项是叠加一条线和散点图,但这会在图例中显示每个系列两次,并可能导致其他不必要的视觉复杂化。

有没有办法优雅地完成这个任务?下面列出了我的格式化技术的示例代码,但 test_data 中的 'size' 和 'shape' 属性对当前代码的线图没有影响。

test_data = [ {     key: 'series1',
            values: [
                { x: 1, y: 2.33, size:5, shape:"circle" },
                { x: 2, y: 2.34, size:5, shape:"circle" },
                { x: 3, y: 2.03, size:5, shape:"circle" },
        ] } ];


nv.addGraph(function() {
  var test_chart = nv.models.lineChart();
  test_chart.xAxis.axisLabel('Sample Number');
  test_chart.yAxis
        .axisLabel('Voltage (V)')
        .tickFormat(d3.format('.02f'));

  d3.select('#test_plot')
      .datum(test_data)
    .transition().duration(500)
      .call(test_chart);

  nv.utils.windowResize(test_chart.update);
  return test_chart;
});

【问题讨论】:

  • nvd3 版本 1.8.6 或 1.8.4 的任何解决方案?

标签: nvd3.js


【解决方案1】:

我还想在我正在进行的项目中添加标记。这是我和我的搭档找到的解决方案。

首先,您必须选择图表中的所有点并将填充不透明度设置为 1:

#my-chart .nv-lineChart circle.nv-point
{
    fill-opacity: 1;
}

现在您的积分将可见。要调整每个点的大小,您需要修改每个点的“r”(半径)属性。这不是一种风格,所以你不能用 css 来做。这是一些可以完成这项工作的 jQuery 代码。 500 毫秒的延迟是为了让代码在图表呈现之前不会运行。这个sn-p设置半径为3.5:

        setTimeout(function() {
            $('#my-chart .nv-lineChart circle.nv-point').attr("r", "3.5");
        }, 500);

【讨论】:

  • 我也是这样做的,这就是解决方案。
  • 但是,这是更新或重绘点,会出现图表先在屏幕上绘制不同半径的点,然后重新绘制另一个r为3.5和a在屏幕上闪烁。
  • 我看到在源代码中,您可以为每个数据设置一个大小字段,但是,我尝试了但它不起作用,并且有一行代码:Math.sqrt(z (getSize(d,i))/Math.PI) 来计算 r 属性。
  • 这似乎适用于 1.8.1 版本,但不适用于 1.8.4 或 1.8.6 的最新版本。有什么解决方案吗?
【解决方案2】:

这让我很困惑,直到我得到社区的帮助:

css styling of points in figure

这是我的解决方案,基于css

.nv-point {
    stroke-opacity: 1!important;
    stroke-width: 5px!important;
    fill-opacity: 1!important;
}

如果有人从rCharts 来到这里,下面是一个rmarkdown 模板,用于创建带有线条和标记的nPlot

 ```{r 'Figure'}  
require(rCharts)
load("data/df.Rda") 
# round data for rChart tooltip display
df$value <- round(df$value, 2)
n <- nPlot(value ~ Year, group = 'variable', data = df, type = 'lineChart') 
n$yAxis(axisLabel = 'Labor and capital income (% national income)')
n$chart(margin = list(left = 100)) # margin makes room for label
n$yAxis(tickFormat = "#! function(d) {return Math.round(d*100*100)/100 + '%'} !#")
n$xAxis(axisLabel = 'Year')
n$chart(useInteractiveGuideline=TRUE)
n$chart(color = colorPalette)
n$addParams(height = 500, width = 800)
n$setTemplate(afterScript = '<style>
  .nv-point {
    stroke-opacity: 1!important;
    stroke-width: 6px!important;
    fill-opacity: 1!important;
  } 
</style>'
)
n$save('figures/Figure.html', standalone = TRUE)
```

【讨论】:

    【解决方案3】:

    当前版本的 nvd3 使用 path 而不是 circle 来绘制标记。这是我用来显示标记的一段 css 代码。

    #chart g.nv-scatter g.nv-series-0 path.nv-point
    {
        fill-opacity: 1;
        stroke-opacity: 1;
    }
    

    我也在https://github.com/novus/nvd3/issues/321写了一些关于这个的东西,你可以发现我是如何改变制造者的形状的。

    我不知道如何更改标记的大小。正在努力寻找解决方案。

    【讨论】:

    • 谢谢。我参考了您提到的代码,它帮助我将一个特定系列转换为散点图。但我无法改变形状。我将它与 angularjs 一起使用并使用 angular-nvd3 指令 - github.com/krispo/angular-nvd3/issues/44
    【解决方案4】:

    使用 nvd3 中的以下逻辑有选择地启用指向某些系列的点。

    //i is the series number; starts with 0
    
    var selector = 'g.nv-series-'+i+' circle';
    d3.selectAll(selector).classed("hover",true);
    

    但是,数据中的附加参数(比如说'enable_points':'true')会更有意义。我希望用这个想法对 nvd3 进行一些更改。

    【讨论】:

      【解决方案5】:

      对于当前版本的 NVD3 (1.8.x),我使用这个基于 D3 的解决方案(仅脚本,不需要 CSS 文件或样式块):

      nv.addGraph(function() {
        // ...
        return chart;
      },
      function() {
        // this function is called after the chart is added to document
        d3.selectAll('#myChart .nv-lineChart .nv-point').style("stroke-width",
          "7px").style("fill-opacity", ".95").style("stroke-opacity", ".95");
      }
      );
      

      使用的样式正是 NVD3 通过将“悬停”类应用于每个点(悬停时)添加的样式。根据您的需要调整它们。

      【讨论】:

      • 我在上面实现了这个解决方案,但我不确定为什么在绘制图表之前调用我的回调函数。
      • @Dinesh 该函数是在图表添加到文档后调用的(正如内联注释所说),不一定是在绘制之后。你会遇到什么(不想要的)影响?
      • 我希望在绘图完全绘制(全部绘制)后调用该函数。我正在尝试修改绘制的某些元素(在绘制之后)。但我的函数甚至在情节完成之前就被调用了。
      • 所以您正在尝试解决另一个问题,而不是这个问题所涉及的问题,对吧?在这种情况下,也许在这里创建另一个问题是正确的方法......
      猜你喜欢
      • 1970-01-01
      • 2013-02-26
      • 1970-01-01
      • 2011-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 1970-01-01
      相关资源
      最近更新 更多