plugin piechart nvd3 docs chart bar javascript d3.js charts nvd3.js

javascript - piechart - nvd3 pasando el evento incorrecto en stateChange(cuando se hace clic en leyenda) después de que se cargue el gráfico



nvd3 piechart (1)

Tengo un gráfico nvid3 multibar (pero el mismo problema ocurre con un gráfico circular).

Quiero guardar el estado de la leyenda cuando el usuario habilita o deshabilita una serie, haciendo clic en ella en la leyenda. Así que estoy escuchando eventos stateChange .

En el siguiente código de ejemplo, hay dos series. Cuando el usuario hace clic, por ejemplo, en la serie 1 para desactivarlo, la consola debe iniciar sesión:

New State: {"disabled":[true,false]}

El problema comienza a producirse después de actualizar el gráfico con nuevos datos del servidor (simulado por setInterval en el código siguiente). Después de la primera actualización siempre recibo un evento incorrecto, es decir, los valores del atributo deshabilitado están en mal estado .

Tal vez la forma en que actualizo el gráfico es incorrecta?

Aquí el código de muestra:

var initialData = [ { key: ''series1'', values: [ { x: 0, y: 10}, { x: 1, y: 44} ]}, { key: ''series2'', values: [ { x: 0, y: 25}, { x: 1, y: 11} ]} ]; var chart; nv.addGraph(function() { chart = nv.models.multiBarChart() .delay(0); d3.select(''#chart1 svg'') .datum(initialData) .call(chart); nv.utils.windowResize(chart.update); chart.dispatch.on(''stateChange'', function(e) { nv.log(''New State:'', JSON.stringify(e)); }); setInterval(function () { var newDataFromServer = [ { key: ''series1'', values: [ { x: 0, y: Math.floor((Math.random()*100)+1)}, { x: 1, y: Math.floor((Math.random()*100)+1)} ]}, { key: ''series2'', values: [ { x: 0, y: Math.floor((Math.random()*100)+1)}, { x: 1, y: Math.floor((Math.random()*100)+1)} ]} ]; d3.select(''#chart1 svg'') .datum(newDataFromServer) .call(chart); nv.utils.windowResize(chart.update); }, 5000); return chart; });


He encontrado una solución de trabajo. No tengo tiempo para investigar más, pero en el siguiente código ( nvd3 / legend.js ):

.on(''click'', function(d,i) { dispatch.legendClick(d,i); if (updateState) { if (radioButtonMode) { // etc ... } else { // Note: this ''d'' doesn''t belong to the ''data'' array in the current scope d.disabled = !d.disabled; // etc ... } dispatch.stateChange({ // The old data is notified as event disabled: data.map(function(d) { return !!d.disabled }) }); } })

cuando se está comportando mal (es decir, después de la primera actualización), el objeto d no pertenece a la matriz de datos en este ámbito (se supone que debe hacerlo). Supongo que estos datos siempre apuntan a la matriz de datos inicial.

Como solución alternativa para actualizar el gráfico, obtengo el conjunto inicial y lo actualizo en el lugar:

// Get reference to data array object var chartDatum = d3.select(''#chart1 svg'') .datum(); // Clear array and copy new data into it chartDatum.length = 0; angular.extend(chartDatum, newDataFromServer); // Or jQuery extend, or equivalent chart.update();