43 votes

Recharger les données des graphiques via JSON avec Highcharts

J'essaie de recharger les données d'un graphique Highcharts via JSON en fonction d'un clic sur un bouton situé ailleurs dans la page. Au départ, j'aimerais afficher un ensemble de données par défaut (dépenses par catégorie), puis charger de nouvelles données en fonction de l'entrée de l'utilisateur (dépenses par mois, par exemple). Le moyen le plus simple auquel je pense pour sortir le JSON du serveur est de passer une requête GET à la page PHP, par exemple $.get('/dough/includes/live-chart.php?mode=month' en récupérant cette valeur à partir de l'attribut ID du bouton.

Voici ce que j'ai jusqu'à présent pour récupérer les données par défaut (dépenses par catégorie). J'ai besoin de trouver comment charger des données complètement différentes dans le graphique circulaire, en fonction des entrées de l'utilisateur, à la demande :

$(document).ready(function() {
            //This is an example of how I would retrieve the value for the button
            $(".clickMe").click(function() {
                var clickID = $(this).attr("id");
            });
            var options = {
                chart: {
                    renderTo: 'graph-container',
                    margin: [10, 175, 40, 40]
                },
                title: {
                    text: 'Spending by Category'
                },
                plotArea: {
                    shadow: null,
                    borderWidth: null,
                    backgroundColor: null
                },
                tooltip: {
                    formatter: function() {
                        return '<b>'+ this.point.name +'</b>: $'+ this.y;
                    }
                },
                credits: {
                    enabled: false
                },
                plotOptions: {
                    pie: {
                        allowPointSelect: true,
                        cursor: 'pointer',
                        dataLabels: {
                            enabled: true,
                            formatter: function() {
                                if (this.y > 5) return '$' + this.y;
                            },
                            color: 'white',
                            style: {
                                font: '13px Trebuchet MS, Verdana, sans-serif'
                            }
                        }
                    }
                },
                legend: {
                    layout: 'vertical',
                    style: {
                        left: 'auto',
                        bottom: 'auto',
                        right: '50px',
                        top: '100px'
                    }
                },
                series: [{
                    type: 'pie',
                    name: 'Spending',
                    data: []
                }]
            };
            $.get('/dough/includes/live-chart.php', function(data) {
            var lines = data.split('\n');
            $.each(lines, function(lineNo, line) {
                var items = line.split(',');
                var data = {};
                $.each(items, function(itemNo, item) {
                    if (itemNo === 0) {
                        data.name = item;
                    } else {
                        data.y = parseFloat(item);
                    }
                });
                options.series[0].data.push(data);
            });
            // Create the chart
            var chart = new Highcharts.Chart(options);
        });
        });

Toute aide serait grandement appréciée.

EDITAR

Voici le Javascript mis à jour grâce à Robodude. John, vous m'avez mis sur la bonne voie - merci ! Je suis maintenant bloqué sur la façon de remplacer les données sur le graphique à partir de la requête AJAX. Je dois admettre que le code qui suit le $.get() est très probablement un exemple de code, je ne comprends pas bien ce qui se passe lorsqu'il est exécuté - peut-être y a-t-il une meilleure façon de formater les données ?

J'ai pu progresser dans la mesure où le graphique charge maintenant de nouvelles données, mais celles-ci sont ajoutées à celles qui sont déjà présentes. Je pense que le coupable est cette ligne :

options.series[0].data.push(data);

J'ai essayé options.series[0].setData(data) ; mais rien ne se passe. En revanche, la requête AJAX fonctionne parfaitement en fonction de la valeur du menu de sélection et il n'y a pas d'erreur Javascript. Voici le code en question, sans les options du graphique :

$.get('/dough/includes/live-chart.php?mode=cat', function(data) {
            var lines = data.split('\n');
            $.each(lines, function(lineNo, line) {
                var items = line.split(',');
                var data = {};
                $.each(items, function(itemNo, item) {
                    if (itemNo === 0) {
                        data.name = item;
                    } else {
                        data.y = parseFloat(item);
                    }
                });
                options.series[0].data.push(data);
            });
            // Create the chart
            var chart = new Highcharts.Chart(options);
        });
        $("#loadChart").click(function() {
            var loadChartData = $("#chartCat").val();
                $.get('/dough/includes/live-chart.php?mode=' + loadChartData, function(data) {
                var lines = data.split('\n');
                $.each(lines, function(lineNo, line) {
                    var items = line.split(',');
                    var data = {};
                    $.each(items, function(itemNo, item) {
                        if (itemNo === 0) {
                            data.name = item;
                        } else {
                            data.y = parseFloat(item);
                        }
                    });
                    options.series[0].data.push(data);
                });
                // Create the chart
                var chart = new Highcharts.Chart(options);
            });
        });
    });

EDIT 2 Il s'agit du format utilisé pour le graphique - très simple, le nom de la catégorie et la valeur avec le nom de la catégorie. \n après chaque.

Coffee, 4.08
Dining Out, 5.05
Dining: ODU, 5.97
Dining: Work, 38.41
Entertainment, 4.14
Gas, 79.65
Groceries, 228.23
Household, 11.21
Misc, 12.20
Snacks, 20.27

103voto

jspooner Points 3963

Les autres réponses n'ont pas fonctionné pour moi. J'ai trouvé la réponse dans leur documentation :

http://api.highcharts.com/highcharts#Series

En utilisant cette méthode ( voir l'exemple de JSFiddle ):

var chart = new Highcharts.Chart({
    chart: {
        renderTo: 'container'
    },

    series: [{
        data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]        
    }]
});

// the button action
$('#button').click(function() {
    chart.series[0].setData([129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4, 29.9, 71.5, 106.4] );
});

19voto

Robodude Points 1777

EDIT : La réponse ci-dessous est plus correcte !

http://stackoverflow.com/a/8408466/387285

http://www.highcharts.com/ref/#series-object

HTML :

<SELECT id="list">
<OPTION VALUE="A">Data Set A
<OPTION VALUE="B">Data Set B
</SELECT>
<button id="change">Refresh Table</button>

<div id="container" style="height: 400px"></div>

Javascript :

var options = {
    chart: {
        renderTo: 'container',
        defaultSeriesType: 'spline'
    },
    series: []
};

$("#change").click(function() {
    if ($("#list").val() == "A") {
        options.series = [{name: 'A', data: [1,2,3,2,1]}]
        // $.get('/dough/includes/live-chart.php?mode=month'
    } else {
        options.series = [{name: 'B', data: [3,2,1,2,3]}]
        // $.get('/dough/includes/live-chart.php?mode=newmode'
    } 

    var chart = new Highcharts.Chart(options);    
});

Il s'agit d'un exemple très simple puisque je n'ai pas mes fichiers avec moi, mais l'idée de base est que chaque fois que l'utilisateur sélectionne de nouvelles options pour les éléments qu'il veut voir, vous allez devoir remplacer l'objet de données .series par les nouvelles informations de votre serveur, puis recréer le graphique en utilisant le nouveau Highcharts.Chart() ;.

J'espère que cela vous aidera ! John

EDITAR:

Regardez ça, ça vient d'un projet sur lequel j'ai travaillé dans le passé :

$("table#tblGeneralInfo2 > tbody > tr").each(function (index) {
    if (index != 0) {
        var chartnumbervalue = parseInt($(this).find("td:last").text());
        var charttextvalue = $(this).find("td:first").text();
        chartoptions.series[0].data.push([charttextvalue, chartnumbervalue]);
    }
});

J'avais un tableau avec des informations dans la première et la dernière ligne que j'avais besoin d'ajouter au camembert. J'ai parcouru en boucle chacune des lignes et j'ai introduit les valeurs. Remarque : j'utilise chartoptions.series[0].data car les camemberts n'ont qu'une seule série.

4voto

mcoffey Points 41

Vous devez effacer l'ancien tableau avant d'y introduire les nouvelles données. Il existe de nombreuses façons d'y parvenir, mais j'ai utilisé celle-ci :

options.series[0].data.length = 0;

Votre code devrait donc ressembler à ceci :

options.series[0].data.length = 0;
$.each(lines, function(lineNo, line) {
                    var items = line.split(',');
                    var data = {};
                    $.each(items, function(itemNo, item) {
                        if (itemNo === 0) {
                            data.name = item;
                        } else {
                            data.y = parseFloat(item);
                        }
                    });
                    options.series[0].data.push(data);
                });

Maintenant, lorsque vous cliquez sur le bouton, les anciennes données sont effacées et seules les nouvelles données s'affichent. J'espère que cela vous aidera.

2voto

Dipanjan Points 29

La bonne réponse est :

$.each(lines, function(lineNo, line) {
                    var items = line.split(',');
                    var data = {};
                    $.each(items, function(itemNo, item) {
                        if (itemNo === 0) {
                            data.name = item;
                        } else {
                            data.y = parseFloat(item);
                        }
                    });
                    options.series[0].data.push(data);
                    data = {};
                });

Vous devez vider le tableau 'data'.

data = {};

1voto

Jamsi Points 989

Si vous sont en utilisant push pour pousser les données vers l'option.series dynamiquement utilisez simplement

options.series = [];  

pour l'effacer.

options.series = [];
$("#change").click(function(){
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X