|
Boost-Commit : |
From: pbristow_at_[hidden]
Date: 2007-11-29 14:34:36
Author: pbristow
Date: 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
New Revision: 41469
URL: http://svn.boost.org/trac/boost/changeset/41469
Log:
More improvements & tests but still unfinished, especially vertical and horizontal labels not implemented yet. And still needed Boost.Parameter replaced by class.
Text files modified:
sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp | 536 ++++++++++++++++------
sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_style_detail.hpp | 39
sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp | 63 +-
sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp | 63 +
sandbox/SOC/2007/visualization/boost/svg_plot/svg_1d_plot.hpp | 52 +
sandbox/SOC/2007/visualization/boost/svg_plot/svg_2d_plot.hpp | 935 +++++++++++++++++++++++++--------------
sandbox/SOC/2007/visualization/boost/svg_plot/svg_boxplot.hpp | 24
sandbox/SOC/2007/visualization/boost/svg_plot/svg_color.hpp | 11
sandbox/SOC/2007/visualization/boost/svg_plot/svg_style.hpp | 21
sandbox/SOC/2007/visualization/libs/svg_plot/doc/svg_plot.qbk | 43 +
sandbox/SOC/2007/visualization/libs/svg_plot/test/1d_color_consistency.cpp | 4
11 files changed, 1187 insertions(+), 604 deletions(-)
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
@@ -85,7 +85,7 @@
}
void draw_x_minor_ticks(double value, path_element& tick_path, path_element& grid_path)
- { // draw X-axis minor ticks, and optionaloly grid.
+ { // draw X-axis minor ticks, and optional grid.
// value is NOT (yet) shown beside the minor tick.
double x1(value);
transform_x(x1);
@@ -93,18 +93,18 @@
double y2(derived().image.y_size());
// Draw the minor grid, if wanted.
- if(derived().use_x_minor_grid)
+ if(derived().use_x_minor_grid_)
{
if(!derived().use_plot_window)
{ // Use whole image.
// Make space for title and X-axis labels.
if(derived().use_title)
- { // Allow text_margin * font_size around text (pixels).
- y1 += derived().title_info.font_size() * derived().text_margin;
+ { // Allow text_margin_ * font_size around text (pixels).
+ y1 += derived().title_info.font_size() * derived().text_margin_;
}
if(derived().use_x_label)
{
- y2 -= derived().x_label_info.font_size() * derived().text_margin;
+ y2 -= derived().x_label_info.font_size() * derived().text_margin_;
}
}
else
@@ -177,17 +177,17 @@
transform_x(x1);
double y1(0.); // // y1 = upper,
double y2(derived().image.x_size()); // y2 = lower end of tick.
- if(derived().use_x_major_grid)
+ if(derived().use_x_major_grid_)
{ // Draw major grid vertical line.
if(!derived().use_plot_window)
{ // Allow a modest margin around text of title and X-axis labels, if in use.
if(derived().use_title)
{
- y1 += derived().title_info.font_size() * derived().text_margin;
+ y1 += derived().title_info.font_size() * derived().text_margin_;
}
if(derived().use_x_label)
{ // If use_x_major_labels then value may be shown beside the major tick.
- y2 -= derived().x_label_info.font_size() * derived().text_margin;
+ y2 -= derived().x_label_info.font_size() * derived().text_margin_;
}
}
else
@@ -200,7 +200,7 @@
// Draw major tick (perhaps as well as grid - ticks might be wider than grid).
// Make sure that we are drawing inside the allowed plot window.
- if((x1 > derived().plot_x1) && (x1 < derived().plot_x2)) // < or <= ???
+ if((x1 >= derived().plot_x1) && (x1 <= derived().plot_x2)) // now <=
{
double x_tick_length = derived().x_major_tick_length_;
if(derived().use_x_ticks_on_plot_window_)
@@ -230,36 +230,42 @@
}
}
tick_path.M(x1, y1).L(x1, y2);
+ // Leaving current position at the bottom end of the tick.
if(derived().use_x_major_labels )
{ // Show value by the tick.
- std::stringstream fmt;
- fmt << value; // TODO precision problems here?
- // TODO if 2-D, don NOT want a "0" here - cut in two by the Y-axis line!
- // But DO want it if 1-D. How do we tell if 2-D?
- if(fmt.str() != "0") // && is_2D) wanted here.
- {
- if(derived().use_x_ticks)
- {
- y2 += derived().text_margin;
- // move down by a font height?
- if (derived().use_down_ticks)
- { // Move down a tick.
- y2 += derived().x_major_tick_length_;
- }
- }
- else
- { // ! internal_style
- y2 += derived().text_margin + x_tick_length; // Move down.
+ std::stringstream label;
+ label << value; // TODO precision problems here?
+
+ if(derived().use_down_ticks)
+ { // No need to shift if derived().use_up_ticks as labels are below the X-axis.
+ y2 += derived().x_label_info.font_size(); // Move down just below bottom end of tick.
+ }
+ if(derived().use_x_ticks_on_plot_window_)
+ { // Always want all values including "0" if labelling on the external plot window.
+ y2,
+ derived().image.get_g_element(detail::PLOT_VALUE_LABELS).text(x1, y2,
+ label.str(), derived().x_label_info.font_size(), derived().x_label_info.font_family(),
+ "", "", "", "", center_align, // center label on the tick.
+ horizontal);
+ }
+ else
+ { // Internal - value labels just below horizontal X-axis.
+ if ((value != 0) && derived().use_x_axis_lines_)
+ { // Avoid a "0" below the X-axis if it would be cut through by the vertical Y-axis line.
+ y2,
+ derived().image.get_g_element(detail::PLOT_VALUE_LABELS).text(x1, y2,
+ label.str(), derived().x_label_info.font_size(), derived().x_label_info.font_family(),
+ "", "", "", "", center_align, // center label on the tick.
+ horizontal);
}
- derived().image.get_g_element(PLOT_PLOT_LABELS).text(x1, y2, fmt.str());
}
- }// use_x_major_labels
+ } // use_x_major_labels
}
else
{ // Outside plot window - so do nothing? Warning?
- //std::cerr << "Writing draw_x_major_ticks OUTside plot window: "
- // "x1 = " << x1 << ", plot_x1 = " << derived().plot_x1 << ", plot_x2 = " << derived().plot_x2 << std::endl;
+ //std::cerr << "Writing draw_x_major_ticks OUTside plot window: "
+ // "x1 = " << x1 << ", plot_x1 = " << derived().plot_x1 << ", plot_x2 = " << derived().plot_x2 << std::endl;
}
} // draw_x_major_ticks
@@ -276,22 +282,23 @@
if(derived().use_x_axis_lines_)
{ // Draw the horizontal X-axis line.
- derived().image.get_g_element(PLOT_X_AXIS).line(derived().plot_x1, derived().x_axis,
+ derived().image.get_g_element(PLOT_X_AXIS).line(
+ derived().plot_x1, derived().x_axis,
derived().plot_x2, derived().x_axis);
}
// x_minor_jump is the interval between minor ticks.
- double x_minor_jump = derived().x_major /
- ((double)(derived().x_num_minor_ticks_ + 1.) );
+ double x_minor_jump = derived().x_major_interval_ /
+ (derived().x_num_minor_ticks_ + 1.);
// TODO Problem here when using floating point??
// Was i < y_max; but didn't show the tick and value at y_max so now i <= y_max;
// But may still fail if a least significant bit or few out??
// Draw the ticks on the positive side (right of zero).
- for(double x = 0; x <= derived().x_max; x += derived().x_major)
+ for(double x = 0.; x <= derived().x_max; x += derived().x_major_interval_)
{
- for(double j = x + x_minor_jump; j < x + derived().x_major; j += x_minor_jump)
+ for(double j = x + x_minor_jump; j < x + derived().x_major_interval_; j += x_minor_jump)
{ // This will output 'orphaned' minor ticks that are beyond the plot window,
// if the last major tick does not coincide with the plot window.
// These are just ignored in draw_x_minor_ticks.
@@ -304,10 +311,12 @@
}
// Draw the ticks on the negative side (left of zero).
- for(double x = 0; x >= derived().x_min; x -= derived().x_major)
+ for(double x = 0; x >= derived().x_min; x -= derived().x_major_interval_)
{
// Draw minor ticks.
- for(double j = x; j > x-derived().x_major; j-= derived().x_major / (derived().x_num_minor_ticks_+1))
+ for(double j = x;
+ j > x-derived().x_major_interval_;
+ j-= derived().x_major_interval_ / (derived().x_num_minor_ticks_+1))
{
draw_x_minor_ticks(j, minor_tick_path, minor_grid_path);
}
@@ -341,7 +350,7 @@
}
else
{ // use all image.
- y = derived().title_info.font_size() * derived().text_margin; // Leave a linespace above.
+ y = derived().title_info.font_size() * derived().text_margin_; // Leave a linespace above.
}
derived().title_info.y(y);
derived().image.get_g_element(PLOT_TITLE).push_back(new text_element(derived().title_info));
@@ -350,12 +359,12 @@
void draw_legend()
{
size_t num_points = derived().series.size();
- int font_size = derived().legend_header.font_size();
+ int font_size = derived().legend_header_.font_size();
int point_size = derived().series[0].point_style.size;
// Use whichever is the biggest of point marker and font.
double spacing = (std::max)(font_size, point_size);
- bool is_header = (derived().legend_header.text() != "");
+ bool is_header = (derived().legend_header_.text() != "");
// std::cerr << spacing << ' ' << font_size << ' ' << point_size << endl;
double legend_width(0); //
size_t longest = 0;
@@ -375,12 +384,12 @@
// space, text, trailing space before box margin.
// legend_height must be *at least* enough for
- // the legend title and text_margins around it
- // (if any) plus a text_margin top and bottom.
+ // the legend title and text_margin_s around it
+ // (if any) plus a text_margin_ top and bottom.
// Add more height depending on the number of lines of text.
double legend_height = 2. * spacing;
if (derived().use_title) // plot title
- // && derived().legend_header.text() != "" leave space even if no string?
+ // && derived().legend_header_.text() != "" leave space even if no string?
{
legend_height += spacing;
}
@@ -400,21 +409,25 @@
<< " pixels, & so truncated. legend_width == " << legend_width << std::endl;
// For example:
// "Legend text line was too long by about 84 pixels & so truncated. legend_width == 252"
- legend_width = x_size - legend_x_start - derived().text_margin;
- // text_margin just allows the border box to show.
+ legend_width = x_size - legend_x_start - derived().text_margin_;
+ // text_margin_ just allows the border box to show.
}
// Draw border box round legend.
g_element* g_ptr = &(derived().image.get_g_element(PLOT_LEGEND_BACKGROUND));
- g_ptr->push_back(new rect_element(legend_x_start, legend_y_start,
- legend_width, legend_height));
+ g_ptr->push_back(new
+ rect_element(legend_x_start, legend_y_start, legend_width, legend_height));
+ derived().legend_x1_ = legend_x_start; // Save for acces by legend_to_left
+ derived().legend_x2_ = legend_width;
+ derived().legend_y1_ = legend_y_start; // and legend_bottom_right.
+ derived().legend_y2_ = legend_height;
- double legend_y_pos = legend_y_start + derived().text_margin * spacing;
+ double legend_y_pos = legend_y_start + derived().text_margin_ * spacing;
if (is_header)
{ // Draw the legend text.
- derived().legend_header.x(legend_x_start + legend_width / 2.); // / 2. to center in legend box.
- derived().legend_header.y(legend_y_pos);
- derived().image.get_g_element(PLOT_LEGEND_TEXT).push_back(new text_element(derived().legend_header));
+ derived().legend_header_.x(legend_x_start + legend_width / 2.); // / 2. to center in legend box.
+ derived().legend_header_.y(legend_y_pos);
+ derived().image.get_g_element(PLOT_LEGEND_TEXT).push_back(new text_element(derived().legend_header_));
legend_y_pos += 2 * spacing;
}
@@ -464,7 +477,7 @@
legend_x_pos, // allow space for the marker.
legend_y_pos,
derived().series[i].title, // Text for this data series.
- derived().legend_header.font_size(), // font size
+ derived().legend_header_.font_size(), // font size
"", "", "", "", "", // TODO full font info for legend needed here?
left_align));
legend_y_pos += 2 * spacing;
@@ -473,38 +486,47 @@
// TODO reconsider this.
//if(derived().plot_x2 >= (int)derived().image.x_size())
//{ // Put legend above plot because image is tall & thin.
- // // TODO this properly.
+ // // TODO this with use control of the legend box position.
//}
} // void draw_legend()
void draw_x_label()
{
- // color set in constructor.
+ // color is set in constructor.
//image.get_g_element(detail::PLOT_X_LABEL).style().stroke_color(black);
+ // and using y_label_color(color)
std::string label = derived().x_label_info.text(); // x_axis label, and optional units.
if (derived().use_x_label_units && (derived().x_units_info.text() != ""))
{ // Append the units, if any, providing brackets ().
label += " (" + derived().x_units_info.text() + ")";
}
+ // Simplest to start from the bottom of the image.
+ // and move up to give enough sapce for the X-axis label.
- double y(0.);
- transform_y(y);
- derived().x_axis = y; // X-axis line at y = 0.
- y += derived().x_label_font_size() * 2.5; // values & label & half line space.
- if (derived().use_down_ticks)
- { // Make space for ticks down.
- y += derived().x_major_tick_length(); // down.
- // TODO actually want (std::max)::(derived().x_major_tick_length(), derived().x_minor_tick_length())?
- //TODO where do the brackets go??
-
- }
+ //double y(0.);
+ //transform_y(y);
+ //derived().x_axis = y; // X-axis line at y = 0.
+ //y += derived().x_label_font_size() * 2.5; // values & label & half line space.
+ //if (derived().use_down_ticks)
+ //{ // Make space for ticks down.
+ // y += (std::max)(derived().x_major_tick_length(), derived().x_minor_tick_length());
+ // // Brackets avoid trouble with any nasty macro max.
+ // // Use max in case some joker uses longer minor ticks than major.
+ //}
+ //if (derived().x_ticks_on_plot_window_on())
+ //{ // Allow space for the values labelling the ticks.
+ // y += derived().x_label_font_size() * derived().text_margin_;
+ //}
+ // Bottom of plot window plus two char height.
+ // derived().plot_y2 + (derived().x_label_font_size() * derived().text_margin_),
+ double y = derived().image.y_size(); // bottom edge of image.
+ y -= derived().x_label_font_size(); // Up enough for a space underneath label.
derived().image.get_g_element(PLOT_X_LABEL).push_back(new text_element(
( // x position relative to the x-axis which is middle of plot window.
derived().plot_x2 + derived().plot_x1) / 2, // x coordinate - middle.
- // y position is down from plot window.
- derived().plot_y2 + (derived().x_label_font_size() * derived().text_margin),
+ y, // Up from image bottom edge.
label,
derived().x_label_font_size(),
derived().x_label_font_family(), "", "", "", "", center_align, horizontal)
@@ -687,12 +709,12 @@
void clear_points()
{
- derived().image.get_g_element(PLOT_PLOT_POINTS).clear();
+ derived().image.get_g_element(PLOT_DATA_POINTS).clear();
}
void clear_plot_background()
{
- derived().image.get_g_element(PLOT_PLOT_BACKGROUND).clear();
+ derived().image.get_g_element(PLOT_WINDOW_BACKGROUND).clear();
}
void clear_legend()
@@ -708,7 +730,7 @@
derived().image.get_g_element(PLOT_X_MINOR_TICKS).clear();
derived().image.get_g_element(PLOT_X_MAJOR_TICKS).clear();
derived().image.get_g_element(PLOT_X_LABEL).clear();
- derived().image.get_g_element(PLOT_PLOT_LABELS).clear();
+ derived().image.get_g_element(PLOT_VALUE_LABELS).clear();
}
void clear_y_axis()
@@ -720,6 +742,9 @@
{
derived().image.get_g_element(PLOT_X_MAJOR_GRID).clear();
derived().image.get_g_element(PLOT_X_MINOR_GRID).clear();
+ // TODO don't we need to clear Y grids too??????
+ derived().image.get_g_element(PLOT_Y_MAJOR_GRID).clear();
+ derived().image.get_g_element(PLOT_Y_MINOR_GRID).clear();
}
private:
@@ -906,6 +931,33 @@
return derived();
}
+ svg_color background_color()
+ {
+ return derived().image.get_g_element(PLOT_BACKGROUND).style().fill_color();
+ }
+
+ Derived& background_border_color(const svg_color& col)
+ {
+ derived().image.get_g_element(PLOT_BACKGROUND).style().stroke_color(col);
+ return derived();
+ }
+
+ svg_color background_border_color()
+ {
+ return derived().image.get_g_element(PLOT_BACKGROUND).style().stroke_color();
+ }
+
+ Derived& background_border_width(double w)
+ {
+ derived().image.get_g_element(PLOT_BACKGROUND).style().stroke_width(w);
+ return derived();
+ }
+
+ double background_border_width()
+ {
+ return derived().image.get_g_element(PLOT_BACKGROUND).style().stroke_width();
+ }
+
Derived& description(const std::string d)
{ // Writes description to the document(for header as <desc>).
derived().image.description(d);
@@ -952,13 +1004,40 @@
return derived().image.copyright_date();
}
- Derived& license(std::string repro, std::string distrib, std::string attrib, std::string commercial)
+ Derived& license(std::string repro = "permits",
+ std::string distrib = "permits",
+ std::string attrib = "requires",
+ std::string commercial = "permits")
{ // Might check these are "permits", "requires", or "prohibits"?
- // Default is permits.
derived().image.license(repro, distrib, attrib, commercial);
return derived();
}
+ const bool license_on()
+ {
+ return derived().image.is_license();
+ }
+
+ const std::string license_reproduction()
+ { // Get copyright_date.
+ return derived().image.reproduction();
+ }
+
+ const std::string license_distribution()
+ { // Get copyright_date.
+ return derived().image.distribution();
+ }
+
+ const std::string license_attribution()
+ { // Get copyright_date.
+ return derived().image.attribution();
+ }
+
+ const std::string license_commercialuse()
+ { // Get copyright_date.
+ return derived().image.commercialuse();
+ }
+
Derived& coord_precision(int digits)
{ // Precision of coordinates in decimal digits (default 3).
derived().image.coord_precision(digits);
@@ -970,6 +1049,17 @@
return derived().image.coord_precision();
}
+ Derived& value_precision(int digits)
+ { // Precision of tick label values in decimal digits (default 3).
+ derived().value_precision_(digits);
+ return derived();
+ }
+
+ int value_precision()
+ { //
+ return derived().value_precision_;
+ }
+
Derived& title(const std::string title)
{ // Plot title.
derived().title_info.text(title);
@@ -1071,24 +1161,52 @@
Derived& legend_title(const std::string title)
{
- derived().legend_header.text(title);
+ derived().legend_header_.text(title);
return derived();
}
const std::string legend_title()
{
- return derived().legend_header.text();
+ return derived().legend_header_.text();
}
Derived& legend_title_font_size(unsigned int size)
{
- derived().legend_header.font_size(size);
+ derived().legend_header_.font_size(size);
return derived();
}
unsigned int legend_title_font_size()
{
- return derived().legend_header.font_size();
+ return derived().legend_header_.font_size();
+ }
+
+ Derived& legend_top_left(double x, double y)
+ { // Position of top left of legend box (svg coordinates).
+ // Bottom right is controlled by contents, so cannot set it.
+ if((x < 0) || (x > derived().image.x_size()) || (y < 0) || (y > derived().image.y_size()))
+ {
+ throw std::runtime_error("Illegal legend box position.");
+ }
+ derived().legend_x1_ = x;
+ derived().legend_y1_ = y;
+ return derived();
+ }
+
+ std::pair<double, double> legend_top_left()
+ {// Top left of legend box
+ std::pair<double, double> r;
+ r.first = derived().legend_x1_;
+ r.second = derived().legend_y1_;
+ return r;
+ }
+
+ std::pair<double, double> legend_bottom_right()
+ {// Top left of legend box
+ std::pair<double, double> r;
+ r.first = derived().legend_x2_;
+ r.second = derived().legend_y2_;
+ return r;
}
Derived& line_on(bool is)
@@ -1105,7 +1223,6 @@
Derived& legend_on(bool cmd)
{
derived().use_legend = cmd;
-
if(cmd)
{
derived().image.get_g_element(detail::PLOT_LEGEND_BACKGROUND)
@@ -1127,7 +1244,7 @@
if(cmd)
{ // set plot window color and border color.
// TODO - allow user to change these.
- derived().image.get_g_element(detail::PLOT_PLOT_BACKGROUND)
+ derived().image.get_g_element(detail::PLOT_WINDOW_BACKGROUND)
.style().fill_color(white)
.stroke_color(black);
}
@@ -1139,7 +1256,51 @@
return derived().use_plot_window;
}
- Derived& plot_window_x(unsigned int min_x, unsigned int max_x)
+ Derived& plot_border_color(const svg_color& col)
+ {
+ derived().image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).style().stroke_color(col);
+ return derived();
+ }
+
+ svg_color plot_border_color()
+ {
+ return derived().image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).style().stroke_color();
+ }
+
+ double plot_border_width()
+ {
+ return derived().image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).style().stroke_width();
+ }
+
+ Derived& plot_border_width(double w)
+ {
+ derived().image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).style().stroke_width(w);
+ return derived();
+ }
+
+ Derived& border_margin(double w)
+ {
+ derived().border_margin_ = w;
+ return derived();
+ }
+
+ double border_margin()
+ {
+ return derived().border_margin_;
+ }
+
+ Derived& border_width(double w)
+ {
+ derived().border_width_ = w;
+ return derived();
+ }
+
+ double border_width()
+ {
+ return derived().border_width_;
+ }
+
+ Derived& plot_window_x(double min_x, double max_x)
{ // This is normally calculated from other plot values.
if(max_x <= min_x)
{
@@ -1150,7 +1311,7 @@
return derived();
}
- Derived& plot_window_y(unsigned int min_y, unsigned int max_y)
+ Derived& plot_window_y(double min_y, double max_y)
{ // This is normally calculated from other plot values.
if(max_y <= min_y)
{
@@ -1161,22 +1322,50 @@
return derived();
}
- std::pair<unsigned int, unsigned int> plot_window_x()
+ std::pair<double, double> plot_window_x()
{
- std::pair<unsigned int, unsigned int> r;
+ std::pair<double, double> r;
r.first = derived().plot_x1;
r.second = derived().plot_x2;
return r;
}
- std::pair<unsigned int, unsigned int> plot_window_y()
+ double plot_window_x_left()
+ {
+ return derived().plot_x1;
+ }
+ double plot_window_x_right()
{
- std::pair<unsigned int, unsigned int> r;
+ return derived().plot_x2;
+ }
+ double plot_window_y_top()
+ {
+ return derived().plot_y1;
+ }
+ double plot_window_y_bottom()
+ {
+ return derived().plot_y2;
+ }
+
+
+ std::pair<double, double> plot_window_y()
+ {
+ std::pair<double, double> r;
r.first = derived().plot_y1;
r.second = derived().plot_y2;
return r;
}
+ double x_minor_interval()
+ {
+ return derived().x_minor_interval_; // interval
+ }
+
+ double y_minor_interval()
+ {
+ return derived().y_minor_interval_; // interval
+ }
+
Derived& x_ticks_up_on(bool cmd)
{
derived().use_up_ticks = cmd;
@@ -1201,7 +1390,7 @@
// Only need y_ticks_left_on & y_ticks_right_on in 2D
Derived& x_label_on(bool cmd)
- { // Show X-axis label text.
+ { // Show X-axis label text, or not.
derived().use_x_label = cmd;
return derived();
}
@@ -1223,7 +1412,6 @@
return derived().x_label_info.font_size();
}
-
Derived& x_label_font_family(const std::string& family)
{
derived().x_label_info.font_family(family);
@@ -1237,36 +1425,36 @@
Derived& x_axis_label_color(const svg_color& col)
{ // Set BOTH stroke and fill to the same color.
- image.get_g_element(detail::PLOT_X_LABEL).style().fill_color(col);
- image.get_g_element(detail::PLOT_X_LABEL).style().stroke_color(col);
+ derived().image.get_g_element(detail::PLOT_X_LABEL).style().fill_color(col);
+ derived().image.get_g_element(detail::PLOT_X_LABEL).style().stroke_color(col);
return *this;
}
svg_color x_axis_label_color()
{ // But only return the stroke color.
- return image.get_g_element(detail::PLOT_X_LABEL).style().stroke_color();
+ return derived().image.get_g_element(detail::PLOT_X_LABEL).style().stroke_color();
}
Derived& x_axis_value_color(const svg_color& col)
{ // Set BOTH stroke and fill to the same color.
- image.get_g_element(detail::PLOT_PLOT_LABELS).style().fill_color(col);
- image.get_g_element(detail::PLOT_PLOT_LABELS).style().stroke_color(col);
+ derived().image.get_g_element(detail::PLOT_VALUE_LABELS).style().fill_color(col);
+ derived().image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color(col);
return *this;
}
svg_color x_axis_value_color()
{ // But only return the stroke color.
- return image.get_g_element(detail::PLOT_PLOT_LABELS).style().stroke_color();
+ return derived().image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color();
}
- Derived& use_x_ticks_on_plot_window(bool cmd)
- { // Was External style.
+ Derived& x_ticks_on_plot_window_on(bool cmd)
+ { // External style.
derived().use_x_ticks_on_plot_window_ = cmd;
return derived();
}
- bool use_x_ticks_on_plot_window()
- {
+ bool x_ticks_on_plot_window_on()
+ { // External style = true.
return derived().use_x_ticks_on_plot_window_;
}
@@ -1292,6 +1480,17 @@
return derived().use_x_major_labels;
}
+ Derived& x_major_label_up(bool cmd)
+ {
+ derived().use_x_label_up_ = cmd;
+ return derived();
+ }
+
+ bool x_major_label_up()
+ {
+ return derived().use_x_label_up_;
+ }
+
Derived& title_on(bool cmd)
{
derived().use_title = cmd;
@@ -1305,24 +1504,24 @@
Derived& x_major_grid_on(bool is)
{
- derived().use_x_major_grid = is;
+ derived().use_x_major_grid_ = is;
return derived();
}
bool x_major_grid_on()
{
- return derived().use_x_major_grid;
+ return derived().use_x_major_grid_;
}
Derived& x_minor_grid_on(bool is)
{
- derived().use_x_minor_grid = is;
+ derived().use_x_minor_grid_ = is;
return derived();
}
bool x_minor_grid_on()
{
- return derived().use_x_minor_grid;
+ return derived().use_x_minor_grid_;
}
Derived& axes_on(bool is)
@@ -1338,7 +1537,7 @@
}
Derived& x_axis_on(bool is)
- {
+ { // Draw a horizontal x_axis line.
derived().use_x_axis_lines_ = is;
return derived();
}
@@ -1349,14 +1548,14 @@
}
Derived& y_axis_on(bool is)
- {
- derived().use_x_axis_lines_ = is;
+ {// Draw a vertical y_axis line.
+ derived().use_y_axis_lines_ = is;
return derived();
}
bool y_axis_on()
{ // Should be always false for 1D.
- return derived().use_x_axis_lines_;
+ return derived().use_y_axis_lines_;
}
// enums like PLOT_TITLE provide a std:string like "title"
@@ -1375,15 +1574,45 @@
return derived().image.get_g_element(PLOT_TITLE).style().stroke_color();
}
- Derived& background_color(const svg_color& col)
+ Derived& title_width(double width)
+ { // width of text is effectively the boldness
+ derived().image.get_g_element(PLOT_TITLE).style().stroke_width(width);
+ return derived();
+ }
+
+ double title_width()
{
- derived().image.get_g_element(PLOT_BACKGROUND).style().fill_color(col);
+ return derived().image.get_g_element(PLOT_TITLE).style().stroke_width();
+ }
+
+ Derived& legend_color(const svg_color& col)
+ {
+ derived().image.get_g_element(PLOT_LEGEND_TEXT).style().fill_color(col);
+ derived().image.get_g_element(PLOT_LEGEND_TEXT).style().stroke_color(col);
return derived();
}
- svg_color background_color()
+ svg_color legend_color()
+ { // Function legend_color sets both fill and stroke,
+ // but stroke (outside) is considered 'more important'.
+ return derived().image.get_g_element(PLOT_LEGEND_TEXT).style().stroke_color();
+ }
+
+ Derived& legend_width(double width)
+ { // width of text is effectively the boldness
+ derived().image.get_g_element(PLOT_LEGENDTEXT).style().stroke_width(width);
+ return derived();
+ }
+
+ double legend_width()
{
- return derived().image.get_g_element(PLOT_BACKGROUND).style().fill_color();
+ return derived().image.get_g_element(PLOT_LEGEND_TEXT).style().stroke_width();
+ }
+
+ Derived& background_color(const svg_color& col)
+ {
+ derived().image.get_g_element(PLOT_BACKGROUND).style().fill_color(col);
+ return derived();
}
Derived& legend_background_color(const svg_color& col)
@@ -1408,26 +1637,15 @@
return derived().image.get_g_element(PLOT_LEGEND_BACKGROUND).style().stroke_color();
}
- Derived& background_border_color(const svg_color& col)
- {
- derived().image.get_g_element(PLOT_BACKGROUND).style().stroke_color(col);
- return derived();
- }
-
- svg_color background_border_color()
- {
- return derived().image.get_g_element(PLOT_BACKGROUND).style().stroke_color();
- }
-
Derived& plot_background_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_PLOT_BACKGROUND).style().fill_color(col);
+ derived().image.get_g_element(PLOT_WINDOW_BACKGROUND).style().fill_color(col);
return derived();
}
svg_color plot_background_color()
{
- return derived().image.get_g_element(PLOT_PLOT_BACKGROUND).style().fill_color();
+ return derived().image.get_g_element(PLOT_WINDOW_BACKGROUND).style().fill_color();
}
Derived& x_axis_color(const svg_color& col)
@@ -1463,6 +1681,19 @@
return derived();
}
+ Derived& x_label_width(double width)
+ { // width of text is effectively the boldness.
+ x_label_width_ = width;
+ derived().image.get_g_element(PLOT_X_LABEL).style().stroke_width(width);
+ return derived();
+ }
+
+ double x_label_width()
+ {
+ //return x_label_width_;
+ return derived().image.get_g_element(PLOT_X_LABEL).style().stroke_width();
+ }
+
svg_color x_label_color()
{
return derived().image.get_g_element(PLOT_X_LABEL).style().fill_color();
@@ -1513,13 +1744,13 @@
return derived().image.get_g_element(PLOT_X_MAJOR_GRID).style().stroke_color();
}
- Derived& x_major_grid_width(unsigned int w)
+ Derived& x_major_grid_width(double w)
{
derived().image.get_g_element(PLOT_X_MAJOR_GRID).style().stroke_width(w);
return derived();
}
- unsigned int x_major_grid_width()
+ double x_major_grid_width()
{
return derived().image.get_g_element(PLOT_X_MAJOR_GRID).style().stroke_width();
}
@@ -1535,24 +1766,24 @@
return derived().image.get_g_element(PLOT_X_MINOR_GRID).style().stroke_color();
}
- Derived& x_minor_grid_width(unsigned int w)
+ Derived& x_minor_grid_width(double w)
{
derived().image.get_g_element(PLOT_X_MINOR_GRID).style().stroke_width(w);
return derived();
}
- unsigned int x_minor_grid_width()
+ double x_minor_grid_width()
{
return derived().image.get_g_element(PLOT_X_MINOR_GRID).style().stroke_width();
}
- Derived& x_axis_width(unsigned int width)
+ Derived& x_axis_width(double width)
{
derived().image.get_g_element(PLOT_X_AXIS).style().stroke_width(width);
return derived();
}
- unsigned int x_axis_width()
+ double x_axis_width()
{
return derived().image.get_g_element(PLOT_X_AXIS).style().stroke_width();
}
@@ -1591,60 +1822,70 @@
return derived().y_label_info.text();
}
+ Derived& y_label_units(const std::string& str)
+ {
+ derived().y_units_info.text(str);
+ return derived();
+ }
+
+ std::string y_label_units()
+ {
+ return derived().y_units_info.text();
+ }
+
Derived& x_major_interval(double inter)
{
- derived().x_major = inter;
+ derived().x_major_interval_ = inter;
return derived();
}
double x_major_interval()
{
- return derived().x_major;
+ return derived().x_major_interval_;
}
- Derived& x_major_tick_length(unsigned int length)
+ Derived& x_major_tick_length(double length)
{
derived().x_major_tick_length_ = length;
return derived();
}
- unsigned int x_major_tick_length()
+ double x_major_tick_length()
{
return derived().x_major_tick_length_;
}
- Derived& x_major_tick_width(unsigned int width)
+ Derived& x_major_tick_width(double width)
{
derived().x_major_tick_width_ = width; // Redundant?
derived().image.get_g_element(PLOT_X_MAJOR_TICKS).style().stroke_width(width);
return derived();
}
- unsigned int x_major_tick_width()
+ double x_major_tick_width()
{
return derived().image.get_g_element(PLOT_X_MAJOR_TICKS).style().stroke_width();
}
- Derived& x_minor_tick_length(unsigned int length)
+ Derived& x_minor_tick_length(double length)
{
derived().x_minor_tick_length_ = length;
- // TODO ?? derived().image.get_g_element(PLOT_X_MINOR_TICKS).style().stroke_width(width);
return derived();
}
- unsigned int x_minor_tick_length()
+ double x_minor_tick_length()
{
return derived().x_minor_tick_length_;
}
- Derived& x_minor_tick_width(unsigned int width)
+ Derived& x_minor_tick_width(double width)
{
derived().x_minor_tick_width_ = width;
derived().image.get_g_element(PLOT_X_MINOR_TICKS).style().stroke_width(width);
return derived();
}
- unsigned int x_minor_tick_width()
+ double x_minor_tick_width()
{
// return derived().x_minor_tick_width_; // should be the same but store in stroke_width is definitive.
return derived().image.get_g_element(PLOT_X_MINOR_TICKS).style().stroke_width();
@@ -1652,12 +1893,18 @@
Derived& x_major_tick(double d)
{ // Interval (Cartesian units) between major ticks.
- derived().x_major = d;
+ derived().x_major_interval_ = d;
}
double x_major_tick()
{ // Interval (Cartesian units) between major ticks.
- return derived().x_major;
+ return derived().x_major_interval_;
+ }
+
+ Derived& x_minor_interval(double interval)
+ { // aka x_minor_tick
+ derived().x_minor_interval_ = interval;
+ return derived();
}
Derived& x_num_minor_ticks(unsigned int num)
@@ -1667,7 +1914,7 @@
}
unsigned int x_num_minor_ticks()
- {
+ { // NB NOT float or double!
return derived().x_num_minor_ticks_;
}
@@ -1690,13 +1937,12 @@
return r;
}
- // Can't use names x_min or x_max because clashes
- // with class svg_1d_plot variable x_min & x_max,
+ // Avoid clashes with class svg_1d_plot variable x_min & x_max,
// so use longer x_minimum, x_maximum ...
Derived& x_minimum(double min_x)
{
// Can't check here that x_max > x_min because may not have set x_max yet.
- // TODO check that there is another check somewhere.
+ // TODO ensure that there is another check somewhere.
derived().x_min = min_x;
return derived();
}
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_style_detail.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_style_detail.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_style_detail.hpp 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
@@ -17,6 +17,7 @@
// This module provides an id string from named parameter
// so, for example, document_ids[PLOT_BACKGROUND] == "background".
+// to be used as a SVG group is thus: <g id="background" ... /g>
namespace boost
{
@@ -32,36 +33,42 @@
enum plot_doc_structure
{
PLOT_BACKGROUND = 0, // Must be zero to index array document_ids[]
- // TODO better PLOT_IMAGE_BACKGROUND ?
- PLOT_PLOT_BACKGROUND, // 1
- // TODO better PLOT_WINDOW_BACKGROUND ??? Maybe OK?
+ PLOT_WINDOW_BACKGROUND, // the smaller plot window (if used).
PLOT_Y_MINOR_GRID, PLOT_Y_MAJOR_GRID, // 2, 3
PLOT_X_MINOR_GRID, PLOT_X_MAJOR_GRID,
- PLOT_Y_AXIS, PLOT_X_AXIS,
+ PLOT_Y_AXIS, PLOT_X_AXIS, // the X and Y axis lines.
PLOT_Y_MINOR_TICKS, PLOT_X_MINOR_TICKS,
PLOT_Y_MAJOR_TICKS, PLOT_X_MAJOR_TICKS,
- PLOT_PLOT_LABELS, // tick values 10, 20, 30 ...
- PLOT_Y_LABEL, PLOT_X_LABEL,
- PLOT_PLOT_LINES, PLOT_PLOT_POINTS, PLOT_LIMIT_POINTS,
- PLOT_LEGEND_BACKGROUND, PLOT_LEGEND_POINTS, PLOT_LEGEND_TEXT,
- PLOT_TITLE,
+ PLOT_VALUE_LABELS, // tick values 10, 20, 30 ...
+ PLOT_Y_LABEL, PLOT_X_LABEL, // axis text labels "length (cm)"
+ PLOT_DATA_LINES, // lines joing data points.
+ PLOT_DATA_POINTS, // normal data point markers.
+ PLOT_LIMIT_POINTS, // at limit or NaN data point markers.
+ PLOT_LEGEND_BACKGROUND, // legend box.
+ PLOT_LEGEND_POINTS, // data series point markers, circle, cross...
+ PLOT_LEGEND_TEXT, // text describing each data series.
+ PLOT_TITLE, // of the whole plot.
SVG_PLOT_DOC_CHILDREN // Last enum value used as count of children (22).
};
std::string document_ids[]= // TODO change to document_ids_ because private member data.
{ //
- "background", // TODO "imageBackground" better?
- "plotBackground",
+ "imageBackground", // the whole svg image.
+ "plotBackground", // // the smaller plot window (if used).
"yMinorGrid", "yMajorGrid",
"xMinorGrid", "xMajorGrid",
- "yAxis", "xAxis",
+ "yAxis", "xAxis", // the X and Y axis lines.
"yMinorTicks", "xMinorTicks",
"yMajorTicks", "xMajorTicks",
"plotLabels", // TODO tickValueLabels better name???
- "yLabel", "xLabel",
- "plotLines", "plotPoints", "limitPoints",
- "legendBackground", "legendPoints", "legendText",
- "title",
+ "yLabel", "xLabel", // axis text labels "length (cm)"
+ "plotLines", // normal data point markers.
+ "plotPoints", // normal data point markers.
+ "limitPoints", // at limit or NaN data point markers
+ "legendBackground", // legend box.
+ "legendPoints", // data series point markers, circle, cross...
+ "legendText", // text describing each data series.
+ "title", // of the whole plot.
"plotDocChildren" // This last string is not used.
}; // std::string document_ids
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
@@ -104,7 +104,7 @@
{
s_out << " clip-path=\"url(#" << clip_name << ")\""; // Prefix with space.
}
- // Other references, 5.3.1, like color, fill, stroke, gradients...
+ // Inherited classes add other references, 5.3.1, like color, fill, stroke, gradients...
// Example id: <g id="yMinorGrid" ></g>
// Example URI: fill="url(#Gradient01) // local URL
} // void write_attributes(std::ostream& s_out)
@@ -514,13 +514,13 @@
switch(align)
{
case left_align:
- anchor = " start";
+ anchor = "start";
break;
case right_align:
- anchor = " end";
+ anchor = "end";
break;
case center_align:
- anchor = " middle";
+ anchor = "middle";
break;
default:
anchor = "";
@@ -664,7 +664,7 @@
{
if(relative)
{
- o_str<<"l";
+ o_str << "l";
}
else
{ // Absolute.
@@ -741,7 +741,7 @@
{
if(relative)
{
- o_str<<"c";
+ o_str << "c";
}
else
{ // Absolute.
@@ -885,9 +885,11 @@
}
path_element() : fill(true)
- {
+ { // TODO why is the default fill(true)?
}
+
+
// Note 1: return of path_element& permits chaining calls like
// my_path.M(3, 3).l(150, 150).l(200, 200)...;
@@ -999,19 +1001,23 @@
void write(std::ostream& o_str)
{
- o_str << "<path d=\"";
- for(ptr_vector<path_point>::iterator i = path.begin(); i != path.end(); ++i)
- {
- (*i).write(o_str); // M1,2
+ if (path.begin() != path.end() )
+ { // Is some path info (trying to avoid useless <path d=""/>"
+ // TODO or would this omit useful style & attributes?
+ o_str << "<path d=\"";
+ for(ptr_vector<path_point>::iterator i = path.begin(); i != path.end(); ++i)
+ {
+ (*i).write(o_str); // M1,2
+ }
+ o_str << "\"";
+ write_attributes(o_str); // id & clip_path
+ style_info.write(o_str); // fill, stroke, width...
+ if(!fill)
+ {
+ o_str << " fill=\"none\"";
+ }
+ o_str<<"/>"; // closing to match <path d=
}
- o_str << "\"";
- write_attributes(o_str); // id & clip_path
- style_info.write(o_str); // fill, stroke, width...
- if(!fill)
- {
- o_str << " fill = \"none\"";
- }
- o_str<<"/>";
// Example: <path d="M5,175 L5,195 M148.571,175" />
} // void write(std::ostream& o_str)
}; // class path_element
@@ -1177,7 +1183,7 @@
void write(std::ostream& o_str)
{
o_str << "<polygon points=\"";
- for(ptr_vector<poly_path_point>::iterator i = poly_points.begin(); i!=poly_points.end(); ++i)
+ for(ptr_vector<poly_path_point>::iterator i = poly_points.begin(); i != poly_points.end(); ++i)
{
(*i).write(o_str); // x, y coordinates as " 1,2"
}
@@ -1298,17 +1304,20 @@
return children.size();
}
- void write(std::ostream& rhs)
+ void write(std::ostream& os)
{
- rhs << "<g"; // Do NOT need space if convention is to start following with space.
- write_attributes(rhs); // id="background"
- style_info.write(rhs); // stroke="rgb(0,0,0)"
- rhs << ">" ;
+ // WOuld be nice to avoid useless <g id="yMinorGrid"></g>
+ // TODO but would this mean that useful style is lost?
+
+ os << "<g"; // Do NOT need space if convention is to start following item with space.
+ write_attributes(os); // id="background"
+ style_info.write(os); // stroke="rgb(0,0,0)"
+ os << ">" ;
for(unsigned int i = 0; i < children.size(); ++i)
{
- children[i].write(rhs);
+ children[i].write(os);
}
- rhs << "</g>" << std::endl;
+ os << "</g>" << std::endl;
// Example:
// <g fill="rgb(255,255,255)" id="background"><rect x="0" y="0" width="500" height="350"/></g>
} // void write(std::ostream& rhs)
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
@@ -118,7 +118,6 @@
std::string attribution_;
std::string commercialuse_;
std::string distribution_;
-
int coord_precision_; // decimal digits precision for output of x and y coordinates to svg.
private:
@@ -177,11 +176,11 @@
css(""), // stylesheet.
filename_(""), // If written only to ostream, filename will not appear in comment.
is_license_(false), // No default license.
- reproduction_("permits"), // Set with license
+ reproduction_("permits"), // Set with license:
distribution_("permits"), // permits, requires, or prohibits.
attribution_("requires"),
commercialuse_("permits"),
- coord_precision_(3) // enough for 1 in 1000 resolution to suit
+ coord_precision_(3) // enough for 1 in 1000 resolution to suit use.
{ // Default constructor.
}
@@ -346,13 +345,16 @@
}
write_css(s_out);// stylesheet, if any.
write_document(s_out); // write clip paths and all document elements.
- s_out << std::endl << "</svg>" << std::endl; // close off svg tag (added newline).
+ s_out << "</svg>" << std::endl; // close off svg tag.
return *this;
}
- svg& license(const std::string repro, const std::string distrib, const std::string attrib, const std::string commercial)
+ svg& license( // Set license requirements for the svg document.
+ const std::string repro = "permits",
+ const std::string distrib = "permits",
+ const std::string attrib = "requires",
+ const std::string commercial = "permits")
{ // Might check these are "permits", "requires", or "prohibits"?
- // Default is permits.
reproduction_ = repro;
distribution_ = distrib;
attribution_ = attrib;
@@ -362,19 +364,37 @@
}
svg& license(bool l)
- { // Set license using all defaults (permits).
+ { // Set (or not) license using all requirement (default permits).
is_license_ = l;
}
bool is_license()
- { // Shows if a license has been requested.
+ { // Shows if a license has been requested in the svg header metatadata.
return is_license_;
}
- // ------------------------------------------------------------------
+ const std::string& reproduction()
+ { // Gets license reproduction requirement.
+ return reproduction_;
+ }
+
+ const std::string& distribution()
+ { // Gets license distribution requirement.
+ return distribution_;
+ }
+ const std::string& attribution()
+ { // Gets license attribution requirement.
+ return attribution_;
+ }
+ const std::string& commercialuse()
+ { // Gets license commercialuse requirement.
+ return commercialuse_;
+ }
+
+ // -------------------------------------------------------
// Writes the information about the image to the document.
// TODO: allow other unit identifiers.
- // ------------------------------------------------------------------
+ // -------------------------------------------------------
svg& image_size(unsigned int x, unsigned int y)
{
x_size_ = x;
@@ -403,6 +423,7 @@
{ // Gets description of the document(for header as <desc>).
return author_;
}
+
svg& document_title(const std::string d)
{ // Writes document title for the document(for header as <title>)..
title_document_ = d;
@@ -447,9 +468,9 @@
return filename_;
}
- // ----------------------------------------------------------------------------
- // push_back the information about line, rec, circle & ellipse to the document.
- // ----------------------------------------------------------------------------
+ // ------------------------------------------------------------------------
+ // push_back information about line, rec, circle & ellipse to the document.
+ // ------------------------------------------------------------------------
svg& line(double x1, double y1, double x2, double y2)
{ // 'line' element defines a line segment
// that starts at one point and ends at another.
@@ -476,9 +497,9 @@
return *this;
}
- // -----------------------------------------------------------------
- // push_back the information about text to the document.
- // -----------------------------------------------------------------
+ // -------------------------------------------------
+ // push_back information about text to the document.
+ // -------------------------------------------------
svg& text(double x, double y, const std::string& text, int text_size = 12,
const std::string& font = "Lucida Sans Unicode",
const std::string& style = "", const std::string& weight = "",
@@ -540,8 +561,8 @@
return *this;
}
- svg& polyline(double x1, double y1, double x2, double y2) // Two points only, add others later with .P(x, y).
- {
+ svg& polyline(double x1, double y1, double x2, double y2)
+ { // Two points only, add others later with .P(x, y).
document.push_back(new polyline_element(x1, y1));
document.push_back(new polyline_element(x2, y2));
return *this;
@@ -566,13 +587,13 @@
}
svg& clip_path(const rect_element& rect, const std::string& id)
- {
+ { // Rectangle outside which 'painting' is 'clipped' so doesn't show.
clip_paths.push_back(clip_path_element(id, rect));
return *this;
}
// -------------------------------------------------------------
- // Writes the information about a group element to the document.
+ // Writes information about a group element to the document.
// -------------------------------------------------------------
g_element& add_g_element()
@@ -582,7 +603,7 @@
g_element& get_g_element(int i)
{ // Array of g_elements document,
- // indexed by group type, PLOT_BACKGROUND, PLOT_PLOT_BACKGROUND, ... SVG_PLOT_DOC_CHILDREN
+ // indexed by group type, PLOT_BACKGROUND, PLOT_WINDOW_BACKGROUND, ... SVG_PLOT_DOC_CHILDREN
return document.g_tag(i);
}
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg_1d_plot.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg_1d_plot.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_1d_plot.hpp 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
@@ -156,20 +156,32 @@
//unsigned int x_major_label; // pixels. Now in x_units_info font size
// Other information.
- double text_margin; // Marginal space around text items like title,
+ double text_margin_; // Marginal space around text items like title,
// as a fraction of font size, (pixels) (was fixed at 1.5).
- int border_margin; // Marginal (pixels) space around the plot border.
+ int border_margin_; // Marginal (pixels) space around the plot border.
+ // text width is effectively the boldness of the font.
+ // 0 is default, 1 is bolder, 2 very bold...
+ // TODO SVG has also a not yet implemented boldness.
+ double title_width_;
+ double legend_width_;
+ double legend_x1_; // Left of legend box. (Optionally set by legend_position).
+ double legend_y1_; // Top of legend box.
+ // Size of legend box is controlled by its contents,
+ // but may be helpful to store bottom right coordinates.
+ // legend_bottom_right() gives access.
+ double legend_x2_; // right of legend box.
+ double legend_y2_; // bottom of legend box.
// X-Axis information.
// (Y_axis stored as one point because this is a 1D graph).
double x_min; // minimum x (Cartesian units).
double x_max; // maximum x (Cartesian units).
double x_axis; // stroke width (pixels). ????
- double x_major; // Interval (Cartesian units) between major ticks.
+ double x_major_interval_; // Interval (Cartesian units) between major ticks.
// set/get by x_major_interval
- double x_minor; // Interval (Cartesian units) between minor ticks.
+ double x_minor_interval_; // Interval (Cartesian units) between minor ticks.
// because x_num_minor_ticks_ used to determine this instead,
- // but one could calculate x_minor.
+ // but one could calculate x_minor_interval_.
// Yes/no options.
bool use_title; // Show plot title.
@@ -177,7 +189,9 @@
bool use_plot_window; // rather than whole image.
bool use_x_axis_lines_; // = x_axis_on()
bool use_y_axis_lines_; // Note: is needed in 1D version too in draw_axes.
- bool use_x_major_labels; // For example, to show value (like 1.2) by ticks.
+ bool use_x_major_labels; // For example, to show value (like 1.2) by major ticks.
+ //bool use_x_minor_labels; // For example, to show value (like 1.2) by minor ticks.
+ // Not yet implemented (doubt if needed).
bool use_x_label_units; // For example, to show, "length (meter)"
bool use_x_major_grid; // provide major vertical lines.
bool use_x_minor_grid;// provide minor vertical lines.
@@ -220,8 +234,10 @@
x_label_info(0, 0, "X Axis", 14, "Lucida Sans Console", "", "", "", "", center_align, horizontal), //
x_units_info(0, 0, "(units)", 14, "Lucida Sans Console", "", "", "", "", right_align, horizontal),
//x_units_info(0, 0, "(units)", 14, "Times New Roman", "italic", "bold", "wider", "underline", right_align, horizontal),
- text_margin(2.), // for text was 1.5 // as a fraction of the font size.
- border_margin(5), // Prevent plot window box begin right on edge.
+ text_margin_(2.), // for text was 1.5 // as a fraction of the font size.
+ border_margin_(5), // Prevent plot window box begin right on edge.
+ legend_x1_(-1), legend_x2_(-1),legend_y1_(-1),legend_y2_(-1), // Indicates not yet set.
+
x_min(-10), x_max(10),
use_legend(false),
use_title(true),
@@ -243,7 +259,7 @@
use_x_minor_grid(false),
use_x_axis_lines_(true),
use_y_axis_lines_(false), // Not needed for 1D, but leave at false.
- x_major(2), // interval between x major ticks
+ x_major_interval_(2), // interval between x major ticks
x_major_tick_width_(3),
x_minor_tick_width_(1),
x_major_tick_length_(10), // If both up and down, total is twice this.
@@ -306,11 +322,11 @@
{ // Use whole image.
if(use_title)
{ // Allow space for title, taking account of font size.
- y1 += title_info.font_size() * (text_margin +1);
+ y1 += title_info.font_size() * (text_margin_ +1);
}
if(use_x_label)
{// Allow space for x tick values, taking account of font size.
- y2 -= x_label_info.font_size() * text_margin;
+ y2 -= x_label_info.font_size() * text_margin_;
}
}
else
@@ -333,10 +349,10 @@
if(use_plot_window)
{
- plot_x1 += border_margin; // small margin around border.
- plot_x2 -= border_margin; //
- plot_y1 += border_margin; //
- plot_y2 -= border_margin;
+ plot_x1 += border_margin_; // small margin around border.
+ plot_x2 -= border_margin_; //
+ plot_y1 += border_margin_; //
+ plot_y2 -= border_margin_;
if(use_title)
{
@@ -350,7 +366,7 @@
}
if(use_x_label)
{// Allow space for x_label at bottom.
- plot_y2 -= static_cast<int>(x_label_info.font_size() * text_margin);
+ plot_y2 -= static_cast<int>(x_label_info.font_size() * text_margin_);
}
if(use_down_ticks)
{ // Allow space for the downward ticks
@@ -361,7 +377,7 @@
x_major_tick_length_ : x_minor_tick_length_;
}
// Draw plot window rect.
- image.get_g_element(detail::PLOT_PLOT_BACKGROUND).push_back(
+ image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).push_back(
new rect_element(plot_x1, plot_y1, (plot_x2 - plot_x1), plot_y2 - plot_y1));
// <g id="plotBackground" fill="rgb(248,248,255)"><rect x="43" y="53" width="302" height="304"/></g>
} // use_plot_window
@@ -395,7 +411,7 @@
transform_y(y);
for(unsigned int i = 0; i < series.size(); ++i)
{ // For each of the data series.
- g_element& g_ptr = image.get_g_element(detail::PLOT_PLOT_POINTS).add_g_element();
+ g_element& g_ptr = image.get_g_element(detail::PLOT_DATA_POINTS).add_g_element();
g_ptr.style().stroke_color(series[i].point_style.stroke_color);
g_ptr.style().fill_color(series[i].point_style.fill_color);
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg_2d_plot.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg_2d_plot.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_2d_plot.hpp 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
@@ -43,6 +43,7 @@
#include <ostream>
#include <iterator>
#include <exception>
+#include <iostream> // for debug
namespace boost
{
@@ -73,15 +74,19 @@
// written to the document would be difficult. We store the Cartesian
// coordinates locally and transform them before we write them.
// -----------------------------------------------------------------
+struct svg_2d_plot_series;
+class svg_2d_plot;
struct svg_2d_plot_series
{
// 2-D Data series points to plot.
std::multimap<double, double> series; // Normal 'OK to plot' data values.
std::multimap<double, double> series_limits; // 'limit' values: too big or small, or NaN.
- // TODO is there a reason why multimap is used rather than vector of pairs?
- // multimap sorts, which will take time and isn't needed?
-
+ // multimap is used rather than vector of pairs because
+ // multimap sorts and ensures that lines joining data points
+ // are unaffected by the order in which data is presented.
+ // (For 1-D a vector of doubles can be used).
+
std::string title;
plot_point_style point_style;
plot_line_style line_style;
@@ -126,76 +131,96 @@
svg image;
text_element title_info; // Plot title.
- text_element legend_header; // legend box header or title (if any).
+ text_element legend_header_; // legend box header or title (if any).
text_element x_label_info; // For example: "length"
text_element y_label_info; // For example: "volume"
text_element x_units_info; // For example: "mm"
text_element y_units_info; // 2-D only.
- double text_margin; // Marginal space around text items like title,
+ int value_precision_; // precision for tick value labels, usually 3 will suffice.
+ // Used to decide how much space to allow for tick values.
+ double text_margin_; // Marginal space around text items like title,
// as a fraction of font size, (pixels) (was fixed at 1.5).
- int border_margin; // Marginal (pixels) space around the plot border.
+ double border_margin_; // Marginal (pixels) space around the plot border.
+ double border_width_; // plot border rectangle width.
// Border information for the plot window (<= image size).
// Allows for title and legend to be separate.
// Initially will be set to the width and height of the graph image.
// calculate_plot_window() sets these values.
- int plot_x1; // TODO unsigned int? or double?
- int plot_x2;
- int plot_y1;
- int plot_y2;
+ double plot_x1; // TODO These (and many others) also could be float?
+ double plot_x2;
+ double plot_y1;
+ double plot_y2;
// X-Axis information.
double x_min; // minimum x value (Cartesian units).
double x_max; // maximum x value (Cartesian units).
double x_axis; // // x-axis (y = 0) transformed into SVG coordinates.
- double x_major; // x_major is the stride or interval for major x ticks.
- // set/get by x_major_interval
- double x_minor; // Interval (Cartesian units) between minor ticks.
- // because x_num_minor_ticks_ used to determine this instead,
- // but one could calculate x_minor.
-
- unsigned int x_major_tick_length_; // pixels.
- unsigned int x_major_tick_width_; // pixels.
- unsigned int x_minor_tick_length_; // pixels.
- unsigned int x_minor_tick_width_; // pixels.
+ double x_major_interval_; // x_major_interval_ is the stride or interval for major x ticks.
+ // (Cartesian units) set/get by x_major_interval
+ double x_minor_interval_; // Interval (Cartesian units) between minor ticks.
+ // No set function because x_num_minor_ticks_ used to determine this instead,
+ // but one could calculate x_minor_interval_.
+
+ // text width is effectively the boldness of the font.
+ // 0 is default, 1 is bolder, 2 very bold...
+ // TODO SVG has also a not yet implemented boldness.
+ double title_width_;
+ double legend_width_;
+ double legend_x1_; // Left of legend box. (Optionally set by legend_position).
+ double legend_y1_; // Top of legend box.
+ // Size of legend box is controlled by its contents,
+ // but may be helpful to store bottom right coordinates.
+ // legend_bottom_right() gives access.
+ double legend_x2_; // right of legend box.
+ double legend_y2_; // bottom of legend box.
+ double x_label_width_; // Used for
+ double y_label_width_; // TODO used for axis width too for now. OK?
+ double x_major_tick_length_; // pixels.
+ double x_major_tick_width_; // pixels.
+ double x_minor_tick_length_; // pixels.
+ double x_minor_tick_width_; // pixels.
// Avoid name clash with x_m*_tick_length and width.
unsigned int x_num_minor_ticks_; // number of minor ticks, eg 4 gives major 0, minor 1,2,3,4, major 5
- unsigned int x_major_grid_width_; // pixels.
- unsigned int x_minor_grid_width_; // pixels.
+ double x_major_grid_width_; // pixels.
+ double x_minor_grid_width_; // pixels.
// grid width is set in style.stroke_width
- //unsigned int x_major_label; // pixels. Now in x_units_info font size
+ // unsigned int x_major_label; // pixels. Now in x_units_info font size
// Y-Axis information.
+ unsigned int y_num_minor_ticks_; // number of minor ticks, eg 4 gives major 0, minor 1,2,3,4, major 5
double y_min; // minimum y value (Cartesian units).
double y_max; // maximum y value (Cartesian units).
- double y_major; // y_major is the stride or interval for major y ticks.
+ double y_major_interval_; // y_major_interval_ is the stride or interval for major y ticks.
+ double y_minor_interval_; // y_minor_interval_ is the stride or interval for minor y ticks.
double y_axis; // Y-axis (x = 0) transformed into SVG coordinates.
-
- unsigned int y_major_tick_length_; // pixels.
- unsigned int y_major_tick_width_; // pixels.
- unsigned int y_minor_tick_length_; // pixels.
- unsigned int y_minor_tick_width_; // pixels.
+ double y_major_tick_length_; // pixels.
+ double y_major_tick_width_; // pixels.
+ double y_minor_tick_length_; // pixels.
+ double y_minor_tick_width_; // pixels.
// Avoid name clash with x_m*_tick_length and width.
- unsigned int y_num_minor_ticks_; // number of minor ticks, eg 4 gives major 0, minor 1,2,3,4, major 5
// grid width is set in style.stroke_width
- unsigned int y_major_grid_width_; // pixels.
- unsigned int y_minor_grid_width_; // pixels.
- //unsigned int y_major_label; // pixels.
+ double y_major_grid_width_; // pixels.
+ double y_minor_grid_width_; // pixels.
// Yes/no options.
- bool use_title;
- bool use_legend;
- bool use_axis;
- bool use_plot_window;
+ bool use_title; // Provide a title for the whole plot.
+ bool use_legend; // Provide a legend box.
+ bool use_axis; // Draw x and y axes. TODO split so can have either or both.
+ bool use_plot_window; // Use a separate plot window.
+ bool use_x_label; // Label axis with text.
+ bool use_y_label;
bool use_x_major_labels; // values for major ticks.
bool use_y_major_labels;
- bool use_x_major_grid;
- bool use_x_minor_grid;
- bool use_x_label;
- bool use_y_label;
bool use_x_label_units;
bool use_y_label_units;
+ bool use_x_label_up_; // X_axis value labels written vertically up.
+ bool use_y_label_up_; // Y_axis value labels written vertically up.
+ bool use_x_major_grid_;
+ bool use_x_minor_grid_;
+ bool use_y_major_grid_;
+ bool use_y_minor_grid_;
// Note: can have ticks both up and/or down, and/or left and right.
bool use_up_ticks;
@@ -203,14 +228,13 @@
bool use_x_ticks; // = use_up_ticks || use_down_ticks
bool use_left_ticks;
bool use_right_ticks;
- bool use_y_ticks; // = use_left_ticks || use_right_ticks
- bool use_x_ticks_on_plot_window_; // was external style.
- bool use_y_ticks_on_plot_window_; // rather than on y-axis.
- bool use_x_axis_lines_; // ??? TODO what does this do?
- bool use_y_axis_lines_; // ??? TODO what does this do?
- bool use_y_major_grid;
- bool use_y_minor_grid;
- bool use_line; // set by line_on(bool); // Not really useful for 1-D,
+ // bool use_y_ticks; // = use_left_ticks || use_right_ticks
+ // was external style.
+ bool use_x_ticks_on_plot_window_; // Value labels & ticks on the plot window rather than on X-axis.
+ bool use_y_ticks_on_plot_window_; // Value labels & ticks on the plot window rather than on Y-axis.
+ bool use_x_axis_lines_; // Draw a horizontal X-axis line.
+ bool use_y_axis_lines_; // Draw a vertical Y-axis line.
+ bool use_line; // get/set by line_on(bool); // Not really useful for 1-D,
// TODO but needs Boost-Parameter removed to do properly.
// Where we will be storing the data points (series) for transformation.
@@ -232,116 +256,157 @@
// See documentation for default settings rationale.
title_info(0, 0, "Plot of data", 16, "Verdana", "", "", "", "", center_align, horizontal),
- x_label_info(0, 0, "X Axis", 14, "verdana", "", "", "", "", center_align, horizontal),
- y_label_info(0, 0, "Y Axis", 14, "verdana", "", "", "", "", center_align, upward),
- //x_label_info(0, 0, "X Axis", 12, "Lucida Sans Console", "", "", "", "", center_align, horizontal),
- //y_label_info(0, 0, "Y Axis", 12, "Lucida Sans Console", "", "", "", "", center_align, upward),
- x_units_info(0, 0, "(units)", 14, "Lucida Sans Console", "", "", "", "", center_align, horizontal),
- y_units_info(0, 0, "(units)", 14, "Lucida Sans Console", "", "", "", "", center_align, upward),
+ title_width_(1), // text width is effectively the boldness of the font.
+ legend_width_(0.5),
+ x_label_info(0, 0, "X Axis", 14, "Verdana", "", "", "", "", center_align, horizontal),
+ x_label_width_(0.5),
+ y_label_info(0, 0, "Y Axis", 14, "Verdana", "", "", "", "", center_align, upward),
+ y_label_width_(0.5),
+ x_units_info(0, 0, "(units)", 14, "Verdana", "", "", "", "", center_align, horizontal),
+ y_units_info(0, 0, "(units)", 14, "Verdana", "", "", "", "", center_align, upward),
// Plot may look odd if font and size of label & units are different!
// y_units_info(0, 0, "(units)", 11, "Times New Roman", "italic", "bold", "wider", "underline", right_align, upsidedown),
// shows some values that might be useful if svg browsers are fully implemented
- // to support modification to text characters.
- text_margin(2.), // for text was 1.5 // as a fraction of the font size.
- border_margin(5), // Prevent plot window box begin right on edge.
+ // to support font modification to text characters.
+ value_precision_(3), // precision for tick value labels, usually 3 will suffice.
+ // TODO provide a way of controlling scientific format.
+ text_margin_(2.), // for text was 1.5
+ // as a multiplier of the font size.
+ border_margin_(5), // Prevent plot window box begin right on edge?
// plot_x1, x2, y1, 2 are set in calculate_plot_window
+ border_width_(2), // width of border to plot window and legend box.
+ legend_x1_(-1), legend_x2_(-1),legend_y1_(-1),legend_y2_(-1), // Indicates not yet set.
x_min(-10), x_max(10), // so plots from -10 to +10
y_min(-10), y_max(10),
- x_major(2), // x stride
- y_major(2), // y stride
+ x_major_interval_(2), // x stride between major ticks & value label.
+ y_major_interval_(2), // y stride
// Ticks on axes.
- x_num_minor_ticks_(2),
+ x_num_minor_ticks_(2), // suits
y_num_minor_ticks_(4), // suits: major 0, minor 2, 4, 6, 8, major 10
- x_major_tick_length_(10), // If both up and down, total is twice this.
- x_minor_tick_length_(5),
- x_major_tick_width_(2),
- x_minor_tick_width_(1),
- y_major_tick_length_(10), // If both left and right, total is twice this.
- y_minor_tick_length_(5),
- y_major_tick_width_(2),
- y_minor_tick_width_(1),
+ x_major_tick_length_(10.), // If both up and down, total is twice this.
+ x_minor_tick_length_(5.),
+ x_major_tick_width_(2.),
+ x_minor_tick_width_(1.),
+ y_major_tick_length_(10.), // If both left and right, total is twice this.
+ y_minor_tick_length_(5.),
+ y_major_tick_width_(2.),
+ y_minor_tick_width_(1.),
// grids
- x_major_grid_width_(2),
- x_minor_grid_width_(1),
- y_major_grid_width_(2),
- y_minor_grid_width_(1),
- x_scale(1.), x_shift(0),
- y_scale(1.), y_shift(0),
+ x_major_grid_width_(1.),
+ x_minor_grid_width_(0.5),
+ y_major_grid_width_(1.),
+ y_minor_grid_width_(0.5),
+ x_scale(1.), x_shift(0.),
+ y_scale(1.), y_shift(0.),
+ x_minor_interval_(0), // These are calculated from x & y_num_minor_ticks_
+ y_minor_interval_(0), // but given a value here for safety.
plot_window_clip("plot_window"), // for <clipPath id="plot_window" ...
// Boolean options.
use_down_ticks(true), // On X-axis.
use_up_ticks(false), // external ticks only.
- use_x_ticks(false), // = use_up_ticks || use_down_ticks
+ //use_x_ticks(false), // = use_up_ticks || use_down_ticks
use_left_ticks(true), // On y-axis.
- use_right_ticks(false), //
- use_y_ticks(false), // = use_left_ticks || use_right_ticks
+ use_right_ticks(false), // On y-axis
+ //use_y_ticks(true), // = use_left_ticks || use_right_ticks TODO get rid of this. NOT useful
use_x_ticks_on_plot_window_(false), // was external_style
use_y_ticks_on_plot_window_(false), // was external_style
use_x_label_units(false),
use_y_label_units(false),
- use_x_major_labels(true),
- use_y_major_labels(false),
- use_x_label(false),
- use_y_label(true), // true for 2-D
+ use_x_major_labels(true), // tick value labels.
+ use_y_major_labels(true),
+ use_x_label_up_(false),
+ use_y_label_up_(false),
+ use_x_label(true), // "X-axis"
+ use_y_label(true), // "Y-axis" - true for 2-D, false for 1-D.
use_title(true),
use_legend(false), use_axis(true),
- use_x_axis_lines_(true),
- use_y_axis_lines_(true),
- use_x_major_grid(false),
- use_x_minor_grid(false),
- use_y_major_grid(false),
- use_y_minor_grid(false),
+ use_x_axis_lines_(true), // draw horizontal X-axis line.
+ use_y_axis_lines_(true), // draw vertical Y-axis line.
+ use_x_major_grid_(true),
+ use_x_minor_grid_(false),
+ use_y_major_grid_(true),
+ use_y_minor_grid_(false),
use_plot_window(true),
use_line(true)
// TODO but needs Boost-Parameter removed to do properly.
{
image_size(500, 400); // Default image size for 2-D.
- // 2-D needs to be squarer than 1-D.
- use_x_ticks = use_up_ticks || use_down_ticks;
- use_y_ticks = use_left_ticks || use_right_ticks;
+ // 2-D usually needs to be squarer than 1-D.
+ //use_x_ticks = use_up_ticks || use_down_ticks;
+ //use_y_ticks = use_left_ticks || use_right_ticks;
// Build the document tree by adding all children of the root node.
for(int i = 0; i < detail::SVG_PLOT_DOC_CHILDREN; ++i)
{
image.add_g_element();
}
+ using namespace boost::svg::detail; // avoid detail::
+ set_ids();
// Set other SVG color, stroke & width defaults for various child PLOT nodes.
- // Tick length etc is now set above in the constructor.
- image.get_g_element(detail::PLOT_BACKGROUND).style().fill_color(white);
- image.get_g_element(detail::PLOT_LIMIT_POINTS).style().stroke_color(lightgray).fill_color(whitesmoke);
- image.get_g_element(detail::PLOT_Y_AXIS).style().stroke_color(black);
- image.get_g_element(detail::PLOT_Y_AXIS).style().stroke_width(1);
- image.get_g_element(detail::PLOT_X_AXIS).style().stroke_color(black);
- image.get_g_element(detail::PLOT_X_MINOR_TICKS).style().stroke_color(black);
- image.get_g_element(detail::PLOT_X_MAJOR_TICKS).style().stroke_color(black);
- image.get_g_element(detail::PLOT_X_LABEL).style().stroke_color(blue); // TODO temp for tests
- image.get_g_element(detail::PLOT_Y_LABEL).style().stroke_color(green); // TODO temp for tests
- image.get_g_element(detail::PLOT_X_LABEL).style().stroke_width(1);
- image.get_g_element(detail::PLOT_Y_LABEL).style().stroke_width(1); // TODO control of this?
- image.get_g_element(detail::PLOT_PLOT_LABELS).style().stroke_color(blue);
- image.get_g_element(detail::PLOT_PLOT_LABELS).style().stroke_width(1); // 1 is bold blue
- //image.get_g_element(detail::PLOT_PLOT_LABELS).style().stroke_width(0); // 0 is thin *black* - ignoring color!
- // control with x_axis_value_color
-
- // TODO separate control of data series point *values* 1.234 and their colors.
-
- // Note that widths are stored in member data and copied here.
- image.get_g_element(detail::PLOT_X_MAJOR_TICKS).style().stroke_width(x_major_tick_width_);
- image.get_g_element(detail::PLOT_X_MINOR_TICKS).style().stroke_width(x_minor_tick_width_);
- image.get_g_element(detail::PLOT_Y_MINOR_TICKS).style().stroke_color(black);
- image.get_g_element(detail::PLOT_Y_MAJOR_TICKS).style().stroke_color(black);
- image.get_g_element(detail::PLOT_Y_MAJOR_TICKS).style().stroke_width(y_major_tick_width_);
- image.get_g_element(detail::PLOT_Y_MINOR_TICKS).style().stroke_width(y_minor_tick_width_);
- image.get_g_element(detail::PLOT_X_MAJOR_GRID).style().stroke_width(y_major_grid_width_);
- image.get_g_element(detail::PLOT_X_MAJOR_GRID).style().stroke_color(cyan);
- image.get_g_element(detail::PLOT_X_MINOR_GRID).style().stroke_width(y_minor_grid_width_);
- image.get_g_element(detail::PLOT_X_MINOR_GRID).style().stroke_color(cyan);
- set_ids();
+ // Tick length etc is now set above in the constructor, but width & color here.
+ image.get_g_element(PLOT_BACKGROUND).style().fill_color(white);
+ image.get_g_element(PLOT_BACKGROUND).style().stroke_color(grey); // TODO test only ?
+ image.get_g_element(PLOT_BACKGROUND).style().stroke_width(1); //
+ image.get_g_element(PLOT_WINDOW_BACKGROUND).style().fill_color(white);
+ image.get_g_element(PLOT_WINDOW_BACKGROUND).style().stroke_width(2).stroke_color(silver);
+ image.get_g_element(PLOT_LIMIT_POINTS).style().stroke_color(lightslategray).fill_color(antiquewhite);
+ image.get_g_element(PLOT_X_AXIS).style().stroke_color(black).stroke_width(x_label_width_);
+ image.get_g_element(PLOT_Y_AXIS).style().stroke_color(black).stroke_width(y_label_width_);
+ image.get_g_element(PLOT_X_LABEL).style().stroke_color(black).stroke_width(x_label_width_);
+ image.get_g_element(PLOT_Y_LABEL).style().stroke_color(black).stroke_width(y_label_width_);
+ image.get_g_element(PLOT_VALUE_LABELS).style().stroke_color(black).stroke_width(x_label_width_); // text
+ // TODO?? Y label width?
+ image.get_g_element(PLOT_LEGEND_TEXT).style().stroke_width(legend_width_);
+ image.get_g_element(PLOT_TITLE).style().stroke_width(title_width_); //
+ image.get_g_element(PLOT_TITLE).style().stroke_color(black);
+ // If color is not set, then get a very 'thin' font and width has not effect!
+
+ // Note that widths are stored in member data *and* copied here.
+ // Not sure if this is wise but ...
+
+ // Ticks
+ // TODO allow color of ticks independent of axes color?
+ if(use_up_ticks || use_down_ticks)
+ {
+ image.get_g_element(PLOT_X_MAJOR_TICKS).style().stroke_width(x_major_tick_width_).stroke_color(black);
+ image.get_g_element(PLOT_X_MINOR_TICKS).style().stroke_width(x_minor_tick_width_).stroke_color(black);
+ }
+ if(use_left_ticks || use_right_ticks)
+ {
+ image.get_g_element(PLOT_Y_MAJOR_TICKS).style().stroke_width(y_major_tick_width_).stroke_color(black);
+ image.get_g_element(PLOT_Y_MINOR_TICKS).style().stroke_width(y_minor_tick_width_).stroke_color(black);
+ }
+ // Grids.
+ // TODO these may not be needed here - they MUST be set at call time in case use_x_major_grid_ has changed.
+ if(use_x_major_grid_)
+ {
+ image.get_g_element(PLOT_X_MAJOR_GRID).style().stroke_width(x_major_grid_width_).stroke_color(svg_color(200, 220, 255));
+ }
+ if(use_x_minor_grid_)
+ {
+ image.get_g_element(PLOT_X_MINOR_GRID).style().stroke_width(x_minor_grid_width_).stroke_color(svg_color(200, 220, 255));
+ }
+ if(use_y_major_grid_)
+ {
+ image.get_g_element(PLOT_Y_MAJOR_GRID).style().stroke_width(y_major_grid_width_).stroke_color(svg_color(200, 220, 255));
+ }
+ if(use_y_minor_grid_)
+ {
+ image.get_g_element(PLOT_Y_MINOR_GRID).style().stroke_width(y_minor_grid_width_).stroke_color(svg_color(200, 220, 255));
+ }
+
+ // NO need to call these even if the default is not to be used.
+ // TODO are these needed?
+ // Default color for grid.
+ image.get_g_element(PLOT_X_MAJOR_GRID).style().stroke_width(x_major_grid_width_).stroke_color(svg_color(200, 220, 255));
+ image.get_g_element(PLOT_X_MINOR_GRID).style().stroke_width(x_minor_grid_width_).stroke_color(svg_color(200, 220, 255));
+ image.get_g_element(PLOT_Y_MAJOR_GRID).style().stroke_width(y_major_grid_width_).stroke_color(svg_color(200, 220, 255));
+ image.get_g_element(PLOT_Y_MINOR_GRID).style().stroke_width(y_minor_grid_width_).stroke_color(svg_color(200, 220, 255));
} // svg_2d_plot() default constructor.
private:
@@ -365,13 +430,16 @@
} // void calculate_transform()
void transform_pair(std::pair<double, double>& pt)
- { // transform both x and y.
+ { // Transform both x and y from Cartesian to SVG coordinates.
+ // SVG image is 0, 0 at top left, Cartesian at bottom left.
transform_point(pt.first, pt.second);
}
void calculate_plot_window()
- { // The plot window is used to set a clip path.
- // Start by using all the image.
+ { // The plot window is used to set a clip path:
+ // this ensures that data points and lines (and anything else)
+ // outside this window is NOT drawn.
+ // Start by assuming we can use all the svg image.
plot_x1 = 0; // left
plot_y1 = 0; // top
plot_x2 = image.x_size(); // right
@@ -379,44 +447,63 @@
if(use_x_label)
{ // Leave space at bottom for X axis label.
- plot_y2 -= (int)(x_label_info.font_size() * text_margin);
+ plot_y2 -= x_label_info.font_size() * text_margin_;
}
if(use_y_label)
{ // Leave space at left for Y axis label.
- plot_x1 += (int)(y_label_info.font_size() * text_margin);
+ plot_x1 += y_label_info.font_size() * text_margin_;
}
if(use_title)
{ // Leave space at top for title.
// TODO what if want to put title at bottom?
- plot_y1 += (int)(title_font_size() * (text_margin +1));
+ plot_y1 += title_font_size() * (text_margin_ +1);
}
if(use_plot_window)
- { // Reduce to allow for legend, axes ticks to be outside plot_window.
- // Give the plot window a small border.
- // Needed to allow any window border rectangle to show OK?
- plot_x1+= border_margin; // pixels.
- plot_x2-= border_margin;
- plot_y1+= border_margin;
- plot_y2-= border_margin;
+ { // Reduce to allow for legend, axes ticks to be on or outside plot_window.
+ // Give the plot window a border (set with plot_border_width(double)).
+ // Needed to allow any window border rectangle to show OK.
+ plot_x1 += plot_border_width(); // pixels.
+ plot_x2 -= plot_border_width();
+ plot_y1 += plot_border_width();
+ plot_y2 -= plot_border_width();
if(use_legend)
{ // Space for legend at right.
// TODO what if want legend elsewhere?
- plot_x2 -= 150; // This 150 is an arbitrary legend box width.
- // TODO size could depend on font_size & length of text?
+ plot_x2 -= 150; // This width 150 is an arbitrary legend box width.
+ // TODO size could depend on font_size & length of text??? Sounds tricky.
+ }
+ if (use_y_major_labels && use_y_ticks_on_plot_window_)
+ { // Move edge right to give space for value_precision_ digits.
+ // (perhaps allow + 1 for negative sign? What about exponent?).
+ plot_x1 += y_label_info.font_size() * (value_precision_ * 0.7);
+ // 0.7 because not as wide as high.
+ }
+ if (use_x_major_labels && use_x_ticks_on_plot_window_)
+ { // Move bottom up to give space for value_precision_ digits.
+ // (perhaps + 1 for negative sign?).
+ if (use_x_label_up_)
+ {
+ plot_y2 -= x_label_info.font_size() * (value_precision_ * 0.7);
+ // 0.7 because not as wide as high.
+ }
+ else
+ { // Only 1 char height needed.
+ plot_y2 -= x_label_info.font_size();
+ }
}
if(use_left_ticks)
- { // Reduce plot to give space for any external left ticks.
- plot_x1 +=
- y_major_tick_length_ > y_minor_tick_length_ ? y_major_tick_length_ : y_minor_tick_length_;
+ { // Reduce plot to give space for biggest of any external left ticks.
+ plot_x1 += (std::max)(y_major_tick_length_, y_minor_tick_length_); // Avoid macro max trap!
+ // TODO y_major_tick_length_ > y_minor_tick_length_ ? y_major_tick_length_ : y_minor_tick_length_;
}
if(use_down_ticks)
{ // Reduce plot to give space for any external down ticks.
- plot_y2 -=
- x_major_tick_length_ > x_minor_tick_length_ ? x_major_tick_length_ : x_minor_tick_length_;
+ plot_y2 -=(std::max)(x_major_tick_length_, x_minor_tick_length_);
+ //x_major_tick_length_ > x_minor_tick_length_ ? x_major_tick_length_ : x_minor_tick_length_;
}
// Draw plot window rectangle with background and/or border.
- image.get_g_element(detail::PLOT_PLOT_BACKGROUND).push_back(
+ image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).push_back(
new rect_element(plot_x1, plot_y1, (plot_x2 - plot_x1), plot_y2 - plot_y1));
} // use_plot_window
} // calculate_plot_window
@@ -426,20 +513,20 @@
double x1(0.);
double y1(value); // for tick position and value label.
transform_y(y1);
- double x2(image.y_size());
+ double x2(image.y_size()); // right edge of image.
- if(use_y_minor_grid)
+ if(use_y_minor_grid_)
{ // Draw the minor grid, if wanted.
if(!use_plot_window)
{ // Use whole image, but make space for title & labels text.
//if(use_title)
//{ // If title at top, should make no difference, unlike X grid.
- // x2 -= title_info.font_size() * text_margin;
+ // x2 -= title_info.font_size() * text_margin_;
//}
if(use_y_label)
- { // TODO ???? Don't draw over the Y axis label?
- x1 += y_label_info.font_size() * text_margin;
- //x2 -= y_label_info.font_size() * text_margin;
+ {
+ x1 += y_label_info.font_size() * text_margin_;
+ x2 -= y_label_info.font_size() * text_margin_;
}
}
else
@@ -447,7 +534,7 @@
x1 = plot_x1 + 1; // TODO what is the +1 for?
x2 = plot_x2 - 1; // Ensure *inside* window?
}
- if((y1 > plot_y1) && (x1 > plot_x1) && (x2 < plot_x2) )
+ if((y1 >= plot_y1) && (x1 >= plot_x1) && (x2 <= plot_x2) )
{ // // Make sure that we are drawing inside the allowed window.
grid_path.M(x1, y1).L(x2, y1);
}
@@ -455,59 +542,54 @@
}
if(use_y_ticks_on_plot_window_)
- { // Put y minor ticks on the plot window border.
- // TODO this can be done slicker?
- x1 = plot_x1; // On the
+ { // Put y minor ticks on the plot window border. External style.
+ x1 = plot_x1; // On the plot window border.
x2 = plot_x1;
- if(use_left_ticks)
- {
- x1 -= y_minor_tick_length_;
- }
- if(use_right_ticks)
- {
- x2 += y_minor_tick_length_;
- }
}
else
{ // Internal style.
x1 = y_axis; // On the Y-axis line.
x2 = y_axis;
- if(use_left_ticks)
- {
- x1 -= y_minor_tick_length_;
- }
- if(use_right_ticks)
- { // Right ticks.
- x2 += y_minor_tick_length_;
- }
}
- if((x1 > plot_x1) && (x2 < plot_x2) && (y1 < plot_y2) && (y1 > plot_y1))
+ if(use_left_ticks)
+ {
+ x1 -= y_minor_tick_length_;
+ }
+ if(use_right_ticks)
+ {
+ x2 += y_minor_tick_length_;
+ }
+ //if((x1 >= plot_x1) && (x2 <= plot_x2) && (y1 <= plot_y2) && (y1 >= plot_y1))
+ // but can never be inside if left tick!
+ if((y1 <= plot_y2) && (y1 >= plot_y1))
{ // Make sure that we are drawing inside of the allowed plot window.
tick_path.M(x1, y1).L(x2, y1); // Draw the tick.
}
else
{// Do nothing? warn?
+ std::cout << "y minor tick OUTside " << x1 << ' ' << y1 << ' ' << x2 << std::endl;
+
}
} // void draw_y_minor_ticks
void draw_y_major_ticks(double value, path_element& tick_path, path_element& grid_path)
- { // Draw Y axis major ticks.
+ { // Draw Y axis major ticks, grids & tick value labels.
double y1(value);
transform_y(y1); // cartesian to SVG coordinates.
double x1(0.); // left end of tick.
double x2(image.y_size()); // right end of tick.
-
- if(use_y_major_grid)
+ if(use_y_major_grid_)
{ // Draw horizontal major grid line.
+
if(!use_plot_window)
{ // TODO is this right?
//if (use_title())
//{ // title has no effect if at the top.
- // y1 += title_info.font_size() * text_margin;
+ // y1 += title_info.font_size() * text_margin_;
//}
if(use_y_label)
{ // Start further right to give space for y axis value label.
- y1 -= y_label_info.font_size() * text_margin ;
+ y1 -= y_label_info.font_size() * text_margin_ ;
}
if(use_left_ticks)
{ // And similarly for left ticks.
@@ -520,102 +602,107 @@
x2 = plot_x2 - 1;
}
grid_path.M(x1, y1).L(x2, y1);
- } // use_y_major_grid
+ } // use_y_major_grid_
- if((y1 < plot_y2) && (y1 > plot_y1))
+ if((y1 <= plot_y2) && (y1 >= plot_y1))
{ // Make sure that we are drawing inside the allowed window.
double y_tick_length = y_major_tick_length_;
if(use_y_ticks_on_plot_window_) // (was external_style)
{ // Start ticks on the plot window border.
x1 = plot_x1; // x1 = left,
x2 = plot_x1; // x2 = right.
- if (use_left_ticks)
- {
- x1 -= y_tick_length; // left a tick.
- }
- if (use_right_ticks)
- {
- x2 += y_tick_length; // right.
- }
}
else
- { // Internal style on Y-axis.
+ { // Internal style ticks on vertical Y-axis.
x1 = y_axis; // Y-axis line.
x2 = y_axis;
- if(use_left_ticks)
- {
- x1 -= y_tick_length; // left
- }
- if (use_right_ticks)
- {
- x2 += y_tick_length; // right.
- }
+ }
+ if(use_left_ticks)
+ {
+ x1 -= y_tick_length; // left
+ }
+ if (use_right_ticks)
+ {
+ x2 += y_tick_length; // right.
}
tick_path.M(x1, y1).L(x2, y1); // Draw the major tick.
+ // leaving x1 at the left most end of any tick.
+ }
- if(use_y_major_labels)
- { // label the tick with value, for example "1.3"
- std::stringstream fmt;
- // TODO precision(?) - will be some ugly precision(6) is we do nothing.
- fmt << value; // fmt.str() == "20"
- if(use_y_ticks)
- {
- x1 -= text_margin; // Or a font height?
- if(use_left_ticks)
- {
- x1 -= y_major_tick_length_; // left, taking account of tick length.
- }
- else
- { // No need to move if right tick, or none?
- }
- }
- if(!use_x_ticks_on_plot_window_ && (value != 0))
- { // TODO orientation control?
- image.get_g_element(detail::PLOT_PLOT_LABELS).text(x1,
- y1 + y_label_info.font_size() / 2, // shift down to center value digits on tick.
- fmt.str(), y_label_info.font_size(), "", "", "", "", "", center_align, horizontal);
+ if(use_y_major_labels)
+ { // Label the tick with value, for example "1.3"
+ std::stringstream label;
+ // TODO precision(?) - may be ugly because precision(6) if we do nothing.
+ label << value; // Example: label.str() == "20" or "0.25"
+ if(use_left_ticks)
+ {
+ if (y_minor_tick_length_ > y_minor_tick_length_)
+ { // In case some joker has made the minor ticks are long than the major,
+ // we might need to move left more for the longer tick.
+ x1 -= (y_minor_tick_length_ - y_minor_tick_length_);
}
- if(use_y_ticks_on_plot_window_)
- {
- image.get_g_element(detail::PLOT_PLOT_LABELS).text(x1 + y_label_info.font_size(),
- y1 + y_label_info.font_size() /2, // shift down to center digit on tick.
- fmt.str(), y_label_info.font_size(), "", "", "", "", "", center_align, upward); // -90 degree rotation.
+ x1 -= y_label_info.font_size() / text_margin_; // font height.
+ }
+ else
+ { // No need to move if right tick, or none.
+ }
+
+ if(use_y_ticks_on_plot_window_)
+ { // Always want all values including "0" if labelling on the external plot window.
+ image.get_g_element(detail::PLOT_VALUE_LABELS).text(
+ x1,
+ y1 + y_label_info.font_size() / 2, // shift down to center value digits on tick.
+ label.str(), y_label_info.font_size(), "", "", "", "", "", right_align, horizontal);
+ // Might want to label tick values vertically on y axis?
+ // then use center_align and no shift down to center.
+ }
+ else
+ { // Internal - value labels close to left of vertical Y-axis.
+ if ((value != 0) && use_x_axis_lines_)
+ { // Avoid a zero ON the Y-axis if it would be cut through by the horizontal X-axis line.
+ image.get_g_element(detail::PLOT_VALUE_LABELS).text(x1,
+ y1,
+ label.str(), y_label_info.font_size(), y_label_info.font_family(),
+ "", "", "", "", center_align, // on the tick
+ upward); // -90 degree rotation.
+ // If want to write horizontal ??
}
- } // if(use_y_major_labels)
- }
+ }
+ } // if(use_y_major_labels)
} // draw_y_major_ticks
void draw_y_axis()
{
double x1(0.);
transform_x(x1);
- // Draw the vertical Y axis line (at cartesian x = 0).
- image.get_g_element(detail::PLOT_Y_AXIS).line(x1, plot_y1, x1, plot_y2);
- // <g id="yAxis" stroke="rgb(0,0,0)"><line x1="70.5" y1="53" x2="70.5" y2="357"/>
y_axis = x1; // in SVG coordinates.
+ if(use_y_axis_lines_)
+ { // Draw the vertical Y-axis line (at cartesian x = 0).
+ image.get_g_element(detail::PLOT_Y_AXIS).line(x1, plot_y1, x1, plot_y2);
+ // <g id="yAxis" stroke="rgb(0,0,0)"><line x1="70.5" y1="53" x2="70.5" y2="357"/>
+ }
// Access the paths for the ticks & grids, ready for additions.
path_element& minor_tick_path = image.get_g_element(detail::PLOT_Y_MINOR_TICKS).path();
path_element& major_tick_path = image.get_g_element(detail::PLOT_Y_MAJOR_TICKS).path();
path_element& minor_grid_path = image.get_g_element(detail::PLOT_Y_MINOR_GRID).path();
path_element& major_grid_path = image.get_g_element(detail::PLOT_Y_MAJOR_GRID).path();
- if(use_y_axis_lines_)
- { // TODO what does this do?
+ if(use_y_ticks_on_plot_window_)
+ { // TODO confirm that labels allow space.
+ // Was y_external style - so both labels (and ticks) are OUTSIDE the plot window.
image.get_g_element(detail::PLOT_Y_AXIS).line(plot_y1, x_axis, plot_x2, x_axis);
- // <line x1="53" y1="-9.26e+061" x2="345" y2="-9.26e+061"/></g>
- // So x_axis is undefined!!!
}
// y_minor_jump is the interval between minor ticks.
- double y_minor_jump = y_major / ((double)(y_num_minor_ticks_ + 1.) );
+ double y_minor_jump = y_major_interval_ / ((double)(y_num_minor_ticks_ + 1.) );
// TODO Problem here with using floating point?
// Was i < y_max; but didn't show the tick and value at y_max so now i <= y_max;
// But may still fail if a ls or few bits out? Seems to fail for y = 100, for example.
// Draw the ticks on the positive side.
- for(double i = 0; i <= y_max; i += y_major)
+ for(double i = 0; i <= y_max; i += y_major_interval_)
{
- for(double j = i + y_minor_jump; j < i + y_major; j += y_minor_jump)
+ for(double j = i + y_minor_jump; j < i + y_major_interval_; j += y_minor_jump)
{ // Draw minor ticks.
// This will output 'orphaned' minor ticks that are beyond the plot window,
// if the last major tick does not coincide with the plot window.
@@ -629,9 +716,9 @@
}
// Draw the ticks on the negative side.
- for(double i = 0; i >= y_min; i -= y_major)
+ for(double i = 0; i >= y_min; i -= y_major_interval_)
{
- for(double j=i; j > i-y_major; j-= y_major / (y_num_minor_ticks_ + 1))
+ for(double j=i; j > i-y_major_interval_; j-= y_major_interval_ / (y_num_minor_ticks_ + 1))
{ // Draw minor ticks.
draw_y_minor_ticks(j, minor_tick_path, minor_grid_path);
}
@@ -652,7 +739,8 @@
}
image.get_g_element(detail::PLOT_Y_LABEL).push_back(new
- text_element(y_label_info.font_size() * text_margin, // shift right
+ text_element(y_label_info.font_size() * text_margin_,
+ // shift over one char height to right from left edge of image.
(plot_y2 + plot_y1) / 2., // center on the plot window.
label, // "Y-Axis" for example.
y_label_info.font_size(),
@@ -661,21 +749,90 @@
upward)); // Y label must be drawn vertically.
} // draw_y_label
+ void draw_straight_lines(const svg_2d_plot_series& series)
+ { // Straight line between data points (rather than a Bezier curve).
+ double prev_x; // Previous data points.
+ double prev_y;
+ double temp_x(0.);
+ double temp_y;
+
+ g_element& g_ptr = image.get_g_element(detail::PLOT_DATA_LINES).add_g_element();
+ g_ptr.clip_id(plot_window_clip);
+ g_ptr.style().stroke_color(series.line_style.color);
+ g_ptr.style().fill_color(series.line_style.area_fill);
+ path_element& path = g_ptr.path();
+ path.style().fill_color(series.line_style.area_fill);
+
+ bool is_fill = !series.line_style.area_fill.blank;
+ path.fill = is_fill; // Ensure includes a fill="none".
+
+ if(series.series.size() > 1)
+ {
+ std::multimap<double, double>::const_iterator j = series.series.begin();
+
+ // If we have to fill the area under the plot,
+ // we first have to move from the X-axis (y = 0) to the first point,
+ // and again at the end after the last point.
+ prev_x = (*j).first;
+ prev_y = 0.;
+ transform_point(prev_x, prev_y);
+ if(is_fill)
+ { // Move to 1st point.
+ path.style().fill_color(series.line_style.area_fill);
+ path.M(prev_x, prev_y);
+ }
+ transform_y(prev_y = (*j).second);
+ if(is_fill)
+ { // fill wanted.
+ path.style().fill_color(series.line_style.area_fill); // TOD why again?
+ path.L(prev_x, prev_y); // Line from X-axis to 1st point.
+ }
+ else
+ { // fill == blank
+ path.M(prev_x, prev_y);
+ }
+ ++j; // so now refers to 2nd point to plot.
+
+ for(; j != series.series.end(); ++j)
+ {
+ temp_x = (*j).first;
+ temp_y = (*j).second;
+ transform_point(temp_x, temp_y);
+ path.L(temp_x, temp_y); // line to next point.
+
+ if(is_fill)
+ {
+ path.M(temp_x, temp_y);
+ }
+ prev_x = temp_x;
+ prev_y = temp_y;
+ } // for j
+
+ if(is_fill)
+ { // fill wanted.
+ transform_y(temp_y = 0.); // X-axis line.
+ path.L(temp_x, temp_y).z(); // closepath with Z to terminate line.
+ }
+ }
+ } // draw_straight_lines
+
void draw_bezier_lines(const svg_2d_plot_series& series)
{
- g_element& g_ptr = image.get_g_element(detail::PLOT_PLOT_LINES).add_g_element();
+ g_element& g_ptr = image.get_g_element(detail::PLOT_DATA_LINES).add_g_element();
g_ptr.clip_id(plot_window_clip);
g_ptr.style().stroke_color(series.line_style.color);
path_element& path = g_ptr.path();
+ std::pair<double, double> n;
+ std::pair<double, double> n_minus_1;
std::pair<double, double> n_minus_2;
- std::pair<double, double> n_minus_1, n;
std::pair<double, double> fwd_vtr;
std::pair<double, double> back_vtr;
- if(series.line_style.area_fill == blank)
+ bool is_fill = !series.line_style.area_fill.blank;
+ if(is_fill == false)
{
- path.fill = false;
+ path.fill = false; // default path constructor is true - TODO why??
}
else
{ // fill
@@ -683,7 +840,7 @@
}
if(series.series.size() > 2)
- {
+ { // Need >= 3 for a curve, of course.
std::multimap<double, double>::const_iterator iter = series.series.begin();
n_minus_1 = *(iter++);
@@ -706,14 +863,16 @@
(n_minus_2.second - n_minus_1.second)) * 0.2;
// 8.3.6 The cubic Bézier curve commands path.S(x, y).
- path.S(n_minus_1.first + back_vtr.first, n_minus_1.second + back_vtr.second,
- n_minus_1.first, n_minus_1.second);
+ path.S(n_minus_1.first + back_vtr.first,
+ n_minus_1.second + back_vtr.second,
+ n_minus_1.first, n_minus_1.second);
}
- back_vtr.first = 0;
+ back_vtr.first = 0.;
back_vtr.second = (n.second - n_minus_1.second)* 0.2;
- path.S(n.first + back_vtr.first, n.second + back_vtr.second,
- n.first, n.second);
+ path.S(n.first + back_vtr.first,
+ n.second + back_vtr.second,
+ n.first, n.second);
}
else
{ // Only one or two points, so no curving possible!
@@ -721,70 +880,8 @@
}
} // draw_bezier_lines
- void draw_straight_lines(const svg_2d_plot_series& series)
- { // Straight line between data points (rather than a Bezier curve).
- double prev_x;
- double prev_y;
- double temp_x(0.);
- double temp_y;
-
- g_element& g_ptr = image.get_g_element(detail::PLOT_PLOT_LINES).add_g_element();
- g_ptr.clip_id(plot_window_clip);
- g_ptr.style().stroke_color(series.line_style.color);
- path_element& path = g_ptr.path();
- if(series.series.size() > 1)
- {
- std::multimap<double, double>::const_iterator j = series.series.begin();
- prev_x = (*j).first;
- prev_y = 0.;
-
- // If we have to fill the area under the plot,
- // we first have to move from the X-axis (y = 0) to the first point,
- // and again at the end after the last point.
- transform_point(prev_x, prev_y); // TODO 0. clearer here.
- if(series.line_style.area_fill != blank)
- { // Move to 1st point.
- path.style().fill_color(series.line_style.area_fill);
- path.M(prev_x, prev_y);
- }
-
- transform_y(prev_y = (*j).second);
- if(series.line_style.area_fill != blank)
- { // fill wanted.
- path.style().fill_color(series.line_style.area_fill);
- path.L(prev_x, prev_y); // Line from X-axis to 1st point.
- }
- else
- { // fill == blank
- path.M(prev_x, prev_y);
- }
- ++j; // refers to 2nd point to plot.
-
- for(; j != series.series.end(); ++j)
- {
- temp_x = (*j).first;
- temp_y = (*j).second;
- transform_point(temp_x, temp_y);
- path.L(temp_x, temp_y); // line to next point.
-
- if(series.line_style.area_fill == blank)
- {
- path.M(temp_x, temp_y);
- }
- prev_x = temp_x;
- prev_y = temp_y;
- } // for j
-
- if(series.line_style.area_fill != blank)
- { // fill wanted.
- transform_y(temp_y = 0.); // X-axis
- path.L(temp_x, temp_y).z(); // terminate line.
- }
- }
- } // draw_straight_lines
-
void draw_plot_lines()
- { // Draw line through data series, curved or straight.
+ { // Draw line through data series, Bezier curved or straight.
for(unsigned int i = 0; i < series.size(); ++i)
{
if(series[i].line_style.bezier_on)
@@ -801,8 +898,10 @@
void update_image()
{
clear_all();
+ // svg paint rules are that later 'painting' writes over previous
+ // painting, so the order of drawing is important.
- // Draw imagebackground (perhaps with border and/or fill color).
+ // Draw image background (perhaps with border and/or fill color).
image.get_g_element(detail::PLOT_BACKGROUND).push_back(
new rect_element(0, 0, image.x_size(), image.y_size()));
@@ -820,12 +919,13 @@
plot_window_clip);
// <clipPath id="plot_window"><rect x="35" y="38" width="309" height="322"/></clipPath>
- image.get_g_element(detail::PLOT_PLOT_POINTS).clip_id(plot_window_clip);
+ image.get_g_element(detail::PLOT_DATA_POINTS).clip_id(plot_window_clip);
+
// Draw axes, labels & legend, as required.
if(use_axis)
{
+ draw_x_axis(); // Must do X-axis first.
draw_y_axis(); // TODO is draw_axes used?
- draw_x_axis();
}
if(use_legend)
{
@@ -847,7 +947,7 @@
double y(0.);
for(unsigned int i = 0; i < series.size(); ++i)
{
- g_element& g_ptr = image.get_g_element(detail::PLOT_PLOT_POINTS).add_g_element();
+ g_element& g_ptr = image.get_g_element(detail::PLOT_DATA_POINTS).add_g_element();
g_ptr.style()
.fill_color(series[i].point_style.fill_color)
@@ -917,18 +1017,62 @@
// These below only refer to 2D plot.
// See axis_plot_label.hpp for all the many 1D functions X-Axis.
- svg_2d_plot& y_name_on(bool cmd)
- {
+ svg_2d_plot& y_label_on(bool cmd)
+ { // Y axis name or label.
use_y_label = cmd;
return *this;
}
+ bool y_label_on()
+ {
+ return use_y_label;
+ }
+
+ svg_2d_plot& x_label_on(bool cmd)
+ {
+ use_x_label = cmd;
+ return *this;
+ }
+
+ bool x_label_on()
+ {
+ return use_x_label;
+ }
+
+
svg_2d_plot& y_major_labels_on(bool cmd)
{
use_y_major_labels = cmd;
return *this;
}
+ bool y_major_labels_on()
+ {
+ return use_y_major_labels;
+ }
+
+ svg_2d_plot& y_major_label_up(bool cmd)
+ {
+ use_y_label_up_ = cmd;
+ return *this;
+ }
+
+ bool y_major_label_up()
+ {
+ return use_y_label_up_;
+ }
+
+ svg_2d_plot& y_axis_width(double width)
+ {
+ image.get_g_element(detail::PLOT_Y_AXIS).style().stroke_width(width);
+ return *this;
+ }
+
+ double y_axis_width()
+ {
+ return image.get_g_element(detail::PLOT_Y_AXIS).style().stroke_width();
+ }
+
svg_2d_plot& y_axis_color(const svg_color& col)
{ // Set BOTH stroke and fill to the same color.
image.get_g_element(detail::PLOT_Y_AXIS).style().fill_color(col);
@@ -943,14 +1087,48 @@
svg_2d_plot& y_axis_label_color(const svg_color& col)
{ // Set BOTH stroke and fill to the same color.
- image.get_g_element(detail::PLOT_Y_LABEL).style().fill_color(col);
- image.get_g_element(detail::PLOT_Y_LABEL).style().stroke_color(col);
+ image.get_g_element(detail::PLOT_VALUE_LABELS).style().fill_color(col);
+ image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color(col);
return *this;
}
svg_color y_axis_label_color()
{ // But only return the stroke color.
- return image.get_g_element(detail::PLOT_Y_LABEL).style().stroke_color();
+ return image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color();
+ }
+
+ svg_2d_plot& y_label_units_on(bool b)
+ {
+ use_y_label_units = b;
+ return *this;
+ }
+
+ bool y_label_units_on()
+ { // But only return the stroke color.
+ return use_y_label_units;
+ }
+
+ svg_2d_plot& y_axis_value_color(const svg_color& col)
+ { // Set BOTH stroke and fill to the same color.
+ image.get_g_element(detail::PLOT_VALUE_LABELS).style().fill_color(col);
+ image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color(col);
+ return *this;
+ }
+
+ svg_color y_axis_value_color()
+ { // But only return the stroke color.
+ return image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color();
+ }
+
+ svg_2d_plot& y_label_width(double width)
+ { // width of text is effectively the boldness
+ image.get_g_element(detail::PLOT_Y_LABEL).style().stroke_width(width);
+ return *this;
+ }
+
+ double y_label_width()
+ {
+ return image.get_g_element(detail::PLOT_Y_LABEL).style().stroke_width();
}
svg_2d_plot& y_major_grid_color(const svg_color& col)
@@ -959,26 +1137,46 @@
return *this;
}
+ const svg_color& y_major_grid_color()
+ {
+ return image.get_g_element(detail::PLOT_Y_MAJOR_GRID).style().stroke_color();
+ }
+
svg_2d_plot& y_minor_grid_color(const svg_color& col)
{
image.get_g_element(detail::PLOT_Y_MINOR_GRID).style().stroke_color(col);
return *this;
}
+ const svg_color& y_minor_grid_color()
+ {
+ return image.get_g_element(detail::PLOT_Y_MINOR_GRID).style().stroke_color();
+ }
+
svg_2d_plot& y_major_tick_color(const svg_color& col)
{
image.get_g_element(detail::PLOT_Y_MAJOR_TICKS).style().stroke_color(col);
return *this;
}
+ const svg_color& y_major_tick_color()
+ {
+ return image.get_g_element(detail::PLOT_Y_MAJOR_TICKS).style().stroke_color();
+ }
+
svg_2d_plot& y_minor_tick_color(const svg_color& col)
{
image.get_g_element(detail::PLOT_Y_MINOR_TICKS).style().stroke_color(col);
return *this;
}
- svg_2d_plot& y_range(double y1, double y2)
+ const svg_color& y_minor_tick_color()
{
+ return image.get_g_element(detail::PLOT_Y_MINOR_TICKS).style().stroke_color();
+ }
+
+ svg_2d_plot& y_range(double y1, double y2)
+ { // Set the range (max and min) for Y values.
y_min = y1;
y_max = y2;
if(y2 <= y1)
@@ -988,42 +1186,53 @@
return *this;
}
- svg_2d_plot& y_axis_width(unsigned int width)
+ std::pair<double, double> y_range()
{
- // TODO should be stored elsewhere too?
- image.get_g_element(detail::PLOT_Y_AXIS).style().stroke_width(width);
- return *this;
+ std::pair<double, double> r;
+ r.first = y_min;
+ r.second = y_max;
+ return r;
+ }
+
+ double y_minimum()
+ {
+ return y_min;
+ }
+
+ double y_maximum()
+ {
+ return y_max;
}
svg_2d_plot& y_major_interval(double inter)
{
- y_major = inter;
+ y_major_interval_ = inter;
return *this;
}
double y_major_interval()
{
- return y_major;
+ return y_major_interval_;
}
- svg_2d_plot& y_major_tick_length(unsigned int length)
+ svg_2d_plot& y_major_tick_length(double length)
{
y_major_tick_length_ = length;
return *this;
}
- unsigned int y_major_tick_length()
+ double y_major_tick_length()
{
return y_major_tick_length_;
}
- svg_2d_plot& y_minor_tick_length(unsigned int length)
+ svg_2d_plot& y_minor_tick_length(double length)
{
y_minor_tick_length_ = length;
return *this;
}
- unsigned int y_minor_tick_length()
+ double y_minor_tick_length()
{
return y_minor_tick_length_;
}
@@ -1039,42 +1248,41 @@
return y_num_minor_ticks_;
}
- svg_2d_plot& y_name(const std::string& str)
+ svg_2d_plot& y_label_axis(const std::string& str)
{ // Label for Y-axis.
y_label_info.text(str);
return *this;
}
- const std::string& y_name()
+ std::string y_label_axis()
{
return y_label_info.text();
}
- svg_2d_plot& y_major_tick_width(unsigned int width)
+ svg_2d_plot& y_major_tick_width(double width)
{
y_major_tick_width_ = width;
image.get_g_element(detail::PLOT_Y_MAJOR_TICKS).style().stroke_width(width);
return *this;
}
- unsigned int y_major_tick_width()
+ double y_major_tick_width()
{
return y_major_tick_width_;
}
- svg_2d_plot& y_minor_tick_width(unsigned int width)
+ svg_2d_plot& y_minor_tick_width(double width)
{
y_minor_tick_width_ = width;
image.get_g_element(detail::PLOT_Y_MINOR_TICKS).style().stroke_width(width);
return *this;
}
- unsigned int y_minor_tick_width()
+ double y_minor_tick_width()
{
return y_minor_tick_width_;
}
-
svg_2d_plot& x_ticks_on_plot_window_on(bool is)
{
use_x_ticks_on_plot_window_ = is;
@@ -1124,32 +1332,50 @@
svg_2d_plot& y_major_grid_on(bool is)
{
- use_y_major_grid = is;
+ use_y_major_grid_ = is;
return *this;
}
bool y_major_grid_on()
{
- return use_y_major_grid;
+ return use_y_major_grid_;
}
svg_2d_plot& y_minor_grid_on(bool is)
{
- use_y_minor_grid = is;
+ use_y_minor_grid_ = is;
return *this;
}
bool y_minor_grid_on()
{
- return use_y_minor_grid;
+ return use_y_minor_grid_;
}
- svg_2d_plot& y_label_on(bool cmd)
+ svg_2d_plot& y_minor_grid_width(double width)
{
- use_y_label = cmd;
+ y_minor_grid_width_ = width;
+ image.get_g_element(detail::PLOT_Y_MINOR_GRID).style().stroke_width(width);
+ return *this;
+ }
+
+ double y_minor_grid_width()
+ {
+ return y_minor_grid_width_;
+ }
+
+ svg_2d_plot& y_major_grid_width(double width)
+ {
+ y_major_grid_width_ = width;
+ image.get_g_element(detail::PLOT_Y_MAJOR_GRID).style().stroke_width(width);
return *this;
}
+ double y_major_grid_width()
+ {
+ return y_major_grid_width_;
+ }
+
svg_2d_plot& y_label_font_size(unsigned int i)
{ // TODO May be best to tie these two font sizes together?
y_label_info.font_size(i);
@@ -1168,10 +1394,15 @@
return *this;
}
- const std::string& y_label_font_family()
- {
- return y_label_info.font_family();
- }
+ const std::string& y_label_font_family();
+ //const std::string& y_label_font_family()
+ //{
+ // return y_label_info.font_family();
+ //}
+
+ // Example of declaration but definition below.
+ // TODO Probably better done this way,
+ // but wait until parameter system removed.
// plot member function, with several parameters, using Boost.Parameter,
// to add data series to the plot window.
@@ -1195,7 +1426,8 @@
(fill_color, (const svg_color&), white)
(stroke_color, (const svg_color&), black)
(line_color, (const svg_color&), black)
- (area_fill_color, (svg_color_constant), blank)
+ (area_fill_color, (const svg_color&), true) // == is blank
+ // (area_fill_color, (svg_color_constant), blank)
(point_style, (point_shape), round)
(size, (int), 10)
(line_on, (bool), true)
@@ -1209,9 +1441,9 @@
// the start to be set, as well as i to update in operator().
// x_functor.start(1.);
- plot_line_style line_style(line_color, line_on, bezier_on);
+ plot_line_style line_style(line_color, blank, line_on, bezier_on);
- line_style.area_fill=area_fill_color;
+ line_style.area_fill = area_fill_color;
series.push_back(
svg_2d_plot_series(
@@ -1224,6 +1456,13 @@
}
}; // class svg_2d_plot : public detail::axis_plot_frame<svg_2d_plot>
+
+ const std::string& svg_2d_plot::y_label_font_family()
+ {
+ return y_label_info.font_family();
+ }
+
+
#if defined (BOOST_MSVC)
# pragma warning(pop)
#endif
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg_boxplot.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg_boxplot.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_boxplot.hpp 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
@@ -122,9 +122,9 @@
double iqr(q3-q1);
double min_ext_cutoff = q1 - 3. * iqr;
- double min_cutoff = q1 - text_margin * iqr;
+ double min_cutoff = q1 - text_margin_ * iqr;
double max_ext_cutoff = q3 + 3. * iqr;
- double max_cutoff = q3 + text_margin * iqr;
+ double max_cutoff = q3 + text_margin_ * iqr;
std::vector<double>::const_iterator i;
@@ -190,7 +190,7 @@
// Axes information.
double y_min;
double y_max;
- double y_major;
+ double y_major_interval_;
double y_axis;
double x_axis;
unsigned int x_major_tick_length_;
@@ -281,13 +281,13 @@
image.get_g_element(boxplot::Y_MAJOR_TICKS).path();
// y_minor_jump is the interval between minor ticks.
- double y_minor_jump = y_major/((double)(y_num_minor_ticks_ + 1.) );
+ double y_minor_jump = y_major_interval_/((double)(y_num_minor_ticks_ + 1.) );
// Draw the ticks on the positive side.
- for(double i = 0; i < y_max; i += y_major)
+ for(double i = 0; i < y_max; i += y_major_interval_)
{
for(double j = i + y_minor_jump;
- j < i + y_major;
+ j < i + y_major_interval_;
j += y_minor_jump)
{
draw_y_minor_ticks(j, minor_tick_path);
@@ -297,10 +297,10 @@
}
// Draw the ticks on the negative side.
- for(double i = 0; i > y_min; i -= y_major)
+ for(double i = 0; i > y_min; i -= y_major_interval_)
{
// draw minor ticks
- for(double j=i; j>i-y_major; j-=y_major / (y_num_minor_ticks_+1))
+ for(double j=i; j>i-y_major_interval_; j-=y_major_interval_ / (y_num_minor_ticks_+1))
{
draw_y_minor_ticks(j, minor_tick_path);
}
@@ -388,12 +388,12 @@
if(use_y_label)
{
- plot_x1 += (int)(y_label_info.font_size() * text_margin);
+ plot_x1 += (int)(y_label_info.font_size() * text_margin_);
}
if(use_title)
{
- plot_y1 += (int)(title_info.font_size() * text_margin);
+ plot_y1 += (int)(title_info.font_size() * text_margin_);
}
// Give the plot window a natural bit of padding.
@@ -603,7 +603,7 @@
// y_units_info(0, 0, "(units)", 12, "Lucida Sans Console", "", "", "", "", center_align, upward),
y_min(0), y_max(100),
- y_major(10),
+ y_major_interval_(10),
use_y_label(true),
use_x_label(true),
x_major_tick_length_(10),
@@ -816,7 +816,7 @@
svg_boxplot& y_major_interval(double inter)
{
- y_major = inter;
+ y_major_interval_ = inter;
return *this;
}
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg_color.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg_color.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_color.hpp 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
@@ -55,7 +55,7 @@
skyblue, slateblue, slategray, slategrey, snow, springgreen,
steelblue, tan, teal, thistle, tomato, turquoise, violet,
wheat, white, whitesmoke, yellow, yellowgreen,
- blank // 'NotAColor'
+ blank // 'NotAColor' == 147
};
// Forward declarations in this module (see svg_fwd):
@@ -79,7 +79,7 @@
unsigned char r; // unsigned char provides range [0 to 255].
unsigned char g;
unsigned char b;
- bool blank; // true means "Not to be displayed" 'pseudo-color'.
+ bool blank; // true means "Not to be displayed" a 'pseudo-color'.
// TODO seems to display as black? - Need a check if is_blank == true?
svg_color(int red, int green, int blue) : blank(false)
@@ -93,7 +93,7 @@
}
svg_color(bool is) : blank(is)
- { // Permits blank as a (non-)color.
+ { // Permits blank (=true) as a (non-)color.
r = 0; // Safer to assign *some* value to rgb? zero, or 255?
g = 0; // rather than leaving them random?
b = 0;
@@ -108,7 +108,8 @@
{ // Write color in svg format, for example, rgb(127,255,212).
if(!blank)
{
- rhs << "rgb(" << (unsigned int)r << "," << (unsigned int) g << ","
+ rhs << "rgb(" << (unsigned int)r << ","
+ << (unsigned int) g << ","
<< (unsigned int)b << ")" ;
}
else
@@ -167,7 +168,7 @@
{
os << "RGB("
<< (unsigned int)color.r << ","
- << (unsigned int) color.g << ","
+ << (unsigned int)color.g << ","
<< (unsigned int)color.b << ")" ;
}
else
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg_style.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg_style.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_style.hpp 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
@@ -74,14 +74,14 @@
struct plot_line_style
{ // TODO dotted and dashed line style? Useful for B&W?
- svg_color color;
- svg_color area_fill; // Fill color from line to axis.
+ svg_color color; // line stroke color.
+ svg_color area_fill; // Fill color from line to axis. == true means color.blank = true.
bool line_on;
bool bezier_on;
- plot_line_style(const svg_color& col, const svg_color& acol = blank, bool on = true, bool bezier_on = false)
+ plot_line_style(const svg_color& col, const svg_color& acol = true, bool on = true, bool bezier_on = false)
:
- color(col), line_on(on), area_fill(acol), bezier_on(bezier_on)
+ color(col), area_fill(acol), line_on(on), bezier_on(bezier_on)
{
}
}; // struct plot_line_style
@@ -97,7 +97,7 @@
// to permit use of names for set & get member functions.
svg_color fill_;
svg_color stroke_;
- unsigned int width_;
+ double width_;
bool fill_on_; // true means there is fill info.
bool stroke_on_;
bool width_on_;
@@ -129,8 +129,8 @@
return svg_color(stroke_);
}
- unsigned int stroke_width() const
- { // TODO probably should be double???
+ double stroke_width() const
+ {
return width_;
}
@@ -168,7 +168,7 @@
svg_style& fill_color(const svg_color& col)
{
fill_ = col;
- fill_on_ = true;
+ fill_on_ = ! col.blank; // if blank fill is off or "none"
return *this;
}
@@ -179,7 +179,7 @@
return *this;
}
- svg_style& stroke_width(unsigned int width)
+ svg_style& stroke_width(double width)
{
width_ = width;
width_on_ = true;
@@ -198,7 +198,7 @@
{
rhs << " fill=\"";
fill_.write(rhs);
- rhs<<"\"";
+ rhs << "\"";
}
if(width_on_)
{
@@ -207,6 +207,7 @@
<< "\"";
}
} // void write
+ // Examples: <g id="yMinorTicks" stroke="rgb(0,0,0)" stroke-width="1">
}; // class svg_style
}//svg
Modified: sandbox/SOC/2007/visualization/libs/svg_plot/doc/svg_plot.qbk
==============================================================================
--- sandbox/SOC/2007/visualization/libs/svg_plot/doc/svg_plot.qbk (original)
+++ sandbox/SOC/2007/visualization/libs/svg_plot/doc/svg_plot.qbk 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
@@ -1390,6 +1390,37 @@
[section:implementation Implementation & Rationale]
+[h4 Number of Minor ticks]
+
+`x_num_minor_ticks()` and `x_num_minor_ticks()`
+
+are provided control the number of minor ticks between the major ticks.
+
+There are a total of x_num_minor_ticks + 1 ticks for each major tick,
+for example, a major on 0, minor on 1,2,3,4, major on 5 ...
+
+For integer usually binary, octal and hexadecimal,
+num_minor_ticks = 2[super]n -1 are useful, for example
+ 1 if major ticks are even will give minor ticks on odd values),
+ 3 if major on 0, minor on 1, 2, 3 and major on 4...
+ 7 if major on 0, minor on 1,2,3,4,5,6,7 and major on 8 ...
+ 15 if major on 0, minor on 1,2,3,4,5,6,7, 8,9,A,B,C,D,E,F, major on 0x10...
+
+ For decimal based values, num_minor_ticks 1, 4, 9 are useful, for example:
+ 1 if major are even, major 0, minor 1, major 2 ...
+ 4 if major on 0, minor on 1,2,3,4, major on 5 ...
+ 9 if major on 0, minor on 1,2,3,4,5,6,7,8,9, major on 10
+
+
+
+
+
+
+
+
+[/h4 Minor ticks]
+
+
This section provide more information about this implementation
and some of the rationale for desing decisions.
@@ -1570,8 +1601,16 @@
but requires both notice & attribution
is probably most suitable for Boost documents as is therefore chosen as the default.
-This license can be included by calling svg member function is_license(true).
-
+This license can be included by calling svg member function `is_license(true)`.
+If this license will be included can be discovered by calling svg member function `is_license()`.
+
+Similarly functions
+ const std::string license_reproduction();`
+ const std::string license_distribution();
+ const std::string license_attribution();
+ const std::string license_commercialuse()
+allow you to find the current license requirements.
+
[@http://web.resource.org/rss/1.0/modules/cc/ RDF] is the metadata format chosen by
[@http://creativecommons.org Creative Commons].
Modified: sandbox/SOC/2007/visualization/libs/svg_plot/test/1d_color_consistency.cpp
==============================================================================
--- sandbox/SOC/2007/visualization/libs/svg_plot/test/1d_color_consistency.cpp (original)
+++ sandbox/SOC/2007/visualization/libs/svg_plot/test/1d_color_consistency.cpp 2007-11-29 14:34:34 EST (Thu, 29 Nov 2007)
@@ -115,6 +115,10 @@
//BOOST_CHECK_EQUAL(my_plot.image_x_size(), 400U);
// check my_plot.image_x_size() == 400U failed [500 != 400]
+ BOOST_CHECK_EQUAL(my_plot.legend_top_left(), std::pair(-1., -1.); // default position unassigned = -1..
+ my_plot.legend_top_left(10., 20.);
+ BOOST_CHECK_EQUAL(my_plot.legend_top_left(), std::pair(10., 20.); // new assigned position.
+
BOOST_CHECK_EQUAL(my_plot.title(), "Plot of data"); // Title of plot.
my_plot.title("test");
BOOST_CHECK_EQUAL(my_plot.title(), "test");
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk