render_svg.hpp 8.9 KB
Newer Older
1
#ifndef RENDER_SVG
2
#define RENDER_SVG
3 4


Pascal Noisette's avatar
Pascal Noisette committed
5 6 7
#include <iostream>
#include <sstream>
#include <fstream>
8

Olivier Lagrasse's avatar
Olivier Lagrasse committed
9
#define BUFFER_SIZE 10 //character number stored before flush the _buffer
Pascal Noisette's avatar
Pascal Noisette committed
10
#define LEVEL 20        //distance between two containers
Pascal Noisette's avatar
Pascal Noisette committed
11
#define MARGIN 10        //distance between two object
12
#define ARROWSIZE 2      //spike size
Pascal Noisette's avatar
wide  
Pascal Noisette committed
13
#define WIDE 1000
14
#define MARGINSTATE 0.5
15

Pascal Noisette's avatar
Pascal Noisette committed
16 17 18
#define WAIT_NEW_CHRONO 0
#define INIT 1
#define WAIT_FOR_POINT 2
19

Pascal Noisette's avatar
Pascal Noisette committed
20 21


22 23 24 25
#include "render.hpp"
#include "resource.hpp"


Pascal Noisette's avatar
Pascal Noisette committed
26 27
#define max(a,b) (a>b?a:b);
#define min(a,b) (a>b?b:a);
28

29
class Svg : public Render{
30 31


32
private:
33
    std::ostringstream _buffer;
34
    std::ostringstream _thin_element_buffer;
35
    std::ostringstream _chronogramme;
Pascal Noisette's avatar
Pascal Noisette committed
36
    int _chronogramme_state;
37
    std::ofstream _svg_file;
Pascal Noisette's avatar
Pascal Noisette committed
38 39 40 41
    Element_pos _container_width_max;
    Element_pos _container_height_min;
    int _debug_counter;
    double _epsilon;
Pascal Noisette's avatar
Pascal Noisette committed
42

Pascal Noisette's avatar
Pascal Noisette committed
43
    inline void print();
Pascal Noisette's avatar
Pascal Noisette committed
44 45 46
  inline void rectangle(const char* name,Element_pos w, Element_pos h,Element_pos x1,Element_pos y1,  unsigned int r,   unsigned int g,   unsigned int b );
    inline void line(const char* name, Element_pos x1, Element_pos y1, Element_pos x2, Element_pos y2);
    inline void triangle(const char* name,Element_pos x1,Element_pos y1,Element_pos x2,Element_pos y2, Element_pos x3,Element_pos y3);
47 48
public:
    /*!
49 50
     * \brief SVG header buiding
     */
51
    void init(const char *path);
52

53
    /*!
54 55
     * \brief SVG bottom file buiding
     */
56
    void end();
57

58 59
    void start_draw();
    void start_draw_containers();
60

61
    /*!
62 63 64 65 66 67
     * \brief Draw a container according to the parameters
     * \param x the x position of the container
     * \param y the y position of the container
     * \param w the width of the container
     * \param h the height of the container
     */
68 69
    void draw_container(const Element_pos x, const Element_pos y, const Element_pos w, const Element_pos h) ;

70 71 72 73 74
    void draw_container_text(const Element_pos x, const Element_pos y, const std::string value);

    void end_draw_containers();
    void start_draw_states();

75 76 77 78 79 80 81 82 83
    /*!
     * \brief Draw a state of the trace.
     * \param r the red color rate of the state.
     * \param g the green color rate of the state.
     * \param b the blue color rate of the state.
     * \param start the beginning time of the state.
     * \param end the ending time of the state.
     * \param level refer to the container which state belongs to.
     */
84
    void draw_state(const Element_pos start , const Element_pos end, const Element_pos level, const Element_pos height, const Element_col r, const Element_col g, const Element_col b) ;
Pascal Noisette's avatar
Pascal Noisette committed
85 86 87 88 89 90 91

    /*!
    * \brief Draw an arrow
    *
    */
    void draw_arrow(const Element_pos start_time, const Element_pos end_time, const Element_pos start_height, const Element_pos end_height);

92 93 94 95
    void end_draw_states();

