Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ on:
- "hatch_build.py"
- "pyproject.toml"
- "scripts/verify_docs_quickstart.py"
- "scripts/verify_docs_local.py"
- "scripts/check_public_api.py"
- ".pre-commit-config.yaml"
- ".github/workflows/docs.yml"
pull_request:
Expand All @@ -26,6 +28,8 @@ on:
- "hatch_build.py"
- "pyproject.toml"
- "scripts/verify_docs_quickstart.py"
- "scripts/verify_docs_local.py"
- "scripts/check_public_api.py"
- ".pre-commit-config.yaml"
- ".github/workflows/docs.yml"
workflow_dispatch:
Expand Down Expand Up @@ -60,17 +64,9 @@ jobs:
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "22"
- name: Install docs dependencies
run: uv sync --project docs/app --frozen --group dev
- name: Run docs tests
run: uv run --project docs/app --no-sync pytest docs/app/tests -v
- name: Run public docs quickstart against the checkout
run: uv run --project docs/app --no-sync python scripts/verify_docs_quickstart.py
- name: Run docs quality hooks
run: |
uv run --project docs/app --no-sync pre-commit run ruff-format --all-files
uv run --project docs/app --no-sync pre-commit run ruff-check --all-files
uv run --project docs/app --no-sync pre-commit run docs-app-codespell --all-files
- name: Run the local docs quality gate
Comment thread
harsh21234i marked this conversation as resolved.
Resolved
shell: bash
run: uv run --no-project python scripts/verify_docs_local.py

production:
name: Production docs (Python ${{ matrix.python-version }})
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ help:
' make check-full run JS, Rust, and ABI gates too' \
' make check-browser run browser smokes (set CHROMIUM=/path/to/chrome)' \
' make check-conformance run accessibility + Chromium/Firefox/WebKit conformance' \
' make check-docs run documentation examples' \
' make check-docs run docs tests, quickstart, and quality hooks' \
' make check-examples run canonical API examples and Reflex asset registry checks' \
' make check-security run standalone HTML safety and client text-sink checks' \
' make check-errors run public error, LOD, and mutation-safety tests' \
Expand Down Expand Up @@ -89,7 +89,7 @@ check-conformance:
node scripts/browser_conformance.mjs

check-docs:
$(PYTHON) scripts/verify_local.py --only examples
$(PYTHON) scripts/verify_local.py --only docs
Comment thread
harsh21234i marked this conversation as resolved.
Resolved
Comment thread
harsh21234i marked this conversation as resolved.
Resolved

check-examples:
$(PYTHON) scripts/verify_local.py --only examples
Expand Down
5 changes: 3 additions & 2 deletions docs/api-reference/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ make check

`make setup` installs the editable development package and builds the required
native core. Source development needs Python 3.11+, a Rust toolchain for that
core, and Node 18+ for bundle checks. Confirm the active compute backend
core, and Node.js ^20.19.0 or >=22.12.0 for bundle checks. Confirm the active compute backend
explicitly:

~~~bash
Expand All @@ -38,7 +38,8 @@ import error rather than silently selecting another backend.
| --- | --- |
| Fast local verification | `make check` |
| Production-facing change | `make check-full` |
| Public docs and examples | `make check-docs` |
| Public docs | `make check-docs` |
Comment thread
harsh21234i marked this conversation as resolved.
Resolved
| Example apps and Reflex chart registry/assets | `make check-examples` |
| Public exports or annotations | `make check-api` |
| Lazy imports and dependency boundaries | `make check-import` |
| Validation and mutation behavior | `make check-errors` |
Expand Down
5 changes: 5 additions & 0 deletions docs/api-reference/events-and-callbacks.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ chart = xy.scatter_chart(
- `index` — all selected indices concatenated; use `per_trace` when trace
identity matters.
- `xy(trace_id=0)` — canonical f64 x/y arrays for one selected trace.
- `rows(limit=None)` — exact canonical row dictionaries for selected rows,
Comment thread
harsh21234i marked this conversation as resolved.
Resolved
optionally capped for large selections. Rows are returned in ascending trace
ID, then ascending canonical row index. A limit keeps the first N rows; this
method does not return a truncation flag, so compare `len(rows)` with
`len(selection)` to detect an incomplete result.
- `len(selection)` — total selected rows across traces.

Clearing selection delivers an empty `Selection`. `Chart.select_range()`
Expand Down
44 changes: 36 additions & 8 deletions docs/api-reference/figure-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ code should build charts through components and call the public methods below.
| Method | Contract |
| --- | --- |
| `chart.widget()` | Build or return the cached live AnyWidget. |
| `chart.show()` | Return the same widget; it does not open a desktop browser. |
| `chart.show()` | Return the live widget in widget mode or an `HtmlView` in HTML mode; it does not open a desktop browser. |
| `chart.figure()` | Build or return the cached internal engine figure. |

In a compatible notebook, leaving a chart as the final cell expression invokes
its display hook automatically. Python callbacks require the live widget or a
framework adapter.
its display hook automatically. In `display="auto"` mode, controlled by
`XY_NOTEBOOK_DISPLAY`, supported notebooks use the live widget and HTML mode
Comment thread
harsh21234i marked this conversation as resolved.
Resolved
uses `chart._repr_html_()` as the standalone-HTML path. Python callbacks require the
live widget or a framework adapter.

## HTML and Static Export

Expand Down Expand Up @@ -106,6 +108,29 @@ selection: xy.Selection = chart.select_range(x0, x1, y0, y1, trace_id=None)
Streaming has additional channel and monotonic-line constraints documented in
[Real-time and streaming data](/docs/xy/guides/real-time-and-streaming-data/).

## View and Selection State

~~~python
Comment thread
harsh21234i marked this conversation as resolved.
Resolved
chart.set_view(ranges, animate=True, history=True)
chart.reset_view(axes=None)
chart.select(range=(x0, x1, y0, y1), history=True)
chart.clear_selection()
state: dict = chart.view_state()
~~~

- `set_view()` applies explicit axis ranges to the live chart state.
- `reset_view()` navigates axes to their home ranges; `axes=None` uses the
configured `reset_axes`.
- `select()` accepts one of `range=`, `polygon=`, or `rows=`. Geometric forms
follow the browser gesture state path; rows resolve kernel-side and are
non-durable.
- `clear_selection()` clears the current selection, including range, polygon,
and row selections.
- `chart.view_state()` returns the last client-confirmed viewport and selection
state; reads after writes are eventually consistent. For `chart.select(rows=...)`,
the state contains an opaque `{"rows": true}` marker rather than the selected
row indices.

## Framework Chrome

~~~python
Expand All @@ -119,11 +144,14 @@ objects. `reflex_components()` is an alias retained for adapter code.

## FacetChart Methods

`FacetChart` provides `figure()`, `widget()`, `show()`, `to_html()`/`html()`,
`to_svg()`, `to_png()`, `to_image()`, `write_image()`, and `memory_report()`.
Its widget methods return one
widget per panel, and its figure escape hatch returns an internal facet grid.
Grid dimensions come from `facet_chart()`, so the facet SVG/PNG methods do not
Assign the value returned by `xy.facet_chart(...)` to `facet_chart` to use its
instance methods: `facet_chart.figure()`, `facet_chart.widget()`,
`facet_chart.show()`, `facet_chart.to_html()`/`facet_chart.html()`,
`facet_chart._repr_html_()`, `facet_chart.to_svg()`, `facet_chart.to_png()`,
`facet_chart.to_image()`, `facet_chart.write_image()`, and
`facet_chart.memory_report()`. Its widget methods return one widget per panel,
and its figure escape hatch returns an internal facet grid. Grid dimensions come
from `facet_chart()`, so the facet SVG/PNG methods do not
accept per-call width or height. Facets do not expose append, pick, or
Python-side range selection methods.

Expand Down
1 change: 1 addition & 0 deletions docs/api-reference/public-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ construct lowercase factory results and only name these types in annotations.
| `Spring` | Serializable spring easing policy used by `animation()` |
| `Chart` | Public composed chart with display, export, and readout methods |
| `FacetChart` | Public small-multiple wrapper |
| `ExportConfig` | Validated defaults for HTML and static image export |

Directly constructing node dataclasses is supported for inspection and typing,
but the lowercase factories perform the intended validation and normalization.
Expand Down
7 changes: 5 additions & 2 deletions docs/app/tests/test_docs_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
AXES_AND_ANNOTATIONS,
CHART_FACTORY_GROUPS,
CHROME_AND_BEHAVIOR,
FACTORY_DOCSTRING_ALIASES,
MARKS,
append_component_api_markdown,
axes_and_annotations_api,
Expand Down Expand Up @@ -973,9 +974,10 @@ def test_handwritten_output_reference_tracks_the_public_api() -> None:
block for block in parse_document(method_reference).blocks if isinstance(block, CodeBlock)
]

assert len(method_blocks) == 4
assert len(method_blocks) == 5
assert all(block.language == "python" for block in method_blocks)
assert "animation_progress=None" in method_blocks[0].content

for method in (xy.Chart.to_html, xy.Chart.html):
assert "animation_progress" in inspect.signature(method).parameters

Expand Down Expand Up @@ -3064,7 +3066,8 @@ def test_documented_factories_describe_every_parameter() -> None:
)

for factory in factories:
docstring = inspect.getdoc(factory) or ""
documentation_source = FACTORY_DOCSTRING_ALIASES.get(factory, factory)
docstring = inspect.getdoc(documentation_source) or ""
assert "Args:" in docstring, factory.__name__
for parameter in inspect.signature(factory).parameters.values():
assert f"{parameter.name}:" in docstring, (
Expand Down
118 changes: 21 additions & 97 deletions docs/app/xy_docs/api_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import reflex_xy
import xy
from xy._public_api_manifest import PUBLIC_API_MANIFEST
from xy.components import _POLAR_INERT_AXIS_KEYWORDS

COMPONENT_API_METADATA_KEY = "components"
Expand All @@ -29,53 +30,9 @@
_COMPONENT_API_COLUMN_WIDTHS = ("w-[20%]", "w-[25%]", "w-[55%]")
_NON_ID_CHARACTER = re.compile(r"[^a-z0-9]+")

CHART_FACTORY_GROUPS = (
(
"Line and Area",
(xy.line_chart, xy.area_chart, xy.step_chart, xy.stairs_chart),
),
("Scatter", (xy.scatter_chart,)),
# The polar compositions are public factories like any other, so they belong
# in the generated inventory. `pie_chart` is listed with them: without an
# entry here the API reference implied the only way to draw a pie was to
# hand-roll wedge bars — the exact thing the factory exists to replace.
(
"Polar",
(
xy.polar_chart,
xy.radar_chart,
xy.polar_bar_chart,
xy.pie_chart,
xy.wind_rose,
),
),
("Bar and Column", (xy.bar_chart, xy.column_chart)),
(
"Distributions",
(
xy.histogram_chart,
xy.ecdf_chart,
xy.box_chart,
xy.violin_chart,
),
),
(
"Density and Grids",
(xy.hexbin_chart, xy.heatmap_chart, xy.contour_chart),
),
("Uncertainty", (xy.error_band_chart, xy.errorbar_chart)),
(
"Specialized",
(
xy.stem_chart,
xy.segments_chart,
xy.sankey_chart,
xy.funnel_chart,
xy.triangle_mesh_chart,
),
),
("Annotations and Layers", (xy.chart,)),
("Facets", (xy.facet_chart,)),
CHART_FACTORY_GROUPS = tuple(
(group_name, tuple(getattr(xy, name) for name in factory_names))
for group_name, factory_names in PUBLIC_API_MANIFEST.chart_factory_groups
)
_CHART_FACTORY_COMPONENTS = frozenset(
factory for _group_name, factories in CHART_FACTORY_GROUPS for factory in factories
Expand All @@ -94,59 +51,25 @@
xy.r_axis: frozenset(_POLAR_INERT_AXIS_KEYWORDS),
}

MARKS = (
xy.line,
xy.scatter,
xy.area,
xy.bar,
xy.column,
xy.histogram,
xy.box,
xy.violin,
xy.ecdf,
xy.heatmap,
xy.hexbin,
xy.contour,
xy.errorbar,
xy.error_band,
xy.step,
xy.stairs,
xy.stem,
xy.segments,
xy.ribbon,
xy.sankey,
xy.funnel,
xy.triangle_mesh,
)
MARKS = tuple(getattr(xy, name) for name in PUBLIC_API_MANIFEST.mark_factories)
Comment thread
harsh21234i marked this conversation as resolved.
Resolved
Comment thread
harsh21234i marked this conversation as resolved.
Resolved

AXES_AND_ANNOTATIONS = (
xy.x_axis,
xy.y_axis,
xy.theta_axis,
xy.r_axis,
xy.vline,
xy.hline,
xy.x_band,
xy.y_band,
xy.threshold,
xy.threshold_zone,
xy.text,
xy.label,
xy.marker,
xy.arrow,
xy.callout,
AXES_AND_ANNOTATIONS = tuple(
getattr(xy, name)
for name in (*PUBLIC_API_MANIFEST.axis_factories, *PUBLIC_API_MANIFEST.annotation_factories)
)

CHROME_AND_BEHAVIOR = (
xy.legend,
xy.tooltip,
xy.colorbar,
xy.modebar,
xy.theme,
xy.interaction_config,
xy.animation,
xy.spring,
CHROME_AND_BEHAVIOR = tuple(
getattr(xy, name)
for name in (
*PUBLIC_API_MANIFEST.chrome_factories,
*(
name
for name in PUBLIC_API_MANIFEST.support_factories
if name in {"animation", "spring"}
),
)
)
FACTORY_DOCSTRING_ALIASES = {xy.hist: xy.histogram}


@dataclass(frozen=True, slots=True)
Expand Down Expand Up @@ -360,7 +283,8 @@ def _component_api_references(
msg = f"Unknown documentation component: {component_path!r}"
raise ValueError(msg)

docstring = inspect.getdoc(component) or ""
documentation_source = FACTORY_DOCSTRING_ALIASES.get(component, component)
docstring = inspect.getdoc(documentation_source) or ""
descriptions = _parameter_descriptions(docstring)
parameters: list[ComponentApiParameter] = []
for parameter, parameter_descriptions in _documented_parameters(
Expand Down
2 changes: 2 additions & 0 deletions docs/components/marks.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ components:
- xy.bar
- xy.column
- xy.histogram
- xy.hist
- xy.box
- xy.violin
- xy.ecdf
Expand All @@ -22,6 +23,7 @@ components:
- xy.segments
- xy.ribbon
- xy.sankey
- xy.mark
- xy.funnel
- xy.triangle_mesh
---
Expand Down
1 change: 1 addition & 0 deletions news/458.docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Document chart view and selection methods, including Selection.rows(), and validate documentation against a shared public API inventory.
Loading
Loading