Getting started

Native charts from the separate xgpui-luma-plot crate.

The luma-plot-viz sample uses SDK controls directly, without Radix or Shadcn. It demonstrates monochrome light/dark UI styling, independent chart colors, and live theme switching. Run just app-plot (release) or just --set profile dev app-plot (debug) from the repository root. See SDK integration and chart palettes.

Use a release build for optimal chart performance: just app-plot or cargo run -p luma-plot-viz --release. Debug builds are intended for development and can make rendering and interactions noticeably slower.

Dependency

Luma plots use xgpui 2.0.1. In the dependencies below, gpui is a local alias for the xgpui package. See framework packages and import aliases for the distinction from gpui-unofficial. Once version 1.0.1 is published, add xgpui-luma-plot alongside your xgpui and SDK dependencies, keeping the gpui alias for existing Rust imports:

Cargo.toml
[dependencies]
# gpui is the local alias; xgpui is the registry package.
gpui = { package = "xgpui", version = "=2.0.1" }
xgpui-luma = "1.0.1"
xgpui-luma-plot = "1.0.1"

The 1.0.1 requirements accept compatible 1.x releases from crates.io. Run cargo update to refresh your lockfile. No repository checkout is required; see the complete app setup.

Your first chart

Create named series, add drawing layers that refer to their IDs, then build a chart element. Give its host an explicit height and available width.

Rust
use gpui::{div, prelude::*, px};
use xgpui_luma_plot::{
    CartesianChartBuilder, CategoryScale, Dataset, DatasetError,
    LineLayer, Sample, Series,
};

fn temperature_chart() -> Result<impl IntoElement, DatasetError> {
    let data = Dataset::new().with_series(Series::new(
        "temperature", "Temperature",
        [Sample::new(0.0, 18.0), Sample::new(1.0, 21.0), Sample::new(2.0, 19.0)],
    ))?;

    let chart = CartesianChartBuilder::new(data)
        .id("temperature-chart")
        .x_scale(CategoryScale::new(["Mon", "Tue", "Wed"]))
        .line(LineLayer::new("temperature"))
        .build();

    Ok(div().w_full().h(px(280.0)).child(chart))
}

Call the helper while composing your view, handle its result using your application’s error handling, and render the returned element. Unique chart IDs distinguish multiple charts in the same view.

Data and rendering

Plot names the library and its rendering-independent specifications, such as CartesianPlot and PiePlot. A chart combines data, a plot specification, and presentation into a GPUI element through a *ChartBuilder / *ChartView. Styling APIs identify their chart family, such as CartesianStyle.

  • Sample: an X/Y observation.
  • Series: observations with a stable ID and display name.
  • Dataset: a collection of series; insertion returns DatasetError for duplicate IDs.
  • Plot specifications select series, scales, and layer behavior. Presentation defines appearance.

Category X coordinates are zero-based indices into the category labels. Line layers connect observations in their input order; they do not sort samples for you.

.build() returns a GPUI chart element rather than spawning a control entity. Retain application data and interaction state in the owning view and compose chart elements during rendering. Frames, headings, and surrounding controls are ordinary SDK content.

Chart families

BuilderChart
CartesianChartBuilderLine, area, and bar layers, including combined charts.
PieChartBuilderPie and donut/ring charts.
RadarChartBuilderSeries plotted around spokes.
RadialChartBuilderRadial bar layouts.

Continue with Cartesian charts and Styling. For shared behavior, see Interaction, View state, and Performance. Explore Pie & donut, Radar, and Radial for the other chart families.

Source

Public API · Native gallery examples