Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3 throws "Cannot read property 'ownerDocument' of null" on setting .data() to appended element

Tags:

d3.js

I'm getting this error:

Uncaught TypeError: Cannot read property 'ownerDocument' of null

This is from a line that sets .data() to an element recently appended by d3:

const someSet = someSelection.filter('.some:(filter)')

someSet.each((d, i, nodes) => {
  const someElement = d3.select(nodes[i])
  const someChild = someElement.append('g')

  someChild.data(this.data) // <-- This line throws the error
   .enter()
   .append('circle')
   .classed('some-class', true)
})

Looking around all I could find is a source saying they had this error when the element in question hadn't yet been added to the page, but I have confirmed that my element was added to the page at the time this error was thrown.

like image 501
user56reinstatemonica8 Avatar asked Apr 06 '18 15:04

user56reinstatemonica8


1 Answers

Turns out I was forgetting to add a new empty selection before adding .data() to the nested element:

const someSet = someSelection.filter('.some:(filter)')

someSet.each((d, i, nodes) => {
  const someElement = d3.select(nodes[i])
  const someChild = someElement.append('g')

  someChild.selectAll('circle.some-class') // added empty selection here
   .data(this.data)
   .enter()
   .append('circle')
   .classed('some-class', true)
})

I've also encountered this error if I do something like create a group, store a reference to the group, attach data and append, then try to attach new data to the reference to the group (<g>) instead of the selection of the contents of the group). For example this will cause this error:

const someObj = {} // or some class etc
const someSet = someSelection.filter('.some:(filter)')

someSet.each((d, i, nodes) => {
  const someElement = d3.select(nodes[i])
  const someChild = someElement.append('g')
  someObj.someChild = someChild

  someChild.selectAll('circle.some-class') // added empty selection here
   .data(this.data)
   .enter()
   .append('circle')
   .classed('some-class', true)
})

// ...do stuff
someObj.someChild.data(newData)
// Error because someObj.someChild is a D3 element, not a D3 selection

So, at the end it should be:

someObj.someChild.selectAll('circle.some-class').data(newData)

...or the stored reference should be to the selection that the data is added to.

like image 175
user56reinstatemonica8 Avatar answered Oct 20 '22 05:10

user56reinstatemonica8