Skip to content

Commit b495883

Browse files
authored
Internal code cleanup (#210)
Just moving things around to make more sense. There is a one change to public API, due to previous exposure of internal API: Changed items in the public API =============================== ``` -pub egui_plot::PlotPoints::Generator(egui_plot::items::values::ExplicitGenerator<'a>) +pub egui_plot::PlotPoints::Generator(egui_plot::values::ExplicitGenerator<'a>) ```
1 parent 2eb6a4e commit b495883

31 files changed

Lines changed: 928 additions & 895 deletions

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ run_checks: check_no_commented_out_code \
119119
checks_no_unfinished \
120120
check_shear \
121121
check_deny \
122+
check_linter \
122123
check_pub_change_intentional
123124

124125
# Performs a compilation check of all crates in the workspace, without building.
@@ -153,6 +154,9 @@ check_license:
153154
check_cycles:
154155
cargo-cycles
155156

157+
check_linter:
158+
python3 ./scripts/lint.py
159+
156160
check_pub_change_intentional:
157161
if [ "$$(cargo public-api diff latest -p egui_plot -sss --deny all)" != "" ]; then \
158162
echo "--------------------------------"; \

egui_plot/src/axis.rs

Lines changed: 6 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@ use egui::emath::Rot2;
1616
use egui::emath::remap_clamp;
1717
use egui::epaint::TextShape;
1818

19-
use super::GridMark;
2019
use super::transform::PlotTransform;
20+
use crate::colors;
21+
use crate::grid::GridMark;
22+
use crate::placement::HPlacement;
23+
use crate::placement::Placement;
24+
use crate::placement::VPlacement;
2125

2226
// Gap between tick labels and axis label in units of the axis label height
2327
const AXIS_LABEL_GAP: f32 = 0.25;
@@ -44,70 +48,6 @@ impl From<Axis> for usize {
4448
}
4549
}
4650

