$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: jakevoytko_at_[hidden]
Date: 2007-06-17 22:48:15
Author: jakevoytko
Date: 2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
New Revision: 7088
URL: http://svn.boost.org/trac/boost/changeset/7088
Log:
Legend added, changed interface, more customizable.
Added:
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_plot_instruction.hpp
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_style.hpp
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_test.cpp
Text files modified: 
   sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp      |   137 +++++---------                          
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot.hpp |   382 ++++++++++++++++++++++++++++----------- 
   2 files changed, 325 insertions(+), 194 deletions(-)
Added: sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_plot_instruction.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_plot_instruction.hpp	2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -0,0 +1,47 @@
+// svg_plot_instruction.hpp
+
+// Copyright (C) Jacob Voytko 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// For more information, see http://www.boost.org
+
+// ----------------------------------------------------------------- 
+
+#ifndef _SVG_PLOT_INSTRUCTION_HPP
+#define _SVG_PLOT_INSTRUCTION_HPP
+
+#include <iterator>
+#include "svg_style.hpp"
+
+namespace boost {
+namespace svg {
+
+// -----------------------------------------------------------------
+// This struct is the smallest amount of information necessary at
+// the moment to display a legend with enough information
+// -----------------------------------------------------------------
+struct legend_point
+{
+    svg_color stroke_color;
+    svg_color fill_color;
+    std::string text;
+
+    legend_point(const svg_color& _stroke, const svg_color& _fill,
+        std::string _text): stroke_color(_stroke), fill_color(_fill),
+        text(_text)
+    {
+
+    }
+
+    legend_point(svg_color_constant _stroke, svg_color_constant _fill,
+        std::string _text): stroke_color(constant_to_rgb(_stroke)), 
+        fill_color(constant_to_rgb(_fill)),
+        text(_text)
+    {
+
+    }
+};
+}
+}
+
+#endif
Added: sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_style.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_style.hpp	2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -0,0 +1,337 @@
+// svg_style.hpp 
+// Copyright (C) Jacob Voytko 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// For more information, see http://www.boost.org
+
+// ----------------------------------------------------------------- 
+
+#ifndef _SVG_STYLE_HPP
+#define _SVG_STYLE_HPP
+
+#include <map>
+
+namespace boost {
+namespace svg {
+
+// -----------------------------------------------------------------
+// Deals with colors that have special names. The reason that the
+// underscoring does not match the normal Boost format
+// is that these are the names that are specifically allowed by the
+// SVG standard
+// -----------------------------------------------------------------
+enum svg_color_constant
+{
+    aliceblue, antiquewhite, aqua, aquamarine, azure, beige, 
+    bisque, black, blanchedalmond, blue, blueviolet, brown, 
+    burlywood, cadetblue, chartreuse, chocolate, coral, 
+    cornflowerblue, cornsilk, crimson, cyan, darkblue, darkcyan, 
+    darkgoldenrod, darkgray, darkgreen, darkgrey, darkkhaki, 
+    darkmagenta, darkolivegreen, darkorange, darkorchid, darkred, 
+    darksalmon, darkseagreen, darkslateblue, darkslategray, 
+    darkslategrey, darkturquoise, darkviolet, deeppink, 
+    deepskyblue, dimgray, dimgrey, dodgerblue, firebrick, 
+    floralwhite, forestgreen, fuchsia, gainsboro, ghostwhite, gold, 
+    goldenrod, gray, grey, green, greenyellow, honeydew, hotpink, 
+    indianred, indigo, ivory, khaki, lavender, lavenderblush, 
+    lawngreen, lemonchiffon, lightblue, lightcoral, lightcyan, 
+    lightgoldenrodyellow, lightgray, lightgreen, lightgrey, 
+    lightpink, lightsalmon, lightseagreen, lightskyblue, 
+    lightslategray, lightslategrey, lightsteelblue, lightyellow, 
+    lime, limegreen, linen, magenta, maroon, mediumaquamarine, 
+    mediumblue, mediumorchid, mediumpurple, mediumseagreen, 
+    mediumslateblue, mediumspringgreen, mediumturquoise, 
+    mediumvioletred, midnightblue, mintcream, mistyrose, moccasin, 
+    navajowhite, navy, oldlace, olive, olivedrab, orange, 
+    orangered, orchid, palegoldenrod, palegreen, paleturquoise, 
+    palevioletred, papayawhip, peachpuff, peru, pink, plum, 
+    powderblue, purple, red, rosybrown, royalblue, saddlebrown, 
+    salmon, sandybrown, seagreen, seashell, sienna, silver, 
+    skyblue, slateblue, slategray, slategrey, snow, springgreen, 
+    steelblue, tan, teal, thistle, tomato, turquoise, violet, 
+    wheat, white, whitesmoke, yellow, yellowgreen
+};
+
+
+void constant_to_rgb(svg_color_constant _c, unsigned char &r, unsigned char &g, 
+            unsigned char &b);
+
+// -----------------------------------------------------------------
+// svg_color is the struct that contains information about sRGB
+// colors.
+//
+// For the constructor: the svg standard specifies that numbers
+// outside the normal rgb range are to be accepted, but are rounded
+// to acceptable values.
+// -----------------------------------------------------------------
+struct svg_color
+{
+    unsigned char r, g, b;
+
+    svg_color(int _r, int _g, int _b)
+    {
+        _r = ( _r < 0 ) ? 0 : _r;
+        _g = ( _g < 0 ) ? 0 : _g;
+        _b = ( _b < 0 ) ? 0 : _b;
+
+        r = (unsigned char)(( _r > 255 ) ? 255 : _r);
+        g = (unsigned char)(( _g > 255 ) ? 255 : _g);
+        b = (unsigned char)(( _b > 255 ) ? 255 : _b);
+    }
+
+    svg_color(svg_color_constant _col)
+    {
+        constant_to_rgb(_col, r, g, b);
+    }
+
+    void write(std::ostream& rhs)
+    {
+        rhs << "rgb(" << (unsigned int)r << "," << (unsigned int) g << ","
+            << (unsigned int)b << ")" ;
+    }
+};
+
+// -----------------------------------------------------------------
+// To facilitate quick lookup of the RGB values of constants
+// -----------------------------------------------------------------
+svg_color color_array[] =
+{
+    svg_color(240, 248, 255), // aliceblue
+    svg_color(250, 235, 215), // antiquewhite
+    svg_color(0  , 255, 255), // aqua
+    svg_color(127, 255, 212), // aquamarine
+    svg_color(240, 255, 255), // azure
+    svg_color(245, 245, 220), // beige
+    svg_color(255, 228, 196), // bisque
+    svg_color(0  , 0  , 0  ), // black
+    svg_color(255, 235, 205), // blanchedalmond. Who thinks of these?
+    svg_color(0  , 0  , 255), // blue
+    svg_color(138, 43 , 226), // blueviolet
+    svg_color(165, 42 , 42 ), // brown
+    svg_color(222, 184, 135), // burlywood
+    svg_color(95 , 158, 160), // cadetblue
+    svg_color(127, 255, 0  ), // chartreuse
+    svg_color(210, 105, 30 ), // chocolate
+    svg_color(255, 127, 80 ), // coral
+    svg_color(100, 149, 237), // cornflowerblue
+    svg_color(255, 248, 220), // cornsilk
+    svg_color(220, 20 , 60 ), // crimson
+    svg_color(0  , 255, 255), // cyan
+    svg_color(0  , 0  , 139), // darkblue
+    svg_color(0  , 139, 139), // darkcyan
+    svg_color(184, 134, 11 ), // darkgoldenrod
+    svg_color(169, 169, 169), // darkgray
+    svg_color(0  , 100, 0  ), // darkgreen
+    svg_color(169, 169, 169), // darkgrey
+    svg_color(189, 183, 107), // darkkhaki
+    svg_color(139, 0  , 139), // darkmagenta
+    svg_color(85 , 107, 47 ), // darkolivegreen
+    svg_color(255, 140, 0  ), // darkorange
+    svg_color(153, 50 , 204), // darkorchid
+    svg_color(139, 0  , 0  ), // darkred
+    svg_color(233, 150, 122), // darksalmon
+    svg_color(143, 188, 143), // darkseagreen
+    svg_color(72 , 61 , 139), // darkslateblue
+    svg_color(47 , 79 , 79 ), // darkslategray
+    svg_color(47 , 79 , 79 ), // darkslategrey
+    svg_color(0  , 206, 209), // darkturquoise
+    svg_color(148, 0  , 211), // darkviolet
+    svg_color(255, 20 , 147), // deeppink
+    svg_color(0  , 191, 255), // deepskyblue
+    svg_color(105, 105, 105), // dimgray
+    svg_color(105, 105, 105), // dimgrey
+    svg_color(30 , 144, 255), // dodgerblue
+    svg_color(178, 34 , 34 ), // firebrick
+    svg_color(255, 250, 240), // floralwhite
+    svg_color(34 , 139, 34 ), // forestgreen
+    svg_color(255, 0  , 255), // fuchsia
+    svg_color(220, 220, 220), // gainsboro
+    svg_color(248, 248, 255), // ghostwhite
+    svg_color(255, 215, 0  ), // gold
+    svg_color(218, 165, 32 ), // goldenrod
+    svg_color(128, 128, 128), // gray
+    svg_color(128, 128, 128), // grey
+    svg_color(0  , 128, 0  ), // green
+    svg_color(173, 255, 47 ), // greenyellow
+    svg_color(240, 255, 240), // honeydew
+    svg_color(255, 105, 180), // hotpink
+    svg_color(205, 92 , 92 ), // indianred
+    svg_color(75 , 0  , 130), // indigo
+    svg_color(255, 255, 240), // ivory
+    svg_color(240, 230, 140), // khaki
+    svg_color(230, 230, 250), // lavender
+    svg_color(255, 240, 245), // lavenderblush
+    svg_color(124, 252, 0  ), // lawngreen
+    svg_color(255, 250, 205), // lemonchiffon
+    svg_color(173, 216, 230), // lightblue
+    svg_color(240, 128, 128), // lightcoral
+    svg_color(224, 255, 255), // lightcyan
+    svg_color(250, 250, 210), // lightgoldenrodyellow
+    svg_color(211, 211, 211), // lightgray
+    svg_color(144, 238, 144), // lightgreen
+    svg_color(211, 211, 211), // lightgrey
+    svg_color(255, 182, 193), // lightpink
+    svg_color(255, 160, 122), // lightsalmon
+    svg_color(32 , 178, 170), // lightseagreen
+    svg_color(135, 206, 250), // lightskyblue
+    svg_color(119, 136, 153), // lightslategray
+    svg_color(119, 136, 153), // lightslategrey
+    svg_color(176, 196, 222), // lightsteelblue
+    svg_color(255, 255, 224), // lightyellow
+    svg_color(0  , 255, 0  ), // lime
+    svg_color(50 , 205, 50 ), // limegreen
+    svg_color(250, 240, 230), // linen
+    svg_color(255, 0  , 255), // magenta
+    svg_color(128, 0  , 0  ), // maroon
+    svg_color(102, 205, 170), // mediumaquamarine
+    svg_color(0  , 0  , 205), // mediumblue
+    svg_color(186, 85 , 211), // mediumorchid
+    svg_color(147, 112, 219), // mediumpurple
+    svg_color(60 , 179, 113), // mediumseagreen
+    svg_color(123, 104, 238), // mediumslateblue
+    svg_color(0  , 250, 154), // mediumspringgreen
+    svg_color(72 , 209, 204), // mediumturquoise
+    svg_color(199, 21 , 133), // mediumvioletred
+    svg_color(25 , 25 , 112), // midnightblue
+    svg_color(245, 255, 250), // mintcream
+    svg_color(255, 228, 225), // mistyrose
+    svg_color(255, 228, 181), // moccasin
+    svg_color(255, 222, 173), // navajowhite
+    svg_color(0  , 0  , 128), // navy
+    svg_color(253, 245, 230), // oldlace
+    svg_color(128, 128, 0  ), // olive
+    svg_color(107, 142, 35 ), // olivedrab
+    svg_color(255, 165, 0  ), // orange
+    svg_color(255, 69 , 0  ), // orangered
+    svg_color(218, 122, 214), // orchid
+    svg_color(238, 232, 170), // palegoldenrod
+    svg_color(152, 251, 152), // palegreen
+    svg_color(175, 238, 238), // paleturquose
+    svg_color(219, 112, 147), // palevioletred
+    svg_color(255, 239, 213), // papayawhip
+    svg_color(255, 218, 185), // peachpuff
+    svg_color(205, 133, 63 ), // peru
+    svg_color(255, 192, 203), // pink
+    svg_color(221, 160, 221), // plum
+    svg_color(176, 224, 230), // powderblue
+    svg_color(128, 0  , 128), // purple
+    svg_color(255, 0  , 0  ), // red
+    svg_color(188, 143, 143), // rosybrown
+    svg_color(65 , 105, 225), // royalblue
+    svg_color(139, 69 , 19 ), // saddlebrown
+    svg_color(250, 128, 114), // salmon
+    svg_color(244, 164, 96 ), // sandybrown
+    svg_color(46 , 139, 87 ), // seagreen
+    svg_color(255, 245, 238), // seashell
+    svg_color(160, 82 , 45 ), // sienna
+    svg_color(192, 192, 192), // silver
+    svg_color(135, 206, 235), // skyblue
+    svg_color(106, 90 , 205), // slateblue
+    svg_color(112, 128, 144), // slategray
+    svg_color(112, 128, 144), // slategrey
+    svg_color(255, 250, 250), // snow
+    svg_color(0  , 255, 127), // springgreen
+    svg_color(70 , 130, 180), // steelblue
+    svg_color(210, 180, 140), // tan
+    svg_color(0  , 128, 128), // teal
+    svg_color(216, 191, 216), // thistle
+    svg_color(255, 99 , 71 ), // tomato
+    svg_color(64 , 224, 208), // turquoise
+    svg_color(238, 130, 238), // violet
+    svg_color(245, 222, 179), // wheat
+    svg_color(255, 255, 255), // white
+    svg_color(245, 245, 245), // whitesmoke
+    svg_color(255, 255, 0  ), // yellow
+    svg_color(154, 205, 50 ), // yellowgreen
+};
+
+
+void constant_to_rgb(svg_color_constant _c, unsigned char &r, unsigned char &g, 
+            unsigned char &b)
+{
+    r = color_array[(unsigned int)_c].r;
+    g = color_array[(unsigned int)_c].g;
+    b = color_array[(unsigned int)_c].b;
+}
+
+svg_color constant_to_rgb(svg_color_constant _c)
+{
+    return svg_color(color_array[(unsigned int)_c].r
+        ,color_array[(unsigned int)_c].g
+        ,color_array[(unsigned int)_c].b);
+}
+
+// -----------------------------------------------------------------
+// This is the style information for any <g> tag. This will be
+// expanded to include more data from the SVG standard when the
+// time comes.
+// -----------------------------------------------------------------
+class svg_g_style
+{
+private:
+    svg_color fill_color;
+    svg_color stroke_color;
+    
+public:
+    svg_g_style();
+    svg_g_style(const svg_color&, const svg_color&);
+    void set_fill_color(const svg_color&);
+    void set_stroke_color(const svg_color&);
+    void write(std::ostream&);
+
+    svg_color get_fill_color()
+    {
+        return svg_color(fill_color);
+    }
+    
+    svg_color get_stroke_color()
+    {
+        return svg_color(stroke_color);
+    }
+};
+
+// -----------------------------------------------------------------
+// These are the defaults that I used in the prototype, and they
+// looked decent enough.
+// -----------------------------------------------------------------
+svg_g_style::svg_g_style():fill_color(svg_color(255, 0, 0)), 
+    stroke_color(svg_color(0, 0, 0))
+{
+
+}
+
+
+// -----------------------------------------------------------------
+// For changing the defaults for the colors
+// -----------------------------------------------------------------
+svg_g_style::svg_g_style(const svg_color& _fill, const svg_color& _stroke)
+:fill_color(_fill), stroke_color(_stroke)
+{
+
+}
+
+void svg_g_style::write(std::ostream& rhs)
+{
+    rhs << "stroke=\"";
+    stroke_color.write(rhs);
+    rhs << "\" fill=\"";
+    fill_color.write(rhs);
+    rhs<<"\"";
+}
+
+void svg_g_style::set_stroke_color(const svg_color& rhs)
+{
+    stroke_color = rhs;
+}
+
+void svg_g_style::set_fill_color(const svg_color& rhs)
+{
+    fill_color = rhs;
+}
+
+
+}//svg
+}//boost
+
+
+#endif
Added: sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp	2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -0,0 +1,257 @@
+// svg_tag.hpp
+
+// Copyright (C) Jacob Voytko 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// For more information, see http://www.boost.org
+
+// ----------------------------------------------------------------- 
+
+#ifndef _SVG_TAG_HPP
+#define _SVG_TAG_HPP
+
+#include <sstream>
+#include <string>
+#include <boost/ptr_container/ptr_container.hpp>
+#include <boost/noncopyable.hpp>
+
+#include "svg_style.hpp"
+
+namespace boost {
+namespace svg {
+
+
+// -----------------------------------------------------------------
+// This file defines all classes that can occur in the SVG parse
+// tree
+// -----------------------------------------------------------------
+
+
+// -----------------------------------------------------------------
+// The base class for all leaf elements
+// -----------------------------------------------------------------
+    
+class svg_element
+{
+public:
+    virtual void write(std::ostream&) = 0;
+};
+
+// -----------------------------------------------------------------
+// The node element of our document tree
+// -----------------------------------------------------------------
+
+class g_element: public svg_element
+{
+private: 
+    svg_g_style style_info;
+
+public:
+    boost::ptr_vector<svg_element> children;
+    
+    svg_element& operator[](unsigned int);
+    size_t size();
+    
+    void set_stroke_color(const svg_color&);
+    void set_fill_color(const svg_color&);
+
+    svg_color get_stroke_color()
+    {
+        return style_info.get_stroke_color();
+    }
+    void write(std::ostream&);
+
+    g_element& g_tag(int);
+};
+
+svg_element& g_element::operator[](unsigned int i)
+{
+    return children[i];
+}
+
+size_t g_element::size()
+{
+    return children.size();
+}
+
+void g_element::write(std::ostream& rhs)
+{
+    rhs << "<g ";
+    style_info.write(rhs);
+    rhs<< " >" << std::endl;
+    
+    for(unsigned int i=0; i<children.size(); ++i)
+    {
+        children[i].write(rhs);
+    }
+
+    rhs << "</g>" << std::endl;
+
+}
+
+g_element& g_element::g_tag(int i)
+{
+    return *(static_cast<g_element*>(&children[i]));
+}
+
+void g_element::set_stroke_color(const svg_color& _col)
+{
+    style_info.set_stroke_color(_col);
+}
+
+void g_element::set_fill_color(const svg_color& _col)
+{
+    style_info.set_fill_color(_col);
+}
+
+
+// -----------------------------------------------------------------
+// Represents a single point
+// -----------------------------------------------------------------
+class point_element: public svg_element
+{
+private:
+    double x, y;
+
+public:
+    point_element(double, double);
+    void write(std::ostream&);
+};
+
+point_element::point_element(double _x, double _y):x(_x), y(_y)
+{
+    
+}
+
+void point_element::write(std::ostream& rhs)
+{
+    rhs<<"<circle cx=\""<<x<<"\" cy=\""<<y<<"\" r=\"5\"/>";
+
+}
+
+// -----------------------------------------------------------------
+// Represents a line
+// -----------------------------------------------------------------
+class line_element: public svg_element
+{
+private:
+    double x1, x2, y1, y2, y;
+
+public:
+    line_element(double, double, double, double);
+    void write(std::ostream&);
+};
+
+line_element::line_element(double _x1, double _y1, double _x2,
+                             double _y2):x1(_x1), y1(_y1),
+                             x2(_x2), y2(_y2)
+{
+    
+}
+
+void line_element::write(std::ostream& rhs)
+{
+    rhs<<"<line x1=\""<<x1<<"\" y1=\""<<y1<<"\" x2=\""<<x2<<"\" y2=\""
+        <<y2<<"\"/>";
+}
+
+// -----------------------------------------------------------------
+// Represents a single block of text
+// -----------------------------------------------------------------
+enum text_style{left_align, right_align, center_align};
+
+class text_element: public svg_element
+{
+private:
+    double x, y;
+    std::string text;
+    text_style alignment;
+
+public:
+    text_element(double, double, std::string);
+    void write(std::ostream&);
+    void set_alignment(text_style _a)
+    {
+        alignment = _a;
+    }
+};
+
+text_element::text_element(double _x, double _y, std::string _text)
+            :x(_x), y(_y), text(_text), alignment(left_align)
+{
+    
+}
+
+void text_element::write(std::ostream& rhs)
+{
+    std::string align;
+
+    switch(alignment)
+    {
+    case left_align:
+        align = "start";
+        break;
+
+    case right_align:
+        align = "end";
+        break;
+
+    case center_align:
+        align = "middle";
+        break;
+
+    default:
+        align = "";
+        break;
+    }
+
+    rhs << "<text x=\"" << x << "\""
+        <<" y=\""<<y<<"\" ";
+    
+    if(align != "")
+    {
+        rhs << "text-anchor=\""<<align<<"\" ";
+    }
+
+    rhs <<" fill=\"black\" stroke=\"black\" font-family=\"verdana\""
+        <<" font-size=\"12\">"
+        << text
+        <<" </text>";
+}
+
+
+
+// -----------------------------------------------------------------
+// Represents a single block of text
+// -----------------------------------------------------------------
+class rect_element: public svg_element
+{
+private:
+    double x, y, height, width;
+
+public:
+    rect_element(double, double, double, double);
+    void write(std::ostream&);
+};
+
+rect_element::rect_element(double _x, double _y, double _w, double _h)
+            :x(_x), y(_y), width(_w), height(_h)
+{
+    
+}
+
+void rect_element::write(std::ostream& rhs)
+{
+    rhs<<"<rect x=\""<<x<<"\""
+                <<" y=\""<<y<<"\" "
+                <<" width=\""<<width<<"\" "
+                <<" height=\""<<height<<"\"/>"
+                ;
+}
+
+
+
+}
+}
+
+#endif
\ No newline at end of file
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-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -16,7 +16,6 @@
 #include <iostream>
 #include <fstream>
 