    void draw_event(const Element_pos time, const Element_pos height, const Element_pos container_height);

96 97
    void start_draw_counter();
    
Pascal Noisette's avatar
Pascal Noisette committed
98
    void draw_counter(const Element_pos x, const Element_pos y);
99 100 101
    
    void end_draw_counter();

102
    void end_draw();
Pascal Noisette's avatar
Pascal Noisette committed
103 104

    void set_accuracy(double epsilon);
105 106
};

107 108 109 110 111 112 113 114 115 116 117 118 119 120


/***********************************
 *
 *
 *
 * Drawing function for the trace.
 *
 *
 *
 **********************************/


inline void Svg::start_draw(){
121
 
122 123 124
}

inline void Svg::draw_container_text(const Element_pos x, const Element_pos y, const std::string value){
Pascal Noisette's avatar
Pascal Noisette committed
125 126 127 128 129 130 131 132 133 134 135
  
  Element_pos xprime,yprime;
  
  yprime = LEVEL*y;
  xprime = LEVEL*x;

  _thin_element_buffer << "<text x='" << xprime <<"' y='" << yprime << "'> ";
  _thin_element_buffer << value;
  _thin_element_buffer << "</text>";

} 
136 137

inline void Svg::start_draw_containers(){
Pascal Noisette's avatar
Pascal Noisette committed
138

139 140 141 142 143 144 145 146 147 148 149
}

inline void Svg::end_draw_containers(){
}

inline void Svg::start_draw_states(){
}

inline void Svg::end_draw_states(){
}

Pascal Noisette's avatar
Pascal Noisette committed
150

151 152 153 154 155
/********************
 * Counter
 *******************/

inline void Svg::start_draw_counter(){
Pascal Noisette's avatar
Pascal Noisette committed
156
  _chronogramme_state=INIT;
157
  // std::cout<<"INIT\n";
158 159 160
}

inline void Svg::draw_counter(const Element_pos x, const Element_pos y){
Pascal Noisette's avatar
Pascal Noisette committed
161

Pascal Noisette's avatar
wide  
Pascal Noisette committed
162 163 164 165
  Element_pos xprime = x*WIDE +  _container_width_max ;
  Element_pos yprime = y*LEVEL;
  Element_pos switchvalue = _container_width_max;

166
  //std::cout<<"s.draw_counter("<<xprime<<","<<yprime<<");\n";
Pascal Noisette's avatar
Pascal Noisette committed
167

Pascal Noisette's avatar
Pascal Noisette committed
168 169
  if (_chronogramme_state==INIT)
    {
Pascal Noisette's avatar
wide  
Pascal Noisette committed
170
      if (xprime==switchvalue)
Pascal Noisette's avatar
Pascal Noisette committed
171
	{
172
            //	 std::cout<<"WAITFORPOINT\n";
Pascal Noisette's avatar
wide  
Pascal Noisette committed
173
	  _chronogramme << "\n<path d='M"<< xprime << " " << yprime;
Pascal Noisette's avatar
Pascal Noisette committed
174 175 176 177 178 179 180 181 182 183
	  _chronogramme_state=WAIT_FOR_POINT;
	}
      else
	std::cerr<<"draw_counter not initialised";
	  
    }
  else  if (_chronogramme_state==WAIT_FOR_POINT)
    
    {
      
Pascal Noisette's avatar
wide  
Pascal Noisette committed
184
      if (xprime==switchvalue)
Pascal Noisette's avatar
Pascal Noisette committed
185
	{
186
            //  std::cout<<"WAITFORNEWCHRONO\n";
Pascal Noisette's avatar
Pascal Noisette committed
187 188 189 190 191 192 193
	  _chronogramme << "'/>";
	  _svg_file.write(_chronogramme.str().c_str(), _chronogramme.str().size());
	  _chronogramme.str("");
	  _chronogramme_state=WAIT_NEW_CHRONO;
	}
      else
	{
Pascal Noisette's avatar
wide  
Pascal Noisette committed
194 195

	  _chronogramme << " L" << xprime << " " << yprime;
Pascal Noisette's avatar
Pascal Noisette committed
196 197 198 199 200 201
	}
      
    }
  
  else  if (_chronogramme_state==WAIT_NEW_CHRONO)
    {
Pascal Noisette's avatar
wide  
Pascal Noisette committed
202
        if (xprime==switchvalue)
Pascal Noisette's avatar
Pascal Noisette committed
203
	{
204
            //  std::cout<<"WAITFORPOINT\n";
Pascal Noisette's avatar
wide  
Pascal Noisette committed
205
	  _chronogramme << "\n<path d='M"<< xprime << " " << yprime;
Pascal Noisette's avatar
Pascal Noisette committed
206 207 208 209 210 211 212 213 214
	  _chronogramme_state=WAIT_FOR_POINT;
	}
      else
	std::cerr<<"draw_counter not initialised";
	  

    }
  

215 216 217
}

