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::style_controls::CustomNumberFormatMsg;
21use crate::config::{
22    ROUNDING_INCREMENTS, RoundingIncrement, RoundingMode, RoundingPriority, TrailingZeroDisplay,
23};
24use crate::ui::{
25    NumberField, NumberRangeField, OptionalField, Select, SelectEnumField, SelectItem,
26};
27
28impl CustomNumberFormat {
29    pub fn digits_section(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
30        let is_float = matches!(ctx.props().view_type, ColumnType::Float);
31        html! {
32            <>
33                <NumberField
34                    label="minimum-integer-digits"
35                    min=1.
36                    max=21.
37                    step=1.
38                    default={ctx.props().defaults.minimum_integer_digits}
39                    current_value={self.config.minimum_integer_digits}
40                    on_change={ctx.link().callback(CustomNumberFormatMsg::MinimumIntegerDigits)}
41                />
42                if is_float { { self.float_section(ctx) } } else { { self.rounding_increment(ctx) } }
43            </>
44        }
45    }
46
47    fn rounding_increment(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
48        // let disabled = self.disable_rounding_increment;
49        let values = ROUNDING_INCREMENTS
50            .iter()
51            .map(|val| RoundingIncrement::Custom(*val))
52            .map(SelectItem::Option)
53            .collect_vec();
54
55        let values = Rc::new([vec![SelectItem::Option(RoundingIncrement::Auto)], values].concat());
56        let on_check = ctx
57            .link()
58            .callback(|_| CustomNumberFormatMsg::RoundingIncrement(RoundingIncrement::default()));
59
60        let selected = self
61            .config
62            .rounding_increment
63            .map(RoundingIncrement::Custom)
64            .unwrap_or_default();
65
66        html! {
67            <div class="row">
68                <OptionalField
69                    label="rounding-increment"
70                    {on_check}
71                    // {disabled}
72                    checked={self.config.rounding_increment.is_some()}
73                >
74                    <Select<RoundingIncrement>
75                        {values}
76                        {selected}
77                        on_select={ctx.link().callback(CustomNumberFormatMsg::RoundingIncrement)}
78                    />
79                </OptionalField>
80            </div>
81        }
82    }
83
84    fn float_section(&self, ctx: &yew::prelude::Context<Self>) -> yew::prelude::Html {
85        let defaults = &ctx.props().defaults;
86        let fractional_value = Some((
87            self.config
88                .minimum_fraction_digits
89                .unwrap_or(defaults.fraction.0),
90            self.config
91                .maximum_fraction_digits
92                .unwrap_or(defaults.fraction.1),
93        ));
94
95        let significant_value = Some((
96            self.config
97                .minimum_significant_digits
98                .unwrap_or(defaults.significant.0),
99            self.config
100                .maximum_significant_digits
101                .unwrap_or(defaults.significant.1),
102        ));
103
104        html! {
105            <>
106                <div class="row">
107                    <NumberRangeField
108                        label="fractional-digits"
109                        min=0.
110                        max=20.
111                        step=1.
112                        default={defaults.fraction}
113                        current_value={fractional_value}
114                        on_change={ctx.link().callback(CustomNumberFormatMsg::FracChange)}
115                    />
116                </div>
117                <div class="row">
118                    <NumberRangeField
119                        label="significant-digits"
120                        min=1.
121                        max=21.
122                        step=1.
123                        default={defaults.significant}
124                        current_value={significant_value}
125                        on_change={ctx.link().callback(CustomNumberFormatMsg::SigChange)}
126                    />
127                </div>
128                { self.rounding_increment(ctx) }
129                <SelectEnumField<RoundingPriority>
130                    label="rounding-priority"
131                    current_value={self.config.rounding_priority.unwrap_or(defaults.rounding_priority)}
132                    default_value={defaults.rounding_priority}
133                    on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingPriority)}
134                />
135                <SelectEnumField<RoundingMode>
136                    label="rounding-mode"
137                    current_value={self.config.rounding_mode.unwrap_or(defaults.rounding_mode)}
138                    default_value={defaults.rounding_mode}
139                    on_change={ctx.link().callback(CustomNumberFormatMsg::RoundingMode)}
140                />
141                <SelectEnumField<TrailingZeroDisplay>
142                    label="trailing-zero-display"
143                    current_value={self.config.trailing_zero_display.unwrap_or(defaults.trailing_zero_display)}
144                    default_value={defaults.trailing_zero_display}
145                    on_change={ctx.link().callback(CustomNumberFormatMsg::TrailingZero)}
146                />
147            </>
148        }
149    }
150}