From d4d092c376c93dc5fdf6b2f3bdc10a4f4a00aee5 Mon Sep 17 00:00:00 2001 From: Kolan Sh Date: Fri, 6 Oct 2017 22:46:51 +0300 Subject: [PATCH] Closes #140: Move feature. --- src/Chart.vala | 46 +++++++++++++++++++++++++++++++++++++++++++++ test/ChartTest.vala | 37 +++++++++++++++++++----------------- 2 files changed, 66 insertions(+), 17 deletions(-) diff --git a/src/Chart.vala b/src/Chart.vala index 281f4a8..905a3c3 100644 --- a/src/Chart.vala +++ b/src/Chart.vala @@ -102,6 +102,11 @@ namespace Gtk.CairoChart { return new_series; } + double rel_zoom_x_min = 0.0; + double rel_zoom_x_max = 1.0; + double rel_zoom_y_min = 0.0; + double rel_zoom_y_max = 1.0; + public virtual void zoom_in (double x0, double y0, double x1, double y1) { for (var i = 0, max_i = zoom_series.length; i < max_i; ++i) { var s = zoom_series[i]; @@ -142,6 +147,15 @@ namespace Gtk.CairoChart { s.place.zoom_y_high = (s.axis_y.zoom_max - real_y1) / (real_y0 - real_y1); } } + + var new_rel_zoom_x_min = rel_zoom_x_min + (x0 - plot_area_x_min) / (plot_area_x_max - plot_area_x_min) * (rel_zoom_x_max - rel_zoom_x_min); + var new_rel_zoom_x_max = rel_zoom_x_min + (x1 - plot_area_x_min) / (plot_area_x_max - plot_area_x_min) * (rel_zoom_x_max - rel_zoom_x_min); + var new_rel_zoom_y_min = rel_zoom_y_min + (y0 - plot_area_y_min) / (plot_area_y_max - plot_area_y_min) * (rel_zoom_y_max - rel_zoom_y_min); + var new_rel_zoom_y_max = rel_zoom_y_min + (y1 - plot_area_y_min) / (plot_area_y_max - plot_area_y_min) * (rel_zoom_y_max - rel_zoom_y_min); + rel_zoom_x_min = new_rel_zoom_x_min; + rel_zoom_x_max = new_rel_zoom_x_max; + rel_zoom_y_min = new_rel_zoom_y_min; + rel_zoom_y_max = new_rel_zoom_y_max; } public virtual void zoom_out () { @@ -160,6 +174,34 @@ namespace Gtk.CairoChart { s.place.zoom_y_low = s.place.y_low; s.place.zoom_y_high = s.place.y_high; } + rel_zoom_x_min = 0; + rel_zoom_x_max = 1; + rel_zoom_y_min = 0; + rel_zoom_y_max = 1; + } + + public virtual void move (double delta_x, double delta_y) { + delta_x /= plot_area_x_max - plot_area_x_min; delta_x *= - 1.0; + delta_y /= plot_area_y_max - plot_area_y_min; delta_y *= - 1.0; + var rzxmin = rel_zoom_x_min, rzxmax = rel_zoom_x_max, rzymin = rel_zoom_y_min, rzymax = rel_zoom_y_max; + zoom_out(); + draw(); // TODO: optimize here + delta_x *= plot_area_x_max - plot_area_x_min; + delta_y *= plot_area_y_max - plot_area_y_min; + var xmin = plot_area_x_min + (plot_area_x_max - plot_area_x_min) * rzxmin; + var xmax = plot_area_x_min + (plot_area_x_max - plot_area_x_min) * rzxmax; + var ymin = plot_area_y_min + (plot_area_y_max - plot_area_y_min) * rzymin; + var ymax = plot_area_y_min + (plot_area_y_max - plot_area_y_min) * rzymax; + + delta_x *= rzxmax - rzxmin; delta_y *= rzymax - rzymin; + + if (xmin + delta_x < plot_area_x_min) delta_x = plot_area_x_min - xmin; + if (xmax + delta_x > plot_area_x_max) delta_x = plot_area_x_max - xmax; + if (ymin + delta_y < plot_area_y_min) delta_y = plot_area_y_min - ymin; + if (ymax + delta_y > plot_area_y_max) delta_y = plot_area_y_max - ymax; + + zoom_in (xmin + delta_x, ymin + delta_y, xmax + delta_x, ymax + delta_y); + draw(); // TODO: optimize here } protected double title_width = 0.0; @@ -1142,6 +1184,10 @@ namespace Gtk.CairoChart { chart.plot_area_x_min = this.plot_area_x_min; chart.plot_area_y_max = this.plot_area_y_max; chart.plot_area_y_min = this.plot_area_y_min; + chart.rel_zoom_x_min = this.rel_zoom_x_min; + chart.rel_zoom_x_max = this.rel_zoom_x_max; + chart.rel_zoom_y_min = this.rel_zoom_y_min; + chart.rel_zoom_y_max = this.rel_zoom_y_max; chart.selection_style = this.selection_style; chart.zoom_series = this.zoom_series.copy(); chart.show_legend = this.show_legend; diff --git a/test/ChartTest.vala b/test/ChartTest.vala index f3db13a..68a6378 100644 --- a/test/ChartTest.vala +++ b/test/ChartTest.vala @@ -336,6 +336,8 @@ int main (string[] args) { bool draw_selection = false; double sel_x0 = 0, sel_x1 = 0, sel_y0 = 0, sel_y1 = 0; + bool moving_chart = false; + double mov_x0 = 0, mov_y0 = 0; da.draw.connect((context) => { // user's pre draw operations here... @@ -362,8 +364,6 @@ int main (string[] args) { da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height()); da.button_press_event.connect((event) => { - // user's pre button_press_event operations here... - //stdout.puts("pre_press\n"); if (event.button == 2 && point_in_chart(chart, event.x, event.y)) { draw_selection = true; @@ -372,14 +372,16 @@ int main (string[] args) { da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height()); } - // user's post button_press_event operations here... - //stdout.puts("post_press\n"); + if (event.button == 3 && point_in_chart(chart, event.x, event.y)) { + moving_chart = true; + mov_x0 = event.x; + mov_y0 = event.y; + da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height()); + } return true; // return ret; }); da.button_release_event.connect((event) => { - // user's pre button_release_event operations here... - //stdout.puts("pre_release\n"); //var ret = chart.button_release_event(event); if (event.button == 2) { @@ -393,37 +395,38 @@ int main (string[] args) { da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height()); } - // user's post button_release_event operations here... - //stdout.puts("post_release\n"); + if (event.button == 3 && point_in_chart(chart, event.x, event.y)) { + moving_chart = false; + da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height()); + } return true; // return ret; }); da.motion_notify_event.connect((event) => { - // user's pre motion_notify_event operations here... - //stdout.puts("pre_motion\n"); //var ret = chart.motion_notify_event(event); - // user's post motion_notify_event operations here... - //stdout.puts("post_motion\n"); if (draw_selection && point_in_chart(chart, event.x, event.y)) { sel_x1 = event.x; sel_y1 = event.y; da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height()); } + if (moving_chart && point_in_chart(chart, event.x, event.y)) { + var delta_x = event.x - mov_x0, delta_y = event.y - mov_y0; + chart.move (delta_x, delta_y); + mov_x0 = event.x; + mov_y0 = event.y; + da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height()); + } + return true; // return ret; }); da.add_events(Gdk.EventMask.SCROLL_MASK); da.scroll_event.connect((event) => { - // user's pre scroll_notify_event operations here... - //stdout.puts("pre_scroll\n"); //var ret = chart.scroll_notify_event(event); - // user's post scroll_notify_event operations here... - //stdout.puts("post_scroll\n"); - return true; // return ret; });