DrawStats.hpp 9 KB
Newer Older
1
2
3
4
5
6
7
8
/*!
 *\file DrawStats.hpp
 */

#ifndef DRAW_STATS_HPP
#define DRAW_STATS_HPP

#include <string>
9
#include <vector>
10
#include <map>
11
12
13
14

#include "../message/Message.hpp"
#include "../trace/Trace.hpp"
#include "../trace/tree/Interval.hpp"
15
#include "Statistic.hpp"
16

17
/*!
18
19
 * \def _HEIGHT_FOR_ONE_CONTAINER_DEFAULT
 * \brief The default height for one container's statistics.
20
 */
21
#define _HEIGHT_FOR_ONE_CONTAINER_DEFAULT 300.0f
22
23

/*!
24
25
26
 * \def _POS_X_CONTAINER_NAME
 * \brief The default x position for the container name.
 *        The origin is set at the north west.
27
 */
28
29
30
31
32
33
#define _POS_X_CONTAINER_NAME 10.0f
/*!
 * \def _POS_Y_CONTAINER_NAME
 * \brief The default y position for the container name.
 *        The origin is set at the north west.
 */
34
#define _POS_Y_CONTAINER_NAME _HEIGHT_FOR_ONE_CONTAINER_DEFAULT-30.0f
35
36
37
38
39
40
41
42
43
44
45

/*!
 * \def _WIDTH_HISTOGRAM_DEFAULT
 * \brief The default width for a container in histogram mode.
 */
#define _WIDTH_HISTOGRAM_DEFAULT 30.f

/*!
 * \def _START_HISTOGRAM_X_DEFAULT
 * \brief The default x position for origin in histogram mode.
 */
46
#define _START_HISTOGRAM_X_DEFAULT 80.f
47
48
49
50
51
52
53
54
55
56
57

/*!
 * \def _START_HISTOGRAM_Y_DEFAULT
 * \brief The default Y position for origin in histogram mode.
 */
#define _START_HISTOGRAM_Y_DEFAULT 100.f

/*!
 * \def _PERCENTAGE_HEIGHT_DEFAULT
 * \brief The default height for 1% in histogram mode.
 */
58
59
60
61
62
63
64
65
66
67
68
69
70
#define _PERCENTAGE_HEIGHT_DEFAULT 3.f

/*!
 * \def _POS_X_LEGEND_DEFAULT
 * \brief The default position for the legend.
 */
#define _POS_X_LEGEND_DEFAULT 10.f

/*!
 * \def _POS_Y_LEGEND_DEFAULT
 * \brief The default position for the legend.
 */
#define _POS_Y_LEGEND_DEFAULT 60.f
71
72
73
74
75
76
77
78
79
80
81


/*!
 * \class DrawStats
 * \brief Browse the stats and call back T drawing methods
 */
template<class T>
class DrawStats {
    
protected:
    
82
    std::vector<Container *> _containers_to_print;
83

84
85
    std::vector<std::map<const EntityValue*, stats*> > _states;

86
87
88
89
    double _start_time;
    double _previous_start_time;
    double _end_time;
    double _previous_end_time;
90

91
92
93
94
    // Geometrical informations about the stats shape.
    double _size_for_one_container;
    double _pos_x_container_name;
    double _pos_y_container_name;
95

96
97
98
99
100
101
    double _percentage_height_default;

    double _width_for_rect_legend;
    double _height_for_rect_legend;


102
103
104
105
106
public:
    /*
     * \brief The default constructor
     */
    DrawStats() {
107
108
109
        _size_for_one_container = _HEIGHT_FOR_ONE_CONTAINER_DEFAULT;
        _pos_x_container_name = _POS_X_CONTAINER_NAME;
        _pos_y_container_name = _POS_Y_CONTAINER_NAME;
110
111
112
113
114
115

        _percentage_height_default = (_size_for_one_container - _START_HISTOGRAM_Y_DEFAULT) / 100.;
     
        /* Size for rectangles in the legend */
        _width_for_rect_legend = 20.;
        _height_for_rect_legend = 15.;
116
117
118
119
120
121
122
123
124
125
126
    }

    
    /*!
     * \brief The destructor
     */
    virtual ~DrawStats() {
    }


