g4tools  5.4.0
axis
Go to the documentation of this file.
1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
2 // See the file tools.license for terms.
3 
4 #ifndef tools_sg_axis
5 #define tools_sg_axis
6 
7 #include "node"
8 #include "line_style"
9 #include "text_style"
10 #include "enums"
11 #include "noderef"
12 #include "vertices"
13 #include "draw_style"
14 #include "rgba"
15 #include "normal"
16 #include "separator"
17 #include "tools"
18 #include "nodekit"
19 
20 #include "../lina/vec3f"
21 #include "../mnmx"
22 #include "../hplot"
23 
24 #include <cstdio> //sprintf
25 #include <cstring> //strcpy
26 
27 namespace tools {
28 namespace sg {
29 
30 class axis : public node {
31 public:
33 public:
38  sf_string modeling; //hippo, hplot
40  // If modeling is hippo or hplot,
41  // labels_enforced true let labels be an input field.
45 
46  // NOTE : if modeling is none,the below are input fields.
47  // If modeling is hippo or hplot, the below are output field
48  // (filled by compute_ticks).
50  mf_string labels; //output
51  mf<float> values; //output //in [minimumValue,maximumValue]
52  mf<float> coords; //output //in [0,width]
54  sf<int> magnitude; //output
55 
60 
63 
65  sf<float> labels_gap; //in percent of width.
66 
67  // time labels only in hplot modeling for the moment.
72 public:
73  virtual const desc_fields& node_desc_fields() const {
75  static const desc_fields s_v(parent::node_desc_fields(),27, //WARNING : take care of count.
99 
104  );
105  return s_v;
106  }
107  virtual bool touched() {
108  if(parent::touched()) return true;
109  if(line_style().touched()) return true;
110  if(ticks_style().touched()) return true;
111  if(labels_style().touched()) return true;
112  if(mag_style().touched()) return true;
113  if(title_style().touched()) return true;
114  return false;
115  }
116  virtual void reset_touched() {
117  parent::reset_touched();
123  }
124 private:
125  void add_fields(){
126  // if adding a field, look for reset_style() and set_from_style()
127  add_field(&width);
132  add_field(&is_log);
134  add_field(&tick_up);
137  add_field(&labels);
138  add_field(&values);
139  add_field(&coords);
142  add_field(&title);
150 
155  }
156  void init_sg(){
157  m_group.add(new noderef(m_line_sep));
158  m_group.add(new noderef(m_ticks_sep));
159  m_group.add(new noderef(m_labels_sep));
160  m_group.add(new noderef(m_mag_sep));
161  m_group.add(new noderef(m_title_sep));
162  }
163 public:
164  virtual void render(render_action& a_action) {
165  if(touched()) {
166  update_sg(a_action.out());
167  reset_touched();
168  }
169  m_group.render(a_action);
170  }
171  virtual void pick(pick_action& a_action) {
172  if(touched()) {
173  update_sg(a_action.out());
174  reset_touched();
175  }
176  //m_group.pick(a_action);
177  nodekit_pick(a_action,m_group,this);
178  }
179  virtual void search(search_action& a_action) {
180  if(touched()) {
181  update_sg(a_action.out());
182  reset_touched();
183  }
184  parent::search(a_action);
185  if(a_action.done()) return;
186  m_group.search(a_action);
187  }
188  virtual void bbox(bbox_action& a_action) {
189  if(touched()) {
190  update_sg(a_action.out());
191  reset_touched();
192  }
193  m_group.bbox(a_action);
194  }
195 
196  virtual bool write(write_action& a_action) {
197  //FIXME : this method should not be needed !
198  // But m_[line,ticks,labels,mag,title]_style not written !
199 
200  if(touched()) {
201  update_sg(a_action.out());
202  reset_touched();
203  }
204  //if(!write_fields(a_action)) return false;
205  return m_group.write(a_action);
206  }
207 public:
208  axis(const base_freetype& a_ttf)
209  :parent()
210  ,width(1)
211  ,minimum_value(0)
212  ,maximum_value(1)
213  ,divisions(510)
215  ,is_log(false)
216  ,labels_enforced(false)
217  ,tick_up(true)
218  ,tick_length(0)
219 
220  ,tick_number(0)
221  ,magnitude(0)
222 
223  ,title("")
224  ,title_to_axis(0) //inited below
225  ,title_height(0) //inited below
227 
228  ,label_to_axis(0) //inited below
229  ,label_height(0) //inited below
230 
232  ,labels_gap(0.02f)
233 
234  ,time_labels(false)
235  ,time_format("%H:%M:%S")
236  ,time_offset(0) //UTC_time_1970_01_01__00_00_00
237  ,time_offset_is_GMT(false)
238 
239  ,m_ttf(a_ttf)
240  {
241  add_fields();
242 
243  init_sg();
244 
245  reset_style(true);
246  }
247  virtual ~axis(){}
248 public:
249  axis(const axis& a_from)
250  :parent(a_from)
251  ,width(a_from.width)
254  ,divisions(a_from.divisions)
255  ,modeling(a_from.modeling)
256  ,is_log(a_from.is_log)
258  ,tick_up(a_from.tick_up)
259  ,tick_length(a_from.tick_length)
260 
261  ,tick_number(a_from.tick_number)
262  ,magnitude(a_from.magnitude)
263 
264  ,title(a_from.title)
266  ,title_height(a_from.title_height)
267  ,title_hjust(a_from.title_hjust)
268 
270  ,label_height(a_from.label_height)
271 
273  ,labels_gap(a_from.labels_gap)
274 
275  ,time_labels(a_from.time_labels)
276  ,time_format(a_from.time_format)
277  ,time_offset(a_from.time_offset)
279 
280  ,m_ttf(a_from.m_ttf)
281 
282  ,m_line_style(a_from.m_line_style)
285  ,m_mag_style(a_from.m_mag_style)
287  {
288  add_fields();
289  init_sg();
290  }
291  axis& operator=(const axis& a_from){
292  parent::operator=(a_from);
293 
294  width = a_from.width;
295  minimum_value = a_from.minimum_value;
296  maximum_value = a_from.maximum_value;
297  divisions = a_from.divisions;
298  modeling = a_from.modeling;
299  is_log = a_from.is_log;
301  tick_up = a_from.tick_up;
302  tick_length = a_from.tick_length;
303 
304  tick_number = a_from.tick_number;
305  magnitude = a_from.magnitude;
306 
307  title = a_from.title;
308  title_to_axis = a_from.title_to_axis;
309  title_height = a_from.title_height;
310  title_hjust = a_from.title_hjust;
311 
312  label_to_axis = a_from.label_to_axis;
313  label_height = a_from.label_height;
314 
316  labels_gap = a_from.labels_gap;
317 
318  time_labels = a_from.time_labels;
319  time_format = a_from.time_format;
320  time_offset = a_from.time_offset;
322 
323  m_line_style = a_from.m_line_style;
324  m_ticks_style = a_from.m_ticks_style;
326  m_mag_style = a_from.m_mag_style;
327  m_title_style = a_from.m_title_style;
328 
329  return *this;
330  }
331 public:
337 
338  void set_color(const colorf& a_color){
339  m_line_style.color = a_color;
340  m_ticks_style.color = a_color;
341  m_labels_style.color = a_color;
342  m_title_style.color = a_color;
343  m_mag_style.color = a_color;
344  }
345 public:
346  void update_sg(std::ostream& a_out) {
347  //a_out << "debug : tools::axis::update_sg :" << std::endl;
348 
349  if(width<=0) {
350  m_line_sep.clear();
351  m_ticks_sep.clear();
353  m_mag_sep.clear();
354  m_title_sep.clear();
355  return;
356  }
357 
358  // line scene graph :
359  m_line_sep.clear();
360  if(m_line_style.visible) {
361  rgba* mat = new rgba();
362  mat->color = m_line_style.color;
363  m_line_sep.add(mat);
364 
365  draw_style* ds = new draw_style;
366  ds->style = draw_lines;
369  m_line_sep.add(ds);
370 
371  vertices* vtxs = new vertices;
372  vtxs->mode = gl::line_strip();
373  vtxs->add(0,0,0);
374  vtxs->add(width,0,0);
375  m_line_sep.add(vtxs);
376  }
377 
378  // ticks scene graph :
380  } else if(modeling==tick_modeling_hplot()) {
381  compute_ticks_HPLOT(a_out);
382  } else {
384  }
385 
386  m_ticks_sep.clear();
387  if(m_ticks_style.visible) {
388 
389  vertices* vtxs = new vertices;
390  vtxs->mode = gl::lines();
391 
393 
394  size_t num = m_sub_ticks.size()/4;
395  size_t pos = 0;
396  for(size_t index=0;index<num;index++) {
397  float bx = m_sub_ticks[pos];pos++;
398  float by = m_sub_ticks[pos];pos++;
399  float ex = m_sub_ticks[pos];pos++;
400  float ey = m_sub_ticks[pos];pos++;
401  if(tick_up) {
402  vtxs->add(bx,by,0);
403  vtxs->add(ex,ey,0);
404  } else {
405  vtxs->add(bx,-by,0);
406  vtxs->add(ex,-ey,0);
407  }
408  }
409 
410  } else {
411 
412  float yy = tick_up ? tick_length.value():-tick_length.value();
413  for(unsigned int index=0;index<tick_number;index++) {
414  float xx = coords.values()[index];
415  vtxs->add(xx,0,0);
416  vtxs->add(xx,yy,0);
417  }
418  }
419 
420  if(vtxs->number()) {
421 
422  rgba* mat = new rgba();
423  mat->color = m_ticks_style.color;
425 
426  draw_style* ds = new draw_style;
427  ds->style = draw_lines;
430  m_ticks_sep.add(ds);
431 
432  m_ticks_sep.add(vtxs);
433  } else {
434  delete vtxs;
435  }
436 
437  }
438 
439  // labels scene graph :
442  m_labels_seps.clear();
443  m_labels_xs.clear();
444  m_labels_mtxs.clear();
445 
446  rgba* mat = new rgba();
447  mat->color = m_labels_style.color;
449 
450  float text_size = label_height*m_labels_style.scale;
451  std::string font = m_labels_style.font.value();
452 
453  if(font==font_hershey()) {
454  draw_style* ds = new draw_style;
455  ds->style = draw_lines;
458  m_labels_sep.add(ds);
459  } else {
460  m_labels_sep.add(new normal);
461  }
462 
465  X.normalize();
466  Y.normalize();
467  vec3f Z;X.cross(Y,Z);
468  Z.cross(X,Y);
469  mat4f scale_rot(X.v0(),Y.v0(),Z.v0(),0, //first row
470  X.v1(),Y.v1(),Z.v1(),0,
471  X.v2(),Y.v2(),Z.v2(),0,
472  0,0,0,1);
473  scale_rot.mul_scale(text_size,text_size,1);
474 
475  bool bin_center = (m_labels_style.options.value()=="center"?true:false); //gopaw.
476 
477  vec3f vec;float xx;
478  {unsigned int number = tick_number;
479  for(unsigned int index=0;index<number;index++) {
480 
481  if(bin_center) { //label at the center of the bin :
482  if(index==(number-1)) continue;
483  xx = 0.5f*(coords.values()[index]+coords.values()[index+1]);
484  } else { // label on tick :
485  xx = coords.values()[index];
486  }
487 
488  vec.set_value(xx,-label_to_axis,0);
490 
491  separator* sep = new separator;
493 
494  matrix* _tsf =
496  font,
500  labels.values()[index],
501  vec[0],vec[1],vec[2],
502  scale_rot,
505  m_ttf);
506  if(_tsf) {
507  m_labels_seps.push_back(sep);
508  m_labels_xs.push_back(xx);
509  m_labels_mtxs.push_back(_tsf);
510  }
511  }}
512 
514  m_labels_seps.clear();
515  m_labels_xs.clear();
516  m_labels_mtxs.clear();
517  }
518 
519  m_mag_sep.clear();
520  if( magnitude.value() && m_mag_style.visible) {
521  rgba* mat = new rgba();
522  mat->color = m_mag_style.color;
523  m_mag_sep.add(mat);
524 
525  char string[64];
526  if(magnitude>=0)
527  snpf(string,sizeof(string),"x10+%d",magnitude.value());
528  else
529  snpf(string,sizeof(string),"x10-%d",::abs(magnitude));
530 
531  vec3f vec(width*1.03f,0,0);
532  vec += m_mag_style.translation.value();
533 
534  float text_size = label_height*0.8f * m_mag_style.scale;
535  std::string font = m_mag_style.font.value();
536 
537  if(font==font_hershey()) {
538  draw_style* ds = new draw_style;
539  ds->style = draw_lines;
542  m_mag_sep.add(ds);
543  }
544 
546  font,
550  string,
551  vec[0],vec[1],vec[2],
554  text_size,
557  m_ttf);
558  }
559 
560  // title scene graph :if(update_title) {
561  m_title_sep.clear();
562  if(title.value().size() && m_title_style.visible) {
563  rgba* mat = new rgba();
564  mat->color = m_title_style.color;
566 
567  float text_size = title_height*m_title_style.scale;
568  std::string font = m_title_style.font.value();
569 
570  if(font==font_hershey()) {
571  draw_style* ds = new draw_style;
572  ds->style = draw_lines;
575  m_title_sep.add(ds);
576  } else {
577  m_title_sep.add(new normal);
578  }
579 
580  float xx = 0; //left
581  if(title_hjust==center) {
582  xx = width/2;
583  } else if(title_hjust==right) {
584  xx = width;
585  }
586 
587  vec3f vec(xx,-title_to_axis,0);
589 
590  //std::cout << "debug : axis : update_title :"
591  // << " pos : " << vec[0] << " " << vec[1] << " " << vec[2]
592  // << std::endl;
593 
595  font,
599  title.value(),
600  vec[0],vec[1],vec[2],
603  text_size,
606  m_ttf);
607  }
608 
609  }
610 
611 public: //style
612  void reset_style(bool a_geom = false) {
613  //reset fields that are considered as part of the style.
614 
616  // we do not touch :
618  //width
619  //minimum_value
620  //maximum_value
621  //labels_enforced
622  //tick_number
623  //magnitude
624  //time_labels
625  //time_format
626  //time_offset
627  //time_offset_is_GMT
628  //labels
629  //values
630  //coords
631  //sub_coords
632 
634  divisions = 510;
636  tick_up = true;
637  is_log = false;
638  title.value().clear();
639 
641  labels_gap = 0.02f;
642 
643  if(a_geom) {
645  // Take PAW default :
646  float YSIZ = 20; //page height
647  float YMGL = 2; //low y margin (to data frame).
648  float YMGU = 2; //up y margin (to data frame).
649  float VSIZ = 0.28F; //tick label character size.
650  float YVAL = 0.4F; //y distance of x tick label to data frame.
651  float XTIC = 0.3F; //y length of X axis ticks.
652  float YLAB = 0.8F; //y distance of x title to data frame.
653  float ASIZ = 0.28F; // axis title (label) character size.
654 
655  float hData = YSIZ-YMGL-YMGU;
656 
657  // To map data space to width :
658  float to1 = width/hData;
659 
660  float vsiz = VSIZ * to1; //0.0175F
661  float yval = YVAL * to1; //0.025F
662  float xtic = XTIC * to1; //0.01875F
663  float ylab = YLAB * to1; //0.05F
664  float asiz = ASIZ * to1; //0.0175F
665 
666  //sf
667  tick_length = xtic;
668  label_to_axis = yval;
669  label_height = vsiz;
670 
671  // The axis title is the PAW axis label.
672  // It is right justified at the end of axis
673  // (at end right for XY_X, at end top for XY_Y)
674  title_to_axis = ylab;
675  title_height = asiz;
676  }
677 
678  title_hjust = right;
679 
681  // setup styles :
687 
688  m_line_style.color = colorf_black();
689  m_ticks_style.color = colorf_black();
690 
691  m_labels_style.color = colorf_black();
694 
695  m_mag_style.color = colorf_black();
698 
699  m_title_style.color = colorf_black();
702  }
703 
704  typedef std::pair<std::string,std::string> style_item_t;
705  typedef std::vector<style_item_t> style_t;
706  bool set_from_style(std::ostream& a_out,const style_t& a_style) {
707  style_t::const_iterator it;
708  for(it=a_style.begin();it!=a_style.end();++it) {
709  const std::string& key = (*it).first;
710  const std::string& sv = (*it).second;
711  //::printf("debug : axis::set_from_style : key \"%s\" \"%s\"\n",key.c_str(),sv.c_str());
712  //if(key=="reset") {}
713 
714  // not part of style :
715  //width
716  //minimum_value
717  //maximum_value
718  //labels_enforced
719  //tick_number
720  //magnitude
721  //title
722  //time_labels
723  //time_format
724  //time_offset
725  //time_offset_is_GMT
726  //labels
727  //values
728  //coords
729  //sub_coords
730 
731  if(key=="divisions") {
732  unsigned int v;
733  if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
734  divisions = v;
735  } else if(key=="modeling") {
736  modeling = sv;
737  } else if(key=="is_log") {
738  bool v;
739  if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
740  is_log = v;
741 
742  } else if(key=="tick_up") {
743  bool v;
744  if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
745  tick_up = v;
746  } else if(key=="tick_length") {
747  float v;
748  if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
749  tick_length = v;
750 
751  } else if(key=="title") {
752  title = sv;
753  } else if(key=="title_to_axis") {
754  float v;
755  if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
756  title_to_axis = v;
757  } else if(key=="title_height") {
758  float v;
759  if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
760  title_height = v;
761  } else if(key=="title_hjust") {
762  hjust v;
763  if(!shjust(sv,v))
764  {style_failed(a_out,key,sv);return false;}
765  title_hjust = v;
766 
767  } else if(key=="label_to_axis") {
768  float v;
769  if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
770  label_to_axis = v;
771  } else if(key=="label_height") {
772  float v;
773  if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
774  label_height = v;
775 
776  } else if(key=="labels_no_overlap_automated") {
777  bool v;
778  if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
780  } else if(key=="labels_gap") {
781  float v;
782  if(!to(sv,v)) {style_failed(a_out,key,sv);return false;}
783  labels_gap = v;
784 
785  } else {
786  a_out << "axis::set_from_style :"
787  << " unknown key " << key << "."
788  << std::endl;
789  }
790  }
791  return true;
792  }
793 
794  void set_encoding(const std::string& a_value) {
795  labels_style().encoding = a_value;
796  mag_style().encoding = a_value;
797  title_style().encoding = a_value;
798  }
799 protected:
800  float get_overlap(std::ostream& a_out,bool& a_overlap) {
801  a_overlap = false;
802  std::vector<float> x_mins;
803  std::vector<float> x_maxs;
804  {size_t index = 0;
805  bbox_action _action(a_out);
807  _action.reset();
808  (*it)->bbox(_action);
809  if(_action.end()) {
810  float dx,dy,dz;
811  if(_action.box().get_size(dx,dy,dz)) {
812  if(dx>0) {
813  x_mins.push_back(m_labels_xs[index]-dx*0.5f);
814  x_maxs.push_back(m_labels_xs[index]+dx*0.5f);
815  }
816  }
817  }
818  index++;
819  }}
820  float dx_overlap = 0;
821  {size_t number = x_mins.size();
822  for(size_t index=1;index<number;index++) {
823  float dx = x_mins[index]-x_maxs[index-1];
824  if(dx<0) {
825  a_overlap = true;
826  dx_overlap = mx(dx_overlap,-dx);
827  }
828  }}
829  return dx_overlap;
830  }
831  void avoid_labels_overlap(std::ostream& a_out) {
832  bool overlap;
833  float first_scale = 1;
834  float first_overlap = get_overlap(a_out,overlap);
835  if(overlap) {
836  float second_scale = 1.1f; // greater than one to be sure to overlap again.
838  (*it)->mul_scale(second_scale,second_scale,1);
839  }}
840  float second_overlap = get_overlap(a_out,overlap);
841  if(overlap) {
842  // first_overlap = a*first_scale+b
843  // second_overlap = a*second_scale+b
844  float a = (second_overlap-first_overlap)/(second_scale-first_scale);
845  float b = first_overlap-a*first_scale;
846  //float wanted_scale = -b/a; //zero overlap.
847  float wanted_gap = width.value()*labels_gap.value();
848  float wanted_scale = (-wanted_gap-b)/a;
849  if(wanted_scale<=0) wanted_scale = 1; // this if() should not happen.
850  wanted_scale /= second_scale;
852  (*it)->mul_scale(wanted_scale,wanted_scale,1);
853  }}
854  } else { //it should not happen.
856  (*it)->mul_scale(1.0f/second_scale,1.0f/second_scale,1);
857  }
858  }
859  }
860  }
861 
862  static void style_failed(std::ostream& a_out,
863  const std::string& a_key,
864  const std::string& a_value) {
865  a_out << "axis::set_from_style :"
866  << " failed for key " << sout(a_key)
867  << " and value " << sout(a_value) << "."
868  << std::endl;
869  }
870 protected:
875  // input fields :
876  // minimum_value
877  // maximum_value
878  // is_log
879  // output fields :
880  // values
881  // coords
882  // sub_coords
883  // labels (if labels_enforced is false)
884  // tick_number
885 
886 
887  float mn = minimum_value;
888  float mx = maximum_value;
889 
890  bool a_is_log = is_log;
891  if(a_is_log) {
892  if((mn<=0) || (mx<=0) ) a_is_log = false;
893  }
894 
895  float magxxx,y,yr,startTick,tickSize;
896  float pmag;
897  char pstr[10] = "";
898  char tmp[10];
899 
900  unsigned int tick_num = 0;
901  std::vector<float> tick_values;
902  std::vector<std::string> tick_labels;
903 
904  // need include <float.h> which does not exist on some system
905  //NUM_FUZZ DBL_EPSILON*4
906  float NUM_FUZZ = 0.01f;
907 
908  if (mn >= mx) {
909  if(tick_number) {
910  tick_number.value(0);
911  values.clear();
912  coords.clear();
913  sub_coords.clear();
914  labels.clear();
915  }
916  if(magnitude.value()) magnitude.value(0);
917  m_sub_ticks.clear();
918  return;
919  }
920 
921  if (!a_is_log) {
922 
923  tickSize = calculate_ticks_hippo(mx-mn,magxxx);
924  startTick = fceil( mn / tickSize) * tickSize;
925 
926  if (ffabs(magxxx) <= 3)
927  pmag = 0.0;
928  else
929  pmag = startTick != 0.0 ? ffloor(flog10(ffabs(startTick))) : magxxx;
930 
931  snpf(pstr,sizeof(pstr),"%%1.%df",(int)max_of<float>((pmag-magxxx),0.0));
932 
933  y = startTick;
934  while (y <= mx*(1.0+NUM_FUZZ)) {
935 
936  yr = ffloor(y/fpow(10,magxxx) + 0.5F);
937 
938  snpf(tmp,sizeof(tmp),pstr,yr*fpow(10,magxxx-pmag));
939 
940  {float val = yr * fpow(10.0,magxxx);
941  if((val>=mn)&&(val<=mx)) { //G.Barrand : add this test.
942  tick_values.push_back(val);
943  tick_labels.push_back(tmp);
944  tick_num++;
945  }}
946 
947  y += tickSize;
948  }
949  if (ffabs(magxxx) <= 3.0) magxxx = 0.0;
950 
951  } else {
952 
953  if (mn <= 0) {
954  if(tick_number) {
955  tick_number.value(0);
956  values.clear();
957  coords.clear();
958  sub_coords.clear();
959  labels.clear();
960  }
961  if(magnitude.value()) magnitude.value(0);
962  m_sub_ticks.clear();
963  return;
964  }
965 
966  int nLogTicks;
967  float logTicks[5];
968  float magStep;
969 
970  float maghigh = fceil(flog10(mx));
971  float maglow = ffloor(flog10(mn));
972  float magrng = maghigh - maglow;
973 
974  if (magrng <=3) {
975  nLogTicks = 3;
976  logTicks[0] = 1.0;
977  logTicks[1] = 2.0;
978  logTicks[2] = 5.0;
979  magStep = 1.0;
980  } else {
981  nLogTicks = 1;
982  logTicks[0] = 1.0;
983  magStep = magrng <= 7 ? 1.0F : 2.0F;
984  }
985 
986  pmag = (nLogTicks == 3 && (ffabs(maglow)>3 || ffabs(maghigh)>3)) ?
987  maglow : 0;
988 
989  magxxx = maglow;
990  int i = 0;
991  while ((y=logTicks[i]*fpow(10,magxxx)) < mx*(1+NUM_FUZZ)) {
992  if (y >= mn) {
993 
994  // be careful: there is a bug in the NeXT (s)printf
995  // routine when you do, eg. printf("%1.0g",0.01);
996  if ((magxxx-pmag) > 4 || (magxxx-pmag) < -3) {
997  ::strcpy(pstr,"%1.0e");
998  } else {
999  snpf(pstr,sizeof(pstr),
1000  "%%1.%df",(int)((magxxx-pmag)>0?0.:-(magxxx-pmag)));
1001  }
1002  snpf(tmp,sizeof(tmp),pstr,y*fpow(10.0,-pmag));
1003 
1004  {float val = flog10(y);
1005  if((val>=flog10(mn))&&(val<=flog10(mx))) { //G.Barrand : add this if
1006  tick_values.push_back(val);
1007  tick_labels.push_back(tmp);
1008  tick_num++;
1009  }}
1010 
1011  }
1012 
1013  i++;
1014  if (i>=nLogTicks) {
1015  i = 0;
1016  magxxx += magStep;
1017  }
1018  }
1019 
1020  mn = flog10(mn);
1021  mx = flog10(mx);
1022  }
1023 
1024  float range = mx - mn;
1025 
1026  // it is assumes that tick_values are ordered min to max.
1027  tick_number.value(tick_num);
1028  values.clear();
1029  coords.clear();
1030  for(unsigned int index=0;index<tick_num;index++) {
1031  float val = tick_values[index];
1032  float coord = width * (val-mn)/range;
1033  values.add(val);
1034  coords.add(coord);
1035  }
1036 
1037  if(labels_enforced) {
1038  size_t n = labels.size();
1039  if(tick_num>n) {
1040  for(size_t index=n;index<tick_num;index++) labels.add("");
1041  }
1042  } else {
1043  labels = tick_labels;
1044  }
1045 
1046  magnitude.value((int)pmag);
1047 
1048  sub_coords.clear();
1049  m_sub_ticks.clear();
1050  }
1051 
1052  static float calculate_ticks_hippo(float aSize,float& a_mag) {
1053  unsigned int MIN_TICKS = 4;
1054 
1055  if (aSize <= 0.0) {
1056  //printf ("CalculateTicks : bad value \n");
1057  aSize = ffabs(aSize);
1058  if (aSize == 0.0) aSize = 1.0;
1059  }
1060 
1061  a_mag = ffloor(flog10(aSize));
1062  if (aSize/fpow(10.0,a_mag) < MIN_TICKS) (a_mag)--;
1063 
1064  // now fit the max number of ticks into this range
1065 
1066  float tickSize;
1067  int tickIndex;
1068  static const float goodTicks[] = {10.0, 5.0, 4.0, 2.0, 1.0};
1069  for(tickIndex = 0;
1070  aSize/(tickSize=goodTicks[tickIndex]*fpow(10.0,a_mag))<MIN_TICKS;
1071  tickIndex++){}
1072 
1073  if (tickIndex == 0) a_mag++;
1074 
1075  return tickSize;
1076  }
1077 
1082  void compute_ticks_HPLOT(std::ostream& a_out) {
1083  // Controlled by fields :
1084  // minimum_value
1085  // maximum_value
1086  // divisions
1087  // is_log
1088  // Set value on fields :
1089  // values
1090  // coords
1091  // labels (if labels_enforced is false)
1092  // tick_number
1093 
1094  float mn = minimum_value;
1095  float mx = maximum_value;
1096 
1097  bool a_is_log = is_log;
1098  if(a_is_log) {
1099  if((mn<=0) || (mx<=0) ) a_is_log = false;
1100  }
1101 
1102  // Use hplot::axis to get the ticks and subticks positions
1103  // and the labels text.
1104 
1105  double xmin = 0;
1106  double ymin = 0;
1107  double xmax = width;
1108  double ymax = 0;
1109 
1110  double gridlength = 0;
1111  std::string chopt;
1112  if(a_is_log) chopt += "G";
1113 
1114  std::vector<float> linesGrid;
1115  std::vector<hplot::_text> texts;
1116 
1117  hplot::axis sbAxisHPLOT(a_out);
1118 
1119  chopt += "S";
1120  sbAxisHPLOT.set_tick_size(tick_length/width.value());
1121 
1122  if(time_labels.value()) {
1123  chopt += "t";
1124  sbAxisHPLOT.set_time_format(time_format.value());
1125  sbAxisHPLOT.set_time_offset(time_offset,
1127  }
1128 
1129  // Get ticks :
1130  {double wmin = mn;
1131  double wmax = mx;
1132  int ndiv = divisions;
1133  sbAxisHPLOT.set_title("");
1134  sbAxisHPLOT.paint(xmin,ymin,xmax,ymax,
1135  wmin,wmax,ndiv, //Modified
1136  chopt,gridlength,false,
1137  m_sub_ticks,linesGrid,texts);}
1138 
1139  if(a_is_log) {
1140  mn = flog10(mn);
1141  mx = flog10(mx);
1142  }
1143 
1144  float range = mx - mn;
1145 
1146  size_t tick_num = texts.size();
1147 
1148  // HPLOT stores the magnitude on the last label :
1149  magnitude.value(0);
1150  if(tick_num) {
1151  int pmag;
1152  if(::sscanf(texts[tick_num-1].fString.c_str(),"x10^%d!",&pmag)==1) {
1153  magnitude.value(pmag);
1154  tick_num--;
1155  }
1156  }
1157 
1158  tick_number.value(uint32(tick_num));
1159  values.clear();
1160  coords.clear();
1161  for(size_t index=0;index<tick_num;index++) {
1162  float coord = (float)texts[index].fX;
1163  //NOTE : are we sure that val is in [mn,mx]
1164  float val = (coord/width.value()) * range + mn;
1165  coords.add(coord);
1166  values.add(val);
1167  }
1168 
1169  if(labels_enforced) {
1170  size_t n = labels.size();
1171  if(tick_num>n) {
1172  for(size_t index=n;index<tick_num;index++) labels.add("");
1173  }
1174  } else {
1175  labels.clear();
1176  for(size_t index=0;index<tick_num;index++) {
1177  labels.add(texts[index].fString);
1178  }
1179  }
1180 
1181  {sub_coords.clear();
1182  size_t num = m_sub_ticks.size()/4;
1183  size_t pos = 0;
1184  for(size_t index=0;index<num;index++) {
1185  float coord = m_sub_ticks[pos];
1186  pos += 4;
1187  bool found = false;
1188  for(size_t i=0;i<tick_num;i++) {
1189  if((float)texts[i].fX==coord) {
1190  found = true;
1191  break;
1192  }
1193  }
1194  if(!found) { //not a main tick
1195  sub_coords.add(coord);
1196  }
1197  }}
1198  }
1199 
1200 protected:
1202 
1204 
1210 
1216 
1217  std::vector<float> m_sub_ticks; //n*(2+2)
1218 
1219  std::vector<separator*> m_labels_seps;
1220  std::vector<float> m_labels_xs;
1221  std::vector<matrix*> m_labels_mtxs;
1222 };
1223 
1224 }}
1225 
1226 #endif
tools::sg::line_style
Definition: line_style:17
tools::sg::axis::m_labels_mtxs
std::vector< matrix * > m_labels_mtxs
Definition: axis:1221
tools::vec3::v2
const T & v2() const
Definition: vec3:78
tools::sg::axis::reset_touched
virtual void reset_touched()
Definition: axis:116
node
tools::sg::text_style::x_orientation
sf_vec3f x_orientation
Definition: text_style:38
tools::sg::text_style::font
sf_string font
Definition: text_style:28
tools::sg::axis::coords
mf< float > coords
Definition: axis:52
tools::sg::axis::labels_no_overlap_automated
sf< bool > labels_no_overlap_automated
Definition: axis:64
tools::sg::axis::get_overlap
float get_overlap(std::ostream &a_out, bool &a_overlap)
Definition: axis:800
tools::sg::group::search
virtual void search(search_action &a_action)
Definition: group:51
tools::sg::text_style::vjust
sf_enum< sg::vjust > vjust
Definition: text_style:35
tools::sg::axis::tick_up
sf< bool > tick_up
Definition: axis:43
tools::sg::axis::avoid_labels_overlap
void avoid_labels_overlap(std::ostream &a_out)
Definition: axis:831
tools::sg::axis::pick
virtual void pick(pick_action &a_action)
Definition: axis:171
tools::sg::axis::m_line_sep
separator m_line_sep
Definition: axis:1205
tools::sg::axis::values
mf< float > values
Definition: axis:51
tools::sg::vertices::mode
sf< gl::mode_t > mode
Definition: vertices:26
tools::hplot::axis::set_time_offset
void set_time_offset(double toffset, bool a_is_gmt=false)
Definition: hplot:1818
tools::vec3::v1
const T & v1() const
Definition: vec3:77
tools::sg::axis::m_mag_sep
separator m_mag_sep
Definition: axis:1208
tools::sg::axis::m_labels_seps
std::vector< separator * > m_labels_seps
Definition: axis:1219
tools::sg::bbox_action::box
const box3f & box() const
Definition: bbox_action:129
tools::sg::draw_style::line_pattern
sf< lpat > line_pattern
Definition: draw_style:23
tools::sg::bmf::add
void add(const T &a_value)
Definition: bmf:73
tools::sg::axis::sub_coords
mf< float > sub_coords
Definition: axis:53
tools::sg::axis::width
sf< float > width
Definition: axis:34
tools::sg::group::bbox
virtual void bbox(bbox_action &a_action)
Definition: group:42
tools::sg::axis::divisions
sf< unsigned int > divisions
Definition: axis:37
tools::sg::axis::bbox
virtual void bbox(bbox_action &a_action)
Definition: axis:188
tools::sg::line_style::pattern
sf< lpat > pattern
Definition: line_style:23
tools::sg::line_style::color
sf_vec< colorf, float > color
Definition: line_style:21
tools::sg::draw_style::line_width
sf< float > line_width
Definition: draw_style:22
tools::colorf
Definition: colorf:11
tools::sg::hjust
hjust
Definition: enums:73
tools::vec3::set_value
void set_value(const T &a0, const T &a1, const T &a2)
Definition: vec3:92
tools::hplot::axis::paint
void paint(double xmin, double ymin, double xmax, double ymax, double &wmin, double &wmax, int &ndiv, const std::string &aCHOPT, double gridlength, bool drawGridOnly, std::vector< float > &aLinesAxis, std::vector< float > &aLinesGrid, std::vector< _text > &aTexts)
Definition: hplot:162
tools::sg::line_style::width
sf< float > width
Definition: line_style:22
tools::sg::axis::m_title_style
text_style m_title_style
Definition: axis:1215
tools::hplot::axis::set_title
void set_title(const std::string &aTitle)
Definition: hplot:141
tools::sg::text_style::line_width
sf< float > line_width
Definition: text_style:44
tools::sg::axis::style_failed
static void style_failed(std::ostream &a_out, const std::string &a_key, const std::string &a_value)
Definition: axis:862
tools::sg::axis::compute_ticks_hippo
void compute_ticks_hippo()
Hippodraw tick modeling //////////////////////////////////////////////.
Definition: axis:874
tools::sg::axis::compute_ticks_HPLOT
void compute_ticks_HPLOT(std::ostream &a_out)
HPLOT tick modeling //////////////////////////////////////////////////// ////////////////////////////...
Definition: axis:1082
tools::sg::node
Definition: node:28
draw_style
tools::gl::lines
mode_t lines()
Definition: glprims:17
tools::sg::bbox_action
Definition: bbox_action:15
TOOLS_NODE
#define TOOLS_NODE(a__class, a__sclass, a__parent)
Definition: node:324
tools::sg::search_action::done
bool done() const
Definition: search_action:68
tools::sg::encoding_PAW
const std::string & encoding_PAW()
Definition: strings:42
tools::sg::shjust
bool shjust(const std::string &a_s, hjust &a_v)
Definition: senum:26
tools::sg::write_action
Definition: write_action:21
tools::ffabs
float ffabs(const float &x)
Definition: mathf:58
tools::mn
T mn(const T &a, const T &b)
Definition: mnmx:10
tools::sg::group
Definition: group:21
tools::sg::rgba
Definition: rgba:16
tools::sg::group::write
virtual bool write(write_action &a_action)
Definition: group:67
normal
tools::vec3::v0
const T & v0() const
Definition: vec3:76
tools::sg::axis::maximum_value
sf< float > maximum_value
Definition: axis:36
tools::mx
T mx(const T &a, const T &b)
Definition: mnmx:13
tools::sg::axis::tick_number
sf< unsigned int > tick_number
Definition: axis:49
tools::sg::right
@ right
Definition: enums:76
tools::sg::base_freetype
Definition: base_freetype:16
tools::sg::axis::set_color
void set_color(const colorf &a_color)
Definition: axis:338
tools::sg::axis::labels_enforced
sf< bool > labels_enforced
Definition: axis:42
tools::gl::line_strip
mode_t line_strip()
Definition: glprims:19
line_style
tools::sg::draw_style
Definition: draw_style:18
tools::sg::matrix_action::end
bool end() const
Definition: matrix_action:75
tools::sg::axis::set_from_style
bool set_from_style(std::ostream &a_out, const style_t &a_style)
Definition: axis:706
tools::sg::axis::is_log
sf< bool > is_log
Definition: axis:39
tools::sg::axis
Definition: axis:30
tools::sg::text_style::visible
sf< bool > visible
Definition: text_style:22
tools::sg::desc_fields
Definition: field_desc:148
tools::sg::axis::time_format
sf_string time_format
Definition: axis:69
tools::sg::axis::title_to_axis
sf< float > title_to_axis
Definition: axis:57
tools::sg::axis::m_title_sep
separator m_title_sep
Definition: axis:1209
tools::sg::bmf::values
const std::vector< T > & values() const
Definition: bmf:71
tools::sg::line_style::visible
sf< bool > visible
Definition: line_style:20
tools::sg::axis::m_ticks_style
sg::line_style m_ticks_style
Definition: axis:1212
tools::sg::axis::axis
axis(const base_freetype &a_ttf)
Definition: axis:208
tools::sg::axis::labels_style
text_style & labels_style()
Definition: axis:334
tools::sg::pick_action
Definition: pick_action:59
tools::sg::axis::label_height
sf< float > label_height
Definition: axis:62
tools::sg::axis::m_labels_xs
std::vector< float > m_labels_xs
Definition: axis:1220
tools::sg::tick_modeling_hippo
const std::string & tick_modeling_hippo()
Definition: strings:19
tools::sg::nodekit_pick
void nodekit_pick(pick_action &a_action, node &a_sg, node *a_node)
Definition: nodekit:13
tools::box3::get_size
bool get_size(T_t &a_dx, T_t &a_dy, T_t &a_dz) const
Definition: box3:59
tools::sg::group::render
virtual void render(render_action &a_action)
Definition: group:24
tools::sg::axis::m_line_style
sg::line_style m_line_style
Definition: axis:1211
tools::sg::mf< float >
tools::snpf
int snpf(char *a_s, size_t a_n, const char *a_fmt,...)
Definition: snpf:27
tools::sg::normal
Definition: normal:16
tools::sout
Definition: sout:17
rgba
tools::sg::axis::magnitude
sf< int > magnitude
Definition: axis:54
tools::sg::axis::title_style
text_style & title_style()
Definition: axis:335
tools::sg::axis::search
virtual void search(search_action &a_action)
Definition: axis:179
tools
tools::sg::axis::ticks_style
sg::line_style & ticks_style()
Definition: axis:333
tools::sg::axis::render
virtual void render(render_action &a_action)
Definition: axis:164
tools::hplot::axis
Definition: hplot:71
tools::sg::sf_enum< hjust >
tools::sg::text_style::font_modeling
sf_enum< sg::font_modeling > font_modeling
Definition: text_style:30
tools::sg::text_style::smoothing
sf< bool > smoothing
Definition: text_style:32
tools::sg::group::add
void add(node *a_node)
Definition: group:96
tools::fceil
float fceil(const float &x)
Definition: mathf:55
tools::sg::axis::label_to_axis
sf< float > label_to_axis
Definition: axis:61
tools::sg::axis::m_mag_style
text_style m_mag_style
Definition: axis:1214
tools::sg::axis::calculate_ticks_hippo
static float calculate_ticks_hippo(float aSize, float &a_mag)
Definition: axis:1052
tools::sg::search_action
Definition: search_action:19
tools::sg::axis::tick_length
sf< float > tick_length
Definition: axis:44
tools::flog10
float flog10(const float &x)
Definition: mathf:53
tools::to
std::vector< std::string > to(int a_argc, char **a_argv)
Definition: args:507
tools::sg::axis::update_sg
void update_sg(std::ostream &a_out)
Definition: axis:346
tools::sg::axis::reset_style
void reset_style(bool a_geom=false)
Definition: axis:612
tools::vec3f
Definition: vec3f:13
tools::sg::render_action
Definition: render_action:24
tools::sg::axis::m_ticks_sep
separator m_ticks_sep
Definition: axis:1206
tools::sg::separator
Definition: separator:15
tools::hplot::axis::set_tick_size
void set_tick_size(float aValue)
Definition: hplot:2088
tools::sg::axis::m_sub_ticks
std::vector< float > m_sub_ticks
Definition: axis:1217
tools::vec3::cross
void cross(const vec3< T > &aV, vec3< T > &a_value) const
Definition: vec3:131
tools::sg::mf_string
Definition: mf:76
tools::sg::text_style::color
sf_vec< colorf, float > color
Definition: text_style:23
tools::sg::axis::m_ttf
const base_freetype & m_ttf
Definition: axis:1201
tools::sg::axis::write
virtual bool write(write_action &a_action)
Definition: axis:196
tools::sg::bbox_action::reset
void reset()
Definition: bbox_action:125
noderef
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
tools::mat4::mul_scale
void mul_scale(const T &a_sx, const T &a_sy, const T &a_sz)
Definition: mat4:234
vertices
tools::sg::bmf::clear
void clear()
Definition: bmf:108
tools::sg::text_style::line_pattern
sf< lpat > line_pattern
Definition: text_style:45
tools::sg::node::add_field
void add_field(field *a_field)
Definition: node:128
tools::sg::matrix
Definition: matrix:19
tools::sg::axis::m_labels_style
text_style m_labels_style
Definition: axis:1213
tools::sg::axis::~axis
virtual ~axis()
Definition: axis:247
tools::sg::add_string
void add_string(separator &a_sep, const std::string &a_font, font_modeling &a_font_modeling, const std::string &a_encoding, bool, const std::string &a_string, float a_x, float a_y, float a_z, const vec3f &a_X, const vec3f &a_Y, float a_size, hjust a_hjust, vjust a_vjust, const base_freetype &a_ttf)
Definition: tools:19
tools::sg::text_style::hjust
sf_enum< sg::hjust > hjust
Definition: text_style:34
enums
tools::sg::text_style
Definition: text_style:19
tools::mat4f
Definition: mat4f:12
tools::sg::tick_modeling_none
const std::string & tick_modeling_none()
Definition: strings:15
TOOLS_FIELD_DESC_NODE_CLASS
#define TOOLS_FIELD_DESC_NODE_CLASS(a__class)
Definition: field:68
tools::sg::axis::labels
mf_string labels
Definition: axis:50
tools::mat
Definition: mat:19
text_style
tools::sg::axis::time_labels
sf< bool > time_labels
Definition: axis:68
tools::sg::axis::operator=
axis & operator=(const axis &a_from)
Definition: axis:291
tools::sg::text_style::scale
sf< float > scale
Definition: text_style:36
tools::file::found
bool found(const std::string &a_file, const std::string &a_what, std::vector< std::string > &a_found)
Definition: file:507
tools::sg::group::clear
void clear()
Definition: group:235
tools::sg::axis::m_group
group m_group
Definition: axis:1203
tools::sg::sf_string
Definition: sf_string:15
tools::sg::text_style::y_orientation
sf_vec3f y_orientation
Definition: text_style:39
tools::sg::axis::style_item_t
std::pair< std::string, std::string > style_item_t
Definition: axis:704
tools::sg::axis::m_labels_sep
separator m_labels_sep
Definition: axis:1207
tools::ffloor
float ffloor(const float &x)
Definition: mathf:54
tools::fpow
float fpow(const float &x, const float &y)
Definition: mathf:50
tools::sg::bsf::value
T & value()
Definition: bsf:98
tools::sg::action::out
std::ostream & out() const
Definition: action:51
nodekit
tools::sg::bmf::size
size_t size() const
Definition: bmf:69
tools::sg::axis::title
sf_string title
Definition: axis:56
tools::sg::axis::title_hjust
sf_enum< hjust > title_hjust
Definition: axis:59
tools::sg::font_hershey
const std::string & font_hershey()
Definition: strings:186
tools::sg::axis::line_style
sg::line_style & line_style()
Definition: axis:332
tools::sep
const std::string & sep()
Definition: sep:11
tools::vec3f::normalize
float normalize()
Definition: vec3f:74
tools::sg::axis::mag_style
text_style & mag_style()
Definition: axis:336
tools::sg::center
@ center
Definition: enums:75
tools_vforcit
#define tools_vforcit(a__T, a__v, a__it)
Definition: forit:7
tools::sg::text_style::translation
sf_vec3f translation
Definition: text_style:47
separator
tools::hplot::axis::set_time_format
void set_time_format(const std::string &a_format)
Definition: hplot:1764
tools::sg::draw_style::style
sf_enum< draw_type > style
Definition: draw_style:21
tools::sg::axis::time_offset_is_GMT
sf< bool > time_offset_is_GMT
Definition: axis:71
tools::sg::axis::node_desc_fields
virtual const desc_fields & node_desc_fields() const
Definition: axis:73
tools::uint32
unsigned int uint32
Definition: typedefs:71
tools::sg::text_style::options
sf_string options
Definition: text_style:52
tools::sg::axis::touched
virtual bool touched()
Definition: axis:107
tools::sg::vertices::number
size_t number() const
Definition: vertices:184
tools::sg::axis::time_offset
sf< double > time_offset
Definition: axis:70
tools::sg::draw_lines
@ draw_lines
Definition: enums:192
tools::sg::vertices::add
void add(const VEC &a_v)
Definition: vertices:155
tools::sg::axis::minimum_value
sf< float > minimum_value
Definition: axis:35
tools::sg::axis::modeling
sf_string modeling
Definition: axis:38
tools::sg::sf< float >
tools::sg::axis::axis
axis(const axis &a_from)
Definition: axis:249
tools::sg::tick_modeling_hplot
const std::string & tick_modeling_hplot()
Definition: strings:23
tools::sg::add_string_opt
matrix * add_string_opt(separator &a_sep, const std::string &a_font, font_modeling a_font_modeling, const std::string &a_encoding, bool, const std::string &a_string, float a_x, float a_y, float a_z, mat4f &a_scale_rot, hjust a_hjust, vjust a_vjust, const base_freetype &a_ttf)
Definition: tools:82
TOOLS_ARG_FIELD_DESC
#define TOOLS_ARG_FIELD_DESC(a__field)
Definition: field:71
tools::sg::axis::labels_gap
sf< float > labels_gap
Definition: axis:65
tools::sg::axis::title_height
sf< float > title_height
Definition: axis:58
tools::sg::node::reset_touched
virtual void reset_touched()
Definition: node:102
tools::sg::text_style::encoding
sf_string encoding
Definition: text_style:31
tools::sg::axis::set_encoding
void set_encoding(const std::string &a_value)
Definition: axis:794
tools::sg::axis::style_t
std::vector< style_item_t > style_t
Definition: axis:705
tools::sg::vertices
Definition: vertices:22