-#include "svg_instruction.hpp"
 #include "svg_tag.hpp"
 #include "svg_style.hpp"
 
@@ -42,35 +41,28 @@
     
     g_element document;
 
-    void _size(unsigned int, unsigned int);
-
-    void _write();
-
-    void _point(double, double);
-    void _point(double, double, g_element&);
-    
-    void _line(double, double, double, double);
-    void _line(double, double, double, double, g_element&); 
-    
-    void _text(double, double, std::string);
-    void _line_color(svg_color);
-
-
 public:
     svg(const std::string&);
     
     virtual ~svg();
+
     svg(const svg&);
     svg& operator=(const svg&);
 
-    svg& operator<<(const svg_instruction&);
+    svg& image_size(unsigned int, unsigned int);
+    svg& write();
 
-    svg& operator<<(const svg_point&);
-
-    svg& operator<<(const svg_line&);
-    svg& operator<<(const svg_text&);
+    svg& point(double, double);
+    svg& point(double, double, g_element&);
+    
+    svg& line(double, double, double, double);
+    svg& line(double, double, double, double, g_element&); 
+    
+    svg& text(double, double, std::string);
+    svg& line_color(svg_color);
 
-    svg& operator<<(const svg_stroke_color&);
+    svg& rect(double, double, double, double);
+    svg& rect(double, double, double, double, g_element&); 
 
     friend std::ostream& operator<<(std::ostream&, const svg&);
 };
