Skip to main content

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}