Skip to content

Add support for selections on multi-view vega charts#13591

Merged
lukasmasuch merged 8 commits intodevelopfrom
feature/multi-view-vega-chart-selections
Feb 5, 2026
Merged

Add support for selections on multi-view vega charts#13591
lukasmasuch merged 8 commits intodevelopfrom
feature/multi-view-vega-chart-selections

Conversation

@lukasmasuch
Copy link
Copy Markdown
Collaborator

@lukasmasuch lukasmasuch commented Jan 14, 2026

Describe your changes

Adds support for adding selections to multi-view vega-charts.

GitHub Issue Link (if applicable)

Testing Plan

  • Added unit and e2e tests.

Contribution License Agreement

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.

@snyk-io
Copy link
Copy Markdown
Contributor

snyk-io bot commented Jan 14, 2026

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@lukasmasuch lukasmasuch changed the title Add support for selections on multi-view vega charts [Prototype] Add support for selections on multi-view vega charts Jan 14, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 14, 2026

✅ PR preview is ready!

Name Link
📦 Wheel file https://core-previews.s3-us-west-2.amazonaws.com/pr-13591/streamlit-1.53.1-py3-none-any.whl
📦 @streamlit/component-v2-lib Download from artifacts
🕹️ Preview app pr-13591.streamlit.app (☁️ Deploy here if not accessible)

@lukasmasuch lukasmasuch added security-assessment-completed change:feature PR contains new feature or enhancement implementation impact:users PR changes affect end users labels Jan 14, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 14, 2026

📉 Frontend coverage change detected

The frontend unit test (vitest) coverage has decreased by 0.0000%

  • Current PR: 86.4500% (13862 lines, 1877 missed)
  • Latest develop: 86.4500% (13862 lines, 1877 missed)

✅ Coverage change is within normal range.

📊 View detailed coverage comparison

@lukasmasuch
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for selections on multi-view (composite) Vega/Altair charts by removing the previous restriction and implementing recursive parameter extraction to find selections at any level of the view hierarchy.

Changes:

  • Modified _extract_selection_parameters() to recursively traverse composite view specs (layer, hconcat, vconcat, concat, facet, repeat)
  • Removed the _disallow_multi_view_charts() restriction from the selection activation flow
  • Added comprehensive documentation about field/encoding requirements for consistent selection output in multi-view charts
  • Added extensive unit tests and E2E tests covering various multi-view chart types and selection scenarios

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
lib/streamlit/elements/vega_charts.py Updated _extract_selection_parameters() to recursively traverse multi-view specs; removed _disallow_multi_view_charts() call; added documentation about fields/encodings in multi-view selections
lib/tests/streamlit/elements/vega_charts_test.py Renamed and updated test for multi-view selections; added comprehensive test classes for Altair and Vega-Lite multi-view selections covering layer, concat, facet, repeat, and nested scenarios
e2e_playwright/st_altair_chart_multiview_select.py New E2E test app with multi-view charts using various selection types
e2e_playwright/st_altair_chart_multiview_select_test.py New E2E tests for multi-view chart selections with different chart types

@lukasmasuch lukasmasuch changed the title [Prototype] Add support for selections on multi-view vega charts Add support for selections on multi-view vega charts Jan 15, 2026
@lukasmasuch lukasmasuch marked this pull request as ready for review January 15, 2026 00:26
@lukasmasuch lukasmasuch added the ai-review If applied to PR or issue will run AI review workflow label Jan 15, 2026
@github-actions github-actions bot removed the ai-review If applied to PR or issue will run AI review workflow label Jan 15, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Summary

This PR adds support for selections on multi-view Vega-Lite charts (layer, hconcat, vconcat, concat, facet, and repeat compositions). Previously, selections on multi-view charts were explicitly blocked with a StreamlitAPIException. The PR:

  1. Modifies _extract_selection_parameters() to recursively traverse composite view specs to find all selection parameters at any level in the spec hierarchy
  2. Removes the call to _disallow_multi_view_charts() that was blocking this functionality
  3. Updates documentation to guide users on best practices for multi-view selections
  4. Adds comprehensive unit and E2E tests

