Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make scatter plot legends clickable #690

Merged
merged 13 commits into from
Feb 4, 2025

Conversation

dv-usama-ansari
Copy link
Contributor

@dv-usama-ansari dv-usama-ansari commented Jan 23, 2025

Closes https://github.com/datavisyn/reprovisyn/issues/2249

Developer Checklist (Definition of Done)

Issue

  • All acceptance criteria from the issue are met
  • Tested in latest Chrome/Firefox

UI/UX/Vis

  • Requires UI/UX/Vis review
    • Reviewer(s) are notified @dvmoritzschoefl
    • Review has occurred (link to notes)
    • Feedback is included in this PR
    • Reviewer(s) approve of concept and design

Code

  • Branch is up-to-date with the branch to be merged with, i.e., develop
  • Code is cleaned up and formatted
  • Unit tests are written (frontend/backend if applicable)
  • Integration tests are written (if applicable)

PR

  • Descriptive title for this pull request is provided (will be used for release notes later)
  • Reviewer and assignees are defined
  • Add type label (e.g., bug, feature) to this pull request
  • Add release label (e.g., release: minor) to this PR following semver
  • The PR is connected to the corresponding issue (via Closes #...)
  • Summary of changes is written

Summary of changes

  • Implement click event on the legend to toggle the points in the scatter plot

Screenshots

EDIT: As of 47071b9

2025-01-28.14-00-45.mp4

Additional notes for the reviewer(s)

  • @thinkh: What should be the behavior of the regression line when we filter out something using the legend items

Sorry, something went wrong.

wip: click changes the colors of points in an unexpected way
@dv-usama-ansari dv-usama-ansari self-assigned this Jan 23, 2025
@dv-usama-ansari dv-usama-ansari added release: minor PR merge results in a new minor version type: feature New feature or request labels Jan 23, 2025
@dvdanielamoitzi
Copy link
Contributor

As discussed with @dv-usama-ansari , this is already implemented in visyn_core, and ready to use 🙂

@dv-usama-ansari
Copy link
Contributor Author

Implemented in 7d22667 and it works beautifully!

image

Thanks for the hint @dvdanielamoitzi!

return <LegendItem key={c} color={colorMap(c)} label={c} onClick={() => onClick(c)} filtered={false} />;
})}
{categories.map((c) => (
<LegendItem key={c} color={colorMap(c)} label={c} onClick={() => onClick(c)} filtered={hiddenCategories.some((hc) => hc === c)} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point, why dont you just pass the set to the component and use Set.has()?

<Legend
categories={legendData.color.categories}
colorMap={legendData.color.mappingFunction}
hiddenCategories={[...hiddenCategoriesSet]}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass the set?

});

React.useEffect(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a very flaky solution. In general I tried to remove all useEffects from the scatter plot, since they visually they introduce the problem of flickering (since they run 2-3 ms after the values changed) and there are just better alternatives.
Without thinking long about it, the solution that I had in mind is to pass the categories to useDataPreparation and just do the filtering the useMemo then this should not be necessary

@@ -290,6 +313,13 @@ export function ScatterVis({
internalLayoutRef,
});

React.useEffect(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be necessary

} else {
hiddenCategoriesSet.add(e);
}
calculateScatter([...hiddenCategoriesSet]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we should just set the categories and useDataPreparation should react to that with useMemo

ids.forEach((v, i) => {
idToIndex.set(v, i);
});
const calculateScatter = React.useCallback(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this code to the memo

@@ -163,6 +164,7 @@ export function useLayout({
height,
};

setLayout(finalLayout);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove all those

idToIndex,
};
}, [status, value]);
const finalScatter = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general:

The approach with useEffect and the callback broke multiple things. For instance the state is stale. When I switch between facet/scatter then the legend does not reset (e.g. its still hidden which is weird). Also the regression line switch does not work anymore as well as the scale switch. All these problems can be mitigated if the useMemo is left in place

There are the 4 cases for

  • scatter, splom, facet, subplots. They are split up because each case is slightly different. So for each of the 4 cases you need to move the filtering code to the useMemo case and use that data in the plotly component then it should work

@dv-usama-ansari
Copy link
Contributor Author

dv-usama-ansari commented Jan 28, 2025

As of 47071b9

2025-01-28.14-00-45.mp4

@dv-usama-ansari dv-usama-ansari marked this pull request as ready for review January 28, 2025 13:39
@dv-usama-ansari dv-usama-ansari requested a review from a team as a code owner January 28, 2025 13:39
@dv-usama-ansari
Copy link
Contributor Author

As of e6cd58d

Fixed selection flickering:

2025-01-30.12-42-57.mp4

@thinkh thinkh merged commit e1eefbb into develop Feb 4, 2025
9 of 11 checks passed
@thinkh thinkh deleted the ua/reprovisyn-2249-make-scatter-plot-legend-clickable branch February 4, 2025 08:20
@github-actions github-actions bot mentioned this pull request Feb 11, 2025
puehringer added a commit that referenced this pull request Feb 11, 2025
* chore: prepare next dev release

* feat: make scatter plot legends clickable (#690)

* feat(wip): make scatter plot legends clickable
wip: click changes the colors of points in an unexpected way

* fix: build

* fix: make legend ui more intuitive to the user

* fix: address PR feedback + rectify logic to filter out values on legend click

* chore: add comments

* basic principle

* fix: selectedpoints computation

* chore: improve tooltips

* chore: cleanup

---------

Co-authored-by: Moritz Heckmann <moritz.heckmann@datavisyn.io>

* fix: removed use-deep-compare-effect, removed Awaited type (#716)

- Removed **use-deep-compare-effect** from package.json, since we have
our own version
- Removed Awaited<T> type, since TS 4.5 has an inbuilt one
- Moved 4 individual state properties to one common object, to remove
flaky behavior (double renders with out-of-sync values) in case React
will not batch the setStates

* feat: add waitForClientConfig flag to allow skipping the wait for the clientConfig (#717)

feat: add waitForClientConfig flag to skip waiting for the clientConfig

* Prepare release version 16.1.0

---------

Co-authored-by: datavisyn-bot <>
Co-authored-by: Usama Ansari <115616380+dv-usama-ansari@users.noreply.github.com>
Co-authored-by: Moritz Heckmann <moritz.heckmann@datavisyn.io>
Co-authored-by: Moritz Heckmann <77104411+dvmoritzschoefl@users.noreply.github.com>
Co-authored-by: Michael Pühringer <51900829+puehringer@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release: minor PR merge results in a new minor version type: feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants