gsl-shell.git - gsl-shell

index : gsl-shell.git
gsl-shell
summary refs log tree commit diff
path: root/agg-plot
diff options
context:
space:
mode:
authorFrancesco Abbate <francesco.bbt@gmail.com>2013年01月30日 18:16:12 +0100
committerFrancesco Abbate <francesco.bbt@gmail.com>2013年02月03日 22:30:35 +0100
commita366fbb4d0ede381163976dc46d39ab4a1e9fdba (patch)
tree95e1e5beb1e77bb31fc6c1a843409081c10bae45 /agg-plot
parent44b1bffb2220da2220aee2588143e11026e10083 (diff)
downloadgsl-shell-a366fbb4d0ede381163976dc46d39ab4a1e9fdba.tar.gz
Implement plot's multi level labels
Preliminary implementation.
Diffstat (limited to 'agg-plot')
-rw-r--r--agg-plot/factor_labels.h 28
-rw-r--r--agg-plot/lua-plot.cpp 40
-rw-r--r--agg-plot/plot.h 102
-rw-r--r--agg-plot/units.h 1
-rw-r--r--agg-plot/utils.h 4
5 files changed, 171 insertions, 4 deletions
diff --git a/agg-plot/factor_labels.h b/agg-plot/factor_labels.h
new file mode 100644
index 00000000..27f6ef47
--- /dev/null
+++ b/agg-plot/factor_labels.h
@@ -0,0 +1,28 @@
+#include "agg_array.h"
+#include "utils.h"
+#include "strpp.h"
+
+class factor_labels
+{
+public:
+ factor_labels(double delta): m_mark_delta(delta) {}
+
+ double mark(int k) const { return m_mark_index[k] * m_mark_delta; }
+ const char *label_text(int k) const { return m_label_text[k]->cstr(); }
+ int labels_number() const { return m_label_text.size(); }
+
+ void add_mark(int index, const char *text)
+ {
+ m_mark_index.add(index);
+ if (text)
+ {
+ str* text_str = new str(text);
+ m_label_text.add(text_str);
+ }
+ }
+
+private:
+ double m_mark_delta;
+ agg::pod_bvector<short> m_mark_index;
+ ptr_list<str> m_label_text;
+};
diff --git a/agg-plot/lua-plot.cpp b/agg-plot/lua-plot.cpp
index 42961d46..7194a0b3 100644
--- a/agg-plot/lua-plot.cpp
+++ b/agg-plot/lua-plot.cpp
@@ -70,6 +70,7 @@ static int plot_ylab_angle_get (lua_State *L);
static int plot_set_categories (lua_State *L);
static int plot_set_legend (lua_State *L);
static int plot_get_legend (lua_State *L);
+static int plot_xaxis_hol_set (lua_State *L);
static int plot_sync_mode_get (lua_State *L);
static int plot_sync_mode_set (lua_State *L);
@@ -109,6 +110,7 @@ static const struct luaL_Reg plot_methods[] = {
{"set_categories", plot_set_categories},
{"set_legend", plot_set_legend},
{"get_legend", plot_get_legend},
+ {"set_hol", plot_xaxis_hol_set},
{NULL, NULL}
};
@@ -467,6 +469,44 @@ plot_units_get (lua_State *L)
return plot_bool_property_get(L, &sg_plot::use_units);
}
+int plot_xaxis_hol_set (lua_State *L)
+{
+ sg_plot *p = object_check<sg_plot>(L, 1, GS_PLOT);
+ double delta = lua_tonumber(L, 2);
+
+ if (!lua_istable(L, 3))
+ return luaL_error(L, "expect labels table specification");
+
+ ptr_list<factor_labels>* hol = p->get_xaxis_hol();
+ bool create_hol = (hol == 0);
+ if (create_hol)
+ hol = new ptr_list<factor_labels>();
+
+ factor_labels* fl = new factor_labels(delta);
+ int n = lua_objlen(L, 3);
+ for (int k = 1; k <= n; k += 2)
+ {
+ lua_rawgeti(L, 3, k);
+ int idx = lua_tonumber(L, -1);
+ lua_pop(L, 1);
+
+ lua_rawgeti(L, 3, k + 1);
+ const char* str = lua_tostring(L, -1);
+ fl->add_mark(idx, str);
+ lua_pop(L, 1);
+
+ if (!str)
+ break;
+ }
+
+ hol->add(fl);
+
+ if (create_hol)
+ p->set_xaxis_hol(hol);
+
+ return 0;
+}
+
void
plot_update_raw (lua_State *L, sg_plot *p, int plot_index)
{
diff --git a/agg-plot/plot.h b/agg-plot/plot.h
index 06d0d35a..49a61587 100644
--- a/agg-plot/plot.h
+++ b/agg-plot/plot.h
@@ -36,6 +36,7 @@
#include "text.h"
#include "categories.h"
#include "sg_object.h"
+#include "factor_labels.h"
#include "agg_array.h"
#include "agg_bounding_rect.h"
@@ -239,7 +240,8 @@ public:
m_drawing_queue(0), m_clip_flag(true),
m_need_redraw(true), m_rect(),
m_use_units(use_units), m_pad_units(false), m_title(),
- m_sync_mode(true), m_x_axis(x_axis), m_y_axis(y_axis)
+ m_sync_mode(true), m_x_axis(x_axis), m_y_axis(y_axis),
+ m_xaxis_hol(0)
{
m_layers.add(&m_root_layer);
compute_user_trans();
@@ -256,6 +258,8 @@ public:
if (k > 0)
delete layer;
}
+
+ delete m_xaxis_hol;
};
str& title() {
@@ -301,6 +305,14 @@ public:
void set_limits(const agg::rect_base<double>& r);
void unset_limits();
+ ptr_list<factor_labels>* get_xaxis_hol() { return m_xaxis_hol; }
+
+ void set_xaxis_hol(ptr_list<factor_labels>* hol)
+ {
+ delete m_xaxis_hol;
+ m_xaxis_hol = hol;
+ }
+
virtual void add(sg_object* vs, agg::rgba8& color, bool outline);
virtual void before_draw() { }
@@ -421,6 +433,11 @@ protected:
ptr_list<draw::text>& labels, double scale,
agg::path_storage& mark, agg::path_storage& ln);
+ double draw_xaxis_factors(units& u, const agg::trans_affine& user_mtx,
+ ptr_list<draw::text>& labels,
+ ptr_list<factor_labels>* f_labels, double scale,
+ agg::path_storage& mark, agg::path_storage& ln);
+
void draw_elements(canvas_type &canvas, const plot_layout& layout);
void draw_element(item& c, canvas_type &canvas, const agg::trans_affine& m);
void draw_axis(canvas_type& can, plot_layout& layout, const agg::rect_i* clip = 0);
@@ -486,6 +503,8 @@ private:
axis m_x_axis, m_y_axis;
plot* m_legend[4];
+
+ ptr_list<factor_labels>* m_xaxis_hol;
};
static double compute_scale(const agg::trans_affine& m)
@@ -695,6 +714,7 @@ double plot<RM>::draw_axis_m(axis_e dir, units& u,
const double text_label_size = get_default_font_size(text_axis_labels, scale);
const double eps = 1.0e-3;
+ // used to store the bounding box of text labels
opt_rect<double> bb;
agg::rect_base<double> r;
@@ -764,6 +784,77 @@ double plot<RM>::draw_axis_m(axis_e dir, units& u,
return label_size;
}
+template <class RM>
+double plot<RM>::draw_xaxis_factors(units& u,
+ const agg::trans_affine& user_mtx,
+ ptr_list<draw::text>& labels,
+ ptr_list<factor_labels>* f_labels, double scale,
+ agg::path_storage& mark, agg::path_storage& ln)
+{
+ const double text_label_size = get_default_font_size(text_axis_labels, scale);
+ const double eps = 1.0e-3;
+
+ const double y_spacing = 0.05;
+ const unsigned layers_number = f_labels->size();
+ double p_lab = - double(layers_number) * y_spacing;
+ for (unsigned layer = 0; layer < layers_number; layer++)
+ {
+ factor_labels* factor = f_labels->at(layer);
+ for (int k = 0; k < factor->labels_number(); k++)
+ {
+ double x_lab_a = factor->mark(k);
+ double x_lab_b = factor->mark(k+1);
+
+ double x_a = x_lab_a, y_a = 0.0;
+ user_mtx.transform(&x_a, &y_a);
+ double q_a = x_a;
+
+ double x_lab = (x_lab_a + x_lab_b) / 2, y_lab = 0.0;
+ user_mtx.transform(&x_lab, &y_lab);
+ double q_lab = x_lab;
+
+ mark.move_to(q_a, p_lab);
+ mark.line_to(q_a, p_lab + y_spacing);
+
+ const char* text = factor->label_text(k);
+ draw::text* label = new draw::text(text, text_label_size, 0.5, -0.2);
+
+ label->set_point(q_lab, p_lab);
+ label->angle(0.0);
+
+ labels.add(label);
+ }
+
+ double x_lab = factor->mark(layers_number);
+ double x_a = x_lab, y_a = 0.0;
+ user_mtx.transform(&x_a, &y_a);
+ double q_a = x_a;
+ mark.move_to(q_a, p_lab);
+ mark.line_to(q_a, p_lab + y_spacing);
+
+ p_lab += y_spacing;
+ }
+
+ // NB: IMPORTANT
+ // the following code should be factored in a separate routine
+ int jinf = u.begin(), jsup = u.end();
+ for (int j = jinf+1; j < jsup; j++)
+ {
+ double uq = u.mark_value(j);
+ double x = uq, y = 0.0;
+ user_mtx.transform(&x, &y);
+ double q = x;
+
+ if (q >= -eps && q <= 1.0 + eps)
+ {
+ ln.move_to(q, 0.0);
+ ln.line_to(q, 1.0);
+ }
+ }
+
+ return y_spacing * layers_number;
+}
+
static inline double approx_text_height(double text_size)
{
return text_size * 1.5;
@@ -936,11 +1027,16 @@ void plot<RM>::draw_axis(canvas_type& canvas, plot_layout& layout, const agg::re
ptr_list<draw::text> labels;
- double dy_label = draw_axis_m(x_axis, m_ux, m_trans, labels, scale, mark, ln);
+ double dy_label = 0, pdy_label = 0;
+ if (this->m_xaxis_hol)
+ pdy_label = draw_xaxis_factors(m_ux, m_trans, labels, this->m_xaxis_hol, scale, mark, ln);
+ else
+ dy_label = draw_axis_m(x_axis, m_ux, m_trans, labels, scale, mark, ln);
+
double dx_label = draw_axis_m(y_axis, m_uy, m_trans, labels, scale, mark, ln);
double ppad_left = plpad, ppad_right = plpad;
- double ppad_bottom = plpad, ppad_top = plpad;
+ double ppad_bottom = plpad + pdy_label, ppad_top = plpad;
double dx_left = dx_label, dx_right = 0.0;
double dy_bottom = dy_label, dy_top = 0.0;
diff --git a/agg-plot/units.h b/agg-plot/units.h
index f315d804..b929e38d 100644
--- a/agg-plot/units.h
+++ b/agg-plot/units.h
@@ -90,7 +90,6 @@ public:
val = m_units.mark_value(m_index);
text = m_buffer;
- text = m_buffer;
m_index ++;
return true;
}
diff --git a/agg-plot/utils.h b/agg-plot/utils.h
index d1274d32..1e66be31 100644
--- a/agg-plot/utils.h
+++ b/agg-plot/utils.h
@@ -40,6 +40,10 @@ public:
return m_list[k];
}
+ T* at(unsigned k) const {
+ return m_list[k];
+ }
+
unsigned size() const {
return m_list.size();
}
generated by cgit v1.2.3 (git 2.25.1) at 2025年09月18日 10:49:23 +0000

AltStyle によって変換されたページ (->オリジナル) /