marmelab / EventDrops

A time based / event series interactive visualization using d3.js

Home Page:http://marmelab.com/EventDrops/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

drop color function or radius is not called again to fill or resize on merge.

martyquinn opened this issue · comments

Please do not submit support requests or "How to" questions here. For that, go to StackOverflow.

What you were expecting:
I was expecting my color function to work properly and color events based on type. It does so initially but on zoom it fails to reflect the data correctly!!! Not good data visualization to say the least. :)

I have set a color function on drop to color individual drops differently based on a type of event. However when I zoom in and out the colors of individual drops change as the merge does not redraw the fill using the color function for drop and simply changes what actual object on the screen is used but not the underlying data associated with that particular dom object so the hover over is still correct.
What happened instead:

  .merge(drops)
    .attr('cx', d => xScale(dropDate(d)));

// no call to fill or radius..

Steps to reproduce:
For instance: in the config use something like
color: (d, index) => d.surveyId === "GAD-7" ? 'green' : 'red',
Make sure there are enough event objects that when zooming in and out the number of events change that are displayed. You'll see the color change despite the actual data values in the object.

Related code:

insert short code snippets here

Other information:

Here's how I fixed it locally:

Wt = function (s, h) {
return function (t) {
var e, n, r = s.drop,
o = r.color,
u = r.radius,
a = r.date,
i = r.onClick,
c = r.onMouseOver,
f = r.onMouseOut,
l = t.selectAll(".drop").data((e = h, n = a, function (t) {
return $t(t.data, function (t) {
return Math.round(e(n(t)))
})
}));
l
.enter().append("circle").classed("drop", !0).on("click", i).on("mouseover", c).on("mouseout", f)
.merge(l).attr("cx", function (t) {
return h(a(t))
}).attr("r", u).attr("fill", o), l.exit().on("click", null).on("mouseover", null).on("mouseout", null).remove()
}
};

I also have the meatballs turned off since I am also trying to use my own radius sizing. The important lines are:
.enter().append("circle").classed("drop", !0).on("click", i).on("mouseover", c).on("mouseout", f)
.merge(l).attr("cx", function (t) {
return h(a(t))
}).attr("r", u).attr("fill", o), l.exit().on("click", null).on("mouseover", null).on("mouseout", null).remove()
}

Environment

  • EventDrops version "event-drops": "^1.1.1",
  • Browser: chrome.
  • Stack trace (in case of a JS error):

In event-drops there is no provision for keyed dom elements from what I can tell. So, you must provide all the drawing updates color size etc after the merge() by moving those calls from the enter section into the merge.
"There’s many instances when key functions are not required but if there’s any chance that your data elements can change position (e.g. through insertion or sorting) and you’re using transitions then you should probably use them."

This looks like a duplicate of #239 but with a bit more info on a suggested fix.

There is a similar problem with the circle radius when it depends of the drop data, this happens even without metaballs.
When zoomed out the event radius isn't honored. We can have a huge circle almost hidden that only becomes visible when zooming in.
As it is dynamic color and radius are unusable.

cf #257 solution