flekschas / regl-scatterplot

Scalable WebGL-based scatter plot library build with Regl
https://flekschas.github.io/regl-scatterplot/
MIT License
184 stars 21 forks source link

Inability to draw with active filter #136

Closed insertmike closed 1 year ago

insertmike commented 1 year ago

Abstract (Enhancement)

Currently, it is not possible to draw points with active filter. This results in enforcing users to first draw the points and then filter, which itself results in a flashy UI.

What triggered the issue

Users may want to change the point values for the colorBy. For example, you want to color by for different Value A. In order to do this with the current API, the only way is to redraw by passing a new points object. (E.G [[x,y,A,B]...).

However, while doing this, you may have active filter applied. The filter is reset on the .draw call.

Proposal

To improve the user experience, it would be useful to be able to set filteredPoints while drawing already, or give the ability for users to pass new data objects for the points without needing to redraw (I guess this may be more complex)

flekschas commented 1 year ago

Could you provide a small example illustrating the problem? I'm not 100% sure I fully understand what you mean with

Currently, it is not possible to draw points with active filter. This results in enforcing users to first draw the points and then filter, which itself results in a flashy UI.

Is the following the issue:

const points = [
  [x1, y1, a1, b1],
  [x2, y2, a2, b2],
  [x3, y3, a3, b3],
  [x4, y4, a4, b4],
]
scatter.draw(points);
scatter.filter([0, 1]);
points[0][2] = a1.2; // Assign a new `A` value to the first point
scatter.draw(points); // This clears the filter, which is not desired?

If I understand correctly, one solution might be to add an option to draw() that prevents the filter from unsetting. And I agree another option to set the filter within draw() could also be useful.

The first option (maybe we call it preventFilterReset is super simple to implement. The second option might be a bit more involved.

or give the ability for users to pass new data objects for the points without needing to redraw

I don't see the use case for this. What's the point in changing the data and not re-drawing the scatterplot? E.g., if the A value is used for coloring points, why update the data but not redraw the plot? And if the A value is used for nothing, why even update the data?

One thing I can see is that if only the A or B value change, one could skip the re-creation of the spatial index and index buffer. That could be useful. In that case I would propose another flag in draw() called something like sameXYCoordinates

insertmike commented 1 year ago

@flekschas Here is a reproducible demo of the problem:

https://codesandbox.io/s/awesome-hertz-gpjyw8 (Uncomment // alert('State with all points (flicker time)' to see the state when it flickers.

By the way, I was not aware that you can assign new values to the current object (by reference). Maybe for the meantime I can use this and try to make a PR about preventFilterReset since it's a nice to have. If you have any suggestions for the PR, let me know