2012-09-22 33 views
10

Tengo un gráfico de líneas muy simple escrito usando NVD3.js. He escrito un redibujado simple basado en temporizador, sacado de ejemplos que he visto, pero me sale el errorGráfico de líneas NVD3 con datos en tiempo real

no detectada TypeError: No se puede leer la propiedad 'y' de la indefinida

La JS es

var data = [{ 
     "key": "Long", 
     "values": getData() 
    }]; 
    var chart; 

    nv.addGraph(function() { 
      chart = nv.models.cumulativeLineChart() 
         .x(function (d) { return d[0] }) 
         .y(function (d) { return d[1]/100 }) 
         .color(d3.scale.category10().range()); 

     chart.xAxis 
      .tickFormat(function (d) { 
       return d3.time.format('%x')(new Date(d)) 
      }); 

     chart.yAxis 
      .tickFormat(d3.format(',.1%')); 

     d3.select('#chart svg') 
      .datum(data) 
      .transition().duration(500) 
      .call(chart); 

     nv.utils.windowResize(chart.update); 

     return chart; 
    }); 


    function redraw() { 
     d3.select('#chart svg') 
      .datum(data) 
      .transition().duration(500) 
      .call(chart); 
    } 

    function getData() { 
     var arr = []; 
     var theDate = new Date(2012, 01, 01, 0, 0, 0, 0); 
     for (var x = 0; x < 30; x++) { 
      arr.push([theDate.getTime(), Math.random() * 10]); 
      theDate.setDate(theDate.getDate() + 1); 
     } 
     return arr; 
    } 

    setInterval(function() { 
     var long = data[0].values; 
     var next = new Date(long[long.length - 1][0]); 
     next.setMonth(next.getMonth() + 1) 
     long.shift(); 
     long.push([next.getTime(), Math.random() * 100]); 
     redraw(); 
    }, 1500); 
+1

¿Se puede agregar un jsfiddle que demuestre el problema? –

+0

http://jsfiddle.net/khp9d/ –

+0

@JaimalChohan ¿cómo solucionó esto? – Sajeetharan

Respuesta

11

segunda respuesta (después de comentario)

miré a source for cumulativeLineChart. Puede ver la propiedad display.y create durante la creación del gráfico. Se basa en un método privado: "indexify". Si alguna derivada de ese método se hizo pública, entonces quizás podría hacer algo como chart.reindexify() antes de volver a dibujar.

Como solución temporal, puede volver a crear el gráfico desde cero en cada actualización. Si elimina la transición, eso parece funcionar bien. Ejemplo jsfiddle: http://jsfiddle.net/kaliatech/PGyKF/.

Primera respuesta

Creo que hay error en cumulativeLineChart. Parece que cumulativeLineChart agrega una propiedad "display.y" dinámicamente a los valores de datos en la serie. Sin embargo, no regenera esta propiedad cuando se agregan nuevos valores a la serie para un redibujado. No sé de todos modos para que haga esto, aunque soy nuevo en NVD3.

¿Realmente necesita un LineLine Cumulative, o sería un gráfico de líneas normal suficiente? Si es así, he tenido que hacer los siguientes cambios en su código:

  • Cambio de cumulativeLineChart a Linechart
  • Cambio de uso de matrices de 2 dimensiones de los datos, a la utilización de objetos de datos (con x, y propiedades)
    • (no estoy lo suficientemente familiarizado con NVD3 decir qué formatos de datos se espera. La matriz 2D obviamente funciona para cargas iniciales, pero creo que no funciona para redibujado posteriores. Esto está probablemente relacionado con el mismo problema que está teniendo con cumulativeLineChart. ¿Debería cambiar a objetos fijaría cumulativeLineChart así, pero no parecía)

También ha cambiado la siguiente, aunque no es tan importante:.

  • Modificado su función getData a cree una nueva instancia de Fecha para evitar consecuencias inesperadas de compartir una referencia a medida que la fecha se incrementa.

  • Se modificó la función del intervalo de actualización para generar nuevos datos en incrementos de días (no meses) con valores y en el mismo rango que la función getData.

Aquí hay una jsFiddle trabajar con estos cambios:

+0

No, debe ser un gráfico de líneas acumulativas, simplifiqué mi jsfiddle para mostrar solo 1 línea para que el problema sea más fácil de comprender –

+1

ah. Bueno, realmente creo que es una especie de error en NVD3. Pude hacer la función cumulativeLineChart sin lanzar errores al agregar manualmente una propiedad display: {y: ???} al punto de datos. JSfiddle: http://jsfiddle.net/kaliatech/khp9d/30/. Por supuesto, el resultado no es correcto. Creo que el único recurso es examinar la fuente y averiguar cómo obtener esa propiedad generada/actualizada en el redibujado. – kaliatech

+0

En realidad prefiero el comentario anterior como una solución, ya que el propuesto en su pregunta resulta en un nuevo trazado del gráfico completo. Además de un problema de interpolación fácil de resolver, http://jsfiddle.net/kaliatech/khp9d/30/ es lo que estaba buscando –

0

me encontré con el mismo problema. He cambiado la función y() en las líneas de

.y(function(d) { return d.display.y }) 

a

.y(function(d) { return d.display ? d.display.y : d.y }) 

Esto se deshace del error. Obviamente, no mostrará el valor indexado (inexistente) en el caso de error, pero en mi experiencia, el gráfico se actualiza nuevamente con la visualización definida, y se ve correcto.

1

Encontré lo que creo que es una mejor solución. El problema ocurre porque el gráfico acumulativo establece la función y durante el procesamiento. Siempre que desee actualizar el gráfico, primero configúrelo de nuevo en un valor predeterminado que devuelva el original correcto y. En su función de redibujado hacer esto antes de actualizar:

chart.y(function (d) { return d.y; }); 

Aún mejor sería si el gráfico acumulado podría hacer esto por sí mismo (almacenar la función de acceso original antes de establecer el nuevo, y poner de nuevo antes de volver a la indexación) . Si tengo la oportunidad, intentaré solucionarlo.

Cuestiones relacionadas