2
votes

I've searched and searched for the answer to this and cannot find it anywhere.

I have a highcharts line charts that reads data into 5 series from a CSV file, this works absolutely fine and plots well. The data in the CSV file is updated every hour (the latest value in each series will change) and currently I have to manually refresh (press F5) to refresh the actual chart data.

So far I have tried chart.destroy, series.remove, series,setData all to no avail, each time, the chart will destroy happily, then press the create new button and the chart comes back with all 5 series duplicated, each time I click create, it adds five new series to the chart rather than destroying it and recreating.

see code below:

var chart;

        $(document).ready(function() {
            var options = {
                chart: {
                    renderTo: 'linegr',
                    defaultSeriesType: 'line'
                },
                title: {
                    text: 'Malicious IPs BY Type'
                },
                xAxis: {
                    categories: []
                },
                yAxis: {
            title: {
                   text: 'Unique IPs'
                   }
                },
                subtitle: {
                    text: 'Last 10 Days'
                },
                tooltip: {
                    formatter: function() {
                    return '<b>'+ this.x +'</b>: '+ roundVal(this.y);
                    }
                },
                plotOptions: {
                    pie: {
                        allowPointSelect: true,
                        cursor: 'pointer',
                        dataLabels: {
                            enabled: false
                    },
                    showInLegend: true
                    }
                },
                series: [],
                exporting: {
        buttons: [
            {
                symbol: 'diamond',
                x: -62,
                symbolFill: '#B5C9DF',
                hoverSymbolFill: '#779ABF',
                _titleKey: 'reloadGraph',
                onclick: function() {
                chart.destroy();
                }
            }
        ]
    }
};
create();

function create() {
    $.get('dat.csv', function(data) {
    // Split the lines
    var lines = data.split('\n');

    // Iterate over the lines and add categories or series
    $.each(lines, function(lineNo, line) {
        var items = line.split(',');

        // header line containes categories
        if (lineNo == 0) {
            $.each(items, function(itemNo, item) {
                if (itemNo > 0) options.xAxis.categories.push(item);
            });
        }

        // the rest of the lines contain data with their name in the first position
        else {
            var series = {
                data: []
            };
            $.each(items, function(itemNo, item) {
                if (itemNo == 0) {
                    series.name = item;
                } else {
                    series.data.push(parseFloat(item));
                }
            });

            options.series.push(series);

        }

    });

    // Create the chart
    var chart = new Highcharts.Chart(options);
function destroy() {
    chart.destroy();
    var data='';
            window.alert(chart.series.length);
    for(i=0; i<chart.series.length; i++){
        chart.redraw(true);
        chart.series[i].remove(false);
    }
        }
        $('#create').click(create);
        $('#destroy').click(destroy);
});

I'm hoping and guessing that its something really simple and stupid that I've just become code blind to and cant find :)

1

1 Answers

1
votes

I think your problem is that you are reusing the same options object each time you create the chart. Try cloning the default options, then modify the cloned object to create the chart options. You can use jQuery's extend method to do this. Just make sure that you create new arrays for the categories and series each time, like so:

(function(){
    var chart,
    options = {
        chart: {
            renderTo: 'linegr',
            defaultSeriesType: 'line'
        },
        title: {
            text: 'Malicious IPs BY Type'
        },
        xAxis: {
            categories: []
        },
        yAxis: {
    title: {
           text: 'Unique IPs'
           }
        },
        subtitle: {
            text: 'Last 10 Days'
        },
        tooltip: {
            formatter: function() {
            return '<b>'+ this.x +'</b>: '+ roundVal(this.y);
            }
        },
        plotOptions: {
            pie: {
                allowPointSelect: true,
                cursor: 'pointer',
                dataLabels: {
                    enabled: false
            },
            showInLegend: true
            }
        },
        series: [],
        exporting: {
            buttons: [
                {
                    symbol: 'diamond',
                    x: -62,
                    symbolFill: '#B5C9DF',
                    hoverSymbolFill: '#779ABF',
                    _titleKey: 'reloadGraph',
                    onclick: function() {
                                        create();
                    }
                }
            ]
        }
    };

    function create() {
            if(chart) chart.destroy();
        $.get('dat.csv', function(data) {
            var newOptions = $.extend(true, {}, options, {
                xAxis : {
                    categories : []
                },
                series : []
            });

            // Split the lines
            var lines = data.split('\n');

            // Iterate over the lines and add categories or series
            $.each(lines, function(lineNo, line) {
                var items = line.split(',');

                // header line containes categories
                if (lineNo == 0) {
                    $.each(items, function(itemNo, item) {
                        if (itemNo > 0) newOptions.xAxis.categories.push(item);
                    });
                }

                // the rest of the lines contain data with their name in the first position
                else {
                    var series = {
                        data: []
                    };
                    $.each(items, function(itemNo, item) {
                        if (itemNo == 0) {
                            series.name = item;
                        } else {
                            series.data.push(parseFloat(item));
                        }
                    });

                    newOptions.series.push(series);

                }

            });

            // Create the chart
            chart = new Highcharts.Chart(newOptions);

            $('#create').click(create);
            $('#destroy').click(chart.destroy);
        });
    }

    $(document).ready(create);
}());