$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: pbristow_at_[hidden]
Date: 2008-01-23 16:44:52
Author: pbristow
Date: 2008-01-23 16:44:51 EST (Wed, 23 Jan 2008)
New Revision: 42932
URL: http://svn.boost.org/trac/boost/changeset/42932
Log:
Improvements for legend box to use box style (but created problem with boxplot to be solved).
TODO labels on right/top of axes.
Text files modified: 
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp |    86 ++++++++++++++++++++----------------    
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_2d_plot.hpp            |     4 +                                       
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_style.hpp              |    93 +++++++++++++++++++++++++++++++++++---- 
   3 files changed, 133 insertions(+), 50 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	2008-01-23 16:44:51 EST (Wed, 23 Jan 2008)
@@ -474,13 +474,13 @@
         { // Calculate how big the legend box needs to be.
           // Store in legend_width_ and legend_height_
           if(derived().legend_on_ == false)
-          { // No legend, so set values to show legend position invalid.
-            derived().legend_left_ = -1;
-            derived().legend_right_ = -1;
-            derived().legend_top_ = -1;
-            derived().legend_bottom_ = -1;
-            derived().legend_height_ = 0;
-            derived().legend_width_ = 0;
+          { // No legend, so set values to show legend positions invalid.
+            derived().legend_left_ = -1.;
+            derived().legend_right_ = -1.;
+            derived().legend_top_ = -1.;
+            derived().legend_bottom_ = -1.;
+            derived().legend_height_ = 0.;
+            derived().legend_width_ = 0.;
             return;
           }
           else
@@ -495,13 +495,12 @@
             // std::cout << spacing <<  ' ' << font_size << ' ' << point_size << std::endl;
             bool is_header = (derived().legend_header_.text() != "");
 
-            double longest = string_svg_length(derived().legend_header_.text(), derived().legend_style_);
-            std::cout << "\nLegend header " << longest << " svg units." << std::endl;
-
             //text_element legend_header_; // legend box header or title (if any).
             //text_style legend_style_;
-            // was size_t longest = derived().legend_header_.text().size();
-            // 0 if no header.
+            double longest = string_svg_length(derived().legend_header_.text(), derived().legend_style_);
+            //std::cout << "\nLegend header " << longest << " svg units." << std::endl;
+            derived().legend_width_ = 2 * (derived().legend_box_.margin() * derived().legend_box_.width());
+            // Don't plan to write on the border, or within the 'forbidden' margin of the box.
             for(size_t i = 0; i < num_series; ++i)
             { // Find the longest text (if longer than header) in all the data series.
               std::string s = derived().series[i].title_;
@@ -512,23 +511,23 @@
               }
             } // for
             // std::cout.flags(std::ios_base::dec); should not be needed  TODO
-            std::cout << "\nLongest legend header or data descriptor " << longest << " svg units." << std::endl;
-            derived().legend_width_ = (1 + longest);
+            // std::cout << "\nLongest legend header or data descriptor " << longest << " svg units." << std::endl;
+            derived().legend_width_ += longest; // Space for longest text.
                                     
             // Allow for a leading space, longest text
             // & trailing space before box margin.
             if (derived().legend_lines_)
-            { // colored line marker in legend.
-              derived().legend_width_ += spacing * 2.;
+            { // Add for colored line marker in legend.
+              derived().legend_width_ += spacing * 1.5;
             }
             if(derived().series[0].point_style_.shape() != none)
-            { // colored data point marker, cross, round... & space
-              derived().legend_width_ += 2 * derived().series[0].point_style_.size();
+            { // Add for colored data point marker, cross, round... & space.
+              derived().legend_width_ += 1.5 * derived().series[0].point_style_.size();
             }
             // else no point marker.
 
             // legend_height must be *at least* enough for
-            // any legend header and text_margin_s around it
+            // any legend header 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.
             derived().legend_height_ = spacing; // At top
@@ -544,14 +543,14 @@
 
         void place_legend_box()
         {
-          if(derived().legend_on_) // Legend box required.
+          if(derived().legend_on_ == true) // Legend box required.
           {
             derived().outside_legend_on_ = true; // Unless proves to be inside.
-            //double spacing = derived().y_label_font_size() * 1.; // Around any legend box - beyond any border.
+            //double spacing = derived().legend_box_.margin(); // Might be better to use this, but needs redoing.
             double spacing = derived().y_axis_label_style_.font_size() * 1.; // Around any legend box - beyond any border.
             switch (derived().legend_place_)
             {
-            case nowhere:
+            case nowhere: 
               return;
             case inside:
               derived().outside_legend_on_ = false;
@@ -641,6 +640,13 @@
                   << " outside " << derived().image.y_size() << std::endl;
               }
 
+               derived().image.g(detail::PLOT_LEGEND_BACKGROUND)
+              .style().fill_color(derived().legend_box_.fill()) // 
+              .stroke_color(derived().legend_box_.stroke())
+              .stroke_width(derived().legend_box_.width())
+              .stroke_on(derived().legend_box_.border_on())
+              ;
+
               // Draw border box round legend.
               g_element* g_ptr = &(derived().image.g(PLOT_LEGEND_BACKGROUND));
               g_ptr->push_back(new
@@ -651,6 +657,8 @@
           void draw_legend()
           {
             // size_t num_points = derived().series.size();
+            //cout << derived().legend_box_.width() <<  ' ' << derived().legend_box_.margin() << endl;
+
             int font_size = derived().legend_header_.style().font_size();
             int point_size =  derived().series[0].point_style_.size();
             // Use whichever is the biggest of point marker and font.
@@ -667,6 +675,7 @@
 
             // Draw border box round legend.
             g_element* g_ptr = &(derived().image.g(PLOT_LEGEND_BACKGROUND));
+            
             g_ptr->push_back(new
               rect_element(legend_x_start, legend_y_start, legend_width, legend_height));
 
@@ -677,7 +686,7 @@
               derived().legend_header_.y(legend_y_pos);
               derived().image.g(PLOT_LEGEND_TEXT).push_back(new
                 text_element(derived().legend_header_));
-              legend_y_pos += 2 * spacing;
+              legend_y_pos += 2 * spacing; // Might be 1.5?
             }
 
             g_ptr = &(derived().image.g(PLOT_LEGEND_POINTS));
@@ -685,23 +694,23 @@
             g_inner_ptr = &(derived().image.g(PLOT_LEGEND_TEXT));
 
             for(unsigned int i = 0; i < derived().series.size(); ++i)
-            { // Show point marker, text info and perhaps line for all the data series.
+            { // Show point marker, perhaps line, & text info for all the data series.
               double legend_x_pos = legend_x_start;
-              legend_x_pos += spacing; // space before point marker.
+              legend_x_pos += spacing; // space before point marker and/or line & text.
               g_inner_ptr = &(g_ptr->g());
               // Use both stroke & fill colors from the point's style.
               g_inner_ptr->style().stroke_color(derived().series[i].point_style_.stroke_color_);
               g_inner_ptr->style().fill_color(derived().series[i].point_style_.fill_color_);
-              g_inner_ptr->style().stroke_width(2); // Applies to shape AND line.
+              g_inner_ptr->style().stroke_width(derived().series[i].line_style_.width_); // Applies to shape AND line.
 
               if(derived().series[i].point_style_.shape_ != none)
-              { // Is a shape to show.
+              { // Is a data marker shape to show.
                 draw_plot_point( // Plot point like circle, square...
                   legend_x_pos,
                   legend_y_pos,
                   *g_inner_ptr,
                   derived().series[i].point_style_);
-                legend_x_pos += 1.0 * spacing;
+                legend_x_pos += 1.5 * spacing;
               }
 
               // Line markers  - only really applicable to 2-D sets plot_line_style,
@@ -709,15 +718,15 @@
               { // Need to draw a short line to show color for that data series.
                 g_inner_ptr->style() // Use stroke colors from line style.
                   .stroke_color(derived().series[i].line_style_.color_);
-               // g_inner_ptr->style().width(4); // Use stroke colors from line style. 
+               // Use stroke colors from line style. 
                // == image.g(PLOT_DATA_LINES).style().stroke_width(width);
                 // but this sets width for BOTH point and line :-(
                 g_inner_ptr->push_back(new line_element(
-                  legend_x_pos + spacing /2., // half space leading space
+                  legend_x_pos,
                   legend_y_pos,
-                  legend_x_pos + spacing * 2., // line sample is two char long.
+                  legend_x_pos + spacing, // line sample is one char long.
                   legend_y_pos));
-                legend_x_pos += 2.5 * spacing; // short line & half space.
+                legend_x_pos += 1.5 * spacing; // short line & a space.
               } // legend_lines_
 
               // Legend text for each Data Series added to the plot.
@@ -1516,12 +1525,13 @@
           Derived& legend_on(bool cmd)
           {
             derived().legend_on_ = cmd;
-            if(cmd)
-            {
-              derived().image.g(detail::PLOT_LEGEND_BACKGROUND)
-                .style().fill_color(white)
-                .stroke_color(black);
-            }
+            //if(cmd)
+            //{
+            //  derived().image.g(detail::PLOT_LEGEND_BACKGROUND)
+            //    .style().fill_color(white) // defaults.
+            //    .stroke_color(black).
+            //    .stroke_on(derived().legend_box_.border_on());
+            //}
             return derived();
           }
 
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	2008-01-23 16:44:51 EST (Wed, 23 Jan 2008)
@@ -195,6 +195,7 @@
 
       box_style image_border_; // rectangular border of all image width, color...
       box_style plot_window_border_; // rectangular border of plot window width, color...
+      box_style legend_box_; // rectangular box of legend width, color...
 
  // TODO doubles also could be float?
       double plot_left_;
@@ -273,7 +274,8 @@
         y_label_value_(0, 0, "", y_value_label_style_, center_align, upward),
         text_margin_(2.), // for axis label text, as a multiplier of the font size.
         image_border_(yellow, white, 2, 10, true, true), // margin should be about axis label font size.
-        plot_window_border_(yellow, svg_color(255, 255, 255), 2, 3, true, false),
+        plot_window_border_(red, svg_color(255, 255, 255), 2, 3, true, false),
+        legend_box_(yellow, azure, 2, 4, true, true),
         legend_header_(0, 0, "", legend_style_, center_align, horizontal),
         legend_width_(200), // width of legend box (pixels) // TODO isn't this calculated?
         legend_height_(0), // height of legend box (pixels)
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	2008-01-23 16:44:51 EST (Wed, 23 Jan 2008)
@@ -237,7 +237,7 @@
 
 public: 
   text_style(int size = 20,  
-  const std::string& font = "", // default is sans with Firefox & IE but serif with Opera
+  const std::string& font = "", // Default is sans with Firefox & IE but serif with Opera.
   const std::string& style = "",
   const std::string& weight = "",
   const std::string& stretch = "",
@@ -378,7 +378,6 @@
 
 text_style no_style; // Uses all constructor defaults.
 
-
 enum point_shape
 { // Marking a data point.
   // Used in draw_plot_point in axis_plot_frame.hpp
@@ -417,14 +416,13 @@
     point_shape shape_; // round, square, point...
     std::string symbols_; // Unicode symbol (letters, digits, squiggles etc)
     // Caution: not all Unicode symbols are output by all browsers!
-    // Set symbol(s) font using .style().font_family("arial");
     text_style symbols_style_;
 
-    plot_point_style(const svg_color& fill = blank, const svg_color& stroke = blank,
+    plot_point_style(const svg_color& fill = blank, const svg_color& stroke = black,
       int size = 10, point_shape shape = round, const std::string& symbols = "X")
         :
         fill_color_(fill), stroke_color_(stroke), size_(size), shape_(shape), symbols_(symbols)
-    { // TODO Should there be default colors? or "none" == blank?
+    { // Best to have a fixed width font for symbols?
       symbols_style_.font_size(size);
       symbols_style_.font_family("Lucida Sans Unicode");
     }
@@ -928,18 +926,91 @@
     bool fill_on_; // Color fill the box.
 
     box_style(const svg_color& scolor = black,
-      const svg_color& fcolor = antiquewhite,
+      const svg_color& fcolor = white,
       double width = 1, // of border
-      double margin = 2.,
-      bool border_on = true,
-      bool fill_on = false)
+      double margin = 2., // 
+      bool border_on = true, // Draw a border of width.
+      bool fill_on = false) // Apply fill color.
       :
     stroke_(scolor), fill_(fcolor), width_(width),
     margin_(margin),
     border_on_(border_on),
     fill_on_(fill_on)
-    { // Initializes all private data.
+    { // Initializes all private data with defaults.
     }
+
+  box_style& stroke(const svg_color& color)
+  {
+    stroke_ = color;
+    return *this; // Make chainable.
+  }
+
+  svg_color stroke()
+  {
+    return stroke_;
+  }
+
+  box_style& fill(const svg_color& color)
+  {
+    fill_ = color;
+    return *this; // Make chainable.
+  }
+
+  svg_color fill()
+  {
+    return fill_;
+  }
+
+  box_style& width(double w)
+  {
+    width_ = w;
+    return *this; // Make chainable.
+  }
+
+  double width()
+  {
+    return width_;
+  }
+
+  box_style& margin(double w)
+  {
+    margin_ = w;
+    return *this; // Make chainable.
+  }
+
+  double margin()
+  {
+    return margin_;
+  }
+
+  bool border_on() const
+  {
+    return border_on_;
+  }
+
+  box_style& border_on(bool is) 
+  {
+    border_on_ = is;
+    return *this; // Make chainable.
+  }  
+  
+  bool fill_on() const
+  {
+    return fill_on_;
+  }
+
+  box_style& fill_on(bool is) 
+  {
+    fill_on_ = is;
+    return *this; // Make chainable.
+  }
+
+
+
+
+
+
+
 }; // class box_style
 
 const std::string strip_e0s(std::string s);
@@ -1029,7 +1100,7 @@
     }
     d++;
  }
- std::cout << "string " << s << " has " << d << " characters." << std::endl; 
+ // std::cout << "string " << s << " has " << d << " characters." << std::endl; 
  return d * style.font_size() * wh;
 } // double string_svg_length(