$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r55227 - in sandbox/SOC/2007/visualization/boost/svg_plot: . detail
From: pbristow_at_[hidden]
Date: 2009-07-30 14:44:01
Author: pbristow
Date: 2009-07-28 07:45:58 EDT (Tue, 28 Jul 2009)
New Revision: 55227
URL: http://svn.boost.org/trac/boost/changeset/55227
Log:
demo_2d_fonts now seems to align axis labels OK, but demo_2d_plot still seems to put X axis label slightly wrong on some plots.
Text files modified: 
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp |   321 +++++++++++++++++++++++++-------------- 
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp         |    48 +++--                                   
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_2d_plot.hpp            |   234 +++++++++++++++++++++++-----            
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_style.hpp              |    16                                         
   4 files changed, 424 insertions(+), 195 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	2009-07-28 07:45:58 EDT (Tue, 28 Jul 2009)
@@ -316,11 +316,9 @@
                 std::string v = strip_e0s(tick_value_label.str());
                 tick_value_label.str(v);
               }
-
               double y = 0; // Where to start writing from, at end of bottom or top tick, if any.
               // = 0 is only to avoid unitialised warning.
               align_style alignment = center_align;
-              // rotate_style rot = derived().x_ticks_.label_rotation_;  // TODO for debug only.
               // Adjustments to provide space from end of tick before or after writing label.
               if (derived().x_ticks_.label_rotation_ == upward) // vertical writing up.
               {  // Shift to center value digits and minus sign on tick.
@@ -350,6 +348,20 @@
                   alignment = right_align;
                 }
               }
+              else if (derived().x_ticks_.label_rotation_ == steepup)
+              {  // Should handle other directions too.
+                x -= derived().x_value_label_style_.font_size() * 0.3;
+                if (derived().x_ticks_.major_value_labels_side_ < 0)
+                { // labels upward, so start a little below y_down.
+                  y = y_down + derived().x_value_label_style_.font_size() * 0.5;
+                  alignment = left_align;
+                }
+                else if(derived().x_ticks_.major_value_labels_side_ > 0)
+                { // labels to top, so start a little above y_up.
+                  y = y_up - derived().x_value_label_style_.font_size() * 0.5;
+                  alignment = right_align;
+                }
+              }
               else if (derived().x_ticks_.label_rotation_ == uphill)
               { // Assume some 45 slope, so need about sqrt(2) less space.
                 x += derived().x_value_label_style_.font_size() * 0.5;
@@ -361,6 +373,21 @@
                 }
                 else if(derived().x_ticks_.major_value_labels_side_ > 0)
                 { // labels to top, so start a little to top of y_top.
+                  y = y_up - derived().x_value_label_style_.font_size() * 0.3;
+                  alignment = left_align;
+                }
+              }
+              else if (derived().x_ticks_.label_rotation_ == slopeup)
+              { // Assume for 30 degree slope, need about sqrt(2) less space.
+                x += derived().x_value_label_style_.font_size() * 0.5;
+                if (derived().x_ticks_.major_value_labels_side_ < 0)
+                { // labels to bottom, so start a little to bottom of y_bottom.
+                  y = y_down + derived().x_value_label_style_.font_size() * sin45;
+                  // Seems to need a bit more space for top than bottom if rotated.
+                  alignment = right_align;
+                }
+                else if(derived().x_ticks_.major_value_labels_side_ > 0)
+                { // labels to top, so start a little to top of y_top.
                   y = y_up - derived().x_value_label_style_.font_size() * 0.2;
                   alignment = left_align;
                 }
@@ -380,12 +407,44 @@
                   alignment = right_align;
                 }
               }
