2016-04-27 7 views
1

Ich habe ein paar verschiedene Beispiele ausgesucht, um so weit wie möglich zu kommen. Ich habe ein einfaches zweizeiliges Liniendiagramm, das von einem Objekt gespeist wird. Zum Testen habe ich eine Funktion erstellt, die die Daten erhöht, indem am Ende ein neuer Datenpunkt hinzugefügt wird. Ich möchte, dass mein Diagramm diese Ergänzungen widerspiegelt.Wie aktualisiere ich meine Daten mit mehreren Liniendiagrammen in D3?

Was funktioniert:

  • Die Daten werden zu dem Objekt hinzugefügt.
  • Wenn Schaltfläche geklickt haben, passt Yscale

Was nicht funktioniert:

  • XScale nicht anpassen, um neue Daten.
  • Team 1-Linie passt die Daten der Team2-Linie an und skaliert dann entsprechend entlang der Y-Linie.

Es ist ein Durcheinander. Und gerade wenn ich denke, dass ich D3 verstehe, erniedrigt mich die Datenintegration!

Hier ist ein Code und a mostly-working fiddle.

AKTUALISIERT: Hier ist an updated fiddle, die funktioniert wie erwartet. Ich weiß, dass D3 viele dieser Dinge einfacher macht. Während es funktioniert, suche ich nach einer eleganteren Methode, um das gleiche Ergebnis zu erzielen.

Mein Datenformat ...

//SET SAMPLE DATA 
var data = [{ 
    "team": "Team 1", 
    "score": 0, 
    "elapsedTime": 0 
}, { 
    "team": "Team 1", 
    "score": 2, 
    "elapsedTime": 3 
}, 
    ... 
{ 
    "team": "Team 2", 
    "score": 18, 
    "elapsedTime": 60 
}]; 

Meine Update-Funktion ...

function updateChart(){ 
    //SPLIT UPDATED DATA OBJECT INTO TWO TEAMS 
    dataGroup = d3.nest() 
    .key(function(d) { 
     return d.team; 
    }) 
    .entries(data); 

    //DRAW LINES 
    dataGroup.forEach(function(d, i) { 

    // Select the section we want to apply our changes to 
    var vis = d3.select("#visualisation").transition(); 

    xScale.domain([0, d3.max(data, function(d) { 
     return d.elapsedTime; 
    })]); 
    yScale.domain([0, d3.max(data, function(d) { 
    return d.score; 
    })]); 

    //PROBLEM: Team 1 line changes to Team 2's data 
    vis.select("#line_team1") 
     .duration(750) 
     .attr("d", lineGen(d.values)); 
    }); 

    vis.select("#line_team2") 
     .duration(750) 
     .attr("d", lineGen(data)); 

    // X-SCALE NEVER ADJUSTS 
    vis.select(".x.axis") // change the x axis 
     .duration(750) 
     .call(xAxis); 

    // Y-AXIS SEEMS TO SCALE AS EXPECTED 
    vis.select(".y.axis") // change the x axis 
     .duration(750) 
     .call(yAxis); 
}; 

würde Einsicht sehr zu schätzen!

+0

Lieber Layne, hat dir meine Lösung geholfen? – iulian

Antwort

1

Eine Möglichkeit, Ihren Code weiter zu vereinfachen, besteht darin, ihn basierend auf den Daten selbst so zu ändern, dass er aktualisiert.

Eine Methode, die ich oft verwende, ist das Ermitteln des Selektors zum Aktualisieren der Daten von den Daten selbst. In Ihrem Fall könnten Sie die key Eigenschaft Ihrer dataGroup Objekte verwenden:

dataGroup.forEach(function(d, i) { 
    vis.select("#line_"+d.key.toLowerCase().split(' ').join('')) 
    .duration(750) 
    .attr("d", lineGen(d.values)); 

    var maxi = d3.max(data, function(d) { 
    return d.elapsedTime; 
    }); 
    ... 
}); 

Oder Sie könnten die Vorverarbeitung in Ihrem d3.nest() Anruf, um den Schlüssel in Form von team1 und verwenden Sie es als Wähler tun zu erhalten.

Hier ist eine Gabel von Ihrem fiddle mit funktionierenden Beispiel.

Verwandte Themen