47-
/// Placement of the horizontal X-Axis.
48-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49-
pub enum VPlacement {
50-
Top,
51-
Bottom,
52-
}
53-
54-
/// Placement of the vertical Y-Axis.
55-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56-
pub enum HPlacement {
57-
Left,
58-
Right,
59-
}
60-
61-
/// Placement of an axis.
62-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63-
pub enum Placement {
64-
/// Bottom for X-axis, or left for Y-axis.
65-
LeftBottom,
66-
67-
/// Top for x-axis and right for y-axis.
68-
RightTop,
69-
}
70-
71-
impl From<HPlacement> for Placement {
72-
#[inline]
73-
fn from(placement: HPlacement) -> Self {
74-
match placement {
75-
HPlacement::Left => Self::LeftBottom,
76-
HPlacement::Right => Self::RightTop,
77-
}
78-
}
79-
}
80-
81-
impl From<Placement> for HPlacement {
82-
#[inline]
83-
fn from(placement: Placement) -> Self {
84-
match placement {
85-
Placement::LeftBottom => Self::Left,
86-
Placement::RightTop => Self::Right,
87-
}
88-
}
89-
}
90-
91-
impl From<VPlacement> for Placement {
92-
#[inline]
93-
fn from(placement: VPlacement) -> Self {
94-
match placement {
95-
VPlacement::Top => Self::RightTop,
96-
VPlacement::Bottom => Self::LeftBottom,
97-
}
98-
}
99-
}
100-
101-
impl From<Placement> for VPlacement {
102-
#[inline]
103-
fn from(placement: Placement) -> Self {
104-
match placement {
105-
Placement::LeftBottom => Self::Bottom,
106-
Placement::RightTop => Self::Top,
107-
}
108-
}
109-
}
110-
11151
/// Axis configuration.
11252
///
11353
/// Used to configure axis label and ticks.
@@ -330,7 +270,7 @@ impl<'a> AxisWidget<'a> {
330270
// Fade in labels as they get further apart:
331271
let strength = remap_clamp(spacing_in_points, label_spacing, 0.0..=1.0);
332272

333-
let text_color = super::color_from_strength(ui, strength);
273+
let text_color = colors::color_from_strength(ui, strength);
334274
let galley = painter.layout_no_wrap(text, font_id.clone(), text_color);
335275
let galley_size = match axis {
336276
Axis::X => galley.size(),

egui_plot/src/bounds.rs

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
use std::ops::RangeInclusive;
2+
3+
use ahash::HashMap;
4+
use egui::Id;
5+
use emath::Vec2;
6+
use emath::Vec2b;
7+
8+
use crate::PlotPoint;
9+
10+
/// 2D bounding box of f64 precision.
11+
///
12+
/// The range of data values we show.
13+
#[derive(Clone, Copy, PartialEq, Debug)]
14+
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
15+
pub struct PlotBounds {
16+
pub(crate) min: [f64; 2],
17+
pub(crate) max: [f64; 2],
18+
}
19+
20+
impl PlotBounds {
21+
pub const NOTHING: Self = Self {
22+
min: [f64::INFINITY; 2],
23+
max: [-f64::INFINITY; 2],
24+
};
25+
26+
#[inline]
27+
pub fn from_min_max(min: [f64; 2], max: [f64; 2]) -> Self {
28+
Self { min, max }
29+
}
30+
31+
#[inline]
32+
pub fn min(&self) -> [f64; 2] {
33+
self.min
34+
}
35+
36+
#[inline]
37+
pub fn max(&self) -> [f64; 2] {
38+
self.max
39+
}
40+
41+
#[inline]
42+
pub fn new_symmetrical(half_extent: f64) -> Self {
43+
Self {
44+
min: [-half_extent; 2],
45+
max: [half_extent; 2],
46+
}
47+
}
48+
49+
#[inline]
50+
pub fn is_finite(&self) -> bool {
51+
self.min[0].is_finite() && self.min[1].is_finite() && self.max[0].is_finite() && self.max[1].is_finite()
52+
}
53+
54+
#[inline]
55+
pub fn is_finite_x(&self) -> bool {
56+
self.min[0].is_finite() && self.max[0].is_finite()
57+
}
58+
59+
#[inline]
60+
pub fn is_finite_y(&self) -> bool {
61+
self.min[1].is_finite() && self.max[1].is_finite()
62+
}
63+
64+
#[inline]
65+
pub fn is_valid(&self) -> bool {
66+
self.is_finite() && self.width() > 0.0 && self.height() > 0.0
67+
}
68+
69+
#[inline]
70+
pub fn is_valid_x(&self) -> bool {
71+
self.is_finite_x() && self.width() > 0.0
72+
}
73+
74+
#[inline]
75+
pub fn is_valid_y(&self) -> bool {
76+
self.is_finite_y() && self.height() > 0.0
77+
}
78+
79+
#[inline]
80+
pub fn width(&self) -> f64 {
81+
self.max[0] - self.min[0]
82+
}
83+
84+
#[inline]
85+
pub fn height(&self) -> f64 {
86+
self.max[1] - self.min[1]
87+
}
88+
89+
#[inline]
90+
pub fn center(&self) -> PlotPoint {
91+
[
92+
emath::fast_midpoint(self.min[0], self.max[0]),
93+
emath::fast_midpoint(self.min[1], self.max[1]),
94+
]
95+
.into()
96+
}
97+
98+
/// Expand to include the given (x,y) value
99+
#[inline]
100+
pub fn extend_with(&mut self, value: &PlotPoint) {
101+
self.extend_with_x(value.x);
102+
self.extend_with_y(value.y);
103+
}
104+
105+
/// Expand to include the given x coordinate
106+
#[inline]
107+
pub fn extend_with_x(&mut self, x: f64) {
108+
self.min[0] = self.min[0].min(x);
109+
self.max[0] = self.max[0].max(x);
110+
}
111+
112+
/// Expand to include the given y coordinate
113+
#[inline]
114+
pub fn extend_with_y(&mut self, y: f64) {
115+
self.min[1] = self.min[1].min(y);
116+
self.max[1] = self.max[1].max(y);
117+
}
118+
119+
#[inline]
120+
fn clamp_to_finite(&mut self) {
121+
for d in 0..2 {
122+
self.min[d] = self.min[d].clamp(f64::MIN, f64::MAX);
123+
if self.min[d].is_nan() {
124+
self.min[d] = 0.0;
125+
}
126+
127+
self.max[d] = self.max[d].clamp(f64::MIN, f64::MAX);
128+
if self.max[d].is_nan() {
129+
self.max[d] = 0.0;
130+
}
131+
}
132+
}
133+
134+
#[inline]
135+
pub fn expand_x(&mut self, pad: f64) {
136+
if pad.is_finite() {
137+
self.min[0] -= pad;
138+
self.max[0] += pad;
139+
self.clamp_to_finite();
140+
}
141+
}
142+
143+
#[inline]
144+
pub fn expand_y(&mut self, pad: f64) {
145+
if pad.is_finite() {
146+
self.min[1] -= pad;
147+
self.max[1] += pad;
148+
self.clamp_to_finite();
149+
}
150+
}
151+
152+
#[inline]
153+
pub fn merge_x(&mut self, other: &Self) {
154+
self.min[0] = self.min[0].min(other.min[0]);
155+
self.max[0] = self.max[0].max(other.max[0]);
156+
}
157+
158+
#[inline]
159+
pub fn merge_y(&mut self, other: &Self) {
160+
self.min[1] = self.min[1].min(other.min[1]);
161+
self.max[1] = self.max[1].max(other.max[1]);
162+
}
163+
164+
#[inline]
165+
pub fn set_x(&mut self, other: &Self) {
166+
self.min[0] = other.min[0];
167+
self.max[0] = other.max[0];
168+
}
169+
170+
#[inline]
171+
pub fn set_x_center_width(&mut self, x: f64, width: f64) {
172+
self.min[0] = x - width / 2.0;
173+
self.max[0] = x + width / 2.0;
174+
}
175+
176+
#[inline]
177+
pub fn set_y(&mut self, other: &Self) {
178+
self.min[1] = other.min[1];
179+
self.max[1] = other.max[1];
180+
}
181+
182+
#[inline]
183+
pub fn set_y_center_height(&mut self, y: f64, height: f64) {
184+
self.min[1] = y - height / 2.0;
185+
self.max[1] = y + height / 2.0;
186+
}
187+
188+
#[inline]
189+
pub fn merge(&mut self, other: &Self) {
190+
self.min[0] = self.min[0].min(other.min[0]);
191+
self.min[1] = self.min[1].min(other.min[1]);
192+
self.max[0] = self.max[0].max(other.max[0]);
193+
self.max[1] = self.max[1].max(other.max[1]);
194+
}
195+
196+
#[inline]
197+
pub fn translate_x(&mut self, delta: f64) {
198+
if delta.is_finite() {
199+
self.min[0] += delta;
200+
self.max[0] += delta;
201+
self.clamp_to_finite();
202+
}
203+
}
204+
205+
#[inline]
206+
pub fn translate_y(&mut self, delta: f64) {
207+
if delta.is_finite() {
208+
self.min[1] += delta;
209+
self.max[1] += delta;
210+
self.clamp_to_finite();
211+
}
212+
}
213+
214+
#[inline]
215+
pub fn translate(&mut self, delta: (f64, f64)) {
216+
self.translate_x(delta.0);
217+
self.translate_y(delta.1);
218+
}
219+
220+
#[inline]
221+
pub fn zoom(&mut self, zoom_factor: Vec2, center: PlotPoint) {
222+
self.min[0] = center.x + (self.min[0] - center.x) / (zoom_factor.x as f64);
223+
self.max[0] = center.x + (self.max[0] - center.x) / (zoom_factor.x as f64);
224+
self.min[1] = center.y + (self.min[1] - center.y) / (zoom_factor.y as f64);
225+
self.max[1] = center.y + (self.max[1] - center.y) / (zoom_factor.y as f64);
226+
}
227+
228+
#[inline]
229+
pub fn add_relative_margin_x(&mut self, margin_fraction: Vec2) {
230+
let width = self.width().max(0.0);
231+
self.expand_x(margin_fraction.x as f64 * width);
232+
}
233+
234+
#[inline]
235+
pub fn add_relative_margin_y(&mut self, margin_fraction: Vec2) {
236+
let height = self.height().max(0.0);
237+
self.expand_y(margin_fraction.y as f64 * height);
238+
}
239+
240+
#[inline]
241+
pub fn range_x(&self) -> RangeInclusive<f64> {
242+
self.min[0]..=self.max[0]
243+
}
244+
245+
#[inline]
246+
pub fn range_y(&self) -> RangeInclusive<f64> {
247+
self.min[1]..=self.max[1]
248+
}
249+
250+
#[inline]
251+
pub fn make_x_symmetrical(&mut self) {
252+
let x_abs = self.min[0].abs().max(self.max[0].abs());
253+
self.min[0] = -x_abs;
254+
self.max[0] = x_abs;
255+
}
256+
257+
#[inline]
258+
pub fn make_y_symmetrical(&mut self) {
259+
let y_abs = self.min[1].abs().max(self.max[1].abs());
260+
self.min[1] = -y_abs;
261+
self.max[1] = y_abs;
262+
}
263+
}
264+
265+
#[derive(Clone)]
266+
pub struct LinkedBounds {
267+
pub bounds: PlotBounds,
268+
pub auto_bounds: Vec2b,
269+
}
270+
271+
#[derive(Default, Clone)]
272+
pub struct BoundsLinkGroups(pub HashMap<Id, LinkedBounds>);
273+
274+
/// User-requested modifications to the plot bounds. We collect them in the plot
275+
/// build function to later apply them at the right time, as other modifications
276+
/// need to happen first.
277+
pub enum BoundsModification {
278+
SetX(RangeInclusive<f64>),
279+
SetY(RangeInclusive<f64>),
280+
Translate(Vec2),
281+
AutoBounds(Vec2b),
282+
Zoom(Vec2, PlotPoint),
283+
}

0 commit comments

Comments
 (0)