-              else if (derived().x_ticks_.label_rotation_ == horizontal)
-              { // Tick value label on X axis is normal default horizontal.
+              else if (derived().x_ticks_.label_rotation_ == slopedownhill)
+              { // Assume some 30 slope, so need about sqrt(2) less space.
+                x -= derived().x_value_label_style_.font_size() * 0.3;
                 if (derived().x_ticks_.major_value_labels_side_ < 0)
                 { // labels to bottom, so start a little to bottom of y_down.
-                  y = y_down + derived().x_value_label_style_.font_size() * 1.2;
-                  alignment = center_align; // on the tick.
+                  y = y_down + derived().x_value_label_style_.font_size() * 0.7;
+                  // Seems to need a bit more space for top than bottom if rotated.
+                  alignment = left_align;
+                }
+                else if(derived().x_ticks_.major_value_labels_side_ > 0)
+                { // labels to top, so start a little to top of y_up.
+                 y = y_up - derived().x_value_label_style_.font_size() * 0.3;
+                  alignment = right_align;
+                }
+              }
+
+
+              else if (derived().x_ticks_.label_rotation_ == steepdown)
+              {  // Should handle other directions too.
+                x -= derived().x_value_label_style_.font_size() * 0.3;
+                if (derived().x_ticks_.major_value_labels_side_ < 0)
+                { // labels to bottom, so start a little below y_down.
+                  y = y_down + derived().x_value_label_style_.font_size() * 0.5;
+                  alignment = left_align;
+                }
+                else if(derived().x_ticks_.major_value_labels_side_ > 0)
+                { // labels to top, so start a little above y_up.
+                  y = y_up - derived().x_value_label_style_.font_size() * 0.5;
+                  alignment = right_align;
+                }
+              }
+
+              else if (derived().x_ticks_.label_rotation_ == horizontal)
+              { // Tick value label on X-axis is normal default horizontal.
+                if (derived().x_ticks_.major_value_labels_side_ < 0)
+                { // labels to bottom of tick, so start a little below bottom of y_down.
+                  y = y_down + derived().x_value_label_style_.font_size() * 1.3; // 1.3 allows 1/3 font space.
+                  alignment = center_align; // center on the tick.
                 }
                 else if(derived().x_ticks_.major_value_labels_side_ > 0)
                 { // labels to top, so start a little to top of y_up.
@@ -439,9 +498,9 @@
         } // draw_x_major_tick
 
         void draw_x_axis()
-        { //! Draw horizontal X-axis line & plot window line to hold.
+        { //! Draw horizontal X-axis line & plot window line to hold, and ticks and grids.
           if(derived().x_axis_.axis_line_on_)
-          { // Want a horiztonal X-axis line drawn.
+          { // Want a horizontal X-axis line drawn.
             double xleft = derived().plot_left_;
             double xright = derived().plot_right_;
             if (derived().x_axis_position_ == x_intersects_y)
@@ -545,6 +604,142 @@
           }
         } // void draw_x_axis()
 
+        void draw_x_label()
+        { //! Draw the X-axis label text (for example, length),
+          //! and append any optional units (for example, km).
+          // X-label color default is set in constructor thus:
+          // image.g(detail::PLOT_X_LABEL).style().stroke_color(black);
+          // and changed using x_label_color(color);
+          // Similarly for font family and size etc (must be same for both label and units).
+
+          std::string x_label = derived().x_label_info_.text(); // x_axis_ label, and optional units.
+          if (derived().x_axis_.label_units_on_ && (derived().x_units_info_.text() != ""))
+          { // Append the units, if any, user providing brackets () if required. 
+            x_label += derived().x_units_info_.text(); // for example: "time (sec)".
+          }
+
+          double y = derived().plot_bottom_;
+          // Glyphs for western characters are aligned with the left bottom of capital letter,
+          // so need to allow 1/3 more below for any descenders.
+
+          // cout << "derived().x_ticks_.ticks_on_window_or_on_axis_ " << derived().x_ticks_.ticks_on_window_or_on_axis_ << endl;
+          // using derived(0 means debugging doesn't work!  So resort to old-fashioned print statements.
+          if (derived().x_ticks_.ticks_on_window_or_on_axis_ < 0) // -1 means bottom
+          { // Ticks value labels below plot window.
+            if (derived().x_ticks_.major_value_labels_side_ < 0) // bottom
+            { // Shift down to allow for any tick value labels.
+              if ((derived().x_ticks_.label_rotation_ == downward) || (derived().x_ticks_.label_rotation_ == upward))
+              { // downward tick value label direction 90 up or down.
+                y += derived().x_ticks_.label_max_space_;
+                if (derived().x_ticks_.down_ticks_on_ == true)
+                {  // Move down for any downward ticks.
+                  y += 1.1 * (std::max)(derived().x_ticks_.major_tick_length_, derived().x_ticks_.minor_tick_length_); // And avoid macro max trap!
+                  // and a small space.
+                  y += 0.7 * (derived().x_label_info_.textstyle().font_size() + derived().x_value_label_info_.textstyle().font_size()); // best compromise?
+                }
+              }
+              else if ((derived().x_ticks_.label_rotation_ == steepdown) || (derived().x_ticks_.label_rotation_ == steepup))
+              { // downward tick value label direction 60 up or down.
+                y += derived().x_ticks_.label_max_space_;
+                if (derived().x_ticks_.down_ticks_on_ == true)
+                {  // Move down for any downward ticks.
+                  y += 1.1 * (std::max)(derived().x_ticks_.major_tick_length_, derived().x_ticks_.minor_tick_length_); // And avoid macro max trap!
+                  // and a small space.
+                  y += 0.5 * (derived().x_label_info_.textstyle().font_size() + derived().x_value_label_info_.textstyle().font_size()); // best compromise?
+                }
+              }
+              else if ((derived().x_ticks_.label_rotation_ == uphill)  || (derived().x_ticks_.label_rotation_ == downhill))
+              { // sloping 45 degrees up or down.
+                y += derived().x_ticks_.label_max_space_ * sin45; // Move down from end of tick.
+                if (derived().x_ticks_.down_ticks_on_ == true)
+                {  // Move down for any downward ticks.
+                  y += 1.1 * (std::max)(derived().x_ticks_.major_tick_length_, derived().x_ticks_.minor_tick_length_); // And avoid macro max trap!
+                  // and a small space.
+                  y += 0.7 * (derived().x_label_info_.textstyle().font_size() + derived().x_value_label_info_.textstyle().font_size()); // best compromise?
+                }
+              }
+              else if ((derived().x_ticks_.label_rotation_ == slopeup)  || (derived().x_ticks_.label_rotation_ == slopedownhill))
+              { // sloping 30 degrees.
+                y += derived().x_ticks_.label_max_space_ * sin45; // Move down from end of tick.
+                if (derived().x_ticks_.down_ticks_on_ == true)
+                {  // Move down for any downward ticks.
+                  y += 1.1 * (std::max)(derived().x_ticks_.major_tick_length_, derived().x_ticks_.minor_tick_length_); // And avoid macro max trap!
+                  // and a small space.
+                  y += 0.5 * (derived().x_label_info_.textstyle().font_size() + derived().x_value_label_info_.textstyle().font_size()); // best compromise?
+                }
+              }
+              else if (derived().x_ticks_.label_rotation_ == horizontal)
+              { // horizontal X ticks value labels (default).
+                if (derived().x_ticks_.major_value_labels_side_ < 0)
+                { //  Move down to allow space for font size of tick value labels below X-axis.
+                  y += derived().x_value_label_info_.textstyle().font_size();
+                }
+                y += derived().x_label_info_.textstyle().font_size() * 1.3; // Allow for the X-axis label font and space.
+                // See also 1.3 factor drawing ticks.
+              }
+              else
+              {
+                std::cout << " Rotation of X label rotation" << derived().x_ticks_.label_rotation_ << "not yet implemented!" << std::endl;
+              }
+            }
+            if (derived().x_ticks_.down_ticks_on_)
+            { // Shift down for biggest of any ticks, and bit of space.
+              y += 1.1 * (std::max)(derived().x_ticks_.minor_tick_length_, derived().x_ticks_.major_tick_length_);
+            // y += derived().x_ticks_.value_label_style_.font_size() * 1.; // Shift down to suit tick labels.
+            }
+          }
+          else if (derived().x_ticks_.ticks_on_window_or_on_axis_ == 0)
+          { // Ticks are ON the X-axis line, so X label is just below the plot bottom.
+             //y += derived().x_label_info_.textstyle().font_size() * 0.8; // Shift down to suit X labels.
+             // Character starts at bottom of capital letter, so allow for descenders.
+             y = derived().image.y_size() - derived().image_border_width(); // Place X Label just above the image bottom.
+             y -= derived().image_border_.margin_;
+          }
+
+          derived().image.g(PLOT_X_LABEL).push_back(new text_element(
+            ( // x position relative to the x-axis which is middle of plot window.
+            derived().plot_right_ + derived().plot_left_) / 2,  // x coordinate - middle.
+            y, // Down from plot window.
+            x_label,
+            derived().x_label_info_.textstyle(),
+            center_align, horizontal)
+            );
+        } // void draw_x_label()
+
+          void adjust_limits(double& x, double& y)
+          { //! If value of a data point reaches limit of max, min, infinity,
+            //! use the appropriate plot min or max value instead.
+            if(detail::limit_max(x))
+            {
+              x = derived().plot_right_;
+            }
+            if(detail::limit_max(y))
+            {
+              y = derived().plot_top_;
+            }
+            if(detail::limit_min(x))
+            {
+              x = derived().plot_left_;
+            }
+            if(detail::limit_min(y))
+            {
+              y = derived().plot_top_;
+            }
+            // If value is NaN, use zero instead.
+            // TODO Do we want/get a different color or shape for NaNs?
+            if(detail::limit_NaN(x))
+            {
+              x = 0.;
+              transform_x(x);
+            }
+            if(detail::limit_NaN(y))
+            {
+              y = 0.;
+              transform_y(y);
+            }
+          } // void adjust_limits
+
+
         void draw_title()
         { /*! Draw title (for the whole plot).
             Update title_info_ with position.
@@ -848,114 +1043,6 @@
             } // for
           } // void draw_legend()
 
-          void draw_x_label()
-          { //! Draw the X-axis label text (for example, length),
-            //! and append any optional units (for example, km).
-            // X-label color default is set in constructor thus:
-            // image.g(detail::PLOT_X_LABEL).style().stroke_color(black);
-            // and changed using x_label_color(color);
-            // Similarly for font family and size.
-
-            std::string x_label = derived().x_label_info_.text(); // x_axis_ label, and optional units.
-            if (derived().x_axis_.label_units_on_ && (derived().x_units_info_.text() != ""))
-            { // Append the units, if any, user providing brackets () if required. 
-              x_label += derived().x_units_info_.text(); // for example: "time (sec)".
-            }
-
-            double y = derived().plot_bottom_;
-            // Glyphs for western characters are aligned with the left bottom of capital letter,
-            // so need to allow for any descenders.
-
-            // cout << "derived().x_ticks_.ticks_on_window_or_on_axis_ " << derived().x_ticks_.ticks_on_window_or_on_axis_ << endl;
-            // using derived(0 means debugging doesn't work!  So resort to old-fashioned print statements.
-            if (derived().x_ticks_.ticks_on_window_or_on_axis_ < 0) // -1 means bottom
-            { // Ticks value labels below plot window.
-              if (derived().x_ticks_.major_value_labels_side_ < 0) // bottom
-              { // Shift down to allow for any tick value labels.
-                if ((derived().x_ticks_.label_rotation_ == downward) || (derived().x_ticks_.label_rotation_ == upward)
-                    || (derived().x_ticks_.label_rotation_ == steepdown) || (derived().x_ticks_.label_rotation_ == steepup))
-                { // downward tick value label direction 90 up or down, or 60 steep degrees (might handle 60 separately).
-                  y += derived().x_ticks_.label_max_space_;
-                }
-                else if ((derived().x_ticks_.label_rotation_ == uphill)  || (derived().x_ticks_.label_rotation_ == downhill) 
-                         || (derived().x_ticks_.label_rotation_ == slopeup)  || (derived().x_ticks_.label_rotation_ == slopedownhill))
-                { // sloping 45 or 30 degrees (might handle 30 separately).
-                  y += derived().x_ticks_.label_max_space_ * sin45;
-                }
-                else if (derived().x_ticks_.label_rotation_ == horizontal)
-                { // horizontal
-                  if (derived().x_ticks_.major_value_labels_side_ < 0)
-                  { // Allow space for tick value labels below X-axis font size.
-                    y += derived().x_value_label_info_.textstyle().font_size();
-                  }
-                  if (derived().x_ticks_.down_ticks_on_ == true)
-                  {  // Allow for the downward ticks.
-                    y += (std::max)(derived().x_ticks_.major_tick_length_, derived().x_ticks_.minor_tick_length_);// And avoid macro max trap!
-                  }
-                  y += derived().x_label_info_.textstyle().font_size() * 0.8; // Allow for the X-axis label font.
-                }
-                else
-                {
-                  std::cout << " Rotation of X label rotation" << derived().x_ticks_.label_rotation_ << "not yet implemented!" << std::endl;
-                }
-              }
-              if (derived().x_ticks_.down_ticks_on_)
-              { // Shift down for biggest of any ticks.
-                y += (std::max)(derived().x_ticks_.minor_tick_length_, derived().x_ticks_.major_tick_length_);
-              // y += derived().x_ticks_.value_label_style_.font_size() * 1.; // Shift down to suit tick labels.
-              }
-            }
-            if (derived().x_ticks_.ticks_on_window_or_on_axis_ == 0)
-            { // ticks ON the X-axis line, so X label is just below the plot bottom.
-               //y += derived().x_label_info_.textstyle().font_size() * 0.8; // Shift down to suit X labels.
-               // Character starts at bottom of capital letter, so allow for descenders.
-               y = derived().image.y_size() - derived().image_border_width(); // Place X Label just above the image bottom.
-               y -= derived().image_border_.margin_;
-            }
-
-            derived().image.g(PLOT_X_LABEL).push_back(new text_element(
-              ( // x position relative to the x-axis which is middle of plot window.
-              derived().plot_right_ + derived().plot_left_) / 2,  // x coordinate - middle.
-              y, // Down from plot window.
-              x_label,
-              derived().x_label_info_.textstyle(),
-              center_align, horizontal)
-              );
-          } // void draw_x_label()
-
-          void adjust_limits(double& x, double& y)
-          { //! If value of a data point reaches limit of max, min, infinity,
-            //! use the appropriate plot min or max value instead.
-            if(detail::limit_max(x))
-            {
-              x = derived().plot_right_;
-            }
-            if(detail::limit_max(y))
-            {
-              y = derived().plot_top_;
-            }
-            if(detail::limit_min(x))
-            {
-              x = derived().plot_left_;
-            }
-            if(detail::limit_min(y))
-            {
-              y = derived().plot_top_;
-            }
-            // If value is NaN, use zero instead.
-            // TODO Do we want/get a different color or shape for NaNs?
-            if(detail::limit_NaN(x))
-            {
-              x = 0.;
-              transform_x(x);
-            }
-            if(detail::limit_NaN(y))
-            {
-              y = 0.;
-              transform_y(y);
-            }
-          } // void adjust_limits
-
           void draw_plot_point(double x, double y, // SVG coordinates.
           //void draw_plot_point(unc x, unc y, // SVG coordinates.
             g_element& g_ptr,
@@ -2691,6 +2778,8 @@
           Derived& axis_plot_frame<Derived>::x_label_font_size(unsigned int i)
           { //! Set X axis label font size (svg units, default pixels).
             derived().x_label_info_.textstyle().font_size(i);
+            // Also duplicated at 
+            // derived().x_axis_label_style_.font_size(i);
             return derived();
           }
 
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	2009-07-28 07:45:58 EDT (Tue, 28 Jul 2009)
@@ -881,7 +881,7 @@
       \brief Holds text with position, size, font, (& styles) & orientation.
       \details
       \verbatim
-      Not necessarily shown correctly by all browsers, alas.
+      Not necessarily shown correctly (or nicely) by all browsers, alas.
       SVG Coordinates of 1st character EM box, see
       http://www.w3.org/TR/SVG/text.html#TextElement 10.2
       So any text with y coordinate = 0 shows only any roman lower case descenders!\n\n
@@ -903,7 +903,7 @@
       \endverbatim
 
   */
- private: // Access only via member functions below.
+ private: // Access only via member functions below:
   double x_; //!< Left edge.
   double y_; //!< Bottom of roman capital character.
   ptr_vector<text_parent> data_; //!< Stores all of the containing data.
@@ -921,23 +921,23 @@
     }
   }
 public:
-  // Set
-  //void alignment(align_style a);
-  //void rotation(rotate_style rot);
-  //void x(double x);
-  //void y(double y);
-  //void text(const std::string& t);
-  //tspan_element& tspan(const std::string& t);
-  //text_element(double x, double y, const std::string text,text_style ts,align_style align, rotate_style rotate);
-  //text_element(const text_element& rhs);
-
-  // Get
-  //text_style& style();
-  //const text_style& style() const;
-  //align_style alignment();
-  //rotate_style rotation() const;
-  //double x() const;
-  //double y() const;
+  // Set member functions.
+  // void alignment(align_style a);
+  // void rotation(rotate_style rot);
+  // void x(double x);
+  // void y(double y);
+  // void text(const std::string& t);
+  // tspan_element& tspan(const std::string& t);
+  // text_element(double x, double y, const std::string text,text_style ts,align_style align, rotate_style rotate);
+  // text_element(const text_element& rhs);
+
+  // Get member functions.
+  // text_style& style();
+  // const text_style& style() const;
+  // align_style alignment();
+  // rotate_style rotation() const;
+  // double x() const;
+  // double y() const;
 
   text_style& textstyle()
   { //! Get text style for font size, family, decoration ...
@@ -1023,9 +1023,10 @@
   text_element(
     //! Coordinates of 1st character EM box, see
     //! http://www.w3.org/TR/SVG/text.html#TextElement 10.2
-    double x = 0., // Left edge.
-    double y = 0., // Bottom of character (roman capital).
-    // So any text with y coordinate = 0  shows only the roman lower case descenders!
+    double x = 0., //! X = Left edge.
+    double y = 0., //! Y =  Bottom left of (western) character (roman capital).
+    //! So any text with Y coordinate = 0 shows only the roman lower case descenders!
+    //! One must increase Y to allow for the height (font size) of the character.
     const std::string text = "",
     text_style ts = no_style, // Left to SVG defaults.
     align_style align = left_align,
@@ -1033,8 +1034,9 @@
     : // Constructor.
     x_(x), y_(y), // location.
     data_(ptr_vector<text_parent>()),
+    style_(ts), // Simpler to include all these as members?
+    // These is a muddle requiring copying members at present.
     //size(size), font(font), style_(style), weight(weight), stretch(stretch), decoration(decoration),
-    style_(ts),
     align_(align),
     rotate_(rotate)
   { //! text_element Default Constructor, defines defaults for all private members.
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	2009-07-28 07:45:58 EDT (Tue, 28 Jul 2009)
@@ -366,11 +366,11 @@
       text_style y_axis_label_style_; //!< Style for tick labels on Y axis.
       text_style y_value_label_style_;//!< Style for data point value labels on Y axis.
       text_style point_symbols_style_; //!< Style used for symbol marking a data point.
+
       text_element title_info_; //!< Plot title text.
       text_element legend_header_; //!< Legend box header or title (if any).
       text_element x_label_info_; //!< X axis label text, for example: "length".
       text_element x_value_label_info_; //!< X axis tick value text, for example: "1.2" or "1.2e+001"
-
       text_element y_label_info_; //!< Y axis label text, for example: "volume".
       text_element x_units_info_; //!< X axis units, for example: "mm".
       text_element y_units_info_; //!<  Y axis units, for example: "min". (2-D only).
@@ -493,7 +493,7 @@
         legend_style_(14, "Verdana", "", ""), // 2nd "italic"?
         x_axis_label_style_(14, "Verdana", "", ""),
         x_value_label_style_(12, "Verdana", "", ""), // X-axis tick labels.
-        // Separate x and y to allow axes to have different styles.
+        // Separate X and Y to allow axes to have different styles.
         y_axis_label_style_(14, "Verdana", "", ""),
         y_value_label_style_(12, "Verdana", "", ""), // Y-axis tick labels.
         point_symbols_style_(12, "Lucida Sans Unicode"), // Used for data point marking.
@@ -512,7 +512,13 @@
         y_value_label_info_(0, 0, "", y_value_label_style_, center_align, upward), //
         text_margin_(2.), // for axis label text, as a multiplier of the font size.
         // Should allow a 'half line space' above and below the label text.
-        image_border_(yellow, white, 2, 10, true, true), // margin should be about axis label font size.
+        image_border_(yellow, white, 2, 3, true, true),
+        // margin (parameter 4) needs to be at least the width of the border (parameter 3) to ensure any border color shows.
+        // margin should be about axis tick label font size to
+        // allow for axis value labels that mark the min and max
+        // that must extend about half a font width beyond the plot window border.
+        // This is set dynamically in calculate_plot_window because user can change tick value label font size.
+
         plot_window_border_(lightslategray, svg_color(255, 255, 255), 2, 3, true, false),
         legend_box_(yellow, white, 1, 2, true, true),
         legend_header_(0, 0, "", legend_style_, center_align, horizontal),
@@ -681,26 +687,58 @@
           plot_top_ += title_font_size() * (text_margin_ + 0.5);
         }
 
+        // Deal with muddle where text_style is stored in two places
+        // by copying to ensure they are the same.
+        // TODO Sort this out properly by a major class reorganisation!
+        x_axis_label_style_ = x_label_info_.textstyle();
+        if (x_label_info_.textstyle() != x_axis_label_style_ )
+        {
+          cout << "x_label_info_.textstyle() != x_axis_label_style_" << endl;
+        }
+
+        y_axis_label_style_ = y_label_info_.textstyle();
+        if (y_label_info_.textstyle() != y_axis_label_style_ )
+        {
+          cout << "y_label_info_.textstyle() != y_axis_label_style_!" << endl;
+        }
+
         // Assume that X-axis labels are always at bottom.
         if(x_axis_.label_on_ == true == true && x_label_info_.text() != "")
         { // Leave space at bottom for X-axis label.
+          if (x_label_info_.textstyle().font_size() != x_axis_label_style_.font_size())
+          { // Temporary check.
+            cout << "x_label_info_.textstyle().font_size() "<< x_label_info_.textstyle().font_size() << endl;
+            cout << "x_axis_label_style_.font_size() " << x_axis_label_style_.font_size() << endl;
+          }
+
           plot_bottom_ -= x_axis_label_style_.font_size() * text_margin_;
+          // plot_bottom_ -= x_label_info_.textstyle().font_size() * text_margin_; // OK
         }
-        // Assume that Y- axis labels are always at left.
+        // Assume that Y-axis labels are always at left.
         if(y_axis_.label_on_ == true == true && y_label_info_.text() != "")
         { // Leave space at left for Y-axis label.
+          if (y_label_info_.textstyle().font_size() != y_axis_label_style_.font_size())
+          { // Temporary check.
+            cout << "y_label_info_.textstyle().font_size() "<< y_label_info_.textstyle().font_size() << endl;
+            cout << "y_axis_label_style_.font_size() " << y_axis_label_style_.font_size() << endl;
+          }
           plot_left_ += y_axis_label_style_.font_size() * text_margin_;
         }
 
         if(plot_window_on_)
-        { // Needed to allow any plot window border rectangle to show OK.
-          // A small margin is to prevent it overlapping the image border.
-          // Also allows for axis value labels that mark the min and max
-          // that must extend half a font width beyond the plot window border.
-          plot_left_ +=  image_border_.margin_;
-          plot_right_ -=  image_border_.margin_;
-          plot_top_ += image_border_.margin_;
-          plot_bottom_ -=  image_border_.margin_;
+        { 
+       // A margin is needed to allow any plot window border rectangle to show OK. 
+        // A small margin is to prevent it overlapping the image border.
+        // Also allows for axis value labels that mark the min and max
+        // that must extend half a font width beyond the plot window border.
+
+          double margin = (std::max)(image_border_.margin_, static_cast<double>(x_value_label_style_.font_size()/2) );
+          plot_left_ += margin;
+          plot_right_ -= margin;
+
+          margin = (std::max)(image_border_.margin_, static_cast<double>(y_value_label_style_.font_size()/2) );
+          plot_top_ += margin;
+          plot_bottom_ -= margin;
         }
         size_legend_box(); // Size depends on its contents.
         place_legend_box(); // according to options chosen.
@@ -772,8 +810,8 @@
         x_ticks_.longest_label(); // Updates label_max_length_
         y_ticks_.longest_label();
 
-        // Check that labels won't collide and advise if they will?
-        // Change rotation to avoid collision?
+        // Check that labels won't collide and advise if they will - seems very difficult.
+        // Change rotation to avoid collision - not practical.
 
         y_ticks_.label_max_space_ = 0.; // Work out space for y labels, depending on orientation.
         if (y_ticks_.label_rotation_ == horizontal)
@@ -781,8 +819,8 @@
            y_ticks_.label_max_space_ += y_ticks_.label_max_length_; // SVG units (default pixels).
         }
         else if((y_ticks_.label_rotation_ == upward) || (y_ticks_.label_rotation_ == downward))
-        { // Only need one char & 1 space width from Y-axis label.
-          y_ticks_.label_max_space_ += 2 * y_value_label_style_.font_size() * wh;
+        { // Only need one char & 1 space width from Y-axis value label.
+          y_ticks_.label_max_space_ += 2 * y_value_label_style_.font_size();
         }
         else
         { // Assume some slope 45, so diagonally down from tick,
@@ -814,10 +852,10 @@
           }
         } // y_ticks_. major_value_labels_side
 
-        x_ticks_.label_max_space_ = 0; // Work out the longest ticks values label for X-Axis.
+        x_ticks_.label_max_space_ = 0.; // Work out the longest ticks values label for X-Axis.
         if (x_ticks_.label_rotation_ == horizontal)
-        { // Only 1 char height & 1 space needed if labels are horizontal.
-          x_ticks_.label_max_space_ += 2. * x_value_label_style_.font_size(); // 2 SVG chars
+        { // Only 1 char height & small space needed if labels are horizontal.
+          x_ticks_.label_max_space_ += 1.5 * x_value_label_style_.font_size(); // 2 SVG chars
         }
         else if ((x_ticks_.label_rotation_ == upward) || (x_ticks_.label_rotation_ == downward))
         { // ! X_axis ticks labels vertical so will need enough for all the characters in the label.
@@ -830,9 +868,9 @@
 
         if (x_ticks_.major_value_labels_side_ != 0)
         { // Some tick value labels.
-          if ((x_ticks_.ticks_on_window_or_on_axis_ < 0) // on bottom of plot window.
-             && (x_ticks_.major_value_labels_side_ < 0) ) // & labels on bottom.
-          {  // Contract plot window bottom edge up to make space for x value labels on bottom.
+          if ((x_ticks_.ticks_on_window_or_on_axis_ < 0) // ticks on bottom of plot window.
+             && (x_ticks_.major_value_labels_side_ < 0) ) // & labels on bottom too.
+          {  // Contract plot window bottom edge up to make space for X value labels on bottom.
             plot_bottom_ -= x_ticks_.label_max_space_; // Move up.
           }
           else if ((x_ticks_.ticks_on_window_or_on_axis_ > 0) //
@@ -864,7 +902,7 @@
           if ((x_axis_position_ == bottom) // All Y values definitely > zero.
             && !(x_ticks_.ticks_on_window_or_on_axis_ < 0) ) // & not already at bottom.
           { // y_min_ > 0 so X-axis will not intersect Y-axis, so use plot window.
-            plot_bottom_ -= x_ticks_.label_max_space_; // Move up for the value labels.
+            plot_bottom_ -= x_ticks_.label_max_space_; // Move up for the ticks value labels.
             x_axis_.axis_ = plot_bottom_; // Put X-axis on bottom.
           }
           else if ((x_axis_position_ == top)  // All Y values definitely < zero.
@@ -1089,35 +1127,65 @@
           if (y_ticks_.major_value_labels_side_ < 0) // -1 means left
           { // tick values labels are to left of Y axis.
             // Shift right to allow for any tick value labels.
-            if ((y_ticks_.label_rotation_ == downward) || (y_ticks_.label_rotation_ == upward)
-                || (y_ticks_.label_rotation_ == steepdown) || (y_ticks_.label_rotation_ == steepup))
-            { // downward tick value label direction 90 up or down, or 60 steep degrees (might handle 60 separately).
-              if (y_ticks_.major_value_labels_side_ < 0) // left of plot window
+            if ((y_ticks_.label_rotation_ == downward) || (y_ticks_.label_rotation_ == upward))
+            { // downward tick value label direction 90 vertical up or down, or 60 steep degrees (might handle 60 separately).
+              if (y_ticks_.major_value_labels_side_ < 0) // tick value labels are to left of plot window.
+              { // Allow space for tick value labels font size to left of Y-axis or plot window.
+                x -= y_value_label_info_.textstyle().font_size() * 1.3; // 
+              }
+              if (y_ticks_.left_ticks_on_ == true)
+              {  // Allow for any leftward ticks.
+                x -= 1.1 * (std::max)(y_ticks_.major_tick_length_, y_ticks_.minor_tick_length_);// And avoid macro max trap!
+              }
+              x -= 0.7 * (y_label_info_.textstyle().font_size() + y_value_label_info_.textstyle().font_size()); // best compromise?
+
+            }
+            else if ((y_ticks_.label_rotation_ == steepdown) || (y_ticks_.label_rotation_ == steepup))
+            { // downward tick value label direction 90 vertical up or down, or 60 steep degrees (might handle 60 separately).
+              if (y_ticks_.major_value_labels_side_ < 0) // tick value labels are to left of plot window.
               { // Allow space for tick value labels font size to left of Y-axis or plot window.
-                x += y_value_label_info_.textstyle().font_size() * 1.1;
+                x -= y_value_label_info_.textstyle().font_size() * 1.3; // 
               }
               if (y_ticks_.left_ticks_on_ == true)
               {  // Allow for any leftward ticks.
-                x += (std::max)(y_ticks_.major_tick_length_, y_ticks_.minor_tick_length_);// And avoid macro max trap!
+                x -= 1.1 * (std::max)(y_ticks_.major_tick_length_, y_ticks_.minor_tick_length_);// And avoid macro max trap!
               }
+              x -= 0.4 * (y_label_info_.textstyle().font_size() + y_value_label_info_.textstyle().font_size()); // best compromise?
             }
-            else if ((y_ticks_.label_rotation_ == uphill)  || (y_ticks_.label_rotation_ == downhill) 
-                     || (y_ticks_.label_rotation_ == slopeup)  || (y_ticks_.label_rotation_ == slopedownhill))
-            { // sloping 45 or 30 degrees (might handle 30 separately).
-               // x -= y_ticks_.label_may_space_ * sin45;
-               // x -= y_ticks_.label_max_space_;
+            else if ((y_ticks_.label_rotation_ == uphill)  || (y_ticks_.label_rotation_ == downhill))
+            { // sloping 45 degrees .
+               x -= y_ticks_.label_max_space_ * sin45;
+              if (y_ticks_.left_ticks_on_ == true)
+              {  // Move left for any leftward ticks, and a small space.
+                x -= 1.1 * (std::max)(y_ticks_.major_tick_length_, y_ticks_.minor_tick_length_); // And avoid macro max trap!
+                //x -= 1.2 * y_label_info_.textstyle().font_size() ; // Shift left to suit Y labels.
+                //x -= 1.2 * y_value_label_info_.textstyle().font_size() ; // Shift left to suit Y labels.
+                //x -= 1.2 * (std::min)(y_label_info_.textstyle().font_size(), y_value_label_info_.textstyle().font_size() ); // better
+                x -= 0.7 * (y_label_info_.textstyle().font_size() + y_value_label_info_.textstyle().font_size()); // best compromise?
+             }
+            }
+            else if ((y_ticks_.label_rotation_ == slopeup) || (y_ticks_.label_rotation_ == slopedownhill))
+            { // sloping 30 degrees.
+               x -= y_ticks_.label_max_space_ * sin45;
+              if (y_ticks_.left_ticks_on_ == true)
+              {  // Move left for any leftward ticks, and a small space.
+                x -= 1.1 * (std::max)(y_ticks_.major_tick_length_, y_ticks_.minor_tick_length_); // And avoid macro max trap!
+                //x -= 1.2 * y_label_info_.textstyle().font_size() ; // Shift left to suit Y labels.
+                //x -= 1.2 * y_value_label_info_.textstyle().font_size() ; // Shift left to suit Y labels.
+                //x -= 1.2 * (std::min)(y_label_info_.textstyle().font_size(), y_value_label_info_.textstyle().font_size() ); // better
+                x -= 0.7 * (y_label_info_.textstyle().font_size() + y_value_label_info_.textstyle().font_size()); // best compromise?
+             }
             }
             else if  (y_ticks_.label_rotation_ == horizontal)
             { // horizontal
-               // x -= y_value_label_info_.textstyle().font_size() * y_ticks_.label_max_space_; // Might be zero?
-               x -= y_ticks_.label_max_space_; // Might be zero?
               if (y_ticks_.left_ticks_on_ == true)
-              {  // Allow for any leftward ticks.
-                x -= (std::max)(y_ticks_.major_tick_length_, y_ticks_.minor_tick_length_);// And avoid macro max trap!
+              {  // Move left for any leftward ticks, and a small space.
+                x -= 1.1 * (std::max)(y_ticks_.major_tick_length_, y_ticks_.minor_tick_length_); // And avoid macro max trap!
               }
-              x -= y_label_info_.textstyle().font_size() * 1.2; // Shift left to suit Y labels possible descenders.
-
-            }
+              x -= y_ticks_.label_max_space_; // Move left for the longest tick value label. (Might be zero?)
+              //x -= y_label_info_.textstyle().font_size() * 1.0; // Shift left to suit Y labels.
+              x -= 0.6 * (y_label_info_.textstyle().font_size() + y_value_label_info_.textstyle().font_size()); // best compromise?
+           }
             else
             {
               cout << " Rotation of Y label rotation" << y_ticks_.label_rotation_ << "not yet implemented" << endl;
@@ -1286,6 +1354,22 @@
               alignment = left_align;
             }
           }
+          else if (y_ticks_.label_rotation_ == slopeup)
+          { // Assume some 30 slope, so need about sqrt(2) less space.
+            if (y_ticks_.major_value_labels_side_ < 0)
+            { // labels to left, so start a little to left of x_left.
+              y -= y_value_label_style_.font_size() * 0.2;
+              x = x_left - y_value_label_style_.font_size() * 0.2;
+              // Seems to need a bit more space for right than left if rotated.
+              alignment = right_align;
+            }
+            else if(y_ticks_.major_value_labels_side_ > 0)
+            { // labels to right, so start a little to right of x_right.
+              y += y_value_label_style_.font_size() * 0.2;
+              x = x_right + y_value_label_style_.font_size() * 0.7;
+              alignment = left_align;
+            }
+          }
           else if (y_ticks_.label_rotation_ == downhill)
           { // Assume some 45 slope, so need about sqrt(2) less space.
             if (y_ticks_.major_value_labels_side_ < 0)
@@ -1302,6 +1386,39 @@
               alignment = left_align;
             }
           }
+          else if (y_ticks_.label_rotation_ == slopedownhill)
+          { // Assume some 30 slope, so need about sqrt(2) less space.
+            if (y_ticks_.major_value_labels_side_ < 0)
+            { // labels to left, so start a little to left of x_left.
+              y += y_value_label_style_.font_size() * 0.3;
+              x = x_left - y_value_label_style_.font_size() * 0.7;
+              // Seems to need a bit more space for right than left if rotated.
+              alignment = right_align;
+            }
+            else if(y_ticks_.major_value_labels_side_ > 0)
+            { // labels to right, so start a little to right of x_right.
+              y -= y_value_label_style_.font_size() * 0.3;
+              x = x_right + y_value_label_style_.font_size() * 0.1;
+              alignment = left_align;
+            }
+          }
+          else if (y_ticks_.label_rotation_ == steepdown)
+          { // Assume some 45 slope, so need about sqrt(2) less space.
+            if (y_ticks_.major_value_labels_side_ < 0)
+            { // labels to left, so start a little to left of x_left.
+              y += y_value_label_style_.font_size() * 0.3;
+              x = x_left - y_value_label_style_.font_size() * 0.5;
+              // Seems to need a bit more space for right than left if rotated.
+              alignment = right_align;
+            }
+            else if(y_ticks_.major_value_labels_side_ > 0)
+            { // labels to right, so start a little to right of x_right.
+              y -= y_value_label_style_.font_size() * 0.3;
+              x = x_right + y_value_label_style_.font_size() * 0.1;
+              alignment = left_align;
+            }
+          }
+
           else if (y_ticks_.label_rotation_ == upward)
           { // Tick value label straight up vertically on Y-axis.
             y -= y_value_label_style_.font_size() * 0.1;
@@ -1317,6 +1434,21 @@
               alignment = center_align;
             }
           }
+          else if (y_ticks_.label_rotation_ == steepup)
+          { // Tick value label straight up vertically on Y-axis.
+            y -= y_value_label_style_.font_size() * 0.1;
+            if (y_ticks_.major_value_labels_side_ < 0)
+            { // labels to left, so start a little to left of x_left.
+              x = x_left - y_value_label_style_.font_size() * 0.5;
+              // Seems to need a bit more space for right than left if rotated.
+              alignment = center_align;
+            }
+            else if(y_ticks_.major_value_labels_side_ > 0)
+            { // labels to right, so start a little to right of x_right.
+              x = x_right + y_value_label_style_.font_size() * 1.5;
+              alignment = center_align;
+            }
+          }
           else if (y_ticks_.label_rotation_ == downward)
           { // Tick value label straight down vertically on Y-axis.
             y -= y_value_label_style_.font_size() * 0.1;
@@ -2168,7 +2300,7 @@
       svg_2d_plot& svg_2d_plot::y_major_label_rotation(rotate_style rot)
       { /*! Rotation of labels for major ticks on vertical Y axis line.
         \arg \c rot Default is horizontal.
-        \see rotate_style for possible values.
+        \see rotate_style for possible values: horizontal, uphill...
         */
         y_ticks_.label_rotation_ = rot;
         return *this; //! \return reference to svg_2d_plot to make chainable.
@@ -2771,37 +2903,43 @@
       svg_2d_plot& svg_2d_plot::y_label_font_size(unsigned int i)
       { //! Set Y axis label text font size.
         // May be best to tie label & unit font sizes together?
-        y_axis_label_style_.font_size(i);
-        // y_units_info_.font_size(i);
+        // y_axis_label_style_.font_size(i);
+        y_units_info_.textstyle().font_size(i);
+        y_label_info_.textstyle().font_size(i);
         return *this;
       }
 
       unsigned int svg_2d_plot::y_label_font_size()
       { //! \return Y axis label text font size.
-        return y_axis_label_style_.font_size();
+        // return y_axis_label_style_.font_size();
+        return y_label_info_.textstyle().font_size();
       }
 
       svg_2d_plot& svg_2d_plot::y_label_weight(std::string s)
       { //! Set Y axis label text font weight (for example: "bold").
         //! ("bold" is only one that works so far, and quality may be poor for some browsers).
-        y_axis_label_style_.font_weight(s);
+        //y_axis_label_style_.font_weight(s);
+        y_label_info_.textstyle().font_weight(s);
         return *this; //! \return reference to svg_2d_plot to make chainable.
       }
 
       const std::string& svg_2d_plot::y_label_weight()
       { //! \return Y axis label text font weight (for example: "bold").
-        return y_axis_label_style_.font_weight();
+        // return y_axis_label_style_.font_weight();
+        return y_label_info_.textstyle().font_weight();
       }
 
       svg_2d_plot& svg_2d_plot::y_label_font_family(const std::string& family)
       { //! Set Y axis label text font family (for example: "Lucida console sans").
         y_axis_label_style_.font_family(family);
+        y_label_info_.textstyle().font_family(family);
         return *this; //! \return reference to svg_2d_plot to make chainable.
       }
 
       const std::string& svg_2d_plot::y_label_font_family()
       { //! \return the font family for label on Y axis.
-        return y_axis_label_style_.font_family();
+        // return y_axis_label_style_.font_family();
+        return y_label_info_.textstyle().font_family();
       }
 
       // Y-axis tick value labels style.
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	2009-07-28 07:45:58 EDT (Tue, 28 Jul 2009)
@@ -79,7 +79,7 @@
 
 /*!
  This is the style information for any group (g) tag.
- This may be expanded to include more data from the SVG standard.
+ This could be expanded to include more data from the SVG standard.
 
  There are some strange effects for text on some browsers
  (Firefox especially) when only stroke is specified.
@@ -298,7 +298,7 @@
 
 class text_style
 { /*! \class boost::svg::text_style
-     \brief font family, size, weight, style, stretch, decoration.
+     \brief font family, font size, weight, style, stretch & decoration.
   */
   friend std::ostream& operator<< (std::ostream&, const text_style&);
   friend bool operator== (const text_style&, const text_style&);
@@ -914,18 +914,18 @@
 
 enum dim
 { //! \enum dim dimension of plot. (Used so that an axis knows what type it is, or none = N).
-  N = 0, X = 1, Y = 2, Z = 3
+  N = 0, X = 1, Y = 2
 };
 
 class axis_line_style
 { /*! \class boost::svg::axis_line_style
-    \brief Style of the X and/or Y axes lines.
-    \details (But NOT the ticks and value labels because different styles for X and Y are possible).
+    \brief Style of the X or Y-axes lines.
+    \details (But NOT the ticks and value labels because different styles for X and Y-axes are possible).
   */
 public:
-  dim dim_; //!< X, Y or none.
-  double min_; //!< minimum x value (Cartesian units).
-  double max_; //!< maximum x value (Cartesian units).
+  dim dim_; //!< None, X or Y.
+  double min_; //!< minimum X value (Cartesian units).
+  double max_; //!< maximum Y value (Cartesian units).
   // Note that these duplicate the same named in ticks_labels_style,
   // but they might have different uses, so are left pro tem.
   // TODO reconsider the implications of this (largely accidental) decision.