@@ -102,66 +94,8 @@
 }
 
 // -----------------------------------------------------------------
-// Processes the svg_instructions
-// This allows the user to easily enter information than ordinary
-// method calls, and is more clear that the method supports chaining
-// -----------------------------------------------------------------
-svg& svg::operator<<(const svg_instruction& rhs)
-{
-    switch(rhs.i_type)
-    {
-    case SVG_WRITE:
-        _write();
-        break;
-    }
-    return *this;
-}
-
-// -----------------------------------------------------------------
-// Chained stream operators. Each operator overload below will
-// represent a different instruction type, after I rewrite svg's
-// instructions to be more generic.
 // -----------------------------------------------------------------
-svg& svg::operator<<(const svg_point &rhs)
-{
-    switch(rhs.i_type)
-    {
-    case SVG_SIZE:
-        _size((unsigned int)rhs.x, (unsigned int)rhs.y);
-        break;
-    case SVG_POINT:
-        _point(rhs.x, rhs.y, document);
-    }
-
-    return *this;
-}
-
-svg& svg::operator<<(const svg_line &rhs)
-{
-    _line(rhs.x1, rhs.y1, rhs.x2, rhs.y2);
-
-    return *this;
-}
-
-svg& svg::operator<<(const svg_text &rhs)
-{
-    _text(rhs.x, rhs.y, rhs.text);
-
-    return *this;
-}
-
-svg& svg::operator<<(const svg_stroke_color &rhs)
-{
-    _line_color(rhs.col);
-
-    return *this;
-}
-
-// -----------------------------------------------------------------
-// Internal function to write the data to a specified stream
-// TODO: allow other streams than a file stream
-// -----------------------------------------------------------------
-void svg::_write()
+svg& svg::write()
 {
     _write_header();
 
@@ -174,6 +108,8 @@
 
     //close off svg tag
     *s_out<<"</svg>";
+
+    return *this;
 }
 
 // -----------------------------------------------------------------
