Skip to content Skip to sidebar Skip to footer

Highchart Angular Directive Doesn't Redraw From Dynamic (ajax) Data Table

I have an AngularJs app that retrieves data from API and populates them into table. Then, I'm using Highcharts to draw chart based on that table. It is working fine if I'm using st

Solution 1:

Ok. I managed to get it to work. I think the problem is that, Highcharts does not aware about the changes or if it knows about the changes, the DOM at that moment hasn't finish rendering. This is the working version of the code.

Directive:

app.directive('highchart', function($parse, $timeout) {
    return {
        restrict: 'E',
        template: '<div></div>',
        replace: true,
        link: function(scope, element, attrs) {
            var config = $parse(attrs.config)(scope);
            $(element[0]).highcharts(config);

            scope.$watch(attrs.watch, function(newVal) {
                if (newVal) {
                    var complete = function (options) {
                        var chart = $(element[0]).highcharts();
                        // capture all available seriesvar allSeries = chart.series;
                        for (var i = 0; i < allSeries.length; i++) {
                            allSeries[i].setData(options.series[i].data, false);
                        }

                        chart.redraw();
                    };

                    // doesn't work without the timeout $timeout(function() {
                        Highcharts.data({
                            table: config.data.table,
                            complete: complete
                        });   
                    }, 0);
                }
            });
        }
    };
});

In controller, we can setup the config.

    $scope.chartConfig = {
         // config here
    };

To use it:

<highchartconfig="chartConfig"watch="levels"></highchart>

where the attribute config is bind to the $scope.chartConfig and watch is the trigger for watch.$scope() in the directive. When $scope.levels changes in controller, it would re-render the chart.

I don't actually like the dependency of the directive to the watch attribute that I have right now, but I'm not sure what is the best or other way to do this. If anyone have a better idea, do let me know.

Please note that this will only work to convert table to highchart. For others, you might need to use other angularjs highcharts directive.

Solution 2:

In given below example, you can update your graph as per updated data in database using watch.It keeps on checking for new data and makes changes respectively:

app.directive('line',['$compile',function($compile) {
    return {
        restrict:'E',
        replace:true,
        template:'<div></div>',
        scope: {
            data:'=',
        },
        link:function(scope, element) {
            scope.lineGraphInstance=Highcharts.chart(element[0],{
                chart: {
                    type:'spline',
                    style: {
                        fontSize:'8px'
                    },
                    spacingBottom:scope.data.spacingBottom,
                    spacingTop:scope.data.spacingTop,
                    spacingLeft:scope.data.spacingLeft,
                    spacingRight:scope.data.spacingRight,
                },
                title: {
                    text:'',
                },                      
                xAxis: {
                    type:'datetime',
                    title: {
                        text:scope.data.xtitle,
                        enabled:false
                    },
                    labels: {
                        style: {
                            fontSize:'8px'
                        },                  
                        autoRotation:0,
                        formatter:function() {
                            varx=this.value;if(scope.data.hasOwnProperty("dateformat"))x=Highcharts.dateFormat(scope.data.dateformat, this.value);if(scope.data.hasOwnProperty("xSuffix"))x=x+scope.data.xSuffix;if(scope.data.hasOwnProperty("xPrefix"))x=scope.data.xPrefix+x;returnx;
                        },
                    enabled:scope.data.xtitleEnable
                    },
                    tickWidth:3,
                    tickLength:scope.data.tickLength,
                    tickInterval:3600*100
                        },
                yAxis: {
                    opposite:true,
                    title: {
                        text:scope.data.ytitle,
                        enabled:false
                    },
                    min:0,
                    labels: {
                        style: {
                            fontSize:'10px'
                        },
                        formatter:function() {
                            vary=this.value;if(scope.data.hasOwnProperty("ySuffix"))y=y+scope.data.ySuffix;if(scope.data.hasOwnProperty("yPrefix"))y=scope.data.yPrefix+y;returny;
                        },
                    },
                    plotLines: [{
                        value:scope.data.ucl,
                        color:'#F39C12',
                        dashStyle:'shortdash',
                        width:1,
                    }, {
                        value:scope.data.lcl,
                        color:'#F39C12',
                        dashStyle:'shortdash',
                        width:1,
                    }]
                },
                tooltip: {
                    headerFormat:'<b>{series.name}</b><br>',
                    pointFormat:'{point.x:%e. %b}: {point.y:.2f} '
                },
                plotOptions: {
                    spline: {
                        marker: {
                            enabled:true
                        }
                    }
                },
                legend:{
                    enabled:false
                },
                series:[{data:scope.data.data,
                marker: {
                    enabled:true,
                    radius:2
                },
                lineWidth:1
                }],
                credits: {
                    enabled:false
                },  
                exporting: { enabled:false 
                }
            });***scope.$watch('data', function(newValue, oldValue) {
                if(newValue&&newValue.data){
                    vargraphData=newValue.data[0].data.slice(-5);scope.lineGraphInstance.series[0].setData(graphData, true);
                }
            }, true);
        }***
    };
}]);

Solution 3:

Have you tried to set factory, which will use $resourcehttp://docs.angularjs.org/api/ngResource.$resource inside and then iniliatize chart after calling getting values from factory?

EDIT: updated example http://jsfiddle.net/csTzc/184/

Post a Comment for "Highchart Angular Directive Doesn't Redraw From Dynamic (ajax) Data Table"