24 la::scalar min_x = 0, max_x = 1;
25 la::scalar min_y = 0, max_y = 1;
26 bool show_data_points =
true;
27 bool show_lines =
true;
28 std::function<void(
vg::fragment_t&,
int x,
int y)> data_point_fragment =
30 std::function<void(
vg::fragment_t&,
int x1,
int y1,
int x2,
int y2)> line_fragment =
38 const auto size = props.series->size();
40 bool out_of_frame =
false;
41 auto data_point = (*props.series)[0];
42 auto prev = in_screen_space(data_point, $width, $height);
43 if (data_point[0] < props.min_x || data_point[0] > props.max_x ||
44 data_point[1] < props.min_y || data_point[1] > props.max_y) {
47 if (props.show_lines) {
48 for (std::size_t i = 1; i < size; ++i) {
49 data_point = (*props.series)[i];
50 const auto current = in_screen_space(data_point, $width, $height);
51 if ((current - prev).mag2() > 2) {
52 if (out_of_frame && (data_point[0] >= props.min_x && data_point[0] <= props.max_x &&
53 data_point[1] >= props.min_y && data_point[1] <= props.max_y)) {
58 props.line_fragment(fragment, prev[0], prev[1], current[0], current[1]);
62 if (!out_of_frame && (data_point[0] < props.min_x || data_point[0] > props.max_x ||
63 data_point[1] < props.min_y || data_point[1] > props.max_y)) {
69 if (props.show_data_points) {
70 for (std::size_t i = 0; i < size; ++i) {
71 data_point = (*props.series)[i];
72 auto current = in_screen_space(data_point, $width, $height);
73 if (data_point[0] >= props.min_x && data_point[0] <= props.max_x &&
74 data_point[1] >= props.min_y && data_point[1] <= props.max_y) {
75 props.data_point_fragment(fragment, current[0], current[1]);
82 la::vec<2> in_screen_space(
const la::vec<2>& point,
auto $width,
auto $height)
const {
84 la::scalar{$width.value} * ((point[0] - props.min_x) / (props.max_x - props.min_x)),
85 la::scalar{$height.value} -
86 la::scalar{$height.value} * ((point[1] - props.min_y) / (props.max_y - props.min_y)),
97 : ref_(&
plot), index_(index) {
103 show_data_points_ = rhl.show_data_points_;
104 show_line_ = rhl.show_line_;
110 show_data_points_ = show_points;
122 show_data_points_ = rhl.show_data_points_;
123 show_line_ = rhl.show_line_;
133 bool exists_in_plot()
const {
134 return ref_->props.series.size() > index_;
137 PlotView build_component(
auto& x,
auto& y,
auto& w,
auto& h)
const {
140 .series = &ref_->props.series[index_],
141 .min_x = ref_->bottom_axis.min_value_,
142 .max_x = ref_->bottom_axis.max_value_,
143 .min_y = ref_->left_axis.min_value_,
144 .max_y = ref_->left_axis.max_value_,
145 .show_data_points = show_data_points_,
146 .show_lines = show_line_,
147 .data_point_fragment = [](vg::fragment_t& fragment,
int x,
int y) {
148 fragment.
append(vg::circle { }
151 .fill(
"#FCAE1E"_color)
154 .line_fragment = [](vg::fragment_t& fragment,
int x1,
int y1,
int x2,
int y2) {
155 fragment.
append(vg::line { }
158 .stroke(
"#FCAE1E"_color)
163 pa.x(x).y(y).width(w).height(h);
168 friend typename C::event_handler_t;
172 bool show_data_points_ =
true;
173 bool show_line_ =
true;
191 for (
auto &[index, view] : rhl.views_) {
192 views_.emplace(index, view);
193 views_.at(index).set_ref(*ref_);
200 if (!views_.contains(index)) {
201 views_.emplace(index,
view_t<C> {*ref_, index});
203 return views_.at(index);
208 for (
auto &[index, view] : rhl.views_) {
209 views_.emplace(index, view);
210 views_.at(index).set_ref(*ref_);
219 for (
auto &[index, view] : views_) {
225 std::vector<PlotView> build_component(
auto&& x,
auto&& y,
auto&& w,
auto&& h)
const {
226 std::vector<PlotView> result{};
227 for (
const auto & [index, view] : views_) {
228 if (!view.exists_in_plot()) {
continue; }
229 result.push_back(view.build_component(x, y, w, h));
235 friend typename C::event_handler_t;
238 std::map<std::size_t, view_t<C>> views_{};