iced_aksel

Crates.ioiced_aksel
lib.rsiced_aksel
version0.2.0
created_at2025-12-11 19:42:11.890667+00
updated_at2026-01-15 15:39:56.16618+00
descriptionA data-driven charting library for Iced
homepage
repositoryhttps://github.com/QuistHQ/iced_aksel
max_upload_size
id1980439
size433,151
(MellquistD)

documentation

README

📊 Iced Aksel

Built with Iced badge Crate Badge Docs-rs Badge

iced_aksel is a WIP, "batteries not included", charting crate for the Iced GUI toolkit, wrapping the Aksel plotting core in an ergonomic widget. It focuses on rendering large, interactive datasets with customizable axes, grids, styles, and event handlers that plug directly into your Iced application logic.

[!WARNING]

The library is still pretty early in development. Breaking changes will occur as we iron out the API.

Dashboard Demo

🔍 Highlights

  • 📈 Chart-first widgetChart provides layout and event handling that feels native to Iced apps.

  • 🪓 Powerful axes – Configure positions, scales, tick/label policies, cursor labels, visibility, and grid renderers per axis. You can even have multiple axes on the same side.

  • 🖌️Canvas-like API – Implement PlotData to add any shape primitive (shape::Line, shape::Ellipse, shape::Rectangle, etc.) to the plot - Or create your own shape primitives with the Shape trait (Very WIP)!

  • 📏 Internal Transformation - Handles all the math headaches associated with calculating screen- vs. plot-coordinates.

  • 👉 Rich interactivity – Subscribe to click, drag, hover, scroll, and double-click callbacks for both the plot area and individual axes.

  • 🎨 Composable styling – Override per-axis/plot styles or swap in entire style::Catalogs to match your own theming.

  • 🔥 Performant - The library handles layering and mesh-squashing to ensure proper rendering while maintaining performance!

🔽 Install

Add the following to your Cargo.toml:

[dependencies]
iced = { version = "0.14" }
iced_aksel = { version = "0.2" }

🌟 Quick Start

use iced::{Element, Theme};
use iced_aksel::shape::Ellipse;
use iced_aksel::{Axis, Chart, Measure, Plot, PlotData, PlotPoint, State, axis, scale::Linear};

// Initialize IDs for ***individual*** axes
const X_ID: &'static str = "x_id";
const Y_ID: &'static str = "y_id";

struct App {
    state: State<&'static str, f64>,
    scatter: Scatter,
}

#[derive(Debug, Clone)]
enum Message {}

impl App {
    fn new() -> Self {
        let mut state = State::new();
        state.set_axis(
            X_ID,
            Axis::new(Linear::new(0.0, 100.0), axis::Position::Bottom),
        );
        state.set_axis(
            Y_ID,
            Axis::new(Linear::new(0.0, 100.0), axis::Position::Left),
        );

        Self {
            state,
            scatter: Scatter::demo(),
        }
    }

    fn view(&self) -> Element<Message> {
        Chart::new(&self.state)
            .plot_data(&self.scatter, X_ID, Y_ID)
            .into()
    }
}

// Your own custom plot that implements `PlotData`
struct Scatter {
    points: Vec<PlotPoint<f64>>,
}

impl Scatter {
    fn demo() -> Self {
        Self {
            points: vec![
                PlotPoint::new(10.0, 20.0),
                PlotPoint::new(50.0, 80.0),
                PlotPoint::new(90.0, 30.0),
            ],
        }
    }
}

impl PlotData<f64> for Scatter {
    fn draw(&self, plot: &mut Plot<f64>, theme: &Theme) {
        for point in &self.points {
            plot.add_shape(
                Ellipse::new(*point, Measure::Screen(5.0), Measure::Screen(5.0))
                    .fill(theme.palette().primary),
            );
        }
    }
}

Core Concepts

  • Chart is the widget. It is the primary driver that renders the axes and plots and routes user events.
  • State holds every axis definition and is shared between updates and rendering.
  • Axis controls domain, scale, position, grid lines, marker, tick labels and more.
  • PlotData is implemented by your data structures; it receives a Plot builder to push shapes into.
  • Shape, Stroke, and Measure describe how primitives are drawn.

🧩 Examples

The workspace ships multiple runnable examples that showcase axes, shapes, interactions, dashboards, and stress tests. From the repository root:

# Core functionality examples
cargo run -p core_axes
cargo run -p core_scales
cargo run -p core_template

# Fancy Examples
cargo run -p showcase_candlestick
cargo run -p showcase_dashboard
cargo run -p showcase_spectrum

Each example is a separate crate under examples/ so you can copy-paste code into your own application.

All examples can also be run in the web using trunk:

cd examples/core_axes
trunk serve

[!IMPORTANT]

Due to a breaking change to getrandom you might have to enable the wasm_js backend for getrandom when running in WASM by setting the env-var: RUSTFLAGS='--cfg getrandom_backend="wasm_js"'

This only applies to examples depending on getrandom (usually through rand).

💻 Development

  • cargo fmt and cargo clippy enforce the workspace style (Clippy perf, correctness, complexity, and style lints are denied).

Contributions are welcome! Feel free to open issues with bug reports, feature ideas, or performance traces that can help steer the roadmap.

[!NOTE]

A nix-devshell is also supplied in the flake.nix for Nix users.

It can be started by running: nix develop .

Commit count: 0

cargo fmt