This closes GitHub issue #8643.

Code Quality

Strengths:

  • The recursive _extract_selection_parameters() function is well-designed and properly documented. It correctly handles all composition types: layer, hconcat, vconcat, concat, and inner spec (for facet/repeat charts).
  • The code follows existing patterns in the codebase.
  • Documentation updates are helpful and provide guidance on using fields or encodings in selections for consistent output.
  • Type annotations are properly used.

Issues:

  1. Dead code (minor): The _disallow_multi_view_charts() function at lib/streamlit/elements/vega_charts.py:484-502 is now dead code since the call to it was removed (line 2429-2430 in the diff). While it doesn't cause any issues, it should be removed for code cleanliness.
def _extract_selection_parameters(spec: VegaLiteSpec) -> set[str]:
    """Extract the names of all valid selection parameters from the spec.

    This function recursively traverses composite view specs (layer, hconcat,
    vconcat, concat, facet, repeat) to find all selection parameters, regardless
    of where they are defined in the spec hierarchy.

    Altair automatically hoists params to the top level, but raw Vega-Lite specs
    may have params defined at any level in the view hierarchy.
    """
    if not spec:
        return set()

    param_names: set[str] = set()

    # Extract from top-level params
    if "params" in spec:
        for param in spec["params"]:
            # Check if it looks like a valid selection parameter:
            # https://vega.github.io/vega-lite/docs/selection.html
            if param.get("name") and param.get("select"):
                param_names.add(param["name"])

    # Recursively check composite view specs (layer, hconcat, vconcat, concat).
    # Non-dict entries in the list are silently skipped as they are malformed.
    for key in ("layer", "hconcat", "vconcat", "concat"):
        if key in spec and isinstance(spec[key], list):
            for child_spec in spec[key]:
                if isinstance(child_spec, dict):
                    param_names.update(_extract_selection_parameters(child_spec))

    # Check facet/repeat spec (the inner view specification)
    if "spec" in spec and isinstance(spec["spec"], dict):
        param_names.update(_extract_selection_parameters(spec["spec"]))

    return param_names

The implementation correctly handles edge cases by checking isinstance() before recursive calls.

Test Coverage

Unit Tests (Excellent):

The PR adds two comprehensive test classes:

  1. MultiViewSelectionsTest - Tests Altair charts:

    • Layer, hconcat, vconcat, facet, repeat charts with selections
    • Nested compositions (vconcat + hconcat)
    • Multiple selections on the same chart
    • Selection mode filtering
  2. VegaLiteMultiViewSelectionsTest - Tests raw Vega-Lite specs:

    • Nested params in layer/hconcat/vconcat
    • Facet with nested params
    • Deeply nested params (vconcat > hconcat)
    • Mixed top-level and nested params

All tests include:

  • Assertions for proto.selection_mode containing correct selection names
  • Assertions for proto.id being non-empty
  • Assertions for event.selection having correct attributes
  • Negative assertions (e.g., verifying unactivated selections are NOT included in state)

E2E Tests (Good):

New E2E tests cover:

  • Layer chart point selection
  • HConcat chart interval selection
  • VConcat chart point selection
  • HConcat chart with multiple independent selections

The tests follow best practices:

  • Use expect() for auto-wait assertions
  • Include negative assertions (checking text is not visible before interaction)
  • Use get_element_by_key() for stable locators
  • Use helper functions from shared/app_utils.py

Minor observation: The E2E tests use fixed pixel coordinates for click positions (e.g., _MousePosition(264, 120)). This is consistent with existing chart tests in the codebase and is acceptable, though it could be fragile if chart dimensions change in the future.

Backwards Compatibility

No breaking changes. This PR removes a restriction rather than changing existing behavior:

  • Previously: Multi-view charts with on_select="rerun" raised a StreamlitAPIException
  • Now: Multi-view charts with on_select="rerun" work correctly

Users who were not using selections on multi-view charts are unaffected. Users who were blocked by the previous limitation can now use this feature.

Security & Risk

