00001 #include "bsvg_plot.h"
00002
00003
00004
00005
00006
00007 #include <bxml/bxml_find.h>
00008 #include <bxml/bsvg/bsvg_element.h>
00009 #include <vcl_iostream.h>
00010 #include <vcl_sstream.h>
00011
00012 void bsvg_plot::add_axes(float x_min, float x_max, float y_min, float y_max, float stroke_width)
00013 {
00014 float height_y = y_max - y_min;
00015
00016 h2_y = h_ - 4*margin_;
00017 scale_factor_ = h2_y/height_y;
00018
00019 axes_orig_x_ = 2*margin_;
00020 axes_orig_y_ = 2*margin_+h2_y;
00021
00022 bsvg_line* line_y = new bsvg_line(axes_orig_x_, axes_orig_y_, axes_orig_x_, axes_orig_y_-h2_y-margin_);
00023 line_y->set_stroke_color("black");
00024 line_y->set_stroke_width(stroke_width);
00025
00026 float height_x = x_max - x_min;
00027
00028 h2_x = height_x*scale_factor_;
00029
00030 bsvg_line* line_x = new bsvg_line(axes_orig_x_, axes_orig_y_, axes_orig_x_+h2_x+margin_, axes_orig_y_);
00031 line_x->set_stroke_color("black");
00032 line_x->set_stroke_width(stroke_width);
00033
00034 this->add_element(line_y);
00035 this->add_element(line_x);
00036
00037
00038 vcl_stringstream ss; ss << x_min;
00039 bsvg_text* t = new bsvg_text(ss.str());
00040 t->set_location(axes_orig_x_, axes_orig_y_+margin_);
00041 t->set_font_size(font_size_);
00042 this->add_element(t);
00043
00044
00045 vcl_stringstream ssy; ssy << y_min;
00046 bsvg_text* ty = new bsvg_text(ssy.str());
00047 ty->set_location(axes_orig_x_-margin_, axes_orig_y_);
00048 ty->set_font_size(font_size_);
00049 this->add_element(ty);
00050
00051
00052 vcl_stringstream ssx; ssx << x_max;
00053 bsvg_text* txm = new bsvg_text(ssx.str());
00054 txm->set_location(axes_orig_x_+h2_x, axes_orig_y_+margin_);
00055 txm->set_font_size(font_size_);
00056 this->add_element(txm);
00057
00058
00059 bsvg_line* line_xm = new bsvg_line(axes_orig_x_ + h2_x, axes_orig_y_, axes_orig_x_ + h2_x, axes_orig_y_+(margin_/4.0f));
00060 line_xm->set_stroke_color("black");
00061 line_xm->set_stroke_width(stroke_width);
00062 this->add_element(line_xm);
00063
00064
00065 vcl_stringstream ssym; ssym << y_max;
00066 bsvg_text* tym = new bsvg_text(ssym.str());
00067 tym->set_location(axes_orig_x_-margin_, axes_orig_y_-h2_y);
00068 tym->set_font_size(font_size_);
00069 this->add_element(tym);
00070
00071
00072 bsvg_line* line_ym = new bsvg_line(axes_orig_x_-(margin_/4.0f), axes_orig_y_-h2_y, axes_orig_x_, axes_orig_y_-h2_y);
00073 line_ym->set_stroke_color("black");
00074 line_ym->set_stroke_width(stroke_width);
00075 this->add_element(line_ym);
00076
00077
00078 bsvg_arrow_head* a1 = new bsvg_arrow_head(axes_orig_x_+h2_x+margin_, axes_orig_y_, 10.0f);
00079 a1->set_stroke_width(stroke_width);
00080 a1->set_stroke_color("black");
00081 this->add_element(a1);
00082
00083
00084 bsvg_arrow_head* a2 = new bsvg_arrow_head(axes_orig_x_, axes_orig_y_-h2_y-margin_, 10.0f);
00085 a2->set_stroke_width(stroke_width);
00086 a2->set_rotation(-90);
00087 a2->set_stroke_color("black");
00088 this->add_element(a2);
00089 }
00090
00091 void bsvg_plot::add_title(const vcl_string& t)
00092 {
00093 bsvg_text* title = new bsvg_text(t);
00094 float w = float(font_size_*t.size());
00095 title->set_location((this->w_-margin_)/2.0f - w/2, margin_);
00096
00097 title->set_font_size(font_size_);
00098 this->add_element(title);
00099 }
00100
00101
00102 void bsvg_plot::add_x_increments(float x_inc, float stroke_width)
00103 {
00104 float x_inc_scaled = scale_factor_*x_inc;
00105 bsvg_group* g = new bsvg_group();
00106 g->set_stroke_color("black");
00107 g->set_stroke_width(stroke_width);
00108 g->set_stroke_opacity(0.5);
00109
00110 float end = axes_orig_x_ + h2_x;
00111 for (float x = axes_orig_x_ + x_inc_scaled; x <= end; x += x_inc_scaled) {
00112 bsvg_line* line_x = new bsvg_line(x, axes_orig_y_, x, axes_orig_y_-h2_y);
00113 g->add_element(line_x);
00114 }
00115 this->add_element(g);
00116 }
00117
00118
00119 void bsvg_plot::add_y_increments(float y_inc, float stroke_width)
00120 {
00121 float y_inc_scaled = scale_factor_*y_inc;
00122 bsvg_group* g = new bsvg_group();
00123 g->set_stroke_color("black");
00124 g->set_stroke_width(stroke_width);
00125 g->set_stroke_opacity(0.5);
00126
00127 float end = axes_orig_y_ - h2_y;
00128 for (float y = axes_orig_y_ - y_inc_scaled; y >= end; y -= y_inc_scaled) {
00129 bsvg_line* line_y = new bsvg_line(axes_orig_x_, y, axes_orig_x_+h2_x, y);
00130 g->add_element(line_y);
00131 }
00132 this->add_element(g);
00133 }
00134
00135 void bsvg_plot::add_line(const vcl_vector<float>& xs, const vcl_vector<float>& ys, const vcl_string& color, float stroke_width)
00136 {
00137
00138 if (xs.size() != ys.size()) {
00139 vcl_cout << " Error: bsvg_plot::add_line() - input vectors are not of the same size\n";
00140 return;
00141 }
00142 vcl_vector<float> xs_copy(xs);
00143 vcl_vector<float> ys_copy(ys);
00144 for (unsigned i = 0; i < xs.size(); i++) {
00145 xs_copy[i] = xs_copy[i]*scale_factor_ + axes_orig_x_;
00146 ys_copy[i] = axes_orig_y_ - ys_copy[i]*scale_factor_;
00147 }
00148
00149 bsvg_polyline *pl = new bsvg_polyline(xs_copy, ys_copy);
00150 pl->set_stroke_color(color);
00151 pl->set_fill_color("none");
00152 pl->set_stroke_width(stroke_width);
00153
00154 this->add_element(pl);
00155 }
00156
00157 bsvg_group* bsvg_plot::add_bars_helper(const vcl_vector<float>& heights, const vcl_string& color)
00158 {
00159 bsvg_group* g = new bsvg_group();
00160 g->set_fill_color(color);
00161
00162 int n = heights.size();
00163
00164 float bar_w = h2_x / float(n + float(n + 1)/3.0f);
00165 float x = axes_orig_x_ + bar_w/3.0f;
00166 for (int i = 0; i < n; i++) {
00167 float h = heights[i]*scale_factor_;
00168 bsvg_rectangle *r = new bsvg_rectangle(x, axes_orig_y_-h, bar_w, h);
00169 g->add_element(r);
00170 x += bar_w/3 + bar_w;
00171 }
00172 return g;
00173 }
00174
00175 bsvg_group* bsvg_plot::add_x_labels_helper(const vcl_vector<vcl_string>& x_labels, const vcl_string& color, bool vertical_labels)
00176 {
00177 bsvg_group* g = new bsvg_group();
00178 g->set_fill_color(color);
00179
00180 int n = x_labels.size();
00181
00182 float bar_w = h2_x / float(n + float(n + 1)/3.0f);
00183 float x = axes_orig_x_ + bar_w/2.0f + bar_w/3.0f;
00184 for (int i = 0; i < n; i++) {
00185 bsvg_text *t = new bsvg_text(x_labels[i]);
00186 t->set_font_size(font_size_);
00187 t->set_location(x, axes_orig_y_+margin_);
00188 if (vertical_labels)
00189 t->set_rotation(90);
00190 g->add_element(t);
00191 x += bar_w/3.0f + bar_w;
00192 }
00193 return g;
00194 }
00195
00196
00197 void bsvg_plot::add_bars(const vcl_vector<float>& heights, const vcl_string& color)
00198 {
00199 bsvg_group* g = add_bars_helper(heights, color);
00200 this->add_element(g);
00201 }
00202
00203 void bsvg_plot::add_bars(const vcl_vector<float>& heights, const vcl_vector<vcl_string>& x_labels, bool vertical_labels, const vcl_string& color)
00204 {
00205 bsvg_group* g = add_bars_helper(heights, color);
00206 this->add_element(g);
00207 bsvg_group* tg = add_x_labels_helper(x_labels, color, vertical_labels);
00208 this->add_element(tg);
00209 }
00210
00211 void bsvg_plot::add_bars(const vcl_vector<float>& heights, const vcl_vector<float>& x_labels, bool vertical_labels, const vcl_string& color)
00212 {
00213 bsvg_group* g = add_bars_helper(heights, color);
00214 this->add_element(g);
00215 vcl_vector<vcl_string> x_ls;
00216 for (unsigned i = 0; i < x_labels.size(); i++) {
00217 vcl_stringstream ss; ss << x_labels[i];
00218 x_ls.push_back(ss.str());
00219 }
00220 bsvg_group* tg = add_x_labels_helper(x_ls, color, vertical_labels);
00221 this->add_element(tg);
00222 }
00223
00224
00225 int number_of_bars_helper(bxml_data_sptr d)
00226 {
00227 bxml_element* r_elm = dynamic_cast<bxml_element*>(d.ptr());
00228 if (!r_elm)
00229 return 0;
00230
00231 int cnt = 0;
00232 for (bxml_element::const_data_iterator it = r_elm->data_begin(); it != r_elm->data_end(); it++) {
00233 if ((*it)->type() != bxml_element::ELEMENT)
00234 continue;
00235 bxml_element* it_elm = dynamic_cast<bxml_element*>((*it).ptr());
00236 if (it_elm->name() == "rect")
00237 cnt++;
00238 else if (it_elm->name() == "g") {
00239 cnt += number_of_bars_helper(*it);
00240 }
00241 }
00242 return cnt;
00243 }
00244
00245 int bsvg_plot::number_of_bars()
00246 {
00247
00248 bxml_element query("svg");
00249 bxml_data_sptr root = bxml_find_by_name(this->root_element(), query);
00250 if (!root)
00251 return -1;
00252 return number_of_bars_helper(root);
00253 }
00254
00255
00256
00257
00258 int bsvg_plot::add_bar(const float height, const vcl_string& color)
00259 {
00260
00261 int cnt = this->number_of_bars();
00262 if (cnt < 0) {
00263 vcl_cerr << "In bsvg_plot::add_bar() -- problems with the plot document!\n";
00264 return -1;
00265 }
00266 float x = axes_orig_x_ + margin_/3.0f;
00267 x += cnt*(margin_/3.0f + margin_);
00268 float h = height*scale_factor_;
00269 bsvg_rectangle *r = new bsvg_rectangle(x, axes_orig_y_-h, margin_, h);
00270 r->set_fill_color(color);
00271 this->add_element(r);
00272 return cnt;
00273 }
00274
00275 int bsvg_plot::add_bar(const float height, const vcl_string& label, bool vertical_label, const vcl_string& color)
00276 {
00277 int cnt = add_bar(height, color);
00278 if (cnt < 0) {
00279 vcl_cerr << "In bsvg_plot::add_bar() -- problems with the plot document!\n";
00280 return -1;
00281 }
00282 float x = axes_orig_x_ + margin_/2.0f + margin_/3.0f;
00283 x += cnt*(margin_/3.0f + margin_);
00284 bsvg_text *t = new bsvg_text(label);
00285 t->set_font_size(font_size_);
00286 t->set_location(x, axes_orig_y_+margin_);
00287 if (vertical_label)
00288 t->set_rotation(90);
00289 this->add_element(t);
00290 return cnt;
00291 }
00292
00293 int bsvg_plot::add_bar(const float height, const float x_label, bool vertical_label, const vcl_string& color)
00294 {
00295 vcl_stringstream ss; ss << x_label;
00296 return add_bar(height, ss.str(), vertical_label, color);
00297 }
00298
00299
00300 void bsvg_plot::add_splice(float center_x, float center_y, float radius, float start_angle, float end_angle, const vcl_string& color)
00301 {
00302 bsvg_splice* splice_g = new bsvg_splice(center_x, center_y, radius, start_angle, end_angle);
00303 splice_g->set_fill_color(color);
00304 splice_g->set_stroke_color("black");
00305 this->add_element(splice_g);
00306 }
00307
00308 void bsvg_plot::add_splice(float center_x, float center_y, float radius, float start_angle, float end_angle, unsigned red, unsigned green, unsigned blue)
00309 {
00310 bsvg_splice* splice_g = new bsvg_splice(center_x, center_y, radius, start_angle, end_angle);
00311 splice_g->set_fill_color(red, green, blue);
00312 splice_g->set_stroke_color("black");
00313 this->add_element(splice_g);
00314 }
00315