#include "color_legend.h"
#include "graph_drawer.h"
#include "warning.h"
#include "plottable.h"
#include "frame.h"
#include "global.h"
#include <limits>
namespace blop
{
using namespace std;
length color_legend::default_sample_width_ = 3*length(length::base_id_t(terminal::EX));
void color_legend::default_sample_width(const length &l) {default_sample_width_ = l;}
color_legend &color_legend::mknew()
{
color_legend *l = new color_legend;
l->autodel(true);
pad::current().add(l);
l->right(1.0);
return *l;
}
void color_legend::init_()
{
name("color_legend");
box::bottom(0.0);
box::top(1.0);
box::left(0.0);
sample_width_ = default_sample_width_;
sample_right_ = !left()+!sample_width_;
tic_left_ = !sample_right_ - length(length::base_id_t(terminal::EX));
sep_ = EX;
ticlabel_pos_ = !sample_right_+!sep_;
box::width(!sample_width_ + !sep_ + !ticlabel_width_);
}
color_legend::color_legend()
{
init_();
}
color_legend::color_legend(graphd_colorscale *d)
{
init_();
owners_.push_back(d);
}
color_legend::color_legend(const color_legend &rhs)
{
}
const color_legend &color_legend::operator= (const color_legend &rhs)
{
return rhs;
}
void color_legend::remove_owner(graphd_colorscale *o)
{
for(unsigned int i=0; i<owners_.size(); ++i)
{
if(owners_[i] == o)
{
owners_.erase(owners_.begin()+i);
--i;
}
}
}
double color_legend::min() const
{
return min_;
}
double color_legend::max() const
{
return max_;
}
void color_legend::clear_tics()
{
colortics_.clear();
}
void color_legend::calculate_tics()
{
if(global::debug>0) cout<<"[blop] [color_legend] calculate_tics starts..."<<endl;
if(!colortics_.empty())
{
if(global::debug>0)
{
cout<<"[blop] [color_legend] tics have already been calculated"<<endl;
cout<<"[blop] [color_legend] calculate_tics finished."<<endl;
}
return;
}
min_ = numeric_limits<double>::max();
max_ = -numeric_limits<double>::max();
bool cmin_fixed = false;
bool cmax_fixed = false;
bool clogscale = false;
for(unsigned int i=0; i<owners_.size(); ++i)
{
if(!cmin_fixed && owners_[i]->color_min()<min_)
{
min_ = owners_[i]->color_min();
}
if(owners_[i]->color_min_fixed()) cmin_fixed = true;
if(!cmax_fixed && owners_[i]->color_max()>max_)
{
max_ = owners_[i]->color_max();
}
if(owners_[i]->color_max_fixed()) cmax_fixed = true;
if(owners_[i]->color_logscale()) clogscale = true;
}
if(min_ == unset || !finite(min_) || max_ == unset || !finite(max_))
{
if(owners_.size()<=1) warning::print(var("Problem with color-range [") & min_ & var(" .. ") & max_ & var("]"), "color_legend::calculate_tics()");
if(min_ == unset || !finite(min_))
{
if(max_!=unset && finite(max_)) min_ = max_-10;
else min_ = 0;
}
if(max_ == unset || !finite(max_))
{
if(min_!=unset && finite(min_)) max_ = min_+10;
else max_ = 10;
}
}
vector<pair<double,double> > cuts_dummy;
double delta = unset;
tic scaletic;
scaletic.value(unset);
blop::calculate_tics(min_, cmin_fixed,
max_, cmax_fixed,
delta, false,
unset, unset,
scaletic,
1.0,
cuts_dummy,
clogscale,
clogscale,
true,
colortics_);
ticlabel_width_ = maxwidth(colortics_);
if(global::debug>0) cout<<"[blop] [color_legend] calculate_tics finished."<<endl;
}
color_legend &color_legend::title(const var &t)
{
title_.text(t).angle(90*unit::deg)
.left(!ticlabel_pos_+!ticlabel_width_+!sep_)
.ycenter(!ycenter());
if(t.str() != "")
{
box::width(!sample_width_ + 2*!sep_ + !ticlabel_width_ + !title_.width());
}
else
{
box::width(!sample_width_ + !sep_ + !ticlabel_width_);
}
return *this;
}
const var &color_legend::title() const
{
return title_.text();
}
color_legend &color_legend::sample_width(const length &l)
{
sample_width_ = l;
return *this;
}
void color_legend::print(terminal *term)
{
if(print_me_<2) return;
if(owners_.empty())
{
warning::print("No owners of this color_legend",
"color_legend::print(terminal*)");
return;
}
term->open_layer(layer_);
int csamples = 0;
bool clogscale=false;
for(unsigned int i=0; i<owners_.size(); ++i)
{
if(owners_[i]->color_samples()>csamples) csamples=owners_[i]->color_samples();
if(owners_[i]->color_logscale()) clogscale = true;
}
vector<terminal::coord> c;
for(int i=0; i<csamples; ++i)
{
c.clear();
const double pos = double(i)/csamples;
const double val = (clogscale==false ? min_ + (max_-min_)*pos :
::pow(10,pos*(::log10(max_)-
::log10(min_))+ ::log10(min_)) );
c.push_back(terminal::coord(left().termspecific_id(),
terminal::id((double)i/csamples,2)));
c.push_back(terminal::coord(sample_right_.termspecific_id(),
terminal::id((double)i/csamples,2)));
c.push_back(terminal::coord(sample_right_.termspecific_id(),
terminal::id(double(i+1)/csamples,2)));
c.push_back(terminal::coord(left().termspecific_id(),
terminal::id(double(i+1)/csamples,2)));
c.push_back(terminal::coord(left().termspecific_id(),
terminal::id(double(i)/csamples,2)));
term->set_color(owners_[0]->map_color(val,min_,max_));
term->fill_polygon(c);
}
term->set_color(black);
term->set_linewidth(LW.termspecific_id());
c.clear();
c.push_back(terminal::coord(left().termspecific_id(), terminal::id(0,2)));
c.push_back(terminal::coord(sample_right_.termspecific_id(),terminal::id(0,2)));
c.push_back(terminal::coord(sample_right_.termspecific_id(),terminal::id(1,2)));
c.push_back(terminal::coord(left().termspecific_id(),terminal::id(1,2)));
c.push_back(terminal::coord(left().termspecific_id(),terminal::id(0,2)));
term->draw_lines(c);
for(unsigned int i=0; i<colortics_.size(); ++i)
{
double pos = 0;
if(!clogscale) pos = (colortics_[i].value()-min_)/(max_-min_);
else pos =
(::log10(colortics_[i].value())-::log10(min_))/
(::log10(max_)- ::log10(min_));
term->draw_text(terminal::coord(ticlabel_pos_.termspecific_id(),
terminal::id(pos, 2)),
colortics_[i].label().str(),
sym::left, sym::center, 0);
term->draw_line(terminal::coord(tic_left_.termspecific_id(),
terminal::id(pos, 2)),
terminal::coord(sample_right_.termspecific_id(),
terminal::id(pos, 2)));
}
title_.print(term);
term->close_layer(layer_);
}
void color_legend::prepare_for_draw()
{
if(print_me_<1) return;
box::prepare_for_draw();
sample_right_.register_me();
tic_left_.register_me();
ticlabel_pos_.register_me();
title_.prepare_for_draw();
}
color_legend::~color_legend()
{
for(unsigned int i=0; i<owners_.size(); ++i)
{
owners_[i]->colorlegend_ = 0;
}
}
}