2010-11-18 34 views
42

Estoy tratando de volver a cargar los datos para un gráfico de Highcharts a través de JSON basado en un botón, haga clic en otro lugar de la página. Inicialmente me gustaría mostrar un conjunto predeterminado de datos (gasto por categoría) pero luego cargar nuevos datos basados ​​en la entrada del usuario (gasto por mes, por ejemplo). La forma más fácil que se me ocurre para generar el JSON desde el servidor es pasando una solicitud GET a la página PHP, por ejemplo $ .get ('/ dough/includes/live-chart.php? Mode = month', recuperando este valor del atributo ID del botónRecargar los datos del gráfico a través de JSON con Highcharts

Esto es lo que tengo hasta ahora para recuperar los datos por defecto (gasto por categoría). Necesito encontrar cómo cargar datos completamente diferentes en el gráfico circular, en función de la entrada del usuario. 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); 
     }); 
     }); 

Cualquier ayuda sería muy apreciada

EDITAR

Aquí está el Javascript actualizado gracias a Robodude. John, me tienes en el camino correcto aquí, ¡gracias! Ahora estoy atascado con cómo reemplazar los datos en el gráfico de la solicitud AJAX. Debo admitir que el código que sigue a $ .get() probablemente provenga del código de muestra, no entiendo completamente qué está sucediendo cuando se ejecuta; ¿quizás haya una forma mejor de formatear los datos?

Pude hacer algunos progresos ya que ahora el gráfico carga nuevos datos, pero se agrega a lo que ya existe. Sospecho que el culpable es esta línea:

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

Probé options.series [0] .setData (datos); pero nada pasa. En el lado positivo, la solicitud de AJAX funciona de manera impecable en función del valor del menú de selección y no hay errores de Javascript. Aquí está el código en cuestión, sans trazar opciones:

$.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 Este es el formato que el gráfico está tirando de - muy simple, nombre de la categoría y el valor con \ n después de cada uno.

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 

Respuesta

19

EDITAR: La respuesta abajo es más correcta.

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

Este es un ejemplo muy simple, ya que no tengo mis archivos aquí conmigo, pero la idea básica es que cada vez que el usuario seleccione cts nuevas opciones para las cosas que quieren ver, vas a tener que reemplazar el objeto de datos .series con la nueva información de tu servidor y luego volver a crear el gráfico usando el nuevo Highcharts.Chart() ;.

Espero que esto ayude! John

EDIT:

mira esto, la de algo que he trabajado en el pasado:

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

que tenía una tabla con información en la primera y última TDS que necesitaba para agregar al gráfico circular. Recorro cada una de las filas e introduzco los valores. Nota: utilizo chartoptions.series [0] .data ya que los gráficos circulares solo tienen 1 serie.

+0

Tomé el código que escribí y lo puso en jsFiddle para su conveniencia: http://jsfiddle.net/EmMxH/ – Robodude

+0

Hola de nuevo NightMICU! Lo siento, no tengo mucho tiempo para explicar lo que está pasando, pero mira esto: http://jsfiddle.net/w4DKf/ ¿Cuál es el formato de los datos que están volviendo? ¡Recuerde que cada valor de su gráfico circular forma parte de una matriz que forma parte de la matriz de datos de Highcharts que forma parte de la serie en serie! – Robodude

+0

John, creo que tal vez el problema aquí es el formato de los datos del gráfico. No es JSON y supongo que debe ser? Si cambio el resultado del archivo PHP a JSON, ¿cómo lo incluiría en el Javascript? – NightMICU

4

es necesario borrar la matriz de edad a cabo antes de empujar los nuevos datos en el Hay muchas maneras de lograr esto pero he usado éste:.

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

lo que el código debería tener este aspecto:

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

Ahora, cuando se hace clic en el botón, se borran los datos antiguos y solo aparecen los nuevos datos. Espero que ayude.

+0

Después de 2 horas tratando de averiguar, ¿por qué mi diagrama de dispersión fue apilando serries en cada llamada? Finalmente encontré esta solución. Has guardado el resto del día. Funcionó. Gracias. – crashtestxxx

1

Si son usando empuje para empujar los datos a los option.series dinámicamente .. sólo tiene que utilizar

options.series = []; 

para desactivarla.

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

La respuesta correcta es:

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

Usted necesita lavar la matriz '' de datos.

data = {}; 
102

Las otras respuestas no funcionó para mí. He encontrado la respuesta en su documentación:

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

uso de este método (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

Esta solución es incluso más liviana porque solo se cambiarán los valores actualizados y nada más. Ejemplo aquí: http://jsfiddle.net/ebuTs/16/ –

+7

+1 Este es el enfoque adecuado ... La respuesta elegida implica volver a crear el objeto Chart cada vez que se realiza un cambio y es muy ineficiente. –

+1

Para mis propósitos, esto no funcionó en absoluto y de hecho hizo que un cliente se enfadara conmigo. Los datos que intento mostrar son Estadísticas de llamadas para un escuadrón de rescate local. Cada mes, ejecutan un número diferente de llamadas en diferentes categorías, por lo que no siempre es lo mismo cada mes (por ejemplo, es posible que no ejecuten un solo accidente de automóvil un mes, 10 al siguiente). Su respuesta provocó un comportamiento extraño, incluidas las categorías faltantes y el error "a no está definido" en el código de HighCharts. La respuesta seleccionada puede ser ineficiente en algunos aspectos, pero funciona y el cliente está contento. – NightMICU

1

Siempre se puede cargar un conjunto de datos JSON

aquí i definida gráfico como espacio de nombres

$.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

En realidad tal vez deberías elegir la función update es mejor.
Aquí está el documento de la función updatehttp://api.highcharts.com/highcharts#Series.update

Usted puede simplemente escribir código como a continuación:

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

Estos códigos se fusionarán la opción de origen, y actualizar los datos modificados.

Cuestiones relacionadas