Add support to specify a format for printing plot axis numbers - 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>2012年07月28日 19:46:40 +0200
committerFrancesco Abbate <francesco.bbt@gmail.com>2012年07月28日 19:46:40 +0200
commitcf077cb0817f498b8f1bb3a52baf8f89dc919a64 (patch)
tree8a73681aa5c59b60320a5615d6e84048a8daeaf5 /agg-plot
parentab805c660ead21e4376d8b67efee703420c51d63 (diff)
downloadgsl-shell-cf077cb0817f498b8f1bb3a52baf8f89dc919a64.tar.gz
Add support to specify a format for printing plot axis numbers
Diffstat (limited to 'agg-plot')
-rw-r--r--agg-plot/lua-plot.cpp 34
-rw-r--r--agg-plot/plot.h 33
-rw-r--r--agg-plot/units.cpp 44
-rw-r--r--agg-plot/units.h 21
4 files changed, 129 insertions, 3 deletions
diff --git a/agg-plot/lua-plot.cpp b/agg-plot/lua-plot.cpp
index 8a6f186a..94c89ceb 100644
--- a/agg-plot/lua-plot.cpp
+++ b/agg-plot/lua-plot.cpp
@@ -65,6 +65,8 @@ static int plot_clear (lua_State *L);
static int plot_save_svg (lua_State *L);
static int plot_xlab_angle_set (lua_State *L);
static int plot_xlab_angle_get (lua_State *L);
+static int plot_xlab_format (lua_State *L);
+static int plot_ylab_format (lua_State *L);
static int plot_ylab_angle_set (lua_State *L);
static int plot_ylab_angle_get (lua_State *L);
static int plot_set_categories (lua_State *L);
@@ -133,6 +135,8 @@ static const struct luaL_Reg plot_properties_set[] = {
{"ytitle", plot_ytitle_set },
{"xlab_angle", plot_xlab_angle_set },
{"ylab_angle", plot_ylab_angle_set },
+ {"xlab_format", plot_xlab_format },
+ {"ylab_format", plot_ylab_format },
{"units", plot_units_set },
{"sync", plot_sync_mode_set },
{"pad", plot_pad_mode_set },
@@ -363,6 +367,36 @@ plot_axis_label_angle_get (lua_State *L, sg_plot::axis_e axis)
return 1;
}
+static int
+plot_axis_label_format (lua_State *L, sg_plot::axis_e axis)
+{
+ sg_plot *p = object_check<sg_plot>(L, 1, GS_PLOT);
+ const char* fmt = luaL_optstring(L, 2, NULL);
+
+ AGG_LOCK();
+ bool success = p->enable_label_format(axis, fmt);
+ AGG_UNLOCK();
+
+ if (success)
+ plot_update_raw (L, p, 1);
+ else
+ luaL_error(L, "got invalid label format: %s", fmt);
+
+ return 0;
+}
+
+int
+plot_xlab_format (lua_State* L)
+{
+ return plot_axis_label_format(L, sg_plot::x_axis);
+}
+
+int
+plot_ylab_format (lua_State* L)
+{
+ return plot_axis_label_format(L, sg_plot::y_axis);
+}
+
int
plot_xlab_angle_set(lua_State *L)
{
diff --git a/agg-plot/plot.h b/agg-plot/plot.h
index a8f4f930..016a65c8 100644
--- a/agg-plot/plot.h
+++ b/agg-plot/plot.h
@@ -103,14 +103,29 @@ public:
axis_e dir;
bool use_categories;
category_map categories;
+ units::format_e format_tag;
axis(axis_e _dir, const char* _title = 0):
title(_title ? _title : ""), dir(_dir), use_categories(false),
+ format_tag(units::format_invalid),
m_labels_angle(0.0),
m_labels_hjustif(_dir == x_axis ? 0.5 : 1.0),
m_labels_vjustif(_dir == x_axis ? 1.0 : 0.5)
{ }
+ const char* label_format() const
+ {
+ return (format_tag == units::format_invalid ? 0 : m_label_format);
+ }
+
+ void set_label_format(units::format_e tag, const char* fmt)
+ {
+ format_tag = tag;
+ memcpy(m_label_format, fmt, strlen(fmt) + 1);
+ }
+
+ void clear_label_format() { format_tag = units::format_invalid; }
+
void set_labels_angle(double angle)
{
double a = (dir == x_axis ? -angle + M_PI/2 : -angle);
@@ -127,6 +142,7 @@ public:
private:
double m_labels_angle;
double m_labels_hjustif, m_labels_vjustif;
+ char m_label_format[units::label_format_max_size];
};
plot(bool use_units = true) :
@@ -230,6 +246,21 @@ public:
bool pad_mode() const { return m_pad_units; }
+ bool enable_label_format(axis_e dir, const char* fmt)
+ {
+ if (!fmt)
+ {
+ get_axis(dir).clear_label_format();
+ return true;
+ }
+
+ units::format_e tag = units::parse_label_format(fmt);
+ if (tag == units::format_invalid)
+ return false;
+ get_axis(dir).set_label_format(tag, fmt);
+ return true;
+ }
+
void enable_categories(axis_e dir) { get_axis(dir).use_categories = true; }
void disable_categories(axis_e dir)
@@ -505,7 +536,7 @@ double plot<VS,RM>::draw_axis_m(axis_e dir, units& u,
double langle = ax.labels_angle();
category_map::iterator clabels(ax.categories);
- units_iterator ulabels(u);
+ units_iterator ulabels(u, ax.format_tag, ax.label_format());
label_iterator* ilabels = (ax.use_categories ? (label_iterator*) &clabels : (label_iterator*) &ulabels);
diff --git a/agg-plot/units.cpp b/agg-plot/units.cpp
index a336e1a0..e05deb98 100644
--- a/agg-plot/units.cpp
+++ b/agg-plot/units.cpp
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <math.h>
+#include <printf.h>
#include "utils.h"
#include "units.h"
@@ -85,3 +86,46 @@ double units::mark_scale (double x)
double xinf = m_inf * dmajor, xsup = m_sup * dmajor;
return (x - xinf) / (xsup - xinf);
}
+
+void units::fmt_label(char* label, unsigned size, format_e tag, const char* fmt, int mark) const
+{
+ double val = mark_value(mark);
+ switch (tag)
+ {
+ case format_int:
+ {
+ unsigned nchars = snprintf(label, size, fmt, int(val));
+ if (nchars >= size)
+ label[size-1] = 0;
+ break;
+ }
+ case format_float:
+ {
+ unsigned nchars = snprintf(label, size, fmt, val);
+ if (nchars >= size)
+ label[size-1] = 0;
+ break;
+ }
+ default:
+ memcpy(label, "*", 2);
+ }
+}
+
+units::format_e units::parse_label_format(const char* fmt)
+{
+ if (strlen(fmt) >= label_format_max_size)
+ return format_invalid;
+
+ int arg;
+ int nwanted = parse_printf_format(fmt, 1, &arg);
+ const int nope = PA_FLAG_PTR|PA_FLAG_SHORT|PA_FLAG_LONG_LONG|PA_FLAG_LONG_DOUBLE;
+ if (nwanted != 1 || (arg & nope))
+ return format_invalid;
+ int arg_type = (arg & ~PA_FLAG_MASK);
+ if (arg_type == PA_INT)
+ return format_int;
+ else if (arg_type == PA_DOUBLE)
+ return format_float;
+
+ return format_invalid;
+}
diff --git a/agg-plot/units.h b/agg-plot/units.h
index 05eb14a9..4ab0ee9e 100644
--- a/agg-plot/units.h
+++ b/agg-plot/units.h
@@ -37,6 +37,9 @@ private:
void init(double min, double max, double spacefact);
public:
+ enum { label_format_max_size = 12 };
+ enum format_e { format_int, format_float, format_invalid };
+
units(): m_major(1), order(0), dmajor(1), m_inf(0), m_sup(1), nb_decimals(0) {};
units (double min, double max, double spacefact = 4.0)
{ init(min, max, spacefact); };
@@ -52,21 +55,33 @@ public:
};
void mark_label (char *label, unsigned size, int mark) const;
+ void fmt_label(char* label, unsigned size, format_e tag, const char* fmt, int mark) const;
double mark_value (int mark) const { return dmajor * mark; };
double mark_scale(double x);
+
+ static format_e parse_label_format(const char* fmt);
};
class units_iterator : public label_iterator {
public:
- units_iterator(const units& u) : m_units(u) { m_index = u.begin(); }
+ units_iterator(const units& u, units::format_e tag, const char* fmt):
+ m_units(u), m_fmt_tag(tag), m_fmt(fmt)
+ {
+ m_index = u.begin();
+ }
virtual bool next(double& val, const char*& text)
{
if (m_index > m_units.end())
return false;
+ if (m_fmt)
+ m_units.fmt_label(m_buffer, 32, m_fmt_tag, m_fmt, m_index);
+ else
+ m_units.mark_label(m_buffer, 32, m_index);
+
val = m_units.mark_value(m_index);
- m_units.mark_label(m_buffer, 32, m_index);
+ text = m_buffer;
text = m_buffer;
m_index ++;
return true;
@@ -76,6 +91,8 @@ private:
char m_buffer[32];
int m_index;
const units& m_units;
+ units::format_e m_fmt_tag;
+ const char* m_fmt;
};
#endif
generated by cgit v1.2.3 (git 2.39.1) at 2025年09月21日 07:26:35 +0000

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