NVD3堆积面积图

Dea*_*dly 2 stacked-area-chart d3.js nvd3.js

堆积面积图示例http://nvd3.org/ghpages/stackedArea.html

当我点击一个系列时,它会扩展到所有图表区域,删除其他系列.如何禁用此功能?

Ame*_*aBR 6

没有任何NVD3图表选项可以覆盖此行为,但您可以直接覆盖click事件处理程序.然而,堆积面积图有点复杂......

NVD3使用d3.dispatch对象来处理自定义事件.用户点击和鼠标悬停以及相关操作都将转换为这些自定义事件.

如果希望在自定义事件之后发生函数,则可以调用dispatch对象的.on(eventName, function)方法.如果函数参数是null,它将取消附加到该名称的任何先前的事件处理函数.(如果您希望同一事件触发多个函数,可以使用表单的字符串"eventName.namespace"作为第一个参数向事件名称添加"名称空间" ;然后只有在使用该函数on再次调用该函数时才会取消该函数.完全相同的事件名称字符串.)

因此,要取消您不想要的行为,您需要检查源代码以找出触发该行为的自定义事件的名称,并on使用该名称和null函数调用dispatch对象的方法.

这是复杂的地方.实际上有多个不同的事件导致数据系列被打开和关闭.如果单击该区域,如果单击图例,或者单击鼠标悬停时出现的散点图圆之一,则会得到相同的行为.因此,所有这些事件都必须覆盖.它们甚至不是同一个调度对象的所有部分:主图表对象本身有一个调度对象,它处理通过单击图表布局控件创建的完整重绘事件,但堆叠区域上的点击事件由内部处理绘制绘图区域的图表功能,散点图上的点击事件由其中的内部图表功能处理,图例上的点击事件在图例功能中处理.

而这里变得非常复杂.当图表整体更新或其布局发生变化时,绘图区域和散点图的内部图表绘制功能将被主图表功能覆盖.这意味着所有事件都会重置为NVD3默认值.

因此,您不仅必须禁用触发该行为的所有事件,还必须修改更新功能以再次禁用它们.并且因为每次更新都会重置更新函数本身,*您需要将更新函数的修改作为用于禁用事件的函数的一部分.

**更新功能只是使用相同的容器选择重新调用整个图表绘制功能.图表函数的第一行之一创建更新功能.*

这是代码,基于nvd3.org实时代码页上的Stacked Area示例:

nv.addGraph(function() {

  /* Set up chart as normal */
  var chart = nv.models.stackedAreaChart()
                .x(function(d) { return d[0] })
                .y(function(d) { return d[1] })
                .clipEdge(true)
                //.useInteractiveGuideline(true)
      ;

  chart.xAxis
      .showMaxMin(false)
      .tickFormat(function(d) { return d3.time.format('%x')(new Date(d)) });

  chart.yAxis
      .tickFormat(d3.format(',.2f'));

  d3.select('#chart svg')
    .datum(data)
      .transition().duration(500).call(chart);

  /* create a function to disable events and modify the update function */
  function disableAreaClick() {

    //I'm probably over-killing with the amount of events I'm cancelling out
    //but it doesn't seem to have any side effects:
    chart.stacked.dispatch.on("areaClick", null);
    chart.stacked.dispatch.on("areaClick.toggle", null);

    chart.stacked.scatter.dispatch.on("elementClick", null);
    chart.stacked.scatter.dispatch.on("elementClick.area", null);

    chart.legend.dispatch.on("legendClick", null);
    chart.legend.dispatch.on("legendDblclick", null);
    chart.legend.dispatch.on("stateChange", null);

    if (chart.update) {
       //if the chart currently has an update function
       //(created when the chart is called on a container selection)
       //then modify it to re-call this function after update

       var originalUpdate = chart.update; 
           //assign the update function to a new name

       chart.update = function(){
          originalUpdate();
          disableAreaClick();
       }
    }
  } 

  //Call your function, disabling events on current chart and future updates:
  disableAreaClick();
  //this must be called *after* calling the chart on a selection
  //so that it has an update function to modify

  nv.utils.windowResize( chart.update );

  return chart;
});
Run Code Online (Sandbox Code Playgroud)