Skip to content

FE: filter-aware bar colours and dual-series background bars - #1740

Open
ikondrat wants to merge 4 commits into
kondrat-lig-9585-frontend-categorical-metadata-bar-chart-filter-ui-8-sp.p14from
kondrat-lig-9585-frontend-categorical-metadata-bar-chart-filter-ui-8-sp.p15
Open

FE: filter-aware bar colours and dual-series background bars#1740
ikondrat wants to merge 4 commits into
kondrat-lig-9585-frontend-categorical-metadata-bar-chart-filter-ui-8-sp.p14from
kondrat-lig-9585-frontend-categorical-metadata-bar-chart-filter-ui-8-sp.p15

Conversation

@ikondrat

Copy link
Copy Markdown
Contributor

Summary

Stacked on p14. Final visual layer — makes distribution charts aware of active sidebar filters.

Dim unselected bars: when the user has selected one or more categorical values the remaining bars render in grey (#4b5563), matching numeric Histogram behaviour. The selected-bar border is removed — green/grey contrast communicates selection clearly without it.

Keep full distribution visible (+layout.svelte): introduces distributionBaseFilter — a derived filter that strips analysis filters (metadata, annotation, dimensions) while keeping collection-scoping context (tagIds, sampleIds, etc.). Both distribution queries use this filter so bar heights always reflect the full dataset, not the currently filtered subset.

Dual-series background bars (buildEchartsOption, BarChart/types):

  • CategoryCount gains an optional filteredCount field
  • When the layout passes filtered counts alongside full counts, the chart renders two ECharts series: a grey background series at full height and a green/grey foreground series at filtered height
  • Tooltip shows "Total / In filter" when the filter reduces any bar; falls back to single "Count" otherwise
  • When no sidebar filter is active hasActiveFilter is false and a single series is rendered — no visual change

Test plan

  • make static-checks (frontend) passes (includes Prettier fix for the ternary in buildEchartsOption)
  • npm run test:unit passes (new tests in buildEchartsOption.test.ts for the dual-series and hasActiveFilter logic)
  • Manual: apply an annotation-class filter from the left sidebar — verify categorical bars show grey background at full height and green foreground at filtered height; clear the filter — bars return to solid colour

Part of LIG-9585.

@ikondrat
ikondrat requested a review from a team as a code owner July 22, 2026 16:12
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: cc9b59e3-86cd-4beb-8b3c-41c4cd33cb08

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch kondrat-lig-9585-frontend-categorical-metadata-bar-chart-filter-ui-8-sp.p15

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lightly-fast-track-bot

lightly-fast-track-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

❌ Fast Track: checks did not pass

Failed guardrails: frontend/complexity (Guardrail threw: Cannot find module 'eslint'
Require stack:

  • /home/runner/work/lightly-studio/lightly-studio/lightly_studio_view/package.json), frontend/coverage ( [FAIL] lightly_studio_view/src/lib/components/BarChart/types.ts: no test file found
    [FAIL] lightly_studio_view/src/lib/components/DatasetDistributionPanel/types.ts: no test file found
    [FAIL] lightly_studio_view/src/lib/components/BarChart/buildEchartsOption.ts: coverage data not found
    [FAIL] lightly_studio_view/src/lib/components/DatasetDistributionPanel/DatasetDistributionPanel.svelte: coverage data not found
    [FAIL] lightly_studio_view/src/routes/datasets/[dataset_id]/[collection_type]/[collection_id]/+layout.svelte: coverage data not found)
Guardrail Result Message
dummy Always passes.
frontend/complexity Guardrail threw: Cannot find module 'eslint' Require stack: - /home/runner/work/lightly-studio/lightly-studio/lightly_studio_view/package.json
backend/complexity 0 file(s) checked.
backend/coverage 0 file(s) checked.
diff-size PR adds 207 line(s) (limit: 215).
frontend/coverage [FAIL] lightly_studio_view/src/lib/components/BarChart/types.ts: no test file found [FAIL] lightly_studio_view/src/lib/components/DatasetDistributionPanel/types.ts: no test file found [FAIL] lightly_studio_view/src/lib/components/BarChart/buildEchartsOption.ts: coverage data not found [FAIL] lightly_studio_view/src/lib/components/DatasetDistributionPanel/DatasetDistributionPanel.svelte: coverage data not found [FAIL] lightly_studio_view/src/routes/datasets/[dataset_id]/[collection_type]/[collection_id]/+layout.svelte: coverage data not found

Reflects 4e90537.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2a71db8e96

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +132 to +134
const filteredCount =
activeCategorical?.filteredBuckets !== undefined
? (filteredBucket?.count ?? 0)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Count filtered bars with the base bucket definitions

When categorical metadata has more than the endpoint's top-value limit, the full and filtered queries can return different bucket sets, so matching by id here misattributes the foreground counts. For example, a value grouped into the base Other bucket can become a concrete top bucket under a sidebar filter; the base Other bar then gets the filtered query's Other count (often 0) even though those filtered samples belong in that visible base bucket. Compute filtered counts against the same base bucket definitions before overlaying them.

Useful? React with 👍 / 👎.

Comment on lines +628 to +630
const categoricalMetadataFilteredDistributions = $derived(
categoricalMetadataFilteredQuery.data
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Suppress stale placeholder buckets during refetches

When a user changes sidebar filters after the first categorical response, useCategoricalMetadataDistribution keeps the previous result as placeholderData, so this value stays populated rather than becoming undefined while the new filtered query is in flight. The panel then renders foreground bars for the old filter until the request completes; gate filteredBuckets on the filtered query not being placeholder/fetching, or disable placeholder data for this second query.

Useful? React with 👍 / 👎.


// Tooltip shows "Total / In filter" when a filter is active and actually
// reduces the hovered bar; otherwise shows the single "Count" line.
const formatter = (params: { name: string; value: number }[]) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Extract the chart helpers

This new inline formatter/series construction makes buildEchartsOption handle filter detection, tooltip rendering, foreground/background data shaping, and final option assembly in one large function; please split the formatter and series builders into small helpers so the chart logic stays readable and testable per the repo style guidance.

AGENTS.md reference: AGENTS.md:L39-L41

Useful? React with 👍 / 👎.

ikondrat and others added 4 commits July 22, 2026 19:04
When the user selects one or more categorical metadata values the remaining
bars now render in grey (#4b5563), matching the existing behaviour of the
numeric Histogram where bins outside the selected range are dimmed.  The
white border on the selected bar has been removed because the green/grey
colour contrast already communicates selection clearly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Metadata distribution plots previously passed the full imageAnnotationCountsFilter
to the histogram and categorical queries, causing bar heights to shrink as the
user applied annotation, dimension, or metadata filters from the left sidebar.
This made it hard to understand what was being filtered away because the original
distribution context was lost.

Introduce distributionBaseFilter — a derived value that omits the analysis
filters (metadataFilters, annotationFilter, dimensionsValues) while retaining
the collection-scoping context (tagIds, sampleIds, confusionCell, queryExpr).
Both distribution queries now use this filter so bar heights always reflect the
full dataset; the active selection is communicated through bar colour alone
(green = in selection, grey = outside).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…al distributions

When sidebar filters (annotation class, image dimensions, metadata of other
fields) are active, categorical metadata bars previously shrank to show only the
filtered counts, losing the original distribution as context.

This change fetches a second distribution using the full sidebar filter
(imageAnnotationCountsFilter) alongside the existing base-filter query, then
passes the filtered counts as `filteredBuckets` to each categorical group.

The bar chart renders two ECharts series when any bar's filteredCount differs
from its full count:
  - Background series (grey, #374151): full unfiltered count — stable height
  - Foreground series (green/grey): filtered count — shows filter effect

The tooltip updates to "Total / In filter" for bars where the filter actually
reduces the count, falling back to the single-value "Count" line otherwise.

When no filter is active the filtered query returns the same counts as the
base query, so hasActiveFilter is false and a single series is rendered — no
visual change from the pre-filter state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ikondrat
ikondrat force-pushed the kondrat-lig-9585-frontend-categorical-metadata-bar-chart-filter-ui-8-sp.p15 branch from 2a71db8 to 4e90537 Compare July 22, 2026 17:06
@ikondrat
ikondrat force-pushed the kondrat-lig-9585-frontend-categorical-metadata-bar-chart-filter-ui-8-sp.p14 branch from 007379b to 14054f3 Compare July 22, 2026 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant