2016-07-04 1 views
0

Ich versuche ein gestapeltes Balkendiagramm über d3js zu erstellen und es zu aktualisieren, wenn neue Daten durch eine Update-Funktion geleitet werden. Ich rufe diese Update-Funktion, um das Diagramm anfänglich aufzurufen, und es funktioniert gut. Wenn ich jedoch die Daten ändere und sie erneut aufruft, löscht sie alle "rect" -Elemente aus dem Graphen (wenn ich die Daten auf der Konsole protokolliere, scheint sie durchzulaufen). Wie kann ich den Graphen entsprechend neu zeichnen lassen? Ich habe versucht, zu Beginn mit der .remove() - Anweisung zu experimentieren, aber ohne sie gehen die Daten nicht durch, wenn die Balken neu gezeichnet werden.d3js update redraw stacked bar graph

function update(my_data) { 
    svg.selectAll(".year").remove(); 
    var year = svg.selectAll(".year") 
      .data(my_data) 
     .enter().append("g") 
      .attr("class", "year") 
      .attr("transform", function(d) { return "translate(" + x0(d.Year) + ",0)"; }); 
    var bar = year.selectAll(".bar") 
      .data(function(d){ return d.locations; }); 
    bar 
     .enter().append("rect") 
      .attr("class", "bar") 
      .attr("width", x0.rangeBand()) 
      .attr("y", function(d) { return y(d.y1); }) 
      .attr("height", function(d) { return y(d.y0) - y(d.y1); }) 
      .style("fill", function(d) { return color(d.name); }); 
} 
update(data); 

Antwort

0

Es ist schwer genau zu sagen, was Sie tun, weil Ihre Frage nicht die Daten oder das DOM enthält. Es würde helfen, wenn Sie einen Link zu einem Work-in-Progress jsFiddle oder etwas hinzufügen würden.

Wenn ich raten musste, was schief läuft, sieht es so aus, als ob Sie eine verschachtelte Verbindung machen, bei der jedes Jahr an ein g-Element gebunden wird und jeder Ort innerhalb jedes g-Elements an ein rect gebunden wird.

Das Problem ist wahrscheinlich, dass Sie nur das Eingabeverhalten angeben, aber nicht das Aktualisierungsverhalten oder das Beendigungsverhalten. Wenn Sie versuchen, neu zu zeichnen, wird nichts aktualisiert und nichts wird beendet - aber neue Datenelemente werden hinzugefügt.

Es scheint, dass Sie deshalb die selectAll(). Remove() hinzufügen müssen, um alles neu zu zeichnen. Wenn Sie alles entfernen, lösen alle Datenelemente die Enter-Bedingung aus und werden erneut hinzugefügt.

Werfen Sie einen Blick auf diese Tutorials, um besser zu verstehen, wie das enter/update/exit-Muster funktioniert und wie verschachtelte Joins funktionieren.

Allgemeine Update-Muster:https://bl.ocks.org/mbostock/3808218

Nested Auswahl:https://bost.ocks.org/mike/nest/

Auch hier ist ein jsFiddle ich vor einiger Zeit zu zeigen, schrieb, wie verschachtelte Auswahl verwenden und die allgemeine Aktualisierung Muster zusammen:

https://jsfiddle.net/reblace/bWp8L/

var series = svg.selectAll("g.row").data(data, function(d) { return d.key; }); 

/* 
* This section handles the "enter" for each row 
*/ 
// Adding a g element to wrap the svg elements of each row 
var seriesEnter = series.enter().append("g"); 
seriesEnter 
    .attr("class", "row") 
    .attr("transform", function(d, i){ 
     return "translate(" + margin.left + "," + (margin.top + (span*i)) + ")"; 
    }) 
    .attr("opacity", 0).transition().duration(200).attr("opacity", 1); 

// Adding a text label for each series 
seriesEnter.append("text") 
    .style("text-anchor", "end") 
    .attr("x", -6) 
    .attr("y", boxMargin + (boxDim/2)) 
    .attr("dy", ".32em") 
    .text(function(d){ return d.key; }); 

// nested selection for the rects associated with each row  
var seriesEnterRect = seriesEnter.selectAll("rect").data(function(d){ return d.values; }); 

// rect enter. don't need to worry about updates/exit when a row is added 
seriesEnterRect.enter().append("rect") 
    .attr("fill", function(d){ return colorScale(d)}) 
    .attr("x", function(d, i){ return i*span + boxMargin; }) 
    .attr("y", boxMargin) 
    .attr("height", boxDim) 
    .attr("width", boxDim); 

/* 
* This section handles updates to each row 
*/ 
var seriesUpdateRect = series.selectAll("rect").data(function(d){ return d.values}); 

// rect update (Will handle updates after enter) 

// rect enter 
seriesUpdateRect.enter().append("rect") 
    .attr("x", function(d, i){ return i*span + boxMargin; }) 
    .attr("y", boxMargin) 
    .attr("height", boxDim) 
    .attr("width", boxDim); 

// rect enter + update 
seriesUpdateRect 
    .attr("fill", function(d){ return colorScale(d)}); 

// Exit 
seriesUpdateRect.exit(); 

/* 
* This section handles row exit 
*/ 
series.exit() 
    .attr("opacity", 1) 
    .transition().duration(200).attr("opacity", 0) 
     .remove(); 
+0

danke für Ihre Antwort. Ich habe die Update-Funktion geändert und im Wesentlichen versucht, den Code zu kopieren und einzufügen, aber ich habe immer noch das, was wie das selbe Problem aussieht. Wenn ich die remove() -Anweisung am Anfang hinzufüge, werden alle console.log-Anweisungen in Zeile 11 des Codes (das translate-Attribut) entsprechend gedruckt, aber alle Elemente verschwinden im Diagramm, ohne neu gezeichnet zu werden. Wenn ich diese remove() -Anweisung nicht hinzufüge, gibt die console.log in Zeile 11 nichts zurück, und das alte Diagramm bleibt so, wie es vor dem Update war. Weißt du, warum das sein könnte? –

+0

Ich kann wirklich nicht viel mehr Hilfe sein, ohne dass du den eigentlichen Code veröffentlichst, sorry. Sie sollten versuchen, ein grundlegendes Beispiel für die Arbeit mit jsFiddle zu erhalten. – reblace