@@ -206,10 +142,12 @@
 // Writes the information about the size of the file to the document
 // TODO: allow other unit identifiers
 // -----------------------------------------------------------------
-void svg::_size(unsigned int x, unsigned int y)
+svg& svg::image_size(unsigned int x, unsigned int y)
 {
     x_size = x;
     y_size = y;
+
+    return *this;
 }
 
 // -----------------------------------------------------------------
@@ -220,14 +158,18 @@
 // -----------------------------------------------------------------
 
 // this overload has a pointer to a node in the document tree
-void svg::_point(double x, double y, g_element& location)
+svg& svg::point(double x, double y, g_element& location)
 {
     location.children.push_back(new point_element(x, y));
+
+    return *this;
 }
 
-void svg::_point(double x, double y)
+svg& svg::point(double x, double y)
 {
     document.children.push_back(new point_element(x, y));
+
+    return *this;
 }
 
 // -----------------------------------------------------------------
@@ -235,32 +177,53 @@
 // TODO: Allow other line thicknesses
 // TODO: Allow other line colors
 // -----------------------------------------------------------------
-void svg::_line(double x1, double y1, double x2, double y2)
+svg& svg::line(double x1, double y1, double x2, double y2)
 {
     document.children.push_back(new line_element(x1, y1, x2, y2));
+
+    return *this;
 }
 
