最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - NVD3 Angular Directive callback firing too soon - Stack Overflow

programmeradmin6浏览0评论

I've recently started using NVD3's great angular directives for constructing D3 charts. Indeed they are slick. However I'm having a lot of difficulties with callbacks. Callbacks work well enough when I add them using nv.addGraph(), like in Alex's answer and in the examples page. I've also had varying success with other suggestions in these SO answers. But to make it easier for other junior programmers in my pany, I would like to use an HTML directive like those shown on the examples on github. Something like this:

<nvd3-multi-bar-chart
   data="monthData"
   id="monthDataChart"
   ... other properties ...
   callback="monthCallback">
   <svg></svg>
</nvd3-multi-bar-chart>

The function in my scope called monthCallback attempts to attach attributes, such as titles, and events, such as click, to each .nv-bar in the chart. The problem is that the chart starts to render before the data returns from the ajax request, and so monthCallback is fired before there are any .nv-bar on the page. (Note: it doesn't seem to make a difference whether or not the callback is declared with parentheses, i.e. callback="monthCallback" vs. callback="monthCallback()")

I considered using the workaround by liptga, or DavidSouther's answer, but linking the callback to the transition seemed the wrong way to address this problem. Any other suggestions for getting the callback to fire at the right time, using the HTML directive?

I've recently started using NVD3's great angular directives for constructing D3 charts. Indeed they are slick. However I'm having a lot of difficulties with callbacks. Callbacks work well enough when I add them using nv.addGraph(), like in Alex's answer and in the examples page. I've also had varying success with other suggestions in these SO answers. But to make it easier for other junior programmers in my pany, I would like to use an HTML directive like those shown on the examples on github. Something like this:

<nvd3-multi-bar-chart
   data="monthData"
   id="monthDataChart"
   ... other properties ...
   callback="monthCallback">
   <svg></svg>
</nvd3-multi-bar-chart>

The function in my scope called monthCallback attempts to attach attributes, such as titles, and events, such as click, to each .nv-bar in the chart. The problem is that the chart starts to render before the data returns from the ajax request, and so monthCallback is fired before there are any .nv-bar on the page. (Note: it doesn't seem to make a difference whether or not the callback is declared with parentheses, i.e. callback="monthCallback" vs. callback="monthCallback()")

I considered using the workaround by liptga, or DavidSouther's answer, but linking the callback to the transition seemed the wrong way to address this problem. Any other suggestions for getting the callback to fire at the right time, using the HTML directive?

Share edited May 23, 2017 at 11:52 CommunityBot 11 silver badge asked May 29, 2014 at 7:57 moshefnordmoshefnord 3143 silver badges10 bronze badges 1
  • Should have mentioned, another key advantage of using the directives is to utilize Angular's binding and automatic updates. Using nv-addGraph() eliminates this agility. – moshefnord Commented May 29, 2014 at 8:16
Add a ment  | 

2 Answers 2

Reset to default 5

You can also try angular-nvd3 directive. It pletely operates with charts via json, and you can also access to the full nvd3 core api.

In your case, you need to somehow refresh the chart.

1). One can use an api attribute of this directive like:

//in html
<nvd3 options="options" data="data" api="api"></nvd3>  

and then in controller you can pletely refresh directive anywhere using:

//javascript
$scope.api.refresh();

2). Another approach is to just make your chart hidden/visible, using config attribute and varying visible option like:

<nvd3 options="options" data="data" config="{ visible: false }"></nvd3> 

For example, if there is no data yet, set visible: false. While data is returned, set visible: true. See live example below.

3). And the simplest way is to just change your data, and directive automatically will be refreshed with new data:

//javascript
$scope.data = newData;
$scope.$apply();  //sometimes you need to refresh the scope

As for your case with ajax it can look something like:

//ajax request; in the live example below I use timeout 
$http.get("/some_url/")
     .success(function(data){
          $scope.data = data;
          $scope.$apply();
          //chart will render after the data returns
     })

Callback function is defined as any other options:

//javascript, in controller
$scope.options = {
    ..., //any other options
    callback: function(){
        d3.selectAll(".nv-bar").on('click', function(){
            alert("Hi, I'm callback!");
        });
    }
}

So it will be fired after chart renders, and after data is returned.

See live example. (updated with callback)

Not sure if that much related to the question, but ended here by searching callback firing too soon. I had similar problem with the Angular directive and Callback was firing too fast, I just added a simple if statement to see if the item I am trying to access is ready. Like this:

    callback(chart) {
      if (chart && chart.interactiveLayer) {
      // do something
发布评论

评论列表(0)

  1. 暂无评论