|
Boost-Commit : |
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.
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk