2010-11-18 10 views
42

Sto tentando di ricaricare i dati per un grafico Highcharts tramite JSON in base a un clic del pulsante altrove nella pagina. Inizialmente vorrei visualizzare un insieme predefinito di dati (spesa per categoria), ma poi caricare nuovi dati in base all'input dell'utente (spesa per mese, ad esempio). Il modo più semplice con cui posso pensare di emettere il JSON dal server è passare una richiesta GET alla pagina PHP, ad esempio $ .get ('/ dough/includes/live-chart.php? Mode = month', recuperando questo valore dall'attributo ID del pulsanteRicaricare i dati del grafico tramite JSON con Highcharts

Ecco ciò che ho finora per recuperare i dati predefiniti (spesa per categoria). È necessario trovare come caricare dati completamente diversi nel grafico a torta, in base all'input dell'utente, on demand:

$(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); 
     }); 
     }); 

Qualsiasi aiuto sarebbe molto apprezzato

EDIT

Ecco il Javascript aggiornato grazie a Robodude. John, tu hai me sulla strada giusta qui - grazie! Ora mi sto bloccando su come sostituire i dati sul grafico dalla richiesta AJAX. Devo ammettere che il codice che segue $ .get() è molto probabilmente dal codice di esempio, non capisco perfettamente cosa sta succedendo quando viene eseguito - forse c'è un modo migliore per formattare i dati?

Sono stato in grado di fare alcuni progressi in quanto il grafico ora carica nuovi dati ma è aggiunto in cima a ciò che è già lì. Ho il sospetto che il colpevole è questa linea:

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

ho provato options.series [0] .setData (dati); ma non succede nulla. Sul lato positivo, la richiesta AJAX funziona perfettamente in base al valore del menu di selezione e non ci sono errori Javascript. Ecco il codice in questione, sans Opzioni grafico:

$.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 Questo è il formato che il grafico sta tirando da - molto semplice, nome della categoria e il valore con \ n dopo ogni.

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 

risposta

19

MODIFICA: La risposta in basso è più corretta!

https://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);  
}); 

Questo è un esempio molto semplice dal momento che non ho i miei file qui con me, ma l'idea di base è che ogni volta l'utente seleziona cts nuove opzioni per le cose che vogliono vedere, hai intenzione di sostituire l'oggetto dati .series con le nuove informazioni dal tuo server e quindi ricreare il grafico usando il nuovo Highcharts.Chart() ;.

Spero che questo aiuti! John

EDIT:

Check this out, la sua da qualcosa su cui ho lavorato in passato:

$("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]); 
    } 
}); 

ho avuto una tabella con le informazioni nel primo e ultimo TDS che avevo bisogno da aggiungere al grafico a torta. I loop attraverso ciascuna delle righe e spingere i valori. Nota: utilizzo chartpttions.series [0] .data poiché i grafici a torta hanno solo 1 serie.

+0

ho preso il codice che ho scritto e messo sul jsfiddle per la vostra convenienza: http://jsfiddle.net/EmMxH/ – Robodude

+0

nuovo Hey NightMICU! Mi dispiace di non avere molto tempo per spiegare cosa sta succedendo, ma controlla questo: http://jsfiddle.net/w4DKf/ Qual è il formato dei dati che sta tornando? Ricorda che ogni valore per il grafico a torta fa parte di un array che fa parte dell'array di dati highcharts che fa parte dell'array della serie! – Robodude

+0

John, penso che forse il problema qui è il formato dei dati del grafico. Non è JSON e immagino che debba esserlo? Se cambio l'output dal file PHP in JSON, come dovrei includerlo nel Javascript? – NightMICU

4

è necessario cancellare la vecchia matrice fuori prima di spingere i nuovi dati in Ci sono molti modi per ottenere questo risultato, ma ho usato questo:.

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

Quindi il codice dovrebbe essere simile a questo:

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); 
       }); 

Ora, quando si fa clic sul pulsante, i vecchi dati vengono eliminati e si visualizzano solo i nuovi dati. Spero possa aiutare.

+0

Dopo 2 ore di tentativi di capire, perché il mio grafico a dispersione stava accumulando serries su ogni chiamata. Ho finalmente trovato questa soluzione. Mi hai salvato il resto della giornata. Ha funzionato. Grazie. – crashtestxxx

1

Se sono utilizzando spinta per spingere i dati ai option.series dinamicamente .. basta usare

options.series = []; 

per cancellarlo.

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

risposta corretta è:

$.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 = {}; 
       }); 

È necessario svuotare la matrice 'data'.

102

Le altre risposte non hanno funzionato per me. Ho trovato la risposta nella loro documentazione:

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

Utilizzando questo metodo (see JSFiddle example):

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]); 
}); 
+1

Questa soluzione è addirittura bedder perché solo i valori aggiornati verranno modificati e nulla più. Esempio qui: http://jsfiddle.net/ebuTs/16/ –

+7

+1 Questo è l'approccio corretto ... La risposta scelta prevede la ricreazione dell'oggetto grafico ogni volta che viene apportata una modifica ed è molto inefficiente. –

+1

Per i miei scopi, questo non ha funzionato affatto e in realtà ha fatto arrabbiare un cliente con me. I dati che sto cercando di visualizzare sono le statistiche delle chiamate per una squadra di soccorso locale. Ogni mese, eseguono un diverso numero di chiamate in diverse categorie, quindi non è sempre lo stesso ogni mese (ad esempio, potrebbero non eseguire un singolo incidente automobilistico un mese, 10 il successivo). La tua risposta ha causato un comportamento strano, incluse le categorie mancanti e l'errore "a non è definito" nel codice HighCharts. La risposta selezionata potrebbe essere inefficiente in alcuni modi, ma funziona e il cliente è felice. – NightMICU

1

È sempre possibile caricare un dati JSON

qui ho definito grafico come spazio dei nomi

$.getJSON('data.json', function(data){ 
       Chart.options.series[0].data = data[0].data; 
       Chart.options.series[1].data = data[1].data; 
       Chart.options.series[2].data = data[2].data; 

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

      }); 
4

In realtà forse dovresti scegliere la funzione update è meglio.
Ecco il documento della funzione updatehttp://api.highcharts.com/highcharts#Series.update

Si può semplicemente digitare il codice come di seguito:

chart.series[0].update({data: [1,2,3,4,5]})

Questi codici si fonderanno l'opzione origine e aggiornare i dati modificati.