CYD-UI
A C++ library for building native graphic user interfaces
Loading...
Searching...
No Matches
plot_grid.cppm
Go to the documentation of this file.
1//
2// Created by castle on 8/11/24.
3//
4
5module;
7
9
10import cydui;
11
12import fabric.linalg;
13import fabric.logging;
14
15import :axis;
16
17using la = with_precision<double>;
18
19namespace charts {
20 COMPONENT(PlotGrid, {
21 la::scalar min_x = 0, max_x = 1, step_x = 0.1;
22 bool major_ticks_x_show = false;
23 bool minor_ticks_x_show = false;
24 unsigned int minor_ticks_x_count = 4;
25 la::scalar min_y = 0, max_y = 1, step_y = 0.1;
26 bool major_ticks_y_show = false;
27 bool minor_ticks_y_show = false;
28 unsigned int minor_ticks_y_count = 4;
29 }) {
30 ON_REDRAW {
31 return {};
32 }
33
34 FRAGMENT {
35 if (props.major_ticks_x_show) {
36 la::scalar x1 = 0;
37 auto start = props.step_x * std::floor((props.min_x / props.step_x));
38 for (la::scalar X = start; X < props.max_x; X += props.step_x) {
39 auto pos_x = ((X - props.min_x) / (props.max_x - props.min_x));
40
41 x1 = $width.value_as_base_unit() * pos_x;
42 if (X >= props.min_x && X <= props.max_x) {
43 fragment.append(
44 vg::line{}.x1(x1).y1(0).x2(x1).y2($height).stroke_width(2).stroke("#555555"_color)
45 );
46 }
47
48 if (props.minor_ticks_x_show) {
49 auto minor_step = props.step_x / (props.minor_ticks_x_count + 1);
50 for (la::scalar Y = minor_step; Y <= props.step_x - minor_step && (X + Y) < props.max_x;
51 Y += minor_step) {
52 pos_x = (((X + Y) - props.min_x) / (props.max_x - props.min_x));
53
54 x1 = $width.value_as_base_unit() * pos_x;
55 if ((X + Y) >= props.min_x && (X + Y) <= props.max_x) {
56 fragment.append(
57 vg::line{}.x1(x1).y1(0).x2(x1).y2($height).stroke_width(1).stroke("#555555"_color)
58 );
59 }
60 }
61 }
62 }
63 }
64 if (props.major_ticks_y_show) {
65 la::scalar y1 = 0;
66 auto start = props.step_y * std::floor((props.min_y / props.step_y));
67 for (la::scalar X = start; X < props.max_y; X += props.step_y) {
68 auto pos_y = ((X - props.min_y) / (props.max_y - props.min_y));
69
70 y1 = $height.value_as_base_unit() - $height.value_as_base_unit() * pos_y;
71 if (X >= props.min_y && X <= props.max_y) {
72 fragment.append(
73 vg::line{}.x1(0).y1(y1).x2($width).y2(y1).stroke_width(2).stroke("#555555"_color)
74 );
75 }
76
77 if (props.minor_ticks_y_show) {
78 auto minor_step = props.step_y / (props.minor_ticks_y_count + 1);
79 for (la::scalar Y = minor_step; Y <= props.step_y - minor_step && (X + Y) < props.max_y;
80 Y += minor_step) {
81 pos_y = (((X + Y) - props.min_y) / (props.max_y - props.min_y));
82
83 y1 = $height.value_as_base_unit() - $height.value_as_base_unit() * pos_y;
84 if ((X + Y) >= props.min_y && (X + Y) <= props.max_y) {
85 fragment.append(
86 vg::line{}.x1(0).y1(y1).x2($width).y2(y1).stroke_width(1).stroke("#555555"_color)
87 );
88 }
89 }
90 }
91 }
92 }
93 }
94 };
95
96 export template <class C>
97 struct grid_t {
98 explicit grid_t(C& plot)
99 : ref_(&plot),
100 x_axis_ref_(&ref_->bottom_axis),
101 y_axis_ref_(&ref_->left_axis) {}
102
103 grid_t(const grid_t& rhl)
104 : ref_(rhl.ref_),
105 x_axis_ref_(&ref_->bottom_axis),
106 y_axis_ref_(&ref_->left_axis) {
107 x_axis = rhl.x_axis;
108 y_axis = rhl.y_axis;
109 }
110
111 grid_t(grid_t&& rhl) = delete;
112
113 struct axis_ticks {
114 explicit axis_ticks(grid_t& grid)
115 : ref_(&grid) {}
116
117 C& major_ticks_show(const bool show_ticks) {
118 major_ticks_show_ = show_ticks;
119 return *ref_->ref_;
120 }
121
122 C& minor_ticks_show(const bool show_ticks) {
123 minor_ticks_show_ = show_ticks;
124 return *ref_->ref_;
125 }
126
127 private:
128 friend struct grid_t;
129
130 axis_ticks& operator=(const axis_ticks& rhl) {
131 major_ticks_show_ = rhl.major_ticks_show_;
132 minor_ticks_show_ = rhl.minor_ticks_show_;
133 return *this;
134 }
135
136 C& set_ref(grid_t& ref) {
137 ref_ = ref;
138 return *ref_->ref_;
139 }
140
141 bool major_ticks_show_ = false;
142 bool minor_ticks_show_ = false;
143
144 private:
145 grid_t* ref_;
146 };
147
148 public:
151
152 private:
153 friend C;
154 friend typename C::event_handler_t;
155
156 grid_t& operator=(const grid_t& rhl) {
157 x_axis = rhl.x_axis;
158 y_axis = rhl.y_axis;
159
160 return *this;
161 }
162 grid_t& operator=(grid_t&& rhl) = delete;
163
164 C& set_ref(C& ref) {
165 ref_ = &ref;
166 x_axis_ref_ = &ref_->bottom_axis;
167 y_axis_ref_ = &ref_->left_axis;
168 return *ref_;
169 }
170
171 template <typename T1, typename T2, typename T3, typename T4>
172 PlotGrid build_component(T1&& x, T2&& y, T3&& w, T4&& h) const {
173 PlotGrid pa{{
174 .min_x = x_axis_ref_->min_value_,
175 .max_x = x_axis_ref_->max_value_,
176 .step_x = x_axis_ref_->step_,
177 .major_ticks_x_show = x_axis.major_ticks_show_,
178 .minor_ticks_x_show = x_axis.minor_ticks_show_,
179 .minor_ticks_x_count = x_axis_ref_->minor_ticks_count_,
180 .min_y = y_axis_ref_->min_value_,
181 .max_y = y_axis_ref_->max_value_,
182 .step_y = y_axis_ref_->step_,
183 .major_ticks_y_show = y_axis.major_ticks_show_,
184 .minor_ticks_y_show = y_axis.minor_ticks_show_,
185 .minor_ticks_y_count = y_axis_ref_->minor_ticks_count_,
186 }};
187 pa.x(std::forward<T1>(x)).y(std::forward<T2>(y)).width(std::forward<T3>(w)).height(std::forward<T4>(h));
188 return pa;
189 }
190
191 C* ref_;
192 axis_t<C>* x_axis_ref_;
193 axis_t<C>* y_axis_ref_;
194 };
195
196 export template <class C>
198}
#define FRAGMENT
#define COMPONENT(NAME,...)
#define ON_REDRAW
axis_t(C &) -> axis_t< C >
grid_t(C &) -> grid_t< C >
with_precision< double > la
Definition plot.cppm:19
C & minor_ticks_show(const bool show_ticks)
C & major_ticks_show(const bool show_ticks)
grid_t(grid_t &&rhl)=delete
axis_ticks y_axis
axis_ticks x_axis
grid_t(const grid_t &rhl)
grid_t(C &plot)