-void svg::_line(double x1, double y1, double x2, double y2, 
+svg& svg::line(double x1, double y1, double x2, double y2, 
                 g_element& location)
 {
     location.children.push_back(new line_element(x1, y1, x2, y2));
+
+    return *this;
 }
 
 // -----------------------------------------------------------------
 // Writes the information about text to the document
 // TODO: allow different fonts and font sizes
 // -----------------------------------------------------------------
-void svg::_text(double x, double y, std::string text)
+svg& svg::text(double x, double y, std::string text)
 {
     document.children.push_back(new text_element(x, y, text));
+
+    return *this;
 }
 
 // -----------------------------------------------------------------
 // Hopefully this one will be filld out next week
 // -----------------------------------------------------------------
-void svg::_line_color(svg_color col)
+svg& svg::line_color(svg_color col)
+{
+    return *this;
+}
+
+svg& svg::rect(double x1, double y1, double x2, double y2)
+{
+    document.children.push_back(new rect_element(x1, y1, x2, y2));
+
+    return *this;
+}
+
+svg& svg::rect(double x1, double y1, double x2, double y2, 
+                g_element& location)
 {
+    location.children.push_back(new rect_element(x1, y1, x2, y2));
 
+    return *this;
 }
 
 
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot.hpp	(original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot.hpp	2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -16,8 +16,9 @@
 #include <iterator>
 #include <limits>
 
-#include "svg_plot_instruction.hpp"
 #include "svg.hpp"
+#include "svg_plot_instruction.hpp"
+
 
 #include <boost/array.hpp>
 
@@ -30,12 +31,15 @@
 // when I'm building data. It's easier to refer to:
 //      document[SVG_PLOT_BACKGROUND].color()
 //
-// than it is to do it any other way I can think of.
+// than other possibilities I can think of!
+//
+// "legend" is on top because either it'll be laid on top of the graph,
+// or it'll be off to the side. 
 // -----------------------------------------------------------------
 #define SVG_PLOT_DOC_CHILDREN 3
 
-enum svg_plot_doc_structure{SVG_PLOT_BACKGROUND, SVG_PLOT_LEGEND,
-    SVG_PLOT_PLOT};
+enum svg_plot_doc_structure{SVG_PLOT_BACKGROUND, SVG_PLOT_PLOT, 
+    SVG_PLOT_LEGEND};
 
 // -----------------------------------------------------------------
 // The following enums define the children for the legend. This will be
@@ -62,42 +66,53 @@
 {
 private:
     double transform_matrix[3][3];
-
     double x_min, x_max;
 
     //Still keep track of this for when we have a view window
     //for the graph
-    double y_window_min, y_window_max; 
+
+    double y_window_min, y_window_max;
+
+    double y_axis;
     
+    bool legend_on;
+    std::vector<legend_point> legend;
+
     //Don't let the user use this without specifying a stream.
     //I can't think of a reasonable default, and I don't think
     //they'd want the svg formatted output spit to the console
     svg_plot();
 
-    void _x_scale(double, double);
-    void _plot_image_size(unsigned int, unsigned int);
+    void _transform_point(double &x);
+    void _clear_legend();
+    void _draw_legend_header(int, int, int, int);
+    void _draw_legend();
 
-    void _plot_range(std::vector<double>::const_iterator,
-        std::vector<double>::const_iterator);
-    void _plot_range(std::vector<double>::const_iterator,
-        std::vector<double>::const_iterator,
-        svg_color);
+public:
+    svg_plot(const std::string& file);
+    
+    svg_plot& x_scale(double, double);
 
+    svg_plot& draw_axis();
+    svg_plot& show_legend();
+    
+    svg_plot& line_color(const svg_color&);
 
-    void _transform_point(double &x);
-    void _draw_axis();
-    void _line_color(const svg_color&);
+    svg_plot& write();
 
-public:
-    using svg::operator<<;
+    svg_plot& image_size(unsigned int, unsigned int);
 
-    svg_plot(const std::string& file);
-    svg_plot& operator<<(const plot_single_val&);
-    svg_plot& operator<<(const plot_two_vals&);
-    svg_plot& operator<<(const plot_draw_range&);
-    svg_plot& operator<<(const plot_draw_col_range&);
-    svg_plot& operator<<(const plot_command&);
-    svg_plot& operator<<(const plot_color&);
+    svg_plot& set_background_color(svg_color_constant);
+    svg_plot& set_background_color(const svg_color&);
+
+    svg_plot& set_legend_background_color(svg_color_constant);
+    svg_plot& set_legend_background_color(const svg_color&);
+
+    void plot_range(std::vector<double>::const_iterator,
+        std::vector<double>::const_iterator, std::string);
+    
+    void plot_range(std::vector<double>::const_iterator, 
+        std::vector<double>::const_iterator, std::string, svg_color_constant);
 };
 
 // -----------------------------------------------------------------
@@ -121,24 +136,29 @@
     }
     
     //to determine: reasonable default values
-    _size(100, 100);
+    image_size(100, 100);
     
     y_window_min = 0;
     y_window_max = 100;
 
+    y_axis = (y_window_min + y_window_max) / 2.;
+
     x_min = -10;
     x_max = 10;
 
+    legend_on = false;
+
     transform_matrix[0][0] = transform_matrix[2][2] = transform_matrix[1][1] = 1;
 
     transform_matrix[0][2] = x_size * (-x_min / (x_min - x_max));
 
-    //build the document tree
+    //build the document tree.. add children of the root node
     for(int i=0; i<SVG_PLOT_DOC_CHILDREN; ++i)
     {
         document.children.push_back(new g_element());
     }
 
+    //add children of the plot node
     for(int i=0; i<SVG_PLOT_DOC_PLOT_CHILDREN; ++i)
     {
         (static_cast<g_element*>
@@ -146,74 +166,19 @@
                 ->children.push_back(new g_element());
     }
     
-}
-
-// -----------------------------------------------------------------
-// The chained stream operators. Each overload below deals with a
-// different instruction type by cases.
-// -----------------------------------------------------------------
-
-svg_plot& svg_plot::operator<<(const plot_two_vals& rhs)
-{
-    switch(rhs.i_type)
-    {
-    case PLOT_SCALE_X:
-        _x_scale(rhs.x1, rhs.x2);
-        break;
-    
-    case PLOT_SIZE:
-        _plot_image_size((unsigned int)rhs.x1, (unsigned int)rhs.x2);
-        break;
-    }
-
-    return (svg_plot&)*this;
-}
-
-svg_plot& svg_plot::operator <<(const plot_single_val& rhs)
-{
-/*    switch(rhs.i_type)
-    {
-    default:
-        break;
-    }
-*/
-    return (svg_plot&)*this;
-}
-
-svg_plot& svg_plot::operator<<(const plot_command& rhs)
-{
-    _draw_axis();
-    return (svg_plot&)*this;
-}
-
-svg_plot& svg_plot::operator<<(const plot_draw_range& rhs)
-{
-    _plot_range(rhs.data.begin(), rhs.data.end());
-    return (svg_plot&)*this;
-}
-
-svg_plot& svg_plot::operator<<(const plot_draw_col_range& rhs)
-{
-    _plot_range(rhs.data.begin(), rhs.data.end(), rhs.fill_color);
-    return (svg_plot&)*this;
-}
-
-svg_plot& svg_plot::operator<<(const plot_color& rhs)
-{
-    switch(rhs.i_type)
+    //add children of the legend node
+    for(int i=0; i<SVG_PLOT_DOC_LEGEND_CHILDREN; ++i)
     {
-    case PLOT_LINE_COLOR:
-        _line_color(rhs.col);
-        break;
+        (static_cast<g_element*>
+            (&(document.children[SVG_PLOT_LEGEND])))
+                ->children.push_back(new g_element());
     }
-
-    return (svg_plot&)*this;
 }
 
 // -----------------------------------------------------------------
 // Set the scale for x values
 // -----------------------------------------------------------------
-void svg_plot::_x_scale(double x1, double x2)
+svg_plot& svg_plot::x_scale(double x1, double x2)
 {
     x_min = x1;
     x_max = x2;
@@ -225,54 +190,74 @@
 
     transform_matrix[0][0] = x_size/(x2-x1);
     transform_matrix[0][2] = x_size*(-x1 / (x2 - x1));
+
+    return (svg_plot&)*this;
 }
 
 // -----------------------------------------------------------------
 // set the size of the svg image produced
 // -----------------------------------------------------------------
-void svg_plot::_plot_image_size(unsigned int x, unsigned int y)
+svg_plot& svg_plot::image_size(unsigned int x, unsigned int y)
 {
-    _size(x, y);
+    svg::image_size(x, y);
     
     y_window_max = y;
 
+    y_axis = (y + y_window_min)/2.;
+
     transform_matrix[0][2] = x_size * (-x_min / (x_min - x_max) );
+
+    return (svg_plot&)*this;
 }
 
 // -----------------------------------------------------------------
 // Actually draw data to the plot. Default color information
 // -----------------------------------------------------------------
-void svg_plot::_plot_range(std::vector<double>::const_iterator begin,
-                            std::vector<double>::const_iterator end)
+void svg_plot::plot_range(std::vector<double>::const_iterator begin,
+                            std::vector<double>::const_iterator end,
+                            std::string _str)
 {
     double x;
 
     double i=0;
 
-    double y_point = (y_window_min + y_window_max) / 2.;
-    
+    g_element* g_ptr = &(document.g_tag(SVG_PLOT_PLOT).
+        g_tag(SVG_PLOT_PLOT_POINTS));
+
+    g_ptr->children.push_back(new g_element);
+
+    // this sets the current <g> element to the one that will contain
+    // the data that is being pushed back.
+    g_ptr = &(g_ptr->g_tag((int)(g_ptr->size())-1));
+
+    g_ptr->set_fill_color(black);
+
     for(std::vector<double>::const_iterator b = begin; b!=end; ++b)
     {
         x = *b;
         _transform_point(x);
-        _point(x, y_point, 
-            document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_POINTS));
+        point(x, y_axis, 
+            *g_ptr);
     }
+
+    // no matter what, we need to store information for the legend
+    // so that it's easier to deal with when when turn it on after
+    // we call this function =)
+    legend.push_back(legend_point(g_ptr->get_stroke_color(), black, _str));
 }
 
 // -----------------------------------------------------------------
 // Actually draw data to the plot. Fill color information provided
 // -----------------------------------------------------------------