    /*!
127
     * \fn build(T* draw_object, Trace* trace)
128
129
130
131
     * \brief The trace building function.
     * \param draw_object the kind of object which will be drawn (OpenGL, SVG...).
     * \param trace the trace data.
     */
132
    virtual void build(T* draw_object, std::vector<Container *> containers_to_print) {
133

134
135
136
137
        draw_object->clear();

        _size_for_one_container = draw_object->height();

138
139
        _containers_to_print = containers_to_print;
        const int number_of_containers = _containers_to_print.size();
140
        draw_object->start_draw();
141
        draw_object->set_total_height((number_of_containers-1)*_size_for_one_container);
142
143
        draw_object->set_total_width(draw_object->width());

144
145
146
        for(int i = 0 ; i < number_of_containers ; i ++) {
            draw_container_name(draw_object, i);
            
147
            draw_diagram(draw_object, i);
148
149
150
            
            draw_legend(draw_object, i);
        }
151
        end_draw(draw_object);
152
153
    }

154
    virtual void draw_container_name(T* draw_object, const int container_id) const {
155
        // Get the position for the i-th container name
156
        
157
        Element_pos pos_x = _pos_x_container_name;
158
        Element_pos pos_y = _pos_y_container_name - _size_for_one_container * container_id;
159
        std::string name = _containers_to_print[container_id]->get_name().to_string();
160
        
161
162
163
        
        draw_object->draw_text(pos_x, pos_y, name);
    }
164

165
    virtual void draw_diagram(T* draw_object, const int container_id) {
166
167
168
169
170
171
172
        Statistic *stat_temp = new Statistic();
        _containers_to_print[container_id]->fill_stat(stat_temp, Interval(_start_time, _end_time));
        std::map<const EntityValue*, stats*> temp_states = stat_temp->get_states();
        _states.push_back(temp_states);

        // Printing of the trace

173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
	int pos_x = _START_HISTOGRAM_X_DEFAULT;
	int pos_y = _START_HISTOGRAM_Y_DEFAULT - container_id*_size_for_one_container;
	const double max_percentage = get_max_percentage(temp_states);
	// Draw axes
	draw_object->draw_axis(pos_x, pos_y, _WIDTH_HISTOGRAM_DEFAULT*(_states[container_id].size()+1), _percentage_height_default*100);
	draw_object->draw_text(pos_x-30, pos_y+_percentage_height_default*100-5, QString::number(max_percentage*100., 'g', 3).toStdString()+"%");
	draw_object->draw_horizontal_line(pos_x, pos_y+_percentage_height_default*100, _WIDTH_HISTOGRAM_DEFAULT*(_states[container_id].size()+1));
	
	
	// Draw the stats
	for (map<const EntityValue *, stats *>::iterator it = temp_states.begin();
	     it != temp_states.end();
	     it ++) {
	    std::string name = (*it).first->get_name().to_string();

	    // We have to convert the percentage in a rectangle and print it
	    const double length = (*it).second->_total_length;
	    const double height = length*100.*_percentage_height_default/(_end_time-_start_time);
	    
	    // We search for a color
	    if((*it).first->get_extra_fields()->find(std::string("Color")) != (*it).first->get_extra_fields()->end()) {
	      const Color *color = (const Color *)(*it).first->get_extra_fields()->find(std::string("Color"))->second;
	      draw_object->draw_rect(pos_x, pos_y, _WIDTH_HISTOGRAM_DEFAULT, height/max_percentage, color->get_red(), color->get_green(), color->get_blue());
	    }
	    else {
	      draw_object->draw_rect(pos_x, pos_y, _WIDTH_HISTOGRAM_DEFAULT, height/max_percentage, 0.7, 0.7, 0.75);
	    }
            
	    // We print the percentage above
	    draw_object->draw_text(pos_x, pos_y+height/max_percentage+1, QString::number(length/(_end_time-_start_time)*100., 'f', 1).toStdString()+"%");
	    
	    //std::cout << "State : " << name << " for " << (*it).second->_total_length*100./(_end_time-_start_time)<< "% between " << _start_time << " sec and " << _end_time << " sec" << std::endl;
	    
	    pos_x += _WIDTH_HISTOGRAM_DEFAULT;
	}
208
209

        delete stat_temp;
210
    }
211

212
    virtual void draw_legend(T* draw_object, const int container_id) {
213
214
215
216
217
218
219
        Element_pos pos_x = _POS_X_CONTAINER_NAME + _POS_X_LEGEND_DEFAULT;
        Element_pos pos_y = -_size_for_one_container * (container_id) + _POS_Y_LEGEND_DEFAULT;
        const double w = _width_for_rect_legend;
        const double h = _height_for_rect_legend;

        /* used to print legend on 3 rows */
        int decalage = 0;
220
221
222

        for (map<const EntityValue *, stats *>::iterator it = _states[container_id].begin();
             it != _states[container_id].end();
223
             it ++, decalage ++) {
224
            std::string name = (*it).first->get_name().to_string();
225
            draw_object->draw_text(pos_x+w+_POS_X_LEGEND_DEFAULT, pos_y, name);
226
227
228

            if((*it).first->get_extra_fields()->find(std::string("Color")) != (*it).first->get_extra_fields()->end()) {
                const Color *color = (const Color *)(*it).first->get_extra_fields()->find(std::string("Color"))->second;
229
                draw_object->draw_rect(pos_x, pos_y, w, h, color->get_red(), color->get_green(), color->get_blue());
230
            }
231
232
            else {
                draw_object->draw_rect(pos_x, pos_y, w, h, 0.7, 0.7, 0.75);
233
234
            }

235
236
237
238
239
240
241
242
243
            switch(decalage%3) {
            case 2:
                pos_x += 100;
                pos_y += 40;
                break;
            default:
                pos_y -= 20;
                break;
            }
244
        }
245
    }
246
247


248
249
250
251
252
253
    inline void end_draw(T* draw_object) {
        _previous_start_time = _start_time;
        _previous_end_time = _end_time;
        draw_object->end_draw();
    }

254
    inline void set_times(const double start, const double end) {
255
256
257
258
        _start_time = start;
        _end_time = end;
    }

259
260
261
262
263
    /*! 
     *
     * \return a value between 0. and 1.
     *
     */
264
    virtual double get_max_percentage(std::map<const EntityValue*, stats*> &temp_states) const {
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
        double value;
        double max_length = 0.;
        for (map<const EntityValue *, stats *>::iterator it = temp_states.begin();
             it != temp_states.end();
             it ++) {
            if((*it).second->_total_length >= max_length) {
                max_length = (*it).second->_total_length;
            }
        }
        value = max_length/(_end_time-_start_time);

        //std::cerr << value << std::endl;
        return value;
    }

280
    virtual void updateGL(T* draw_object) const {
281
282
283
        draw_object->updateGL();
    }

284
285
286
};
    
#endif