Reputation: 43
I'm trying to update a data array with D3.js but it's doesn't work.
I've read documentation of D3, and many demos on bl.ocks.org but my issue still persist. I don't understand why. I miss something, but I don't find what is this.
This is my code:
const data = [4, 8, 15, 16, 23, 42]
const data2 = [3, 6, 9, 17, 45]
const button = `<button>Click</button>`
document.querySelector('body').insertAdjacentHTML('afterbegin', button)
const svg = d3.select('body')
.append('svg')
const renderArray = (data) => {
const group = svg.selectAll('g')
.data(d => data)
group.exit().remove()
group.enter()
.append('g')
.merge(group)
.attr('id', d => d)
const p = group.selectAll("text")
.data(d => d)
p.enter()
.append("text")
.merge(p)
.text((d) => d)
p.exit().remove()
}
renderArray(data)
document.querySelector('button').addEventListener('click', () => renderArray(data2))
My pen : https://codepen.io/Tirkal/pen/OKOvzN?editors=0010
I expect the update of data array.
Upvotes: 1
Views: 48
Reputation: 102174
You have two main problems:
First, selections are immutable. Therefore, the merge
function here...
group.enter()
.append('g')
.merge(group)
//etc...
... is not going to change group
. You have to reassign it:
group = group.enter()
//etc...
Second, the data
function only accepts three things: an array, a function or nothing. That being said, for the texts, it should be:
const p = group.selectAll("text")
.data(d => [d])
//array-----^
Even better, since those values are not inner arrays or objects just drop those text
selections and append the texts directly.
There are other minor problems, but those two are the most important ones.
Here is the resulting code:
const data = [4, 8, 15, 16, 23, 42]
const data2 = [3, 6, 9, 17, 45]
const button = `<button>Click</button>`
document.querySelector('body').insertAdjacentHTML('afterbegin', button)
const svg = d3.select('body')
.append('svg')
const renderArray = (data) => {
let group = svg.selectAll('g')
.data(data)
group.exit().remove()
group = group.enter()
.append('g')
.merge(group)
.attr("transform", (_, i) => "translate(10," + (i * 20) + ")")
.attr('id', d => d)
const p = group.selectAll("text")
.data(d => [d])
p.enter()
.append("text")
.merge(p)
.text((d) => d)
p.exit().remove()
}
renderArray(data)
document.querySelector('button').addEventListener('click', () => renderArray(data2))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
Upvotes: 2