2013-02-19 18 views
22

Pracuję nad wizualizacją danych przychodzących w czasie rzeczywistym. Używam D3 do wizualizacji i uruchamiane na tym przykładzie: http://bl.ocks.org/mbostock/3883195Dynamicznie aktualizuj dane wykresu w D3

To jest wersja Obecnie pracuję nad:

var margin = {top: 20, right: 20, bottom: 30, left: 50}, 
    width = 500 - margin.left - margin.right, 
    height = 300 - margin.top - margin.bottom; 

    var x = d3.time.scale().range([0, width]); 
    var y = d3.scale.linear().range([height, 0]); 

    var xAxis = d3.svg.axis().scale(x).orient("bottom"); 
    var yAxis = d3.svg.axis().scale(y).orient("left"); 

    var area = d3.svg.area() 
     .x(function(d) { return x(d.x); }) 
     .y0(height) 
     .y1(function(d) { return y(d.y); }); 

    var svg = d3.select("div#chart").append("svg") 
     .attr("width", width + margin.left + margin.right) 
     .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

    var data = [[1,1],[2,3],[3,2],[4,4]]; 

    var dataCallback = function(d) { 
    d.x = +d[0]; 
    d.y = +d[1]; 
    }; 
    data.forEach(dataCallback); 

    x.domain(d3.extent(data, function(d) { return d.x; })); 
    y.domain([0, d3.max(data, function(d) { return d.y; })]); 

    svg.append("path") 
     .datum(data) 
     .attr("class", "area") 
     .attr("d", area); 

    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis); 

    svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis) 
    .append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 6) 
     .attr("dy", ".71em") 
     .style("text-anchor", "end") 
     .text("Number of Messages"); 

To daje następujące wykresu:

simple graph

Teraz, ponieważ powinien regularnie aktualizować się, chciałem dynamicznie aktualizować dane na wykresie, używając następującego kodu:

var n = svg.selectAll("path").data([5,20]) 
    n.enter(); 
    n.exit().remove(); 

To jednak nie działa. Jestem nowy w D3 i wciąż uczę się podstaw. Idealnie, wizualizacja wykresu przesuwa się w lewo, a nowe dane są pokazane na wykresie. Ale do tej pory nie mogę nawet dodać do niego nowych danych. Czy ktoś mógłby mi w tym pomóc? Szukałem również przykładów podobnych do tego, ale nie znalazłem niczego, co naprawdę mi pomogło do tej pory.

+0

Czy widziałeś http://mbostock.github.com/d3/tutorial/bar-2.html? –

+0

Tak, wydaje się łatwiejsze z paskami, ponieważ masz kilka z nich, a nowe dane po prostu tworzą nowe, a najstarsze są usuwane. Wydaje się, że dla obszarów jest trudniej. – str

Odpowiedz

19

d3 jest całkiem niezły w śledzeniu, jakie dane zostały dodane i co jest usuwane - robi to z połączeniami. Spójrz na http://bl.ocks.org/mbostock/3808218

jeśli używamy wiązania danych (zamiast „zerowego”)

svg.append("path") 
    .data([data]) 
    .attr("class", "area") 
    .attr("d", area); 

a następnie na aktualizację zrobić coś takiego:

// update the list of coordinates 
data.splice(0,1); 
data.push([5,20]); 

// re-decorate the last, newly added item 
dataCallback(data[data.length - 1]); 

// You will also need to update your axes 
x.domain(d3.extent(data, function(d) { return d.x; })); 
y.domain([0, d3.max(data, function(d) { return d.y; })]); 

// update the data association with the path and recompute the area 
svg.selectAll("path").data([data]) 
    .attr("d", area); 

i powinieneś dostać swój obszar aktualizować.

Można go wypróbować here

z sposób dane są organizowane za pomocą połączonych danych (zamiast odniesienia) mogą nie robi dużej różnicy. Zauważ, że tutaj (pojedynczym) elementem danych, który kojarzysz ze ścieżką, jest pełna lista współrzędnych, aby zaktualizować obszar, który musisz podać na nowej pełnej liście współrzędnych.

Jeśli naprawdę chcesz zminimalizować kwotę, którą musisz przerysować, możesz podzielić obszar i narysować każdy segment linii. Następnie zasadniczo powraca się do przykładu z wykresem słupkowym, ale z nie płaskimi paskami i bez odstępów.

+2

Dziękuję, to naprawdę bardzo pomogło. Oprócz odpowiedzi, ten link może również pomóc innym osobom z tym samym problemem: http://bl.ocks.org/benjchristensen/1148374 – str

+0

Szybkie pytanie; patrząc teraz na skrzypce, topory nie wydają się uaktualniać. Czy wiesz, co to jest problem? –

+0

Hmm - nie jestem pewien, co się zmieniło, ale potrzebuje tylko svg.select ("g.x.axis"). Call (xAxis); linia w module obsługi kliknięcia, a oś zostanie zaktualizowana. – Superboggly

Powiązane problemy