inline void Svg::end_draw_counter(){
Pascal Noisette's avatar
Pascal Noisette committed
218 219
  if (_chronogramme_state!=WAIT_NEW_CHRONO)
    std::cerr<<"draw_counter not un-initialised";
220 221
}

222 223

inline void Svg::end_draw(){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
224
    Svg::end();
225 226
}

Pascal Noisette's avatar
Pascal Noisette committed
227
void Svg::rectangle(const char* name,Element_pos w, Element_pos h,Element_pos x1,Element_pos y1,  unsigned int r,   unsigned int g,   unsigned int b ){
228
  _buffer << "\n<rect class='"<<name<<"' title='"<<name<<"' width='" << w
Pascal Noisette's avatar
Pascal Noisette committed
229 230 231 232
            <<"' height='"<< h
            <<"' x='"     << x1
            <<"' y='"     << y1
            <<"' fill='rgb("<<r<<","<<g<<","<<b
Pascal Noisette's avatar
Pascal Noisette committed
233
            <<")'/>";
Pascal Noisette's avatar
Pascal Noisette committed
234 235 236 237 238 239 240
    print();
}





Pascal Noisette's avatar
Pascal Noisette committed
241
void Svg::triangle(const char* name,Element_pos x1,Element_pos y1,Element_pos x2,Element_pos y2, Element_pos x3,Element_pos y3){
242
   _thin_element_buffer << "\n<polyline title='"<<name<<"' class='triangle' points='"
Pascal Noisette's avatar
Pascal Noisette committed
243 244 245
            <<        x1 << "," << y1
            << " " << x2 << "," << y2
            << " " << x3 << "," << y3
Pascal Noisette's avatar
Pascal Noisette committed
246
            <<"' />";
247
    
Pascal Noisette's avatar
Pascal Noisette committed
248 249 250
}

void Svg::print(){
Olivier Lagrasse's avatar
Olivier Lagrasse committed
251
    // if (_buffer.str().size()>BUFFER_SIZE){
Pascal Noisette's avatar
Pascal Noisette committed
252
        _svg_file.write(_buffer.str().c_str(),  _buffer.str().size());
Pascal Noisette's avatar
Pascal Noisette committed
253
	_buffer.str("");
Pascal Noisette's avatar
Pascal Noisette committed
254 255 256 257 258
}




Pascal Noisette's avatar
Pascal Noisette committed
259
inline void Svg::line(const char* name, Element_pos x1, Element_pos y1, Element_pos x2, Element_pos y2){
260
   _thin_element_buffer << "\n<line title='"<<name<<"' x1='" << x1
Pascal Noisette's avatar
Pascal Noisette committed
261 262 263 264 265 266 267 268
            <<"' y1='"     << y1
            <<"' x2='"     << x2
            <<"' y2='"     << y2
            <<"' />";
    print();
}

