Skip to main content

egui_charts/scales/
study_format.rs

1//! Study value units and scale placement.
2
3use super::price_formatter::format_decimal;
4use crate::scales::{PriceFormatter, VolumeFormatter};
5
6/// Units used in study legends, axes, tooltips and data windows.
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8#[non_exhaustive]
9pub enum StudyFormat {
10    /// Price, following instrument precision unless explicitly overridden.
11    Price,
12    /// Signed volume with K, M and B suffixes.
13    Volume,
14    /// Percentage units: a value of 5 represents 5%, not 500%.
15    Percent,
16    /// A fixed number of decimal places, capped at twelve.
17    Fixed(usize),
18}
19
20impl StudyFormat {
21    /// Format a finite value with an optional precision override; non-finite values use a dash.
22    pub fn format(self, value: f64, precision: Option<usize>) -> String {
23        if !value.is_finite() {
24            return "-".to_owned();
25        }
26        let decimals = precision
27            .unwrap_or(match self {
28                Self::Fixed(decimals) => decimals,
29                Self::Volume if value.abs() < 1_000.0 => 0,
30                _ => 2,
31            })
32            .min(if self == Self::Price { 18 } else { 12 });
33        match self {
34            Self::Volume => VolumeFormatter {
35                precision: decimals,
36            }
37            .format(value),
38            Self::Percent => format!("{}%", format_decimal(value, decimals)),
39            Self::Price | Self::Fixed(_) => format_decimal(value, decimals),
40        }
41    }
42}