Skip to main content

rustlavel_chart/
lib.rs

1//! rustlavel-chart: charts, drawn in the browser, described in Rust.
2//!
3//! **This package vendors somebody else's library, and that is unusual here.**
4//! Chart.js is 69 KB gzipped and renders to a `<canvas>`; drawing the same
5//! thing from scratch would mean writing an axis scaler, a tick formatter, a
6//! legend layout engine and a hit-tester, and the result would still not have
7//! hover, tooltips or zoom. The copy lives in `assets/`, under its own MIT
8//! licence, and is served from this application's own origin — see [`plugin`].
9//!
10//! The Rust half never draws anything. It builds the *configuration* Chart.js
11//! reads, which is a JSON object, and hands it to the page:
12//!
13//! ```ignore
14//! let chart = Chart::line("Revenue")
15//!     .labels(["Jan", "Feb", "Mar"])
16//!     .series(Series::new("2026", [1_200.0, 1_800.0, 1_500.0]))
17//!     .series(Series::new("2025", [900.0, 1_100.0, 1_400.0]));
18//!
19//! Ok(view("dashboard", context! { revenue: chart.to_json() })?)
20//! ```
21//!
22//! ```html
23//! <canvas data-chart="{{ revenue }}"></canvas>
24//! ```
25//!
26//! # Why an attribute, and why `{{ }}`
27//!
28//! The configuration travels in an ordinary escaped attribute. `{{ }}` turns
29//! every `"` into `&quot;` and every `<` into `&lt;`, the browser reverses that
30//! when it reads `dataset.chart`, and the round trip is exact — so a label
31//! reading `</script>` is a label, not an escape.
32//!
33//! This is the whole reason there is no inline `<script>` anywhere in this
34//! package. A page that writes `<script>new Chart(…)</script>` needs
35//! `script-src 'unsafe-inline'`, and a policy with `unsafe-inline` does not
36//! stop injected script — which is the one thing a Content-Security-Policy is
37//! for. The auth kit ships `default-src 'self'` with no `unsafe-inline`, and
38//! everything here is built to satisfy that policy rather than to ask for an
39//! exception to it.
40
41pub mod chart;
42pub mod palette;
43pub mod plugin;
44pub mod series;
45
46pub use chart::{Axis, Chart, Kind, Legend};
47pub use palette::Palette;
48pub use plugin::{CHART_JS_PATH, Charts, INIT_JS_PATH};
49pub use series::Series;
50
51pub use rustlavel_core::{Error, Json, Result};