没有任何 NVD3 图表选项可以覆盖此行为,但您可以直接覆盖 click 事件处理程序。但是,堆积面积图有点复杂......
NVD3 使用d3.dispatch 对象来处理自定义事件。用户点击和鼠标悬停以及相关动作都被转换成这些自定义事件。
如果您希望某个函数在自定义事件之后发生,您可以调用调度对象的.on(eventName, function) 方法。如果函数参数是null,它将取消附加到该名称的任何先前的事件处理函数。 (如果您希望多个函数由同一个事件触发,您可以使用"eventName.namespace" 形式的字符串作为第一个参数,将“命名空间”添加到事件名称;该函数只有在@987654327 时才会被取消使用完全相同的事件名称字符串再次调用 @。)
因此,要取消您不想要的行为,您需要检查源代码以确定触发该行为的自定义事件的名称,并使用该名称调用调度对象的 on 方法,然后一个空函数。
这就是复杂的地方。实际上有多个不同的事件会导致数据系列被打开和关闭。如果单击该区域,单击图例,或者单击鼠标悬停时出现的散点圆之一,则会得到相同的行为。所以所有这些事件都必须被覆盖。它们甚至不是同一个调度对象的所有部分:主图表对象本身有一个调度对象,它处理通过单击图表布局控件创建的完整重绘事件,但堆叠区域上的点击事件由内部处理绘制绘图区域的图表函数,散点上的单击事件由其中的内部图表函数处理,图例上的单击事件在图例函数中处理。
这就是它变得真正复杂的地方。当整个图表更新或布局更改时,绘图区域和散点图的那些内部图表绘制函数将被主图表函数覆盖。这意味着所有事件都将重置为其 NVD3 默认值。
因此,您不仅必须禁用所有触发行为的事件,还必须修改更新功能以再次禁用它们。并且由于更新函数本身在每次更新时都会重置,*您需要将更新函数的修改包含在用于禁用事件的函数中。
**更新函数只是使用相同的容器选择重新调用整个图表绘制函数。图表函数的第一行之一创建了更新函数。*
以下是代码,基于 nvd3.org live code page 上的 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;
});