perspective_viewer/components/style_controls/number_string_format/
digits_section.rs

1// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2// ┃ ██████ ██████ ██████       █      █      █      █      █ █▄  ▀███ █       ┃
3// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█  ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄  ▀█ █ ▀▀▀▀▀ ┃
4// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄   █ ▄▄▄▄▄ ┃
5// ┃ █      ██████ █  ▀█▄       █ ██████      █      ███▌▐███ ███████▄ █       ┃
6// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7// ┃ Copyright (c) 2017, the Perspective Authors.                              ┃
8// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9// ┃ This file is part of the Perspective library, distributed under the terms ┃
10// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
13use std::rc::Rc;
14
15use itertools::Itertools;
16use perspective_client::config::ColumnType;
17use yew::html;
18
19use super::CustomNumberFormat;
20use crate::components::containers::select::{Select, SelectItem};
21use crate::components::form::number_field::NumberField;
22use crate::components::form::number_range_field::NumberRangeField;
23use crate::components::form::optional_field::OptionalField;
24use crate::components::form::select_field::SelectEnumField;
25use crate::components::style_controls::CustomNumberFormatMsg;
26use crate::config::{
27    ROUNDING_INCREMENTS, RoundingIncrement, RoundingMode, RoundingPriority, TrailingZeroDisplay,
28};
29
30impl CustomNumberFormat {
31    pub fn digits_section(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
32        let is_float = matches!(ctx.props().view_type, ColumnType::Float);
33        html! {
34            <>
35                <NumberField
36                    label="minimum-integer-digits"
37                    min=1.
38                    max=21.
39                    step=1.
40                    default=1.
41                    current_value={self.config.minimum_integer_digits}
42                    on_change={ctx.link().callback(CustomNumberFormatMsg::MinimumIntegerDigits)}
43                />
44                if is_float { { self.float_section(ctx) } } else { { self.rounding_increment(ctx) } }
45            </>
46        }
47    }
48
49    fn rounding_increment(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
50        // let disabled = self.disable_rounding_increment;
51        let values = ROUNDING_INCREMENTS
52            .iter()
53            .map(|val| RoundingIncrement::Custom(*val))
54            .map(SelectItem::Option)
55            .collect_vec();
56
57        let values = Rc::new([vec![SelectItem::Option(RoundingIncrement::Auto)], values].concat());
58        let on_check = ctx
59            .link()
60            .callback(|_| CustomNumberFormatMsg::RoundingIncrement(RoundingIncrement::default()));
61
62        let selected = self
63            .config
64            .rounding_increment
65            .map(RoundingIncrement::Custom)
66            .unwrap_or_default();
67
68        html! {
69            <div class="row">
70                <OptionalField
71                    label="rounding-increment"
72                    {on_check}
73                    // {disabled}
74                    checked={self.config.rounding_increment.is_some()}
75                >
76                    <Select<RoundingIncrement>
77                        {values}
78                        {selected}
79                        on_select={ctx.link().callback(CustomNumberFormatMsg::RoundingIncrement)}
80                    />
81                </OptionalField>
82            </div>
83        }
84    }
85
86    fn float_section(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
87        let fractional_value = Some((
88            self.config.minimum_fraction_digits.unwrap_or(2.),
89            self.config.maximum_fraction_digits.unwrap_or(2.),
90        ));
91
92        let significant_value = Some((
93            self.config.minimum_significant_digits.unwrap_or(1.),
94            self.config.maximum_significant_digits.unwrap_or(21.),
95        ));
96
97        html! {
98            <>
99                <div class="row">
100                    <NumberRangeField
101                        label="fractional-digits"
102                        min=0.
103                        max=20.
104                        step=1.
105                        default={(2., 2.)}
106                        current_value={fractional_value}
107                        on_change={ctx.link().callback(CustomNumberFormatMsg::FracChange)}
108                    />
109                </div>
110                <div class="row">
111                    <NumberRangeField
112                        label="significant-digits"
113                        min=1.
114                        max=21.
115                        step=1.
116                        default={(1., 21.)}
117                        current_value={significant_value}
118                        on_change={ctx.link().callback(CustomNumberFormatMsg::SigChange)}
119                    />
120                </div>
121                { self.rounding_increment(ctx) }
122                <SelectEnumField<RoundingPriority>
123                    label="rounding-priority"
124                    current_value={self.config.rounding_priority}
125                    on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingPriority)}
126                />
127                <SelectEnumField<RoundingMode>
128                    label="rounding-mode"
129                    current_value={self.config.rounding_mode}
130                    on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingMode)}
131                />
132                <SelectEnumField<TrailingZeroDisplay>
133                    label="trailing-zero-display"
134                    current_value={self.config.trailing_zero_display}
135                    on_change={ctx.link().callback(CustomNumberFormatMsg::TrailingZero)}
136                />
137            </>
138        }
139    }
140}