Low risk. The changes are isolated to:

  1. Selection parameter extraction logic (read-only traversal of spec)
  2. Removal of a validation check that blocked functionality

No new attack vectors are introduced. The recursive function has proper termination conditions (if not spec: return set()) and type checks (isinstance(child_spec, dict)) to prevent infinite recursion or type errors from malformed specs.

Recommendations

  1. Remove dead code: Delete the _disallow_multi_view_charts() function since it's no longer called. This will improve code maintainability.

  2. Consider adding a test for malformed specs (optional): The recursive function silently skips non-dict entries in composition lists. While this is safe behavior, a unit test explicitly verifying this would be beneficial for documentation purposes.

    Example test case:

    def test_extract_selection_parameters_skips_malformed_entries(self):
        """Test that non-dict entries in composite views are skipped."""
        spec = {
            "layer": [
                {"mark": "circle", "params": [{"name": "sel", "select": {"type": "point"}}]},
                "not_a_dict",  # malformed entry
                None,  # another malformed entry
            ]
        }
        # Should not raise, should return the valid selection
        params = _extract_selection_parameters(spec)
        assert params == {"sel"}

Verdict

APPROVED: This PR is well-implemented with comprehensive test coverage. It enables a highly requested feature (selections on multi-view charts) while maintaining backwards compatibility. The only suggestion is to clean up the dead code (_disallow_multi_view_charts function), but this is a minor issue that doesn't block approval.


This is an automated AI review. Please verify the feedback and use your judgment.

@github-actions
Copy link
Copy Markdown
Contributor

Summary

Adds multi-view selection support by recursively extracting selection params from Vega-Lite specs, plus new Altair/Vega-Lite unit tests and e2e coverage for multi-view selection interactions.

Code Quality

Overall structure is clear, and the new recursive extraction logic is easy to follow. One robustness gap: _extract_selection_parameters assumes spec["params"] is a list of dicts, so malformed specs could raise an AttributeError instead of a targeted StreamlitAPIException (lib/streamlit/elements/vega_charts.py lines 520-526).

Test Coverage

Good breadth: unit tests cover layer/hconcat/vconcat/facet/repeat/nested compositions and multi-selection filters, plus raw Vega-Lite nested param cases. The new e2e tests cover layer, hconcat, vconcat, and multi-selection interactions. Consider adding a small “must NOT happen” assertion per e2e scenario (e.g., selection text absent before interaction) to align with e2e best practices (e2e_playwright/st_altair_chart_multiview_select_test.py lines 114-169).

Backwards Compatibility

Change is additive: previously unsupported multi-view selections are now enabled. No API or behavioral breakages detected for existing single-view charts.

Security & Risk

No security concerns spotted. The primary risk is potential e2e flakiness from fixed pixel click/drag coordinates and CSS locators (e2e_playwright/st_altair_chart_multiview_select_test.py lines 73-91, 105-163).

Recommendations

  1. Guard spec["params"] iteration with isinstance(..., list) and skip non-dict entries to avoid AttributeError on malformed specs (lib/streamlit/elements/vega_charts.py lines 520-526).
  2. Add a per-test negative assertion in the e2e scenarios (e.g., no selection text before interaction in the hconcat/vconcat/multi tests) to match e2e guidelines (e2e_playwright/st_altair_chart_multiview_select_test.py lines 114-169).
  3. Consider get_by_role("graphics-document") and/or more data-driven interaction targets to reduce reliance on fixed pixel positions (e2e_playwright/st_altair_chart_multiview_select_test.py lines 73-91, 105-163).

Verdict

APPROVED: Solid feature addition with good coverage; only minor robustness and test-style nits.


This is an automated AI review using gpt-5.2-codex-high. Please verify the feedback and use your judgment.

@lukasmasuch lukasmasuch merged commit 83cc844 into develop Feb 5, 2026
43 checks passed
@lukasmasuch lukasmasuch deleted the feature/multi-view-vega-chart-selections branch February 5, 2026 20:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:feature PR contains new feature or enhancement implementation impact:users PR changes affect end users

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support chart selections for multi-view vega-lite & altair charts

3 participants