javascript - hur man uppdaterar ett d3-diagram när man tar emot nya DATA
Hur man uppdaterar d3-diagrammet med ny data: jag implementerar tre funktioner på ngOnChanges:
this.removeSvg(this.data);
this.createSvg();
this.drawBars(this.data);
var createSvg() :
private createSvg(): void {
this.svg = d3.select("figure#histogram")
.append("svg")
.attr("width", '100%')
.attr("height", '100%')
.append("g")
.attr("transform", "translate(" + this.margin + "," + this.margin + ")");
}
och removeSvg() :
this.svg = d3.select("figure#histogram")
.exit().remove()
d3.select("#histogram").select("svg").remove();
och drawBars(data : any [] ) :
private drawBars(data: any[]): void {
// Create the X-axis band scale
const x = d3.scaleBand()
.range([this.axisMin, 340])
.domain(data.map(d => d.xAxis))
.padding(0);
// Create the Y-axis band scale
const y = d3.scaleLinear()
.domain([0, this.axisMax])
.range([this.height, 0])
.nice();
// Create and fill the bars
this.svg.selectAll("bars")
.data(data)
.enter()
.append("rect")
.attr("x", d => x(d.xAxis))
.attr("y", d => y(d.yAxis))
.attr("width", x.bandwidth())
.attr("height", (d) => this.height - y(d.yAxis))
.attr("fill", "rgb(13, 185, 240)");
}
men det uppdaterar inte diagrammet, även om jag är säker på att data uppdateras (så för det första diagrammet fortsätter vi ha alla andra diagram som om det är samma data) någon hjälp? kanske ta bort eller avsluta är fel här!
Svar #1
I D3 kan man manipulera DOM med hjälp av urval. I din drawBars()-funktion använder du enter-urvalet som beskriver vad som händer med ny data. För att beskriva vad som händer med data som har ändrats, använd update-urvalet; för data som lämnar, använd exit-urvalet. För att följa den uppdaterade datan behöver du en nyckelfunktion på data()-anropet som unikt identifierar varje element.
Se den här handledningen för en mer detaljerad översikt.
I din drawBars()-funktion:
private drawBars(data: any[]): void {
// ...
let t = svg.transition().duration(500);
this.svg.selectAll("bars")
.data(data, d => d)
.join(
enter => enter
.append("rect")
.attr("x", d => x(d.xAxis))
.attr("y", d => y(d.yAxis))
.attr("width", x.bandwidth())
.attr("height", (d) => this.height - y(d.yAxis))
.attr("fill", "rgb(13, 185, 240)"),
update => update.call(update => update.transition(t)
.attr("x", d => x(d.xAxis))
.attr("y", d => y(d.yAxis))
.attr("height", (d) => this.height - y(d.yAxis))),
exit => exit.call(exit => exit.transition(t)
.attr("x", 0)
.attr("y", 0)
.attr("height", 0)
.remove()))
}
Svar #2
löste sig!
för alla som står inför detta problem råder jag honom med denna lösning: behåll allt som det är, men se till att uppdatera datan vid varje förändring, och töm sedan svg:n på alla dess element med:
his.svg.selectAll("*").remove()
, rita sedan diagrammet igen med nya data.