-void svg_plot::_plot_range(std::vector<double>::const_iterator begin,
+void svg_plot::plot_range(std::vector<double>::const_iterator begin,
                             std::vector<double>::const_iterator end,
-                            svg_color _col)
+                            std::string _str,
+                            svg_color_constant _col)
 {
     double x;
 
     double i=0;
 
-    double y_point = (y_window_min + y_window_max) / 2.;
-
     g_element* g_ptr = &(document.g_tag(SVG_PLOT_PLOT).
         g_tag(SVG_PLOT_PLOT_POINTS));
 
@@ -288,10 +273,56 @@
     {
         x = *b;
         _transform_point(x);
-        _point(x, y_point, 
+        point(x, y_axis, 
             *g_ptr);
     }
+
+    // no matter what, we need to store information for the legend
+    // so that it's easier to deal with when when turn it on after
+    // we call this function =)
+    legend.push_back(legend_point(g_ptr->get_stroke_color(), _col, _str));
 }
+
+// -----------------------------------------------------------------
+// Sets the background color in the area of the document. Specifically,
+// done by adding a rectangle to the background that hits the edges
+// of the image
+// -----------------------------------------------------------------
+svg_plot& svg_plot::set_background_color(svg_color_constant _col)
+{
+    set_background_color(constant_to_rgb(_col));
+
+    return (svg_plot&)*this;
+}
+
+svg_plot& svg_plot::set_background_color(const svg_color& _col)
+{
+    document.g_tag(SVG_PLOT_BACKGROUND).set_fill_color(_col);
+
+    document.g_tag(SVG_PLOT_BACKGROUND)
+        .children.push_back(new rect_element(0, 0, x_size, y_size));
+
+    return (svg_plot&)*this;
+}
+
+// -----------------------------------------------------------------
+// Sets the background color in the area of the legend
+// -----------------------------------------------------------------
+svg_plot& svg_plot::set_legend_background_color(svg_color_constant _col)
+{
+    set_legend_background_color(constant_to_rgb(_col));
+
+    return (svg_plot&)*this;
+}
+
+svg_plot& svg_plot::set_legend_background_color(const svg_color& _col)
+{
+    document.g_tag(SVG_PLOT_LEGEND).g_tag(SVG_PLOT_LEGEND_BACKGROUND)
+            .set_fill_color(_col);
+
+    return (svg_plot&)*this;
+}
+
 // -----------------------------------------------------------------
 // This transforms a 1-D Cartesian point into a svg point. We don't
 // use the svg-defined coordinate transform because sizing is a harder
@@ -307,7 +338,7 @@
 // -----------------------------------------------------------------
 // TODO: Refactor
 // -----------------------------------------------------------------
-void svg_plot::_draw_axis()
+svg_plot& svg_plot::draw_axis()
 {
     // one major axis. We just need to draw a verticle line through
     // the origin for now. We will make that an option later.
@@ -323,11 +354,11 @@
     double y_mean = (y_window_min + y_window_max)/2.;
     double x_mean = (x1 + x2)/2.;
 
-    _line(x1, y_mean, x2, y_mean, 
+    line(x1, y_mean, x2, y_mean, 
         document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_AXIS));
 
     //origin
-    _line(x_mean, y_window_min, x_mean, y_window_max, 
+    line(x_mean, y_window_min, x_mean, y_window_max, 
         document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_AXIS));
 
     y1 = y2 = 0;
@@ -344,7 +375,7 @@
         _transform_point(x1);
         _transform_point(x2);
 
-        _line(x1, y1, x1, y2, 
+        line(x1, y1, x1, y2, 
             document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_AXIS));
     }
 
@@ -357,9 +388,18 @@
 
         _transform_point(x1);
 
-        _line(x1, y1, x1, y2,
+        line(x1, y1, x1, y2,
             document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_AXIS));
     }
