marmelab/EventDrops

Data not updatable after initial draw

dflor003 opened this issue · 3 comments

There does not seem to be any way to update the data that event drops is bound to after your initial render.

My main use-case for this is to bring in data gradually as you change your time range upon zoom. I'm trying to use this for a tool that will let you view parts of an event stream with potentially millions of events (i.e. not feasible to pre-load all data in the browser).

What you were expecting:

That either the draw method or some other method would allow you to update the data for the event drops visualization.

See this JSFIddle for some things I tried: https://jsfiddle.net/dflor003/m96qhwa7/

What happened instead:

Re-calling the selection with the event drops instance throws:

TypeError: Cannot read property 'length' of undefined

Calling .draw fails unless you pass a full config object with every property set (even defaults).
Even if you do pass a full config object, it still does not redraw the new data set.

Steps to reproduce:

  1. Build a working event drops setup.
  2. Add an onZoomEnd handler that fetches data when the time range is changed.
  3. Try updating the data on the original selection and then do a .call on either draw or the original event drops instance.

Related code:

https://jsfiddle.net/dflor003/m96qhwa7/25/

One approach tried:

function updateData(start, end) {
  // This doesn't work as the original config
  // is lost and even if you build out the entire
  // config, the data still does not update
  const newData = buildData(start, end);
  d3.select(element)
    .data([
      [newData]
    ])
    .call(chart.draw({
      range: {
        start: start.toDate(),
        end: end.toDate(),
      }
    }, chart.scale()));
}
function updateDataAlt(start, end) {
  // This throws a bunch of errors like
  // cannot read length of undefined
  const newData = buildData(start, end);
  d3.select(element)
    .data([
      [newData]
    ])
    .call(chart);
}

Environment

  • EventDrops version: 1.2.0
  • Browser: Chrome
  • Stack trace (in case of a JS error):
Uncaught TypeError: Cannot read property 'length' of undefined
    at VM266 index.js:1
    at ut.call (VM265 d3.min.js:2)
    at VM266 index.js:1
    at ut.call (VM265 d3.min.js:2)
    at g (VM266 index.js:1)
    at ut.call (VM265 d3.min.js:2)
    at updateDataAlt ((index):106)
    at SVGSVGElement.onZoomEnd ((index):58)
    at S.apply (VM265 d3.min.js:2)
    at ot (VM265 d3.min.js:2)

I am interested in this same enhancement. I've been studying the code in an attempt to implement ... but no luck so far either.

Any chance we could get some direction and/or hints from the original authors?

Thanks for the detailed steps. I didn't focus myself on the issue for now. But that's indeed in top priority, as it is an important need in my opinion.

Fixed by #262