From d67e2c26917222664bf2bd753c698c8a0de29003 Mon Sep 17 00:00:00 2001 From: Kolan Sh Date: Mon, 8 Jan 2018 23:33:13 +0300 Subject: [PATCH] In progress... Before Moscow 09.01 --- src/Axis.vala | 6 +- src/Chart.vala | 654 +++++++++++------------------- src/Color.vala | 2 +- src/Cursor.vala | 23 ++ src/Font.vala | 31 ++ src/FontStyle.vala | 27 -- src/Grid.vala | 4 +- src/Label.vala | 12 + src/LabelStyle.vala | 8 - src/Legend.vala | 198 ++++++++- src/Line.vala | 29 ++ src/LineStyle.vala | 24 -- src/Place.vala | 68 ++-- src/Point.vala | 2 +- src/Series.vala | 6 +- src/Text.vala | 20 +- src/cairo-chart-float128type.vapi | 2 +- test/ChartTest.vala | 102 ++--- 18 files changed, 623 insertions(+), 595 deletions(-) create mode 100644 src/Cursor.vala create mode 100644 src/Font.vala delete mode 100644 src/FontStyle.vala create mode 100644 src/Label.vala delete mode 100644 src/LabelStyle.vala create mode 100644 src/Line.vala delete mode 100644 src/LineStyle.vala diff --git a/src/Axis.vala b/src/Axis.vala index 6c14f7f..d906dee 100644 --- a/src/Axis.vala +++ b/src/Axis.vala @@ -1,4 +1,4 @@ -namespace Gtk.CairoChart { +namespace CairoChart { // If one of axis:title or axis:min/max are different // then draw separate axis for each/all series // or specify series name near the axis @@ -72,9 +72,9 @@ namespace Gtk.CairoChart { } default = 2; } - public FontStyle font_style = FontStyle (); + public Font.Style font_style = Font.Style (); public Color color = Color (); - public LineStyle line_style = LineStyle (); + public Line.Style line_style = Line.Style (); public double font_indent = 5; public Axis copy () { diff --git a/src/Chart.vala b/src/Chart.vala index 11f0498..0549542 100644 --- a/src/Chart.vala +++ b/src/Chart.vala @@ -1,4 +1,5 @@ -namespace Gtk.CairoChart { +namespace CairoChart { + public class Chart { public double x_min = 0.0; @@ -9,7 +10,6 @@ namespace Gtk.CairoChart { public Cairo.Context context = null; public Color bg_color; - public bool show_legend = true; public Text title = new Text ("Cairo Chart"); public Color border_color = Color(0, 0, 0, 0.3); @@ -22,12 +22,12 @@ namespace Gtk.CairoChart { bg_color = Color (1, 1, 1); } - protected double cur_x_min = 0.0; - protected double cur_x_max = 1.0; - protected double cur_y_min = 0.0; - protected double cur_y_max = 1.0; + public double cur_x_min = 0.0; + public double cur_x_max = 1.0; + public double cur_y_min = 0.0; + public double cur_y_max = 1.0; - public virtual void check_cur_values () { + protected virtual void check_cur_values () { if (cur_x_min > cur_x_max) cur_x_max = cur_x_min; if (cur_y_min > cur_y_max) @@ -48,7 +48,7 @@ namespace Gtk.CairoChart { draw_chart_title (); check_cur_values (); - draw_legend (); + legend.draw (this); check_cur_values (); set_vertical_axes_titles (); @@ -110,27 +110,27 @@ namespace Gtk.CairoChart { } if (real_x0 >= s.axis_x.zoom_min) { s.axis_x.zoom_min = real_x0; - s.place.zoom_x_low = 0.0; + s.place.zoom_x_min = 0.0; } else { - s.place.zoom_x_low = (s.axis_x.zoom_min - real_x0) / (real_x1 - real_x0); + s.place.zoom_x_min = (s.axis_x.zoom_min - real_x0) / (real_x1 - real_x0); } if (real_x1 <= s.axis_x.zoom_max) { s.axis_x.zoom_max = real_x1; - s.place.zoom_x_high = 1.0; + s.place.zoom_x_max = 1.0; } else { - s.place.zoom_x_high = (s.axis_x.zoom_max - real_x0) / (real_x1 - real_x0); + s.place.zoom_x_max = (s.axis_x.zoom_max - real_x0) / (real_x1 - real_x0); } if (real_y1 >= s.axis_y.zoom_min) { s.axis_y.zoom_min = real_y1; - s.place.zoom_y_low = 0.0; + s.place.zoom_y_min = 0.0; } else { - s.place.zoom_y_low = (s.axis_y.zoom_min - real_y1) / (real_y0 - real_y1); + s.place.zoom_y_min = (s.axis_y.zoom_min - real_y1) / (real_y0 - real_y1); } if (real_y0 <= s.axis_y.zoom_max) { s.axis_y.zoom_max = real_y0; - s.place.zoom_y_high = 1.0; + s.place.zoom_y_max = 1.0; } else { - s.place.zoom_y_high = (s.axis_y.zoom_max - real_y1) / (real_y0 - real_y1); + s.place.zoom_y_max = (s.axis_y.zoom_max - real_y1) / (real_y0 - real_y1); } } @@ -141,10 +141,10 @@ namespace Gtk.CairoChart { break; } - 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); + var new_rel_zoom_x_min = rel_zoom_x_min + (x0 - plot_x_min) / (plot_x_max - plot_x_min) * (rel_zoom_x_max - rel_zoom_x_min); + var new_rel_zoom_x_max = rel_zoom_x_min + (x1 - plot_x_min) / (plot_x_max - plot_x_min) * (rel_zoom_x_max - rel_zoom_x_min); + var new_rel_zoom_y_min = rel_zoom_y_min + (y0 - plot_y_min) / (plot_y_max - plot_y_min) * (rel_zoom_y_max - rel_zoom_y_min); + var new_rel_zoom_y_max = rel_zoom_y_min + (y1 - plot_y_min) / (plot_y_max - plot_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; @@ -158,10 +158,10 @@ namespace Gtk.CairoChart { s.axis_x.zoom_max = s.axis_x.max; s.axis_y.zoom_min = s.axis_y.min; s.axis_y.zoom_max = s.axis_y.max; - s.place.zoom_x_low = s.place.x_low; - s.place.zoom_x_high = s.place.x_high; - s.place.zoom_y_low = s.place.y_low; - s.place.zoom_y_high = s.place.y_high; + s.place.zoom_x_min = s.place.x_min; + s.place.zoom_x_max = s.place.x_max; + s.place.zoom_y_min = s.place.y_min; + s.place.zoom_y_max = s.place.y_max; } rel_zoom_x_min = 0; rel_zoom_x_max = 1; @@ -172,40 +172,40 @@ namespace Gtk.CairoChart { } 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; + delta_x /= plot_x_max - plot_x_min; delta_x *= - 1.0; + delta_y /= plot_y_max - plot_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 *= plot_x_max - plot_x_min; + delta_y *= plot_y_max - plot_y_min; + var xmin = plot_x_min + (plot_x_max - plot_x_min) * rzxmin; + var xmax = plot_x_min + (plot_x_max - plot_x_min) * rzxmax; + var ymin = plot_y_min + (plot_y_max - plot_y_min) * rzymin; + var ymax = plot_y_min + (plot_y_max - plot_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; + if (xmin + delta_x < plot_x_min) delta_x = plot_x_min - xmin; + if (xmax + delta_x > plot_x_max) delta_x = plot_x_max - xmax; + if (ymin + delta_y < plot_y_min) delta_y = plot_y_min - ymin; + if (ymax + delta_y > plot_y_max) delta_y = plot_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; - protected double title_height = 0.0; + public double title_width { get; protected set; default = 0.0; } + public double title_height { get; protected set; default = 0.0; } - public double title_vindent = 4; + public double title_indent = 4; - protected virtual void show_text(Text text) { + public virtual void show_text(Text text) { context.select_font_face(text.style.family, text.style.slant, text.style.weight); context.set_font_size(text.style.size); - if (text.style.orientation == FontOrient.VERTICAL) { + if (text.style.orientation == Font.Orientation.VERTICAL) { context.rotate(- Math.PI / 2.0); context.show_text(text.text); context.rotate(Math.PI / 2.0); @@ -215,73 +215,25 @@ namespace Gtk.CairoChart { } protected virtual void draw_chart_title () { - var sz = title.size(context); - title_height = sz.height + (legend.position == Legend.Position.TOP ? title_vindent * 2 : title_vindent); + var sz = title.get_size(context); + title_height = sz.height + (legend.position == Legend.Position.TOP ? title_indent * 2 : title_indent); cur_y_min += title_height; set_source_rgba(title.color); - context.move_to (width/2 - sz.width/2, sz.height + title_vindent); + context.move_to (width/2 - sz.width/2, sz.height + title_indent); show_text(title); } - protected double legend_width = 0; - protected double legend_height = 0; - - protected enum LegendProcessType { - CALC = 0, // default - DRAW - } - - protected virtual void set_line_style (LineStyle style) { + public virtual void set_line_style (Line.Style style) { set_source_rgba(style.color); - context.set_line_join(style.line_join); - context.set_line_cap(style.line_cap); + context.set_line_join(style.join); + context.set_line_cap(style.cap); context.set_line_width(style.width); context.set_dash(style.dashes, style.dash_offset); } - protected virtual void draw_legend_rect (out double x0, out double y0) { - x0 = y0 = 0.0; - if (context != null) { - switch (legend.position) { - case Legend.Position.TOP: - x0 = (width - legend_width) / 2; - y0 = title_height; - break; - - case Legend.Position.BOTTOM: - x0 = (width - legend_width) / 2; - y0 = height - legend_height; - break; - - case Legend.Position.LEFT: - x0 = 0; - y0 = (height - legend_height) / 2; - break; - - case Legend.Position.RIGHT: - x0 = width - legend_width; - y0 = (height - legend_height) / 2; - break; - } - set_source_rgba(legend.bg_color); - context.rectangle (x0, y0, legend_width, legend_height); - context.fill(); - set_line_style(legend.border_style); - context.move_to (x0, y0); - context.rel_line_to (legend_width, 0); - context.rel_line_to (0, legend_height); - context.rel_line_to (-legend_width, 0); - context.rel_line_to (0, -legend_height); - context.stroke (); - } - } - - public double legend_line_length = 30.0; - public double legend_text_hspace = 10.0; - public double legend_text_vspace = 2.0; public double marker_size = 8.0; - protected virtual void draw_marker_at_pos (Series.MarkerType marker_type, + public virtual void draw_marker_at_pos (Series.MarkerType marker_type, double x, double y) { context.move_to (x, y); switch (marker_type) { @@ -325,141 +277,7 @@ namespace Gtk.CairoChart { } } - double [] max_font_heights; - protected virtual void process_legend (LegendProcessType process_type) { - var legend_x0 = 0.0, legend_y0 = 0.0; - var heights_idx = 0; - var leg_width_sum = 0.0; - var leg_height_sum = 0.0; - double max_font_h = 0.0; - - // prepare - switch (process_type) { - case LegendProcessType.CALC: - legend_width = 0.0; - legend_height = 0.0; - max_font_heights = {}; - heights_idx = 0; - break; - case LegendProcessType.DRAW: - draw_legend_rect(out legend_x0, out legend_y0); - break; - } - - foreach (var s in series) { - - if (!s.zoom_show) continue; - - var title_sz = s.title.size(context); - - // carry - switch (legend.position) { - case Legend.Position.TOP: - case Legend.Position.BOTTOM: - var ser_title_width = title_sz.width + legend_line_length; - if (leg_width_sum + (leg_width_sum == 0 ? 0 : legend_text_hspace) + ser_title_width > width) { // carry - leg_height_sum += max_font_h; - switch (process_type) { - case LegendProcessType.CALC: - max_font_heights += max_font_h; - legend_width = double.max(legend_width, leg_width_sum); - break; - case LegendProcessType.DRAW: - heights_idx++; - break; - } - leg_width_sum = 0.0; - max_font_h = 0; - } - break; - } - - switch (process_type) { - case LegendProcessType.DRAW: - var x = legend_x0 + leg_width_sum + (leg_width_sum == 0.0 ? 0.0 : legend_text_hspace); - var y = legend_y0 + leg_height_sum + max_font_heights[heights_idx]; - - // series title - context.move_to (x + legend_line_length, y); - set_source_rgba (s.title.color); - show_text(s.title); - - // series line style - context.move_to (x, y - title_sz.height / 2); - set_line_style(s.line_style); - context.rel_line_to (legend_line_length, 0); - context.stroke(); - draw_marker_at_pos (s.marker_type, x + legend_line_length / 2, y - title_sz.height / 2); - break; - } - - switch (legend.position) { - case Legend.Position.TOP: - case Legend.Position.BOTTOM: - var ser_title_width = title_sz.width + legend_line_length; - leg_width_sum += (leg_width_sum == 0 ? 0 : legend_text_hspace) + ser_title_width; - max_font_h = double.max (max_font_h, title_sz.height) + (leg_height_sum != 0 ? legend_text_vspace : 0); - break; - - case Legend.Position.LEFT: - case Legend.Position.RIGHT: - switch (process_type) { - case LegendProcessType.CALC: - max_font_heights += title_sz.height + (leg_height_sum != 0 ? legend_text_vspace : 0); - legend_width = double.max (legend_width, title_sz.width + legend_line_length); - break; - case LegendProcessType.DRAW: - heights_idx++; - break; - } - leg_height_sum += title_sz.height + (leg_height_sum != 0 ? legend_text_vspace : 0); - break; - } - } - - // TOP, BOTTOM - switch (legend.position) { - case Legend.Position.TOP: - case Legend.Position.BOTTOM: - if (leg_width_sum != 0) { - leg_height_sum += max_font_h; - switch (process_type) { - case LegendProcessType.CALC: - max_font_heights += max_font_h; - legend_width = double.max(legend_width, leg_width_sum); - break; - } - } - break; - } - - switch (process_type) { - case LegendProcessType.CALC: - legend_height = leg_height_sum; - switch (legend.position) { - case Legend.Position.TOP: - cur_y_min += legend_height; - break; - case Legend.Position.BOTTOM: - cur_y_max -= legend_height; - break; - case Legend.Position.LEFT: - cur_x_min += legend_width; - break; - case Legend.Position.RIGHT: - cur_x_max -= legend_width; - break; - } - break; - } - } - - protected virtual void draw_legend () { - process_legend (LegendProcessType.CALC); - process_legend (LegendProcessType.DRAW); - } - - public LineStyle selection_style = LineStyle (); + public Line.Style selection_style = Line.Style (); public virtual void draw_selection (double x0, double y0, double x1, double y1) { set_line_style (selection_style); @@ -476,7 +294,7 @@ namespace Gtk.CairoChart { switch (axis.type) { case Axis.Type.NUMBERS: var text = new Text (axis.format.printf((LongDouble)x) + (is_horizontal ? "_" : ""), axis.font_style); - var sz = text.size(context); + var sz = text.get_size(context); max_rec_width = double.max (max_rec_width, sz.width); max_rec_height = double.max (max_rec_height, sz.height); break; @@ -487,13 +305,13 @@ namespace Gtk.CairoChart { var h = 0.0; if (axis.date_format != "") { var text = new Text (date + (is_horizontal ? "_" : ""), axis.font_style); - var sz = text.size(context); + var sz = text.get_size(context); max_rec_width = double.max (max_rec_width, sz.width); h = sz.height; } if (axis.time_format != "") { var text = new Text (time + (is_horizontal ? "_" : ""), axis.font_style); - var sz = text.size(context); + var sz = text.get_size(context); max_rec_width = double.max (max_rec_width, sz.width); h += sz.height; } @@ -522,14 +340,14 @@ namespace Gtk.CairoChart { return step; } - public double plot_area_x_min = 0; - public double plot_area_x_max = 0; - public double plot_area_y_min = 0; - public double plot_area_y_max = 0; + public double plot_x_min = 0; + public double plot_x_max = 0; + public double plot_y_min = 0; + public double plot_y_max = 0; - public bool common_x_axes { get; protected set; default = false; } - public bool common_y_axes { get; protected set; default = false; } - public Color common_axis_color = Color (0, 0, 0, 1); + public bool joint_x { get; protected set; default = false; } + public bool joint_y { get; protected set; default = false; } + public Color joint_axis_color = Color (0, 0, 0, 1); bool are_intersect (double a_min, double a_max, double b_min, double b_max) { if ( a_min < a_max <= b_min < b_max @@ -541,18 +359,18 @@ namespace Gtk.CairoChart { protected virtual void set_vertical_axes_titles () { for (var si = 0; si < series.length; ++si) { var s = series[si]; - s.axis_y.title.style.orientation = FontOrient.VERTICAL; + s.axis_y.title.style.orientation = Font.Orientation.VERTICAL; } } protected virtual void calc_plot_area () { - plot_area_x_min = cur_x_min + legend.indent; - plot_area_x_max = cur_x_max - legend.indent; - plot_area_y_min = cur_y_min + legend.indent; - plot_area_y_max = cur_y_max - legend.indent; + plot_x_min = cur_x_min + legend.indent; + plot_x_max = cur_x_max - legend.indent; + plot_y_min = cur_y_min + legend.indent; + plot_y_max = cur_y_max - legend.indent; - // Check for common axes - common_x_axes = common_y_axes = true; + // Check for joint axes + joint_x = joint_y = true; int nzoom_series_show = 0; for (var si = series.length - 1; si >=0; --si) { var s = series[si]; @@ -561,18 +379,18 @@ namespace Gtk.CairoChart { if ( s.axis_x.position != series[0].axis_x.position || s.axis_x.zoom_min != series[0].axis_x.zoom_min || s.axis_x.zoom_max != series[0].axis_x.zoom_max - || s.place.zoom_x_low != series[0].place.zoom_x_low - || s.place.zoom_x_high != series[0].place.zoom_x_high + || s.place.zoom_x_min != series[0].place.zoom_x_min + || s.place.zoom_x_max != series[0].place.zoom_x_max || s.axis_x.type != series[0].axis_x.type) - common_x_axes = false; + joint_x = false; if ( s.axis_y.position != series[0].axis_y.position || s.axis_y.zoom_min != series[0].axis_y.zoom_min || s.axis_y.zoom_max != series[0].axis_y.zoom_max - || s.place.zoom_y_low != series[0].place.zoom_y_low - || s.place.zoom_y_high != series[0].place.zoom_y_high) - common_y_axes = false; + || s.place.zoom_y_min != series[0].place.zoom_y_min + || s.place.zoom_y_max != series[0].place.zoom_y_max) + joint_y = false; } - if (nzoom_series_show == 1) common_x_axes = common_y_axes = false; + if (nzoom_series_show == 1) joint_x = joint_y = false; // Join and calc X-axes for (var si = series.length - 1, nskip = 0; si >=0; --si) { @@ -592,7 +410,7 @@ namespace Gtk.CairoChart { for (int sk = si; sk > sj; --sk) { var s3 = series[sk]; if (!s3.zoom_show) continue; - if (are_intersect(s2.place.zoom_x_low, s2.place.zoom_x_high, s3.place.zoom_x_low, s3.place.zoom_x_high) + if (are_intersect(s2.place.zoom_x_min, s2.place.zoom_x_max, s3.place.zoom_x_min, s3.place.zoom_x_max) || s2.axis_x.position != s3.axis_x.position || s2.axis_x.type != s3.axis_x.type) { has_intersection = true; @@ -613,18 +431,18 @@ namespace Gtk.CairoChart { } } - // for 4.2. Cursor values for common X axis - if (common_x_axes && si == zoom_first_show && cursors_orientation == CursorOrientation.VERTICAL && cursors_crossings.length != 0) { + // for 4.2. Cursor values for joint X axis + if (joint_x && si == zoom_first_show && cursor_style.orientation == Cursor.Orientation.VERTICAL && cursors_crossings.length != 0) { switch (s.axis_x.position) { - case Axis.Position.LOW: plot_area_y_max -= max_rec_height + s.axis_x.font_indent; break; - case Axis.Position.HIGH: plot_area_y_min += max_rec_height + s.axis_x.font_indent; break; + case Axis.Position.LOW: plot_y_max -= max_rec_height + s.axis_x.font_indent; break; + case Axis.Position.HIGH: plot_y_min += max_rec_height + s.axis_x.font_indent; break; } } - if (!common_x_axes || si == zoom_first_show) + if (!joint_x || si == zoom_first_show) switch (s.axis_x.position) { - case Axis.Position.LOW: plot_area_y_max -= max_rec_height + max_font_indent + max_axis_font_height; break; - case Axis.Position.HIGH: plot_area_y_min += max_rec_height + max_font_indent + max_axis_font_height; break; + case Axis.Position.LOW: plot_y_max -= max_rec_height + max_font_indent + max_axis_font_height; break; + case Axis.Position.HIGH: plot_y_min += max_rec_height + max_font_indent + max_axis_font_height; break; } } @@ -646,7 +464,7 @@ namespace Gtk.CairoChart { for (int sk = si; sk > sj; --sk) { var s3 = series[sk]; if (!s3.zoom_show) continue; - if (are_intersect(s2.place.zoom_y_low, s2.place.zoom_y_high, s3.place.zoom_y_low, s3.place.zoom_y_high) + if (are_intersect(s2.place.zoom_y_min, s2.place.zoom_y_max, s3.place.zoom_y_min, s3.place.zoom_y_max) || s2.axis_y.position != s3.axis_y.position || s2.axis_x.type != s3.axis_x.type) { has_intersection = true; @@ -667,18 +485,18 @@ namespace Gtk.CairoChart { } } - // for 4.2. Cursor values for common Y axis - if (common_y_axes && si == zoom_first_show && cursors_orientation == CursorOrientation.HORIZONTAL && cursors_crossings.length != 0) { + // for 4.2. Cursor values for joint Y axis + if (joint_y && si == zoom_first_show && cursor_style.orientation == Cursor.Orientation.HORIZONTAL && cursors_crossings.length != 0) { switch (s.axis_y.position) { - case Axis.Position.LOW: plot_area_x_min += max_rec_width + s.axis_y.font_indent; break; - case Axis.Position.HIGH: plot_area_x_max -= max_rec_width + s.axis_y.font_indent; break; + case Axis.Position.LOW: plot_x_min += max_rec_width + s.axis_y.font_indent; break; + case Axis.Position.HIGH: plot_x_max -= max_rec_width + s.axis_y.font_indent; break; } } - if (!common_y_axes || si == zoom_first_show) + if (!joint_y || si == zoom_first_show) switch (s.axis_y.position) { - case Axis.Position.LOW: plot_area_x_min += max_rec_width + max_font_indent + max_axis_font_width; break; - case Axis.Position.HIGH: plot_area_x_max -= max_rec_width + max_font_indent + max_axis_font_width; break; + case Axis.Position.LOW: plot_x_min += max_rec_width + max_font_indent + max_axis_font_width; break; + case Axis.Position.HIGH: plot_x_max -= max_rec_width + max_font_indent + max_axis_font_width; break; } } } @@ -690,13 +508,13 @@ namespace Gtk.CairoChart { } protected virtual double compact_rec_x_pos (Series s, Float128 x, Text text) { - var sz = text.size(context); + var sz = text.get_size(context); return get_scr_x(s, x) - sz.width / 2.0 - sz.width * (x - (s.axis_x.zoom_min + s.axis_x.zoom_max) / 2.0) / (s.axis_x.zoom_max - s.axis_x.zoom_min); } protected virtual double compact_rec_y_pos (Series s, Float128 y, Text text) { - var sz = text.size(context); + var sz = text.get_size(context); return get_scr_y(s, y) + sz.height / 2.0 + sz.height * (y - (s.axis_y.zoom_min + s.axis_y.zoom_max) / 2.0) / (s.axis_y.zoom_max - s.axis_y.zoom_min); } @@ -714,14 +532,14 @@ namespace Gtk.CairoChart { for (var si = series.length - 1, nskip = 0; si >=0; --si) { var s = series[si]; if (!s.zoom_show) continue; - if (common_x_axes && si != zoom_first_show) continue; + if (joint_x && si != zoom_first_show) continue; // 1. Detect max record width/height by axis_rec_npoints equally selected points using format. double max_rec_width, max_rec_height; calc_axis_rec_sizes (s.axis_x, out max_rec_width, out max_rec_height, true); // 2. Calculate maximal available number of records, take into account the space width. - long max_nrecs = (long) ((plot_area_x_max - plot_area_x_min) * (s.place.zoom_x_high - s.place.zoom_x_low) / max_rec_width); + long max_nrecs = (long) ((plot_x_max - plot_x_min) * (s.place.zoom_x_max - s.place.zoom_x_min) / max_rec_width); // 3. Calculate grid step. Float128 step = calc_round_step ((s.axis_x.zoom_max - s.axis_x.zoom_min) / max_nrecs, s.axis_x.type == Axis.Type.DATE_TIME); @@ -740,19 +558,19 @@ namespace Gtk.CairoChart { } if (x_min < s.axis_x.zoom_min) x_min += step; - // 4.2. Cursor values for common X axis - if (common_x_axes && cursors_orientation == CursorOrientation.VERTICAL && cursors_crossings.length != 0) { + // 4.2. Cursor values for joint X axis + if (joint_x && cursor_style.orientation == Cursor.Orientation.VERTICAL && cursors_crossings.length != 0) { switch (s.axis_x.position) { case Axis.Position.LOW: cur_y_max -= max_rec_height + s.axis_x.font_indent; break; case Axis.Position.HIGH: cur_y_min += max_rec_height + s.axis_x.font_indent; break; } } - var sz = s.axis_x.title.size(context); + var sz = s.axis_x.title.get_size(context); // 4.5. Draw Axis title if (s.axis_x.title.text != "") { - var scr_x = plot_area_x_min + (plot_area_x_max - plot_area_x_min) * (s.place.zoom_x_low + s.place.zoom_x_high) / 2.0; + var scr_x = plot_x_min + (plot_x_max - plot_x_min) * (s.place.zoom_x_min + s.place.zoom_x_max) / 2.0; double scr_y = 0.0; switch (s.axis_x.position) { case Axis.Position.LOW: scr_y = cur_y_max - s.axis_x.font_indent; break; @@ -760,13 +578,13 @@ namespace Gtk.CairoChart { } context.move_to(scr_x - sz.width / 2.0, scr_y); set_source_rgba(s.axis_x.color); - if (common_x_axes) set_source_rgba(common_axis_color); + if (joint_x) set_source_rgba(joint_axis_color); show_text(s.axis_x.title); } // 5. Draw records, update cur_{x,y}_{min,max}. for (Float128 x = x_min, x_max = s.axis_x.zoom_max; point_belong (x, x_min, x_max); x += step) { - if (common_x_axes) set_source_rgba(common_axis_color); + if (joint_x) set_source_rgba(joint_axis_color); else set_source_rgba(s.axis_x.color); string text = "", time_text = ""; switch (s.axis_x.type) { @@ -796,16 +614,16 @@ namespace Gtk.CairoChart { if (s.axis_x.time_format != "") show_text(time_text_t); break; } - // 6. Draw grid lines to the s.place.zoom_y_low. + // 6. Draw grid lines to the s.place.zoom_y_min. var line_style = s.grid.line_style; - if (common_x_axes) line_style.color = Color(0, 0, 0, 0.5); + if (joint_x) line_style.color = Color(0, 0, 0, 0.5); set_line_style(line_style); double y = cur_y_max - max_rec_height - s.axis_x.font_indent - (s.axis_x.title.text == "" ? 0 : sz.height + s.axis_x.font_indent); context.move_to (scr_x, y); - if (common_x_axes) - context.line_to (scr_x, plot_area_y_min); + if (joint_x) + context.line_to (scr_x, plot_y_min); else - context.line_to (scr_x, double.min (y, plot_area_y_max - (plot_area_y_max - plot_area_y_min) * s.place.zoom_y_high)); + context.line_to (scr_x, double.min (y, plot_y_max - (plot_y_max - plot_y_min) * s.place.zoom_y_max)); break; case Axis.Position.HIGH: var print_y = cur_y_min + max_rec_height + s.axis_x.font_indent + (s.axis_x.title.text == "" ? 0 : sz.height + s.axis_x.font_indent); @@ -824,16 +642,16 @@ namespace Gtk.CairoChart { if (s.axis_x.time_format != "") show_text(time_text_t); break; } - // 6. Draw grid lines to the s.place.zoom_y_high. + // 6. Draw grid lines to the s.place.zoom_y_max. var line_style = s.grid.line_style; - if (common_x_axes) line_style.color = Color(0, 0, 0, 0.5); + if (joint_x) line_style.color = Color(0, 0, 0, 0.5); set_line_style(line_style); double y = cur_y_min + max_rec_height + s.axis_x.font_indent + (s.axis_x.title.text == "" ? 0 : sz.height + s.axis_x.font_indent); context.move_to (scr_x, y); - if (common_x_axes) - context.line_to (scr_x, plot_area_y_max); + if (joint_x) + context.line_to (scr_x, plot_y_max); else - context.line_to (scr_x, double.max (y, plot_area_y_max - (plot_area_y_max - plot_area_y_min) * s.place.zoom_y_low)); + context.line_to (scr_x, double.max (y, plot_y_max - (plot_y_max - plot_y_min) * s.place.zoom_y_min)); break; } } @@ -847,7 +665,7 @@ namespace Gtk.CairoChart { for (int sk = si; sk > sj; --sk) { var s3 = series[sk]; if (!s3.zoom_show) continue; - if (are_intersect(s2.place.zoom_x_low, s2.place.zoom_x_high, s3.place.zoom_x_low, s3.place.zoom_x_high) + if (are_intersect(s2.place.zoom_x_min, s2.place.zoom_x_max, s3.place.zoom_x_min, s3.place.zoom_x_max) || s2.axis_x.position != s3.axis_x.position || s2.axis_x.type != s3.axis_x.type) { has_intersection = true; @@ -880,13 +698,13 @@ namespace Gtk.CairoChart { for (var si = series.length - 1, nskip = 0; si >=0; --si) { var s = series[si]; if (!s.zoom_show) continue; - if (common_y_axes && si != zoom_first_show) continue; + if (joint_y && si != zoom_first_show) continue; // 1. Detect max record width/height by axis_rec_npoints equally selected points using format. double max_rec_width, max_rec_height; calc_axis_rec_sizes (s.axis_y, out max_rec_width, out max_rec_height, false); // 2. Calculate maximal available number of records, take into account the space width. - long max_nrecs = (long) ((plot_area_y_max - plot_area_y_min) * (s.place.zoom_y_high - s.place.zoom_y_low) / max_rec_height); + long max_nrecs = (long) ((plot_y_max - plot_y_min) * (s.place.zoom_y_max - s.place.zoom_y_min) / max_rec_height); // 3. Calculate grid step. Float128 step = calc_round_step ((s.axis_y.zoom_max - s.axis_y.zoom_min) / max_nrecs); @@ -905,19 +723,19 @@ namespace Gtk.CairoChart { } if (y_min < s.axis_y.zoom_min) y_min += step; - // 4.2. Cursor values for common Y axis - if (common_y_axes && cursors_orientation == CursorOrientation.HORIZONTAL && cursors_crossings.length != 0) { + // 4.2. Cursor values for joint Y axis + if (joint_y && cursor_style.orientation == Cursor.Orientation.HORIZONTAL && cursors_crossings.length != 0) { switch (s.axis_y.position) { case Axis.Position.LOW: cur_x_min += max_rec_width + s.axis_y.font_indent; break; case Axis.Position.HIGH: cur_x_max -= max_rec_width + s.axis_y.font_indent; break; } } - var sz = s.axis_y.title.size(context); + var sz = s.axis_y.title.get_size(context); // 4.5. Draw Axis title if (s.axis_y.title.text != "") { - var scr_y = plot_area_y_max - (plot_area_y_max - plot_area_y_min) * (s.place.zoom_y_low + s.place.zoom_y_high) / 2.0; + var scr_y = plot_y_max - (plot_y_max - plot_y_min) * (s.place.zoom_y_min + s.place.zoom_y_max) / 2.0; switch (s.axis_y.position) { case Axis.Position.LOW: var scr_x = cur_x_min + s.axis_y.font_indent + sz.width; @@ -929,50 +747,50 @@ namespace Gtk.CairoChart { break; } set_source_rgba(s.axis_y.color); - if (common_y_axes) set_source_rgba(common_axis_color); + if (joint_y) set_source_rgba(joint_axis_color); show_text(s.axis_y.title); } // 5. Draw records, update cur_{x,y}_{min,max}. for (Float128 y = y_min, y_max = s.axis_y.zoom_max; point_belong (y, y_min, y_max); y += step) { - if (common_y_axes) set_source_rgba(common_axis_color); + if (joint_y) set_source_rgba(joint_axis_color); else set_source_rgba(s.axis_y.color); var text = s.axis_y.format.printf((LongDouble)y); var scr_y = get_scr_y (s, y); var text_t = new Text(text, s.axis_y.font_style, s.axis_y.color); - var text_sz = text_t.size(context); + var text_sz = text_t.get_size(context); switch (s.axis_y.position) { case Axis.Position.LOW: context.move_to (cur_x_min + max_rec_width - text_sz.width + s.axis_y.font_indent + (s.axis_y.title.text == "" ? 0 : sz.width + s.axis_y.font_indent), compact_rec_y_pos (s, y, text_t)); show_text(text_t); - // 6. Draw grid lines to the s.place.zoom_x_low. + // 6. Draw grid lines to the s.place.zoom_x_min. var line_style = s.grid.line_style; - if (common_y_axes) line_style.color = Color(0, 0, 0, 0.5); + if (joint_y) line_style.color = Color(0, 0, 0, 0.5); set_line_style(line_style); double x = cur_x_min + max_rec_width + s.axis_y.font_indent + (s.axis_y.title.text == "" ? 0 : sz.width + s.axis_y.font_indent); context.move_to (x, scr_y); - if (common_y_axes) - context.line_to (plot_area_x_max, scr_y); + if (joint_y) + context.line_to (plot_x_max, scr_y); else - context.line_to (double.max (x, plot_area_x_min + (plot_area_x_max - plot_area_x_min) * s.place.zoom_x_high), scr_y); + context.line_to (double.max (x, plot_x_min + (plot_x_max - plot_x_min) * s.place.zoom_x_max), scr_y); break; case Axis.Position.HIGH: context.move_to (cur_x_max - text_sz.width - s.axis_y.font_indent - (s.axis_y.title.text == "" ? 0 : sz.width + s.axis_y.font_indent), compact_rec_y_pos (s, y, text_t)); show_text(text_t); - // 6. Draw grid lines to the s.place.zoom_x_high. + // 6. Draw grid lines to the s.place.zoom_x_max. var line_style = s.grid.line_style; - if (common_y_axes) line_style.color = Color(0, 0, 0, 0.5); + if (joint_y) line_style.color = Color(0, 0, 0, 0.5); set_line_style(line_style); double x = cur_x_max - max_rec_width - s.axis_y.font_indent - (s.axis_y.title.text == "" ? 0 : sz.width + s.axis_y.font_indent); context.move_to (x, scr_y); - if (common_y_axes) - context.line_to (plot_area_x_min, scr_y); + if (joint_y) + context.line_to (plot_x_min, scr_y); else - context.line_to (double.min (x, plot_area_x_min + (plot_area_x_max - plot_area_x_min) * s.place.zoom_x_low), scr_y); + context.line_to (double.min (x, plot_x_min + (plot_x_max - plot_x_min) * s.place.zoom_x_min), scr_y); break; } } @@ -986,7 +804,7 @@ namespace Gtk.CairoChart { for (int sk = si; sk > sj; --sk) { var s3 = series[sk]; if (!s3.zoom_show) continue; - if (are_intersect(s2.place.zoom_y_low, s2.place.zoom_y_high, s3.place.zoom_y_low, s3.place.zoom_y_high) + if (are_intersect(s2.place.zoom_y_min, s2.place.zoom_y_max, s3.place.zoom_y_min, s3.place.zoom_y_max) || s2.axis_y.position != s3.axis_y.position) { has_intersection = true; break; @@ -1015,34 +833,34 @@ namespace Gtk.CairoChart { protected virtual void draw_plot_area_border () { set_source_rgba (border_color); context.set_dash(null, 0); - context.move_to (plot_area_x_min, plot_area_y_min); - context.line_to (plot_area_x_min, plot_area_y_max); - context.line_to (plot_area_x_max, plot_area_y_max); - context.line_to (plot_area_x_max, plot_area_y_min); - context.line_to (plot_area_x_min, plot_area_y_min); + context.move_to (plot_x_min, plot_y_min); + context.line_to (plot_x_min, plot_y_max); + context.line_to (plot_x_max, plot_y_max); + context.line_to (plot_x_max, plot_y_min); + context.line_to (plot_x_min, plot_y_min); context.stroke (); } protected virtual double get_scr_x (Series s, Float128 x) { - return plot_area_x_min + (plot_area_x_max - plot_area_x_min) * (s.place.zoom_x_low + (x - s.axis_x.zoom_min) - / (s.axis_x.zoom_max - s.axis_x.zoom_min) * (s.place.zoom_x_high - s.place.zoom_x_low)); + return plot_x_min + (plot_x_max - plot_x_min) * (s.place.zoom_x_min + (x - s.axis_x.zoom_min) + / (s.axis_x.zoom_max - s.axis_x.zoom_min) * (s.place.zoom_x_max - s.place.zoom_x_min)); } protected virtual double get_scr_y (Series s, Float128 y) { - return plot_area_y_max - (plot_area_y_max - plot_area_y_min) * (s.place.zoom_y_low + (y - s.axis_y.zoom_min) - / (s.axis_y.zoom_max - s.axis_y.zoom_min) * (s.place.zoom_y_high - s.place.zoom_y_low)); + return plot_y_max - (plot_y_max - plot_y_min) * (s.place.zoom_y_min + (y - s.axis_y.zoom_min) + / (s.axis_y.zoom_max - s.axis_y.zoom_min) * (s.place.zoom_y_max - s.place.zoom_y_min)); } protected virtual Point get_scr_point (Series s, Point p) { return Point (get_scr_x(s, p.x), get_scr_y(s, p.y)); } protected virtual Float128 get_real_x (Series s, double scr_x) { - return s.axis_x.zoom_min + ((scr_x - plot_area_x_min) / (plot_area_x_max - plot_area_x_min) - s.place.zoom_x_low) - * (s.axis_x.zoom_max - s.axis_x.zoom_min) / (s.place.zoom_x_high - s.place.zoom_x_low); + return s.axis_x.zoom_min + ((scr_x - plot_x_min) / (plot_x_max - plot_x_min) - s.place.zoom_x_min) + * (s.axis_x.zoom_max - s.axis_x.zoom_min) / (s.place.zoom_x_max - s.place.zoom_x_min); } protected virtual Float128 get_real_y (Series s, double scr_y) { - return s.axis_y.zoom_min + ((plot_area_y_max - scr_y) / (plot_area_y_max - plot_area_y_min) - s.place.zoom_y_low) - * (s.axis_y.zoom_max - s.axis_y.zoom_min) / (s.place.zoom_y_high - s.place.zoom_y_low); + return s.axis_y.zoom_min + ((plot_y_max - scr_y) / (plot_y_max - plot_y_min) - s.place.zoom_y_min) + * (s.axis_y.zoom_max - s.axis_y.zoom_min) / (s.place.zoom_y_max - s.place.zoom_y_min); } protected virtual Point get_real_point (Series s, Point p) { return Point (get_real_x(s, p.x), get_real_y(s, p.y)); @@ -1061,13 +879,13 @@ namespace Gtk.CairoChart { } protected virtual bool x_in_plot_area (double x) { - if (x_in_range(x, plot_area_x_min, plot_area_x_max)) + if (x_in_range(x, plot_x_min, plot_x_max)) return true; return false; } protected virtual bool y_in_plot_area (double y) { - if (y_in_range(y, plot_area_y_min, plot_area_y_max)) + if (y_in_range(y, plot_y_min, plot_y_max)) return true; return false; } @@ -1079,7 +897,7 @@ namespace Gtk.CairoChart { } protected virtual bool point_in_plot_area (Point p) { - if (point_in_rect (p, plot_area_x_min, plot_area_x_max, plot_area_y_min, plot_area_y_max)) + if (point_in_rect (p, plot_x_min, plot_x_max, plot_y_min, plot_y_max)) return true; return false; } @@ -1121,14 +939,14 @@ namespace Gtk.CairoChart { int ncross = 0; Float128 x = 0, y = 0; Point pc[4]; - if (hcross(a, b, plot_area_x_min, plot_area_x_max, plot_area_y_min, out x)) - pc[ncross++] = Point(x, plot_area_y_min); - if (hcross(a, b, plot_area_x_min, plot_area_x_max, plot_area_y_max, out x)) - pc[ncross++] = Point(x, plot_area_y_max); - if (vcross(a, b, plot_area_x_min, plot_area_y_min, plot_area_y_max, out y)) - pc[ncross++] = Point(plot_area_x_min, y); - if (vcross(a, b, plot_area_x_max, plot_area_y_min, plot_area_y_max, out y)) - pc[ncross++] = Point(plot_area_x_max, y); + if (hcross(a, b, plot_x_min, plot_x_max, plot_y_min, out x)) + pc[ncross++] = Point(x, plot_y_min); + if (hcross(a, b, plot_x_min, plot_x_max, plot_y_max, out x)) + pc[ncross++] = Point(x, plot_y_max); + if (vcross(a, b, plot_x_min, plot_y_min, plot_y_max, out y)) + pc[ncross++] = Point(plot_x_min, y); + if (vcross(a, b, plot_x_max, plot_y_min, plot_y_max, out y)) + pc[ncross++] = Point(plot_x_max, y); c = a; d = b; if (ncross == 0) { @@ -1216,14 +1034,7 @@ namespace Gtk.CairoChart { is_cursor_active = false; } - public enum CursorOrientation { - VERTICAL = 0, // default - HORIZONTAL - } - - public CursorOrientation cursors_orientation = CursorOrientation.VERTICAL; - - public double cursor_max_rm_distance = 32; + public Cursor.Style cursor_style = Cursor.Style(); public virtual void remove_active_cursor () { if (cursors.length() == 0) return; @@ -1232,11 +1043,11 @@ namespace Gtk.CairoChart { uint i = 0; foreach (var c in cursors) { double d = distance; - switch (cursors_orientation) { - case CursorOrientation.VERTICAL: + switch (cursor_style.orientation) { + case Cursor.Orientation.VERTICAL: d = (rel2scr_x(c.x) - rel2scr_x(active_cursor.x)).abs(); break; - case CursorOrientation.HORIZONTAL: + case Cursor.Orientation.HORIZONTAL: d = (rel2scr_y(c.y) - rel2scr_y(active_cursor.y)).abs(); break; } @@ -1246,35 +1057,33 @@ namespace Gtk.CairoChart { } ++i; } - if (distance < cursor_max_rm_distance) + if (distance < cursor_style.select_distance) cursors.delete_link(cursors.nth(rm_indx)); is_cursor_active = false; } protected virtual Float128 scr2rel_x (Float128 x) { - return rel_zoom_x_min + (x - plot_area_x_min) / (plot_area_x_max - plot_area_x_min) * (rel_zoom_x_max - rel_zoom_x_min); + return rel_zoom_x_min + (x - plot_x_min) / (plot_x_max - plot_x_min) * (rel_zoom_x_max - rel_zoom_x_min); } protected virtual Float128 scr2rel_y (Float128 y) { - return rel_zoom_y_max - (plot_area_y_max - y) / (plot_area_y_max - plot_area_y_min) * (rel_zoom_y_max - rel_zoom_y_min); + return rel_zoom_y_max - (plot_y_max - y) / (plot_y_max - plot_y_min) * (rel_zoom_y_max - rel_zoom_y_min); } protected virtual Point scr2rel_point (Point p) { return Point (scr2rel_x(p.x), scr2rel_y(p.y)); } protected virtual Float128 rel2scr_x(Float128 x) { - return plot_area_x_min + (plot_area_x_max - plot_area_x_min) * (x - rel_zoom_x_min) / (rel_zoom_x_max - rel_zoom_x_min); + return plot_x_min + (plot_x_max - plot_x_min) * (x - rel_zoom_x_min) / (rel_zoom_x_max - rel_zoom_x_min); } protected virtual Float128 rel2scr_y(Float128 y) { - return plot_area_y_min + (plot_area_y_max - plot_area_y_min) * (y - rel_zoom_y_min) / (rel_zoom_y_max - rel_zoom_y_min); + return plot_y_min + (plot_y_max - plot_y_min) * (y - rel_zoom_y_min) / (rel_zoom_y_max - rel_zoom_y_min); } protected virtual Point rel2scr_point (Point p) { return Point (rel2scr_x(p.x), rel2scr_y(p.y)); } - public LineStyle cursor_line_style = LineStyle(Color(0.2, 0.2, 0.2, 0.8)); - protected struct CursorCross { uint series_index; Point point; @@ -1307,10 +1116,10 @@ namespace Gtk.CairoChart { for (var ci = 0, max_ci = all_cursors.length(); ci < max_ci; ++ci) { var c = all_cursors.nth_data(ci); - switch (cursors_orientation) { - case CursorOrientation.VERTICAL: + switch (cursor_style.orientation) { + case Cursor.Orientation.VERTICAL: if (c.x <= rel_zoom_x_min || c.x >= rel_zoom_x_max) continue; break; - case CursorOrientation.HORIZONTAL: + case Cursor.Orientation.HORIZONTAL: if (c.y <= rel_zoom_y_min || c.y >= rel_zoom_y_max) continue; break; } @@ -1320,21 +1129,21 @@ namespace Gtk.CairoChart { if (!s.zoom_show) continue; Point[] points = {}; - switch (cursors_orientation) { - case CursorOrientation.VERTICAL: + switch (cursor_style.orientation) { + case Cursor.Orientation.VERTICAL: points = sort_points (s, s.sort); break; - case CursorOrientation.HORIZONTAL: + case Cursor.Orientation.HORIZONTAL: points = sort_points (s, s.sort); break; } for (var i = 0; i + 1 < points.length; ++i) { - switch (cursors_orientation) { - case CursorOrientation.VERTICAL: + switch (cursor_style.orientation) { + case Cursor.Orientation.VERTICAL: Float128 y = 0.0; if (vcross(get_scr_point(s, points[i]), get_scr_point(s, points[i+1]), rel2scr_x(c.x), - plot_area_y_min, plot_area_y_max, out y)) { + plot_y_min, plot_y_max, out y)) { var point = Point(get_real_x(s, rel2scr_x(c.x)), get_real_y(s, y)); Point size; bool show_x, show_date, show_time, show_y; cross_what_to_show(s, out show_x, out show_time, out show_date, out show_y); @@ -1343,10 +1152,10 @@ namespace Gtk.CairoChart { crossings += cc; } break; - case CursorOrientation.HORIZONTAL: + case Cursor.Orientation.HORIZONTAL: Float128 x = 0.0; if (hcross(get_scr_point(s, points[i]), get_scr_point(s, points[i+1]), - plot_area_x_min, plot_area_x_max, rel2scr_y(c.y), out x)) { + plot_x_min, plot_x_max, rel2scr_y(c.y), out x)) { var point = Point(get_real_x(s, x), get_real_y(s, rel2scr_y(c.y))); Point size; bool show_x, show_date, show_time, show_y; cross_what_to_show(s, out show_x, out show_time, out show_date, out show_y); @@ -1381,10 +1190,10 @@ namespace Gtk.CairoChart { protected virtual void cross_what_to_show (Series s, out bool show_x, out bool show_time, out bool show_date, out bool show_y) { show_x = show_time = show_date = show_y = false; - switch (cursors_orientation) { - case CursorOrientation.VERTICAL: + switch (cursor_style.orientation) { + case Cursor.Orientation.VERTICAL: show_y = true; - if (!common_x_axes) + if (!joint_x) switch (s.axis_x.type) { case Axis.Type.NUMBERS: show_x = true; break; case Axis.Type.DATE_TIME: @@ -1393,8 +1202,8 @@ namespace Gtk.CairoChart { break; } break; - case CursorOrientation.HORIZONTAL: - if (!common_y_axes) show_y = true; + case Cursor.Orientation.HORIZONTAL: + if (!joint_y) show_y = true; switch (s.axis_x.type) { case Axis.Type.NUMBERS: show_x = true; break; case Axis.Type.DATE_TIME: @@ -1419,10 +1228,10 @@ namespace Gtk.CairoChart { var x_t = new Text (s.axis_x.format.printf((LongDouble)p.x), s.axis_x.font_style, s.axis_x.color); var y_t = new Text (s.axis_y.format.printf((LongDouble)p.y), s.axis_y.font_style, s.axis_y.color); double h_x = 0.0, h_y = 0.0; - if (show_x) { var sz = x_t.size(context); size.x = sz.width; h_x = sz.height; } - if (show_date) { var sz = date_t.size(context); size.x = sz.width; h_x = sz.height; } - if (show_time) { var sz = time_t.size(context); size.x = double.max(size.x, sz.width); h_x += sz.height; } - if (show_y) { var sz = y_t.size(context); size.x += sz.width; h_y = sz.height; } + if (show_x) { var sz = x_t.get_size(context); size.x = sz.width; h_x = sz.height; } + if (show_date) { var sz = date_t.get_size(context); size.x = sz.width; h_x = sz.height; } + if (show_time) { var sz = time_t.get_size(context); size.x = double.max(size.x, sz.width); h_x += sz.height; } + if (show_y) { var sz = y_t.get_size(context); size.x += sz.width; h_y = sz.height; } if ((show_x || show_date || show_time) && show_y) size.x += double.max(s.axis_x.font_indent, s.axis_y.font_indent); if (show_date && show_time) h_x += s.axis_x.font_indent; size.y = double.max (h_x, h_y); @@ -1435,10 +1244,10 @@ namespace Gtk.CairoChart { calc_cursors_value_positions(); for (var cci = 0, max_cci = cursors_crossings.length; cci < max_cci; ++cci) { - var low = Point(plot_area_x_max, plot_area_y_max); // low and high - var high = Point(plot_area_x_min, plot_area_y_min); // points of the cursor + var low = Point(plot_x_max, plot_y_max); // low and high + var high = Point(plot_x_min, plot_y_min); // points of the cursor unowned CursorCross[] ccs = cursors_crossings[cci].crossings; - set_line_style(cursor_line_style); + set_line_style(cursor_style.line_style); for (var ci = 0, max_ci = ccs.length; ci < max_ci; ++ci) { var si = ccs[ci].series_index; var s = series[si]; @@ -1450,23 +1259,23 @@ namespace Gtk.CairoChart { if (scrx > high.x) high.x = scrx; if (scry > high.y) high.y = scry; - if (common_x_axes) { + if (joint_x) { switch (s.axis_x.position) { - case Axis.Position.LOW: high.y = plot_area_y_max + s.axis_x.font_indent; break; - case Axis.Position.HIGH: low.y = plot_area_y_min - s.axis_x.font_indent; break; + case Axis.Position.LOW: high.y = plot_y_max + s.axis_x.font_indent; break; + case Axis.Position.HIGH: low.y = plot_y_min - s.axis_x.font_indent; break; case Axis.Position.BOTH: - high.y = plot_area_y_max + s.axis_x.font_indent; - low.y = plot_area_y_min - s.axis_x.font_indent; + high.y = plot_y_max + s.axis_x.font_indent; + low.y = plot_y_min - s.axis_x.font_indent; break; } } - if (common_y_axes) { + if (joint_y) { switch (s.axis_y.position) { - case Axis.Position.LOW: low.x = plot_area_x_min - s.axis_y.font_indent; break; - case Axis.Position.HIGH: high.x = plot_area_x_max + s.axis_y.font_indent; break; + case Axis.Position.LOW: low.x = plot_x_min - s.axis_y.font_indent; break; + case Axis.Position.HIGH: high.x = plot_x_max + s.axis_y.font_indent; break; case Axis.Position.BOTH: - low.x = plot_area_x_min - s.axis_y.font_indent; - high.x = plot_area_x_max + s.axis_y.font_indent; + low.x = plot_x_min - s.axis_y.font_indent; + high.x = plot_x_max + s.axis_y.font_indent; break; } } @@ -1477,14 +1286,14 @@ namespace Gtk.CairoChart { var c = all_cursors.nth_data(cursors_crossings[cci].cursor_index); - switch (cursors_orientation) { - case CursorOrientation.VERTICAL: + switch (cursor_style.orientation) { + case Cursor.Orientation.VERTICAL: if (low.y > high.y) continue; context.move_to (rel2scr_x(c.x), low.y); context.line_to (rel2scr_x(c.x), high.y); - // show common X value - if (common_x_axes) { + // show joint X value + if (joint_x) { var s = series[zoom_first_show]; var x = get_real_x(s, rel2scr_x(c.x)); string text = "", time_text = ""; @@ -1499,15 +1308,15 @@ namespace Gtk.CairoChart { break; } var text_t = new Text(text, s.axis_x.font_style, s.axis_x.color); - var sz = text_t.size(context); + var sz = text_t.get_size(context); var time_text_t = new Text(time_text, s.axis_x.font_style, s.axis_x.color); var print_y = 0.0; switch (s.axis_x.position) { case Axis.Position.LOW: print_y = y_min + height - s.axis_x.font_indent - - (legend.position == Legend.Position.BOTTOM ? legend_height : 0); + - (legend.position == Legend.Position.BOTTOM ? legend.height : 0); break; case Axis.Position.HIGH: print_y = y_min + title_height + s.axis_x.font_indent - + (legend.position == Legend.Position.TOP ? legend_height : 0); + + (legend.position == Legend.Position.TOP ? legend.height : 0); switch (s.axis_x.type) { case Axis.Type.NUMBERS: print_y += sz.height; @@ -1536,13 +1345,13 @@ namespace Gtk.CairoChart { } } break; - case CursorOrientation.HORIZONTAL: + case Cursor.Orientation.HORIZONTAL: if (low.x > high.x) continue; context.move_to (low.x, rel2scr_y(c.y)); context.line_to (high.x, rel2scr_y(c.y)); - // show common Y value - if (common_y_axes) { + // show joint Y value + if (joint_y) { var s = series[zoom_first_show]; var y = get_real_y(s, rel2scr_y(c.y)); var text_t = new Text(s.axis_y.format.printf((LongDouble)y, s.axis_y.font_style)); @@ -1551,11 +1360,11 @@ namespace Gtk.CairoChart { switch (s.axis_y.position) { case Axis.Position.LOW: print_x = x_min + s.axis_y.font_indent - + (legend.position == Legend.Position.LEFT ? legend_width : 0); + + (legend.position == Legend.Position.LEFT ? legend.width : 0); break; case Axis.Position.HIGH: print_x = x_min + width - text_t.get_width(context) - s.axis_y.font_indent - - (legend.position == Legend.Position.RIGHT ? legend_width : 0); + - (legend.position == Legend.Position.RIGHT ? legend.width : 0); break; } context.move_to (print_x, print_y); @@ -1585,7 +1394,7 @@ namespace Gtk.CairoChart { set_source_rgba(s.axis_x.color); var text_t = new Text(s.axis_x.format.printf((LongDouble)point.x), s.axis_x.font_style); context.move_to (svp.x - size.x / 2, svp.y + text_t.get_height(context) / 2); - if (common_x_axes) set_source_rgba (common_axis_color); + if (joint_x) set_source_rgba (joint_axis_color); show_text(text_t); } @@ -1594,11 +1403,11 @@ namespace Gtk.CairoChart { string date = "", time = ""; format_date_time(s.axis_x, point.x, out date, out time); var text_t = new Text(time, s.axis_x.font_style); - var sz = text_t.size(context); + var sz = text_t.get_size(context); var y = svp.y + sz.height / 2; if (show_date) y -= sz.height / 2 + s.axis_x.font_indent / 2; context.move_to (svp.x - size.x / 2, y); - if (common_x_axes) set_source_rgba (common_axis_color); + if (joint_x) set_source_rgba (joint_axis_color); show_text(text_t); } @@ -1607,20 +1416,20 @@ namespace Gtk.CairoChart { string date = "", time = ""; format_date_time(s.axis_x, point.x, out date, out time); var text_t = new Text(date, s.axis_x.font_style); - var sz = text_t.size(context); + var sz = text_t.get_size(context); var y = svp.y + sz.height / 2; if (show_time) y += sz.height / 2 + s.axis_x.font_indent / 2; context.move_to (svp.x - size.x / 2, y); - if (common_x_axes) set_source_rgba (common_axis_color); + if (joint_x) set_source_rgba (joint_axis_color); show_text(text_t); } if (show_y) { set_source_rgba(s.axis_y.color); var text_t = new Text(s.axis_y.format.printf((LongDouble)point.y), s.axis_y.font_style); - var sz = text_t.size(context); + var sz = text_t.get_size(context); context.move_to (svp.x + size.x / 2 - sz.width, svp.y + sz.height / 2); - if (common_y_axes) set_source_rgba (common_axis_color); + if (joint_y) set_source_rgba (joint_axis_color); show_text(text_t); } } @@ -1631,7 +1440,7 @@ namespace Gtk.CairoChart { delta = 0.0; if (series.length == 0) return false; if (cursors.length() + (is_cursor_active ? 1 : 0) != 2) return false; - if (common_x_axes && cursors_orientation == CursorOrientation.VERTICAL) { + if (joint_x && cursor_style.orientation == Cursor.Orientation.VERTICAL) { Float128 val1 = get_real_x (series[zoom_first_show], rel2scr_x(cursors.nth_data(0).x)); Float128 val2 = 0; if (is_cursor_active) @@ -1644,7 +1453,7 @@ namespace Gtk.CairoChart { delta = val1 - val2; return true; } - if (common_y_axes && cursors_orientation == CursorOrientation.HORIZONTAL) { + if (joint_y && cursor_style.orientation == Cursor.Orientation.HORIZONTAL) { Float128 val1 = get_real_y (series[zoom_first_show], rel2scr_y(cursors.nth_data(0).y)); Float128 val2 = 0; if (is_cursor_active) @@ -1665,7 +1474,7 @@ namespace Gtk.CairoChart { if (!get_cursors_delta(out delta)) return ""; var str = ""; var s = series[zoom_first_show]; - if (common_x_axes) + if (joint_x) switch (s.axis_x.type) { case Axis.Type.NUMBERS: str = s.axis_x.format.printf((LongDouble)delta); @@ -1677,7 +1486,7 @@ namespace Gtk.CairoChart { str = days.to_string() + " + " + time; break; } - if (common_y_axes) { + if (joint_y) { str = s.axis_y.format.printf((LongDouble)delta); } return str; @@ -1689,42 +1498,33 @@ namespace Gtk.CairoChart { chart.axis_rec_npoints = this.axis_rec_npoints; chart.bg_color = this.bg_color; chart.border_color = this.border_color; - chart.common_x_axes = this.common_x_axes; - chart.common_y_axes = this.common_y_axes; + chart.joint_x = this.joint_x; + chart.joint_y = this.joint_y; chart.context = this.context; chart.cur_x_max = this.cur_x_max; chart.cur_x_min = this.cur_x_min; chart.cur_y_max = this.cur_y_max; chart.cur_y_min = this.cur_y_min; - chart.cursor_line_style = this.cursor_line_style; - chart.cursor_max_rm_distance = this.cursor_max_rm_distance; + chart.cursor_style = this.cursor_style; chart.cursors = this.cursors.copy(); chart.cursors_crossings = this.cursors_crossings; - chart.cursors_orientation = this.cursors_orientation; chart.height = this.height; chart.is_cursor_active = this.is_cursor_active; chart.legend = this.legend.copy(); - chart.legend_height = this.legend_height; - chart.legend_line_length = this.legend_line_length; - chart.legend_text_hspace = this.legend_text_hspace; - chart.legend_text_vspace = this.legend_text_vspace; - chart.legend_width = this.legend_width; chart.marker_size = this.marker_size; - chart.max_font_heights = this.max_font_heights; - chart.plot_area_x_max = this.plot_area_x_max; - 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.plot_x_max = this.plot_x_max; + chart.plot_x_min = this.plot_x_min; + chart.plot_y_max = this.plot_y_max; + chart.plot_y_min = this.plot_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.series = this.series; - chart.show_legend = this.show_legend; chart.title = this.title.copy(); chart.title_height = this.title_height; - chart.title_vindent = this.title_vindent; + chart.title_indent = this.title_indent; chart.title_width = this.title_width; chart.width = this.width; chart.x_min = this.x_min; diff --git a/src/Color.vala b/src/Color.vala index 6cbea9a..a6c2104 100644 --- a/src/Color.vala +++ b/src/Color.vala @@ -1,4 +1,4 @@ -namespace Gtk.CairoChart { +namespace CairoChart { public struct Color { double red; double green; diff --git a/src/Cursor.vala b/src/Cursor.vala new file mode 100644 index 0000000..7bc7787 --- /dev/null +++ b/src/Cursor.vala @@ -0,0 +1,23 @@ +namespace CairoChart { + + public class Cursor { + + public enum Orientation { + VERTICAL = 0, // default + HORIZONTAL + } + + public struct Style { + + public Orientation orientation; + public double select_distance; + public Line.Style line_style; + + public Style () { + orientation = Orientation.VERTICAL; + select_distance = 32; + line_style = Line.Style(Color(0.2, 0.2, 0.2, 0.8)); + } + } + } +} diff --git a/src/Font.vala b/src/Font.vala new file mode 100644 index 0000000..054868d --- /dev/null +++ b/src/Font.vala @@ -0,0 +1,31 @@ +namespace CairoChart { + + public class Font { + + public enum Orientation { + HORIZONTAL = 0, + VERTICAL + } + + public struct Style { + string family; + Cairo.FontSlant slant; + Cairo.FontWeight weight; + + Orientation orientation; + double size; + + public Style (string family = "Sans", + Cairo.FontSlant slant = Cairo.FontSlant.NORMAL, + Cairo.FontWeight weight = Cairo.FontWeight.NORMAL, + double size = 10, + Font.Orientation orientation = Font.Orientation.HORIZONTAL) { + this.family = family; + this.slant = slant; + this.weight = weight; + this.size = size; + this.orientation = orientation; + } + } + } +} diff --git a/src/FontStyle.vala b/src/FontStyle.vala deleted file mode 100644 index 685fd0e..0000000 --- a/src/FontStyle.vala +++ /dev/null @@ -1,27 +0,0 @@ -namespace Gtk.CairoChart { - public enum FontOrient { - HORIZONTAL = 0, - VERTICAL - } - - public struct FontStyle { - string family; - Cairo.FontSlant slant; - Cairo.FontWeight weight; - - FontOrient orientation; - double size; - - public FontStyle (string family = "Sans", - Cairo.FontSlant slant = Cairo.FontSlant.NORMAL, - Cairo.FontWeight weight = Cairo.FontWeight.NORMAL, - double size = 10, - FontOrient orientation = FontOrient.HORIZONTAL) { - this.family = family; - this.slant = slant; - this.weight = weight; - this.size = size; - this.orientation = orientation; - } - } -} diff --git a/src/Grid.vala b/src/Grid.vala index d57691e..0c3e62c 100644 --- a/src/Grid.vala +++ b/src/Grid.vala @@ -1,4 +1,4 @@ -namespace Gtk.CairoChart { +namespace CairoChart { public class Grid { /*public enum GridType { PRICK_LINE = 0, // default @@ -6,7 +6,7 @@ namespace Gtk.CairoChart { }*/ public Color color = Color (0, 0, 0, 0.1); - public LineStyle line_style = LineStyle (); + public Line.Style line_style = Line.Style (); public Grid copy () { var grid = new Grid (); diff --git a/src/Label.vala b/src/Label.vala new file mode 100644 index 0000000..1fd57df --- /dev/null +++ b/src/Label.vala @@ -0,0 +1,12 @@ +namespace CairoChart { + + public class Label { + + public struct Style { + Font.Style font_style; + Line.Style frame_line_style; + Color bg_color; + Color frame_color; + } + } +} diff --git a/src/LabelStyle.vala b/src/LabelStyle.vala deleted file mode 100644 index fc610ee..0000000 --- a/src/LabelStyle.vala +++ /dev/null @@ -1,8 +0,0 @@ -namespace Gtk.CairoChart { - public struct LabelStyle { - FontStyle font_style; - LineStyle frame_line_style; - Color bg_color; - Color frame_color; - } -} diff --git a/src/Legend.vala b/src/Legend.vala index 93e63b9..d7144f4 100644 --- a/src/Legend.vala +++ b/src/Legend.vala @@ -1,16 +1,25 @@ -namespace Gtk.CairoChart { +namespace CairoChart { + public class Legend { + public enum Position { TOP = 0, // default LEFT, RIGHT, BOTTOM } + public Position position = Position.TOP; - public FontStyle font_style = FontStyle(); + public Font.Style font_style = Font.Style(); public Color bg_color = Color(1, 1, 1); - public LineStyle border_style = LineStyle (); + public Line.Style border_style = Line.Style (); public double indent = 5; + public double width = 0; + public double height = 0; + public double line_length = 30.0; + public double text_hspace = 10.0; + public double text_vspace = 2.0; + public bool show = true; public Legend copy () { var legend = new Legend (); @@ -18,11 +27,194 @@ namespace Gtk.CairoChart { legend.font_style = this.font_style; legend.bg_color = this.bg_color; legend.indent = this.indent; + legend.height = this.height; + legend.line_length = this.line_length; + legend.text_hspace = this.text_hspace; + legend.text_vspace = this.text_vspace; + legend.width = this.width; + legend.show = this.show; + legend.max_font_heights = this.max_font_heights; return legend; } public Legend () { border_style.color = Color (0, 0, 0, 0.3); } + + public virtual void draw (Chart chart) { + process (chart, ProcessType.CALC); + process (chart, ProcessType.DRAW); + } + + public virtual void draw_rect (Chart chart, out double x0, out double y0) { + x0 = y0 = 0.0; + if (chart.context != null) { + switch (position) { + case Position.TOP: + x0 = (chart.width - width) / 2; + y0 = chart.title_height; + break; + + case Position.BOTTOM: + x0 = (chart.width - width) / 2; + y0 = chart.height - height; + break; + + case Position.LEFT: + x0 = 0; + y0 = (chart.height - height) / 2; + break; + + case Position.RIGHT: + x0 = chart.width - width; + y0 = (chart.height - height) / 2; + break; + } + chart.set_source_rgba(bg_color); + chart.context.rectangle (x0, y0, width, height); + chart.context.fill(); + chart.set_line_style(border_style); + chart.context.move_to (x0, y0); + chart.context.rel_line_to (width, 0); + chart.context.rel_line_to (0, height); + chart.context.rel_line_to (-width, 0); + chart.context.rel_line_to (0, -height); + chart.context.stroke (); + } + } + + public enum ProcessType { + CALC = 0, // default + DRAW + } + + double [] max_font_heights; + public virtual void process (Chart chart, ProcessType process_type) { + var legend_x0 = 0.0, legend_y0 = 0.0; + var heights_idx = 0; + var leg_width_sum = 0.0; + var leg_height_sum = 0.0; + double max_font_h = 0.0; + + // prepare + switch (process_type) { + case ProcessType.CALC: + width = 0.0; + height = 0.0; + max_font_heights = {}; + heights_idx = 0; + break; + case ProcessType.DRAW: + draw_rect(chart, out legend_x0, out legend_y0); + break; + } + + foreach (var s in chart.series) { + + if (!s.zoom_show) continue; + + var title_sz = s.title.get_size(chart.context); + + // carry + switch (position) { + case Position.TOP: + case Position.BOTTOM: + var ser_title_width = title_sz.width + line_length; + if (leg_width_sum + (leg_width_sum == 0 ? 0 : text_hspace) + ser_title_width > chart.width) { // carry + leg_height_sum += max_font_h; + switch (process_type) { + case ProcessType.CALC: + max_font_heights += max_font_h; + width = double.max(width, leg_width_sum); + break; + case ProcessType.DRAW: + heights_idx++; + break; + } + leg_width_sum = 0.0; + max_font_h = 0; + } + break; + } + + switch (process_type) { + case ProcessType.DRAW: + var x = legend_x0 + leg_width_sum + (leg_width_sum == 0.0 ? 0.0 : text_hspace); + var y = legend_y0 + leg_height_sum + max_font_heights[heights_idx]; + + // series title + chart.context.move_to (x + line_length, y); + chart.set_source_rgba (s.title.color); + chart.show_text(s.title); + + // series line style + chart.context.move_to (x, y - title_sz.height / 2); + chart.set_line_style(s.line_style); + chart.context.rel_line_to (line_length, 0); + chart.context.stroke(); + chart.draw_marker_at_pos (s.marker_type, x + line_length / 2, y - title_sz.height / 2); + break; + } + + switch (position) { + case Position.TOP: + case Position.BOTTOM: + var ser_title_width = title_sz.width + line_length; + leg_width_sum += (leg_width_sum == 0 ? 0 : text_hspace) + ser_title_width; + max_font_h = double.max (max_font_h, title_sz.height) + (leg_height_sum != 0 ? text_vspace : 0); + break; + + case Position.LEFT: + case Position.RIGHT: + switch (process_type) { + case ProcessType.CALC: + max_font_heights += title_sz.height + (leg_height_sum != 0 ? text_vspace : 0); + width = double.max (width, title_sz.width + line_length); + break; + case ProcessType.DRAW: + heights_idx++; + break; + } + leg_height_sum += title_sz.height + (leg_height_sum != 0 ? text_vspace : 0); + break; + } + } + + // TOP, BOTTOM + switch (position) { + case Position.TOP: + case Position.BOTTOM: + if (leg_width_sum != 0) { + leg_height_sum += max_font_h; + switch (process_type) { + case ProcessType.CALC: + max_font_heights += max_font_h; + width = double.max(width, leg_width_sum); + break; + } + } + break; + } + + switch (process_type) { + case ProcessType.CALC: + height = leg_height_sum; + switch (position) { + case Position.TOP: + chart.cur_y_min += height; + break; + case Position.BOTTOM: + chart.cur_y_max -= height; + break; + case Position.LEFT: + chart.cur_x_min += width; + break; + case Position.RIGHT: + chart.cur_x_max -= width; + break; + } + break; + } + } } } diff --git a/src/Line.vala b/src/Line.vala new file mode 100644 index 0000000..f74c187 --- /dev/null +++ b/src/Line.vala @@ -0,0 +1,29 @@ +namespace CairoChart { + + public class Line { + + public struct Style { + + double width; + Cairo.LineJoin join; + Cairo.LineCap cap; + double[]? dashes; + double dash_offset; + Color color; + + public Style (Color color = Color(), + double width = 1, + double[]? dashes = null, double dash_offset = 0, + Cairo.LineJoin join = Cairo.LineJoin.MITER, + Cairo.LineCap cap = Cairo.LineCap.ROUND + ) { + this.width = width; + this.join = join; + this.cap = cap; + this.dashes = dashes; + this.dash_offset = dash_offset; + this.color = color; + } + } + } +} diff --git a/src/LineStyle.vala b/src/LineStyle.vala deleted file mode 100644 index 4a58d1e..0000000 --- a/src/LineStyle.vala +++ /dev/null @@ -1,24 +0,0 @@ -namespace Gtk.CairoChart { - public struct LineStyle { - double width; - Cairo.LineJoin line_join; - Cairo.LineCap line_cap; - double[]? dashes; - double dash_offset; - Color color; - - public LineStyle (Color color = Color(), - double width = 1, - double[]? dashes = null, double dash_offset = 0, - Cairo.LineJoin line_join = Cairo.LineJoin.MITER, - Cairo.LineCap line_cap = Cairo.LineCap.ROUND - ) { - this.width = width; - this.line_join = line_join; - this.line_cap = line_cap; - this.dashes = dashes; - this.dash_offset = dash_offset; - this.color = color; - } - } -} diff --git a/src/Place.vala b/src/Place.vala index 6ac611d..fcaad33 100644 --- a/src/Place.vala +++ b/src/Place.vala @@ -1,52 +1,52 @@ -namespace Gtk.CairoChart { +namespace CairoChart { public class Place { - double _x_low = 0; - double _x_high = 0; - double _y_low = 0; - double _y_high = 0; - public double x_low { - get { return _x_low; } - set { _x_low = zoom_x_low = value; } + double _x_min = 0; + double _x_max = 0; + double _y_min = 0; + double _y_max = 0; + public double x_min { + get { return _x_min; } + set { _x_min = zoom_x_min = value; } default = 0; } - public double x_high { - get { return _x_high; } - set { _x_high = zoom_x_high = value; } + public double x_max { + get { return _x_max; } + set { _x_max = zoom_x_max = value; } default = 0; } - public double y_low { - get { return _y_low; } - set { _y_low = zoom_y_low = value; } + public double y_min { + get { return _y_min; } + set { _y_min = zoom_y_min = value; } default = 0; } - public double y_high { - get { return _y_high; } - set { _y_high = zoom_y_high = value; } + public double y_max { + get { return _y_max; } + set { _y_max = zoom_y_max = value; } default = 0; } - public double zoom_x_low = 0; - public double zoom_x_high = 1; - public double zoom_y_low = 0; - public double zoom_y_high = 1; + public double zoom_x_min = 0; + public double zoom_x_max = 1; + public double zoom_y_min = 0; + public double zoom_y_max = 1; public Place copy () { var place = new Place (); - place.x_low = this.x_low; - place.x_high = this.x_high; - place.y_low = this.y_low; - place.y_high = this.y_high; + place.x_min = this.x_min; + place.x_max = this.x_max; + place.y_min = this.y_min; + place.y_max = this.y_max; return place; } - public Place (double x_low = 0, double x_high = 1, double y_low = 0, double y_high = 1) { - this.x_low = x_low; - this.x_high = x_high; - this.y_low = y_low; - this.y_high = y_high; - zoom_x_low = x_low; - zoom_x_high = x_high; - zoom_y_low = y_low; - zoom_y_high = y_high; + public Place (double x_min = 0, double x_max = 1, double y_min = 0, double y_max = 1) { + this.x_min = x_min; + this.x_max = x_max; + this.y_min = y_min; + this.y_max = y_max; + zoom_x_min = x_min; + zoom_x_max = x_max; + zoom_y_min = y_min; + zoom_y_max = y_max; } } } diff --git a/src/Point.vala b/src/Point.vala index 30bee7b..afde491 100644 --- a/src/Point.vala +++ b/src/Point.vala @@ -1,4 +1,4 @@ -namespace Gtk.CairoChart { +namespace CairoChart { public struct Point { Float128 x; Float128 y; diff --git a/src/Series.vala b/src/Series.vala index 284921e..3ad9c41 100644 --- a/src/Series.vala +++ b/src/Series.vala @@ -1,6 +1,6 @@ using Cairo; -namespace Gtk.CairoChart { +namespace CairoChart { public class Series { @@ -8,7 +8,7 @@ namespace Gtk.CairoChart { public enum Sort { BY_X = 0, BY_Y = 1, - NO_SORT + UNSORTED } public Sort sort = Sort.BY_X; @@ -31,7 +31,7 @@ namespace Gtk.CairoChart { public Grid grid = new Grid (); - public LineStyle line_style = LineStyle (); + public Line.Style line_style = Line.Style (); protected Color _color = Color (0.0, 0.0, 0.0, 1.0); public Color color { diff --git a/src/Text.vala b/src/Text.vala index 5a8f3c3..ab07c3c 100644 --- a/src/Text.vala +++ b/src/Text.vala @@ -1,8 +1,8 @@ -namespace Gtk.CairoChart { +namespace CairoChart { [Compact] public class Text { public string text = ""; - public FontStyle style = FontStyle (); + public Font.Style style = Font.Style (); public Color color = Color(); public Cairo.TextExtents get_extents (Cairo.Context context) { @@ -16,8 +16,8 @@ namespace Gtk.CairoChart { public double get_width (Cairo.Context context) { var extents = get_extents (context); switch (style.orientation) { - case FontOrient.HORIZONTAL: return extents.width; - case FontOrient.VERTICAL: return extents.height; + case Font.Orientation.HORIZONTAL: return extents.width; + case Font.Orientation.VERTICAL: return extents.height; default: return 0.0; } } @@ -25,8 +25,8 @@ namespace Gtk.CairoChart { public double get_height (Cairo.Context context) { var extents = get_extents (context); switch (style.orientation) { - case FontOrient.HORIZONTAL: return extents.height; - case FontOrient.VERTICAL: return extents.width; + case Font.Orientation.HORIZONTAL: return extents.height; + case Font.Orientation.VERTICAL: return extents.width; default: return 0.0; } } @@ -36,15 +36,15 @@ namespace Gtk.CairoChart { double height; } - public Size size (Cairo.Context context) { + public Size get_size (Cairo.Context context) { var sz = Size(); var extents = get_extents (context); switch (style.orientation) { - case FontOrient.HORIZONTAL: + case Font.Orientation.HORIZONTAL: sz.width = extents.width + extents.x_bearing; sz.height = extents.height; break; - case FontOrient.VERTICAL: + case Font.Orientation.VERTICAL: sz.width = extents.height; // + extents.x_bearing ? sz.height = extents.width; // +- extents.y_bearing ? break; @@ -53,7 +53,7 @@ namespace Gtk.CairoChart { } public Text (string text = "", - FontStyle style = FontStyle(), + Font.Style style = Font.Style(), Color color = Color()) { this.text = text; this.style = style; diff --git a/src/cairo-chart-float128type.vapi b/src/cairo-chart-float128type.vapi index 04aaa8c..750888f 100644 --- a/src/cairo-chart-float128type.vapi +++ b/src/cairo-chart-float128type.vapi @@ -1,4 +1,4 @@ -namespace Gtk.CairoChart { +namespace CairoChart { [CCode (cname = "cairo_chart_float128", has_type_id = false, cheader_filename = "cairo-chart-float128type.h")] public struct Float128 : double {} [CCode (cname = "cairo_chart_long_double", has_type_id = false, cheader_filename = "cairo-chart-float128type.h")] diff --git a/test/ChartTest.vala b/test/ChartTest.vala index a3e4f15..0ad69cf 100644 --- a/test/ChartTest.vala +++ b/test/ChartTest.vala @@ -17,18 +17,18 @@ void plot_chart1 (Chart chart) { s1.axis_x.min = 0; s1.axis_x.max = 2; s1.axis_y.min = 0; s1.axis_y.max = 3; - s1.place.x_low = 0.25; s1.place.x_high = 0.75; - s1.place.y_low = 0.3; s1.place.y_high = 0.9; + s1.place.x_min = 0.25; s1.place.x_max = 0.75; + s1.place.y_min = 0.3; s1.place.y_max = 0.9; s2.axis_x.min = -15; s2.axis_x.max = 30; s2.axis_y.min = -20; s2.axis_y.max = 200; - s2.place.x_low = 0.5; s2.place.x_high = 1; - s2.place.y_low = 0.0; s2.place.y_high = 0.5; + s2.place.x_min = 0.5; s2.place.x_max = 1; + s2.place.y_min = 0.0; s2.place.y_max = 0.5; s3.axis_x.min = 0; s3.axis_x.max = 130; s3.axis_y.min = 15; s3.axis_y.max = 35; - s3.place.x_low = 0; s3.place.x_high = 0.5; - s3.place.y_low = 0.5; s3.place.y_high = 1.0; + s3.place.x_min = 0; s3.place.x_max = 0.5; + s3.place.y_min = 0.5; s3.place.y_max = 1.0; s2.marker_type = Series.MarkerType.CIRCLE; s3.marker_type = Series.MarkerType.PRICLE_TRIANGLE; @@ -60,18 +60,18 @@ void plot_chart2 (Chart chart) { s1.axis_x.min = -15; s1.axis_x.max = 30; s1.axis_y.min = 0; s1.axis_y.max = 3; - s1.place.x_low = 0.0; s1.place.x_high = 1.0; - s1.place.y_low = 0.3; s1.place.y_high = 0.9; + s1.place.x_min = 0.0; s1.place.x_max = 1.0; + s1.place.y_min = 0.3; s1.place.y_max = 0.9; s2.axis_x.min = -15; s2.axis_x.max = 30; s2.axis_y.min = -20; s2.axis_y.max = 200; - s2.place.x_low = 0.0; s2.place.x_high = 1.0; - s2.place.y_low = 0.0; s2.place.y_high = 0.5; + s2.place.x_min = 0.0; s2.place.x_max = 1.0; + s2.place.y_min = 0.0; s2.place.y_max = 0.5; s3.axis_x.min = -15; s3.axis_x.max = 30; s3.axis_y.min = 15; s3.axis_y.max = 35; - s3.place.x_low = 0.0; s3.place.x_high = 1.0; - s3.place.y_low = 0.5; s3.place.y_high = 1.0; + s3.place.x_min = 0.0; s3.place.x_max = 1.0; + s3.place.y_min = 0.5; s3.place.y_max = 1.0; s1.marker_type = Series.MarkerType.PRICLE_CIRCLE; s2.marker_type = Series.MarkerType.PRICLE_SQUARE; @@ -109,18 +109,18 @@ void plot_chart3 (Chart chart) { s1.axis_x.min = 0; s1.axis_x.max = 2; s1.axis_y.min = -20; s1.axis_y.max = 200; - s1.place.x_low = 0.25; s1.place.x_high = 0.75; - s1.place.y_low = 0.0; s1.place.y_high = 1.0; + s1.place.x_min = 0.25; s1.place.x_max = 0.75; + s1.place.y_min = 0.0; s1.place.y_max = 1.0; s2.axis_x.min = -15; s2.axis_x.max = 30; s2.axis_y.min = -20; s2.axis_y.max = 200; - s2.place.x_low = 0.5; s2.place.x_high = 1; - s2.place.y_low = 0.0; s2.place.y_high = 1.0; + s2.place.x_min = 0.5; s2.place.x_max = 1; + s2.place.y_min = 0.0; s2.place.y_max = 1.0; s3.axis_x.min = 0; s3.axis_x.max = 130; s3.axis_y.min = -20; s3.axis_y.max = 200; - s3.place.x_low = 0; s3.place.x_high = 0.5; - s3.place.y_low = 0.0; s3.place.y_high = 1.0; + s3.place.x_min = 0; s3.place.x_max = 0.5; + s3.place.y_min = 0.0; s3.place.y_max = 1.0; s2.marker_type = Series.MarkerType.PRICLE_CIRCLE; s3.marker_type = Series.MarkerType.TRIANGLE; @@ -167,23 +167,23 @@ void plot_chart4 (Chart chart) { s1.axis_x.min = now - 100000; s1.axis_x.max = now + 100000; s1.axis_y.min = -20; s1.axis_y.max = 200; - s1.place.x_low = 0.25; s1.place.x_high = 0.75; - s1.place.y_low = 0.0; s1.place.y_high = 1.0; + s1.place.x_min = 0.25; s1.place.x_max = 0.75; + s1.place.y_min = 0.0; s1.place.y_max = 1.0; s2.axis_x.min = -15; s2.axis_x.max = 30; s2.axis_y.min = -20; s2.axis_y.max = 200; - s2.place.x_low = 0.2; s2.place.x_high = 1; - s2.place.y_low = 0.0; s2.place.y_high = 1.0; + s2.place.x_min = 0.2; s2.place.x_max = 1; + s2.place.y_min = 0.0; s2.place.y_max = 1.0; s3.axis_x.min = high - 2; s3.axis_x.max = high + 1; s3.axis_y.min = -20; s3.axis_y.max = 200; - s3.place.x_low = 0; s3.place.x_high = 0.8; - s3.place.y_low = 0.0; s3.place.y_high = 1.0; + s3.place.x_min = 0; s3.place.x_max = 0.8; + s3.place.y_min = 0.0; s3.place.y_max = 1.0; s4.axis_x.min = high + 0.0049; s4.axis_x.max = high + 0.0054; s4.axis_y.min = -20; s4.axis_y.max = 200; - s4.place.x_low = 0.2; s4.place.x_high = 1.0; - s4.place.y_low = 0.0; s4.place.y_high = 1.0; + s4.place.x_min = 0.2; s4.place.x_max = 1.0; + s4.place.y_min = 0.0; s4.place.y_max = 1.0; s2.marker_type = Series.MarkerType.PRICLE_CIRCLE; s3.marker_type = Series.MarkerType.TRIANGLE; @@ -202,10 +202,10 @@ void plot_chart4 (Chart chart) { } bool point_in_chart (Chart chart, double x, double y) { - if (x < chart.plot_area_x_min) return false; - if (x > chart.plot_area_x_max) return false; - if (y < chart.plot_area_y_min) return false; - if (y > chart.plot_area_y_max) return false; + if (x < chart.plot_x_min) return false; + if (x > chart.plot_x_max) return false; + if (y < chart.plot_y_min) return false; + if (y > chart.plot_y_max) return false; return true; } @@ -230,10 +230,10 @@ int main (string[] args) { var chart2 = new Chart(); var chart3 = new Chart(); var chart4 = new Chart(); - var label = new Label ("Chart Test!"); + var label = new Gtk.Label ("Chart Test!"); var button1 = new Button.with_label("Separate axes"); - var button2 = new Button.with_label("Common X axes"); - var button3 = new Button.with_label("Common Y axes"); + var button2 = new Button.with_label("Joint X axes"); + var button3 = new Button.with_label("Joint Y axes"); var button4 = new Button.with_label("Dates/Times"); var button5 = new Button.with_label("rm Axis Titles"); var button6 = new Button.with_label("Dates only"); @@ -245,7 +245,7 @@ int main (string[] args) { plot_chart3 (chart3); plot_chart4 (chart4); - chart1.selection_style = LineStyle(Color(0.3, 0.3, 0.3, 0.7), 1); + chart1.selection_style = Line.Style(Color(0.3, 0.3, 0.3, 0.7), 1); var da = new DrawingArea(); da.set_events ( Gdk.EventMask.BUTTON_PRESS_MASK @@ -270,9 +270,9 @@ int main (string[] args) { case Legend.Position.LEFT: radio_button3.set_active(true); break; case Legend.Position.BOTTOM: radio_button4.set_active(true); break; } - switch (chart.cursors_orientation) { - case Chart.CursorOrientation.VERTICAL: radio_button7.set_active(true); break; - case Chart.CursorOrientation.HORIZONTAL: radio_button8.set_active(true); break; + switch (chart.cursor_style.orientation) { + case Cursor.Orientation.VERTICAL: radio_button7.set_active(true); break; + case Cursor.Orientation.HORIZONTAL: radio_button8.set_active(true); break; } }); button2.clicked.connect (() => { @@ -283,9 +283,9 @@ int main (string[] args) { case Legend.Position.LEFT: radio_button3.set_active(true); break; case Legend.Position.BOTTOM: radio_button4.set_active(true); break; } - switch (chart.cursors_orientation) { - case Chart.CursorOrientation.VERTICAL: radio_button7.set_active(true); break; - case Chart.CursorOrientation.HORIZONTAL: radio_button8.set_active(true); break; + switch (chart.cursor_style.orientation) { + case Cursor.Orientation.VERTICAL: radio_button7.set_active(true); break; + case Cursor.Orientation.HORIZONTAL: radio_button8.set_active(true); break; } }); button3.clicked.connect (() => { @@ -296,9 +296,9 @@ int main (string[] args) { case Legend.Position.LEFT: radio_button3.set_active(true); break; case Legend.Position.BOTTOM: radio_button4.set_active(true); break; } - switch (chart.cursors_orientation) { - case Chart.CursorOrientation.VERTICAL: radio_button7.set_active(true); break; - case Chart.CursorOrientation.HORIZONTAL: radio_button8.set_active(true); break; + switch (chart.cursor_style.orientation) { + case Cursor.Orientation.VERTICAL: radio_button7.set_active(true); break; + case Cursor.Orientation.HORIZONTAL: radio_button8.set_active(true); break; } }); button4.clicked.connect (() => { @@ -309,9 +309,9 @@ int main (string[] args) { case Legend.Position.LEFT: radio_button4.set_active(true); break; case Legend.Position.BOTTOM: radio_button4.set_active(true); break; } - switch (chart.cursors_orientation) { - case Chart.CursorOrientation.VERTICAL: radio_button7.set_active(true); break; - case Chart.CursorOrientation.HORIZONTAL: radio_button8.set_active(true); break; + switch (chart.cursor_style.orientation) { + case Cursor.Orientation.VERTICAL: radio_button7.set_active(true); break; + case Cursor.Orientation.HORIZONTAL: radio_button8.set_active(true); break; } }); button5.clicked.connect (() => { @@ -393,13 +393,13 @@ int main (string[] args) { radio_button7.toggled.connect ((button) => { if (button.get_active()) { - chart.cursors_orientation = Chart.CursorOrientation.VERTICAL; + chart.cursor_style.orientation = Cursor.Orientation.VERTICAL; da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height()); } }); radio_button8.toggled.connect ((button) => { if (button.get_active()) { - chart.cursors_orientation = Chart.CursorOrientation.HORIZONTAL; + chart.cursor_style.orientation = Cursor.Orientation.HORIZONTAL; da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height()); } }); @@ -431,13 +431,13 @@ int main (string[] args) { var text_t = new Text(text); var w = text_t.get_width(context); var h = text_t.get_height(context); - var x0 = chart.plot_area_x_max - w - 5; - var y0 = chart.plot_area_y_min + h + 5; + var x0 = chart.plot_x_max - w - 5; + var y0 = chart.plot_y_min + h + 5; chart.set_source_rgba(chart.legend.bg_color); context.rectangle (x0, y0 - h, w, h); context.fill(); context.move_to (x0, y0); - chart.set_source_rgba(chart.common_axis_color); + chart.set_source_rgba(chart.joint_axis_color); context.show_text(text); }