+
+    return (svg_plot&)*this;
+}
+
+svg_plot& svg_plot::show_legend()
+{
+    legend_on = true;
+
+    return (svg_plot&)*this;
 }
 
 // -----------------------------------------------------------------
@@ -368,10 +408,138 @@
 // by removing the default for <g> in the constructor (ran out of
 // time this week)
 // -----------------------------------------------------------------
-void svg_plot::_line_color(const svg_color& _col)
+svg_plot& svg_plot::line_color(const svg_color& _col)
 {
     document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_AXIS)
         .set_stroke_color(_col);
+
+    return (svg_plot&)*this;
+}
+
+// -----------------------------------------------------------------
+// When writing to multiple documents, the contents of the plot
+// may change significantly between. Rather than figuring out what
+// has and has not changed, just erase the contents of the legend
+// in the document and start over.
+// -----------------------------------------------------------------
+void svg_plot::_clear_legend()
+{
+    g_element* g_ptr = &(document.g_tag(SVG_PLOT_LEGEND)
+                        .g_tag(SVG_PLOT_LEGEND_POINTS));
+
+    g_ptr->children.erase(g_ptr->children.begin(), g_ptr->children.end());
+
+    g_ptr = &(document.g_tag(SVG_PLOT_LEGEND).g_tag(SVG_PLOT_LEGEND_TEXT));
+    g_ptr->children.erase(g_ptr->children.begin(), g_ptr->children.end());
+}
+
+// -----------------------------------------------------------------
+// Factored out to make _draw_legend() cleaner
+// -----------------------------------------------------------------
+void svg_plot::_draw_legend_header(int _x, int _y, int _width, int _height)
+{
+    g_element* g_ptr = &(document.g_tag(SVG_PLOT_LEGEND)
+                            .g_tag(SVG_PLOT_LEGEND_TEXT));
+
+    text_element legend_header(_x+(_width/2), _y + 20, "Legend");
+
+    legend_header.set_alignment(center_align);
+
+    g_ptr->children.push_back(new text_element(legend_header));
+}
+
+// -----------------------------------------------------------------
+// Important note: there are a lot of magic numbers that are temporary
+// fill-ins for the time when the legend system is more configurable.
+// This will happen bit-by-bit, as I give the user options to change
+// these values
+// -----------------------------------------------------------------
+void svg_plot::_draw_legend()
+{
+    _clear_legend();
+
+    int num_points = (int)(legend.size());
+
+    int legend_width(200);
+    int legend_height(25);
+
+    // Figure out how wide the legend should be
+    if(x_size < 200)
+    {
+       legend_width = x_size; 
+    }
+
+    int legend_x_start(x_size-legend_width-20);
+    int legend_y_start(40);
+
+    // legend_height = title_spacing + (space per element)(num_elements)
+    //                  + (end spacing)
+    legend_height = 25 + (25 * num_points) + 10;
+
+    // TODO: Figure out how tall the legend should be
+
+    g_element* g_ptr = &(document.g_tag(SVG_PLOT_LEGEND)
+                         .g_tag(SVG_PLOT_LEGEND_BACKGROUND));
+
+    g_ptr->children.push_back(new rect_element(legend_x_start, legend_y_start,
+                                               legend_width, legend_height));
+
+    _draw_legend_header(legend_x_start, legend_y_start, legend_width, legend_height);
+
+    g_ptr = &(document.g_tag(SVG_PLOT_LEGEND)
+                         .g_tag(SVG_PLOT_LEGEND_POINTS));
+
+    g_element* g_inner_ptr;
+    int i=0;
+
+    for(std::vector<legend_point>::iterator iter = legend.begin(); 
+        iter!=legend.end(); ++iter, ++i)
+    {
+        g_ptr -> children.push_back( new g_element() );
+        g_inner_ptr = &(g_ptr->g_tag((int)(g_ptr->children.size())-1));
+        
+        g_inner_ptr->set_fill_color((*iter).fill_color);
+        g_inner_ptr->set_stroke_color((*iter).stroke_color);
+
+        g_inner_ptr->children.push_back(new point_element(legend_x_start + 25,
+                                        legend_y_start + 36 + i*25));
+
+        g_inner_ptr->children.push_back(new text_element(legend_x_start + 40,
+                                        legend_y_start + 42 + i*25, (*iter).text));
+    }
+}
+
+svg_plot& svg_plot::write()
+{
+    // Hold off drawing the legend until the very end.. it's
+    // easier to draw the size that it needs at the end than
+    // it is to 
+    // Don't bother with re-adding things if we don't need to
+    if(legend_on)
+    {
+        _draw_legend();
+    }
+
+    svg::write();
+
+    return (svg_plot&)*this;
+}
+
+template <class iter>
+void plot_range(svg_plot& _cont, iter _begin, iter _end, std::string _str)
+{
+    vector<double> vect(_begin, _end);
+
+    _cont.plot_range(vect.begin(), vect.end(), _str);
+}
+
+template <class iter>
+void plot_range(svg_plot& _cont, iter _begin, iter _end, std::string _str,
+ 	                    svg_color_constant _col)
+{
+    vector<double> vect(_begin, _end);
+
+    _cont.plot_range(vect.begin(), vect.end(), _str, _col);
 }
 
 }
