2012-09-22 15 views
10

Mam naprawdę prosty wykres liniowy napisany przy użyciu NVD3.js. Napisałem prosty narysowany w oparciu o zegar, wyciągnął z przykładów widziałem, ale pojawia się błądWykres liniowy NVD3 z danymi w czasie rzeczywistym

Uncaught TypeError: nie można odczytać właściwość „y” o nieokreślonej

JS jest

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

Czy możesz dodać jsfiddle demonstrujący problem? –

+0

http://jsfiddle.net/khp9d/ –

+0

@JaimalChohan jak to naprawiliście? – Sajeetharan

Odpowiedz

11

Druga odpowiedź (po komentarzu)

Spojrzałem na source for cumulativeLineChart. Możesz zobaczyć właściwość display.y, która zostanie utworzona podczas tworzenia wykresu. Opiera się na prywatnej metodzie: "indeksuj". Jeśli jakaś pochodna tej metody została upubliczniona, być może mógłbyś zrobić coś w stylu chart.reindexify() przed ponownym rysowaniem.

Jako tymczasowe obejście, można odtworzyć wykres od zera przy każdej aktualizacji. Jeśli usuniesz przejście, wydaje się, że działa dobrze. Przykład: jsfiddle: http://jsfiddle.net/kaliatech/PGyKF/.

pierwsza odpowiedź

Wierzę, że jest błąd w cumulativeLineChart. Wygląda na to, że skumulowana linijkaChart dynamicznie dodaje właściwość "display.y" do wartości danych w serii. Jednak nie odtwarza tej właściwości po dodaniu nowych wartości do serii w celu odświeżenia. I tak nie wiem, żeby to zrobić, chociaż jestem nowy w NVD3.

Czy naprawdę potrzebujesz CumulativeLineChart, czy normalny wykres liniowy byłby wystarczający? Jeśli tak, to musiałem dokonać następujących zmian w kodzie:

  • Zmiana od cumulativeLineChart do Linechart
  • zmiana z użyciem tablic 2 wymiar danych, do korzystania obiektów danych (X, Y właściwości)
    • (nie jestem na tyle obeznany z NVD3 powiedzieć jakie formaty danych oczekuje. tablica 2D oczywiście działa na początkowych obciążeń, ale myślę, że to nie działa dla kolejnych przerysowywania. jest to prawdopodobnie związane z ten sam problem z kumulatywną linią danych powinien zmianie do obiektów będzie naprawić cumulativeLineChart jak dobrze, ale to nie wydaje się)

ja również zmienić następujące, choć nie tak ważne.

  • Modified swoją funkcję getData do utwórz nowe wystąpienie Data, aby uniknąć nieoczekiwanych konsekwencji udostępnienia odwołania w miarę zwiększania daty.

  • Zmodyfikowano funkcję interwału aktualizacji, aby wygenerować nowe dane w przyrostach dni (nie miesięcy) z wartościami y w tym samym zakresie co funkcja getData.

Oto jsfiddle pracy z tymi zmianami:

+0

Nie, musi to być skumulowany wykres liniowy, uprościłem mój jsfiddle, tak aby wyświetlał tylko 1 linię, aby ułatwić zrozumienie problemu. –

+1

ah. Cóż, naprawdę myślę, że to rodzaj błędów w NVD3. Udało mi się utworzyć funkcję skumulowanąLineChart bez generowania błędów przez ręczne dodanie właściwości display: {y: ???} do punktu danych. JSfiddle: http://jsfiddle.net/kaliatech/khp9d/30/. Oczywiście wynik jest nieprawidłowy. Myślę, że jedynym rozwiązaniem jest zbadanie źródła i wykombinowanie, jak uzyskać tę właściwość generowaną/zaktualizowaną przy przerysowaniu. – kaliatech

+0

Właściwie wolę powyższy komentarz jako rozwiązanie, ponieważ proponowany w twoim pytaniu powoduje przerysowanie całego wykresu. Oprócz łatwego rozwiązania problemu z interpolacją, szukałem http://jsfiddle.net/kaliatech/khp9d/30/ –

0

wpadłem na ten sam problem. Zmieniłem funkcję y() na liniach z

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

do

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

ten pozbywa się błędem. Oczywiście nie będzie wyświetlać (nieistniejącej) indeksowanej wartości w przypadku błędu, ale z mojego doświadczenia wynika, że ​​wykres jest aktualizowany ponownie z definiowanym wyświetlaczem i wygląda poprawnie.

1

Znalazłem to, co uważam za lepsze rozwiązanie. Problem występuje, ponieważ wykres zbiorczy ustawia funkcję y podczas przetwarzania. Ilekroć chcesz odświeżyć wykres, najpierw ustaw go z powrotem na wartość domyślną, która zwraca prawidłowy oryginalny y. W funkcji odświeżania to zrobić przed aktualizacją:

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

Jeszcze lepiej byłoby, gdyby skumulowany wykres mógłby zrobić to samo za siebie (przechowywanie pierwotną funkcję dostępu przed ustawieniem nowego, i umieścić go z powrotem przed ponownym indeksowaniu) . Jeśli dostanę szansę, spróbuję wprowadzić poprawkę.

Powiązane problemy