2014-02-20 57 views
2
堆积面积的

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

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

+1

在不修改源代码的情况下,您可以最接近地完全禁用图例。 –

+0

如何做到这一点? – Deadly

+0

看看这个http://stackoverflow.com/questions/19009959/how-to-disable-legend-in-nvd3-or-limit-its-size/19010011#19010011 – shabeer90

回答

6

没有任何NVD3图表选项为忽略这种行为,但你可以直接通过骑单击事件处理程序。但是,堆叠面积图会变得有点复杂...

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

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

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

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

而这里是它得到真的复杂。当整体图表更新或其布局更改时,绘图区域和散点图的内部图表绘图功能会被主图表功能覆盖。这意味着所有的事件都会重置为NVD3默认值。

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

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

下面的代码的基础上,对nvd3.org live code page的堆积面积例如:

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; 
}); 
0

你现在可以做的最好的就是禁用图例。 你可以做,使用chart.showLegend(false),或者像一个选项:

var options = { 
    showLegend: false 
}; 
0

,如果你不介意不响应任何鼠标事件一个讨厌的解决方案:

pointer-events: none; 

使用这在元素上。