1

查看代码,我还没有完全弄清楚 NVD3 的lineWithFocusChart是如何创建焦点窗口的,但我相信它是通过在侧面制作两个矩形来实现的。我的问题是,当一个焦点窗口边界碰到取景器的一侧时,它怎么能触发一些事件 - 即。所以你可以加载更多数据?
例如,目前,我让它加载一个月的数据,并希望它在取景器到达左边距时再加载一个月。

我试图在 onBrush() 函数的 nv.d3.js 源代码中触发一个事件:

function onBrush() {
    brushExtent = brush.empty() ? null : brush.extent();
    var extent = brush.empty() ? x2.domain() : brush.extent();
    //The brush extent cannot be less than one.  If it is, don't update the line chart.
    if (Math.abs(extent[0] - extent[1]) <= 1) {
      return;
    }
    if (extent[1] !== x2.domain()[1] && extent[0] === x2.domain()[0]) //my attempt    
        console.log("Wheaton!");  // my attempt - do something here
    dispatch.brush({extent: extent, brush: brush});


    updateBrushBG();

    // Update Main (Focus)
    var focusLinesWrap = g.select('.nv-focus .nv-linesWrap')
        .datum(
          data
            .filter(function(d) { return !d.disabled })
            .map(function(d,i) {
              return {
                key: d.key,
                values: d.values.filter(function(d,i) {
                  return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1];
                })
              }
            })
        );

所以,现在问题变成了,如果这样做,也许这不是正确的方法,我如何通知其他程序这个事件已经发生,以便它可以加载更多数据?

4

1 回答 1

2

(回答我自己的问题:)这对我有用,不管它是否是我不知道的最好方法(可能不是)。如果有人有一个更好的解决方案,我会欢迎。

在 NVD3 之外,我在 rootScope 上创建了一个函数来广播其他函数可以监听的事件,我将 $rootScope 传递给 NVD3 并在 onBrush() 内部调用广播器。

例如。

在我封装 NVD3 的指令中:

    ...
    $rootScope.loadMoreData = function() {
      $rootScope.$broadcast('loadMoreData');
    }
    ...
    var chart = nv.models.lineWithFocusChart($rootScope); // which gets passed to NVD3
    ...

在 nv.d3 源代码中:

...
nv.models.lineWithFocusChart = function(rootScope) { // add parameter
...
   function onBrush() {
        brushExtent = brush.empty() ? null : brush.extent();
        var extent = brush.empty() ? x2.domain() : brush.extent();
        //The brush extent cannot be less than one.  If it is, don't update the line chart.
        if (Math.abs(extent[0] - extent[1]) <= 1) {
          return;
        }
        if (extent[1] !== x2.domain()[1] && extent[0] === x2.domain()[0])   
           rootScope.loadMoreData();
        dispatch.brush({extent: extent, brush: brush});


        updateBrushBG();

        // Update Main (Focus)
        var focusLinesWrap = g.select('.nv-focus .nv-linesWrap')
            .datum(
              data
                .filter(function(d) { return !d.disabled })
                .map(function(d,i) {
                  return {
                    key: d.key,
                    values: d.values.filter(function(d,i) {
                      return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1];
                    })
                  }
                })
            );
        focusLinesWrap.transition().duration(transitionDuration).call(lines);


        // Update Main (Focus) Axes
        g.select('.nv-focus .nv-x.nv-axis').transition().duration(transitionDuration)
            .call(xAxis);
        g.select('.nv-focus .nv-y.nv-axis').transition().duration(transitionDuration)
            .call(yAxis);
      }


}

在控制器中:...

$rootScope.$on('loadMoreData', function() {

    // reload the data with new date range 
    $scope.data = foo.query();
});

也许是一种笨拙的方法,我觉得在 nv.d3 的源代码中乱搞或使用 $rootScope 感到不舒服,但它一直在工作,直到我找到更好的方法。

于 2013-10-01T17:37:15.483 回答