densa_chart/model.rs
1use densa_draw::Canvas;
2
3use crate::{Axis, AxisKind, ChartPalette, Plot};
4
5/// The data of a chart widget (`densa_widgets::Chart`): panes stacked top to bottom on one
6/// horizontal axis, each drawing its own series (candles over a line, volume bars below).
7///
8/// The widget decides what part of `x` shows (it follows the newest data until the user
9/// pans or zooms) and asks each pane for its vertical axis over that part, so panes scale to
10/// what is on screen. Painting goes through the series functions of this crate, which
11/// allocate nothing.
12pub trait ChartModel {
13 /// What the horizontal axis counts.
14 fn x_kind(&self) -> AxisKind {
15 AxisKind::Time
16 }
17
18 /// The lowest and highest `x` of the data, or `None` while there is none. On a
19 /// [`Category`](AxisKind::Category) axis, the edges of the places: `(-0.5, n - 0.5)` for
20 /// `n` bars, so a view of all of them shows every bar whole.
21 fn x_extent(&self) -> Option<(f64, f64)>;
22
23 /// The distance between two points (a candle's period, `1.0` between bars), if the data
24 /// has one: the widget zooms in no further than a few of them, or than all of them when
25 /// there are fewer.
26 fn x_step(&self) -> Option<f64> {
27 None
28 }
29
30 /// How many panes, top to bottom (one is drawn even for zero).
31 fn panes(&self) -> usize {
32 1
33 }
34
35 /// Pane `pane`'s share of the height, against the others' (above zero).
36 fn pane_weight(&self, pane: usize) -> f32 {
37 let _ = pane;
38 1.0
39 }
40
41 /// The vertical axis of pane `pane` while `x` shows: what its series need, with room
42 /// around them (see [`Axis::padded`]); `None` if it has nothing there.
43 fn y_axis(&self, pane: usize, x: &Axis) -> Option<Axis>;
44
45 /// Draws the series of pane `pane` onto `plot`, in `palette`'s colors.
46 fn paint(&self, pane: usize, plot: &Plot, canvas: &mut Canvas<'_>, palette: &ChartPalette);
47
48 /// The name of pane `pane` ("Volume"), written on a line of its own above the pane, cut
49 /// off where the pane ends. A pane without a name (empty, the default) has no such line.
50 fn pane_title(&self, _pane: usize) -> &str {
51 ""
52 }
53
54 /// The name of place `index` of a [`Category`](AxisKind::Category) `x` axis, written
55 /// under it and in the crosshair's box; `None` (the default) for none there.
56 fn category(&self, index: usize) -> Option<&str> {
57 let _ = index;
58 None
59 }
60
61 /// Called before every frame is painted, to catch up with new data. Does nothing by
62 /// default.
63 fn prepare(&mut self) {}
64
65 /// What the chart shows, for screen readers ("ACME, one-minute candles, last 182.40").
66 /// Asked only while one is listening. Empty by default.
67 fn describe(&self) -> String {
68 String::new()
69 }
70}