Skip to main content

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_enum_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={ctx.props().defaults.minimum_integer_digits}
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 defaults = &ctx.props().defaults;
88        let fractional_value = Some((
89            self.config
90                .minimum_fraction_digits
91                .unwrap_or(defaults.fraction.0),
92            self.config
93                .maximum_fraction_digits
94                .unwrap_or(defaults.fraction.1),
95        ));
96
97        let significant_value = Some((
98            self.config
99                .minimum_significant_digits
100                .unwrap_or(defaults.significant.0),
101            self.config
102                .maximum_significant_digits
103                .unwrap_or(defaults.significant.1),
104        ));
105
106        html! {
107            <>
108                <div class="row">
109                    <NumberRangeField
110                        label="fractional-digits"
111                        min=0.
112                        max=20.
113                        step=1.
114                        default={defaults.fraction}
115                        current_value={fractional_value}
116                        on_change={ctx.link().callback(CustomNumberFormatMsg::FracChange)}
117                    />
118                </div>
119                <div class="row">
120                    <NumberRangeField
121                        label="significant-digits"
122                        min=1.
123                        max=21.
124                        step=1.
125                        default={defaults.significant}
126                        current_value={significant_value}
127                        on_change={ctx.link().callback(CustomNumberFormatMsg::SigChange)}
128                    />
129                </div>
130                { self.rounding_increment(ctx) }
131                <SelectEnumField<RoundingPriority>
132                    label="rounding-priority"
133                    current_value={self.config.rounding_priority.unwrap_or(defaults.rounding_priority)}
134                    default_value={defaults.rounding_priority}
135                    on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingPriority)}
136                />
137                <SelectEnumField<RoundingMode>
138                    label="rounding-mode"
139                    current_value={self.config.rounding_mode.unwrap_or(defaults.rounding_mode)}
140                    default_value={defaults.rounding_mode}
141                    on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingMode)}
142                />
143                <SelectEnumField<TrailingZeroDisplay>
144                    label="trailing-zero-display"
145                    current_value={self.config.trailing_zero_display.unwrap_or(defaults.trailing_zero_display)}
146                    default_value={defaults.trailing_zero_display}
147                    on_change={ctx.link().callback(CustomNumberFormatMsg::TrailingZero)}
148                />
149            </>
150        }
151    }
152}