Added: sandbox/SOC/2007/visualization/boost/svg_plot/svg_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_test.cpp	2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -0,0 +1,53 @@
+#include <vector>
+#include <deque>
+#include <cmath>
+
+#include "svg_plot.hpp"
+
+using namespace boost::svg;
+using namespace std;
+
+double f(double x)
+{
+    return (x*x)/2.;
+}
+
+double g(double x)
+{
+    return -2 + x;
+}
+
+int main()
+{
+  double start = 0, finish = 10;
+
+    vector<double> data1;
+    deque<double> data2;
+
+
+    double inter = 3.1415926535 / 4.;
+    
+    for(double i = start; i <= finish; i += inter)
+        data1.push_back(f(i));
+
+    for(double i=start; i <= finish; i += inter)
+        data2.push_back(g(i));
+
+    svg_plot my_plot("D:\\1D_legend_demo.svg");
+
+    my_plot.image_size(500, 350).x_scale(-2, 10);
+    
+    my_plot.draw_axis().show_legend();
+
+    my_plot.set_background_color(lightgray)
+           .set_legend_background_color(whitesmoke);
+
+    
+    plot_range(my_plot, data2.begin(), data2.end(), "Lions", blue);
+    plot_range(my_plot, data1.begin(), data1.end(), "Tigers", limegreen);
+    
+    my_plot.write();
+
+    return 0;
+}
+