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