Boost logo

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