inline void Svg::draw_arrow(const Element_pos start_time, const Element_pos end_time, const Element_pos start_height, const Element_pos end_height){
Pascal Noisette's avatar
Pascal Noisette committed
269

Pascal Noisette's avatar
Pascal Noisette committed
270
  //std::cout<<"s.draw_arrow("<<start_time<<","<<end_time<<","<<start_height<<","<< end_height<<");\n";
Pascal Noisette's avatar
Pascal Noisette committed
271

Pascal Noisette's avatar
Pascal Noisette committed
272
  Element_pos x1=(start_time )*WIDE +  _container_width_max ;
273
  Element_pos y1=start_height*LEVEL;
Pascal Noisette's avatar
Pascal Noisette committed
274
  Element_pos x2=(end_time)*WIDE+  _container_width_max;
275 276 277 278
  Element_pos y2=end_height*LEVEL;


  Svg::line("arrow",x1 ,y1 ,x2,y2);
Pascal Noisette's avatar
Pascal Noisette committed
279

280 281
  Svg::triangle("arrow",x2 ,y2+ARROWSIZE,x2 ,y2-ARROWSIZE,x2+ARROWSIZE,y2);//spike
  
Pascal Noisette's avatar
Pascal Noisette committed
282 283 284
}

inline void Svg::draw_container(const Element_pos x, const Element_pos y, const Element_pos w, const Element_pos h){
Pascal Noisette's avatar
Pascal Noisette committed
285 286 287 288 289 290 291 292

  Element_pos xprime,yprime,wprime,hprime;
  
  wprime = LEVEL*w;
  hprime = LEVEL*h;
  yprime = LEVEL*y;
  xprime = LEVEL*x;

293
  // std::cout<<"s.draw_container("<<x<<","<<y<<","<<w<<","<< h<<");\n";
Pascal Noisette's avatar
Pascal Noisette committed
294 295 296

  Svg::rectangle("container",wprime, hprime, xprime, yprime, 0xff, 0x44, 0xcc);
  
Pascal Noisette's avatar
Pascal Noisette committed
297 298
  _container_width_max = max(wprime+xprime+ MARGIN,_container_width_max);
  _container_height_min = min(hprime,_container_height_min);
Pascal Noisette's avatar
Pascal Noisette committed
299 300 301 302 303
}



inline void Svg::draw_state(const Element_pos start , const Element_pos end, const Element_pos level, const Element_pos height, const Element_col r, const Element_col g, const Element_col b){
304
  
Pascal Noisette's avatar
Pascal Noisette committed
305

306
  
Pascal Noisette's avatar
Pascal Noisette committed
307

308
  Element_pos w =end*WIDE-start*WIDE;
Pascal Noisette's avatar
Pascal Noisette committed
309 310
  Element_pos h = _container_height_min;
  Element_pos x = (start )*WIDE+  _container_width_max + MARGINSTATE;
311 312
  Element_pos y = level*LEVEL;

Pascal Noisette's avatar
Pascal Noisette committed
313
  if(w<_epsilon){
314 315 316
    //std::cerr<<"state width is null";
      return;
  }
Pascal Noisette's avatar
Pascal Noisette committed
317 318
  // if( debug_counter++<1000)
  // std::cout<<"s.draw_state("<<start<<","<<end<<","<<level<<","<< height<<","<<r<<","<<g<<","<< b  <<");\n";
319
 
Pascal Noisette's avatar
Pascal Noisette committed
320
  Svg::rectangle("state",w,h, x,y,r*255 , g*255,  b*255);
Pascal Noisette's avatar
Pascal Noisette committed
321 322 323
}

inline  void Svg::draw_event(const Element_pos time, const Element_pos height, const Element_pos container_height){
Pascal Noisette's avatar
Pascal Noisette committed
324

Pascal Noisette's avatar
Pascal Noisette committed
325
  // std::cout<<"s.draw_event("<<time<<","<< height<<","<<container_height<<");\n";
Pascal Noisette's avatar
Pascal Noisette committed
326

Pascal Noisette's avatar
Pascal Noisette committed
327
  Svg::rectangle("event",MARGIN,container_height, time +  _container_width_max , height, 0x17, 0x60, 0xe7);
Pascal Noisette's avatar
Pascal Noisette committed
328
}
329

Pascal Noisette's avatar
Pascal Noisette committed
330 331 332



333
#endif // RENDER_SVG