densa_chart/lib.rs
1//! Charts over your own data, drawn onto a `densa_draw::Canvas`: lines, candlesticks and
2//! bars, with gridlines and tick labels.
3//!
4//! Domain-agnostic: an application implements [`Points`] (a line or bars) or [`Candles`]
5//! over its data in ascending `x`, picks the visible part with an [`Axis`] for each
6//! direction, and draws onto a [`Plot`] (an area of the canvas and its two axes). Time axes
7//! count seconds since the epoch and label ticks as times of day or dates (UTC); category
8//! axes place named things (a bar chart's bars) at `0, 1, 2, ...` and label them by name.
9//!
10//! A chart widget asks its data through [`ChartModel`]: panes on one time axis, each giving
11//! its vertical axis for what shows and drawing its series.
12//!
13//! A line is drawn as one vertical span per pixel column, shaded at its ends, so a million
14//! points cost about as much as the plot is wide and every high and low still shows (M4
15//! aggregation). No GPU dependency: hand the canvas's instances to `densa-render` (or any
16//! other backend) to show them.
17//!
18//! Painting allocates nothing once the label characters are cached.
19//!
20//! ```
21//! use densa_chart::{paint_line, points_within, y_extent, Axis, LineStyle, Plot, Rect};
22//! use densa_draw::{Canvas, InstanceBuffer};
23//! use densa_text::{AtlasConfig, GlyphCache};
24//!
25//! // A day of readings, one a second: (seconds since the epoch, value).
26//! let readings: Vec<(f64, f64)> = (0..86_400)
27//! .map(|s| (1_792_368_000.0 + f64::from(s), (f64::from(s) / 3_600.0).sin()))
28//! .collect();
29//!
30//! // The last hour, scaled to what it holds.
31//! let x = Axis::time(1_792_450_800.0, 1_792_454_400.0);
32//! let (low, high) = y_extent(&readings[..], points_within(&readings[..], &x)).unwrap();
33//! let plot = Plot::new(Rect::new(0.0, 0.0, 800.0, 300.0), x, Axis::number(low, high).padded(0.05));
34//!
35//! let mut cache = GlyphCache::new(AtlasConfig::DEFAULT);
36//! let mut out = InstanceBuffer::with_capacity(4_096);
37//! let mut canvas = Canvas::begin(&mut cache, &mut out);
38//! paint_line(&mut canvas, &plot, &readings[..], LineStyle::new(densa_chart::Color::WHITE));
39//! assert!(out.len() <= 3 * 800, "at most a few rectangles per pixel column");
40//! ```
41
42mod axis;
43mod bars;
44mod line;
45mod model;
46mod painter;
47mod palette;
48mod plot;
49mod series;
50
51pub use axis::{Axis, AxisKind, Ticks};
52pub use bars::{paint_bars, paint_candles, BarStyle, CandleStyle};
53pub use densa_core::{Color, Point, Rect};
54pub use line::{paint_line, LineStyle};
55pub use model::ChartModel;
56pub use painter::ChartPainter;
57pub use palette::ChartPalette;
58pub use plot::Plot;
59pub use series::{candle_extent, candles_within, points_within, y_extent, Candle, Candles, Points};