DrawVDiagram.hpp 10.3 KB
Newer Older
Mathieu Faverge's avatar
Mathieu Faverge committed
1 2 3 4 5 6 7 8
/*
** This file is part of the ViTE project.
**
** This software is governed by the CeCILL-A license under French law
** and abiding by the rules of distribution of free software. You can
** use, modify and/or redistribute the software under the terms of the
** CeCILL-A license as circulated by CEA, CNRS and INRIA at the following
** URL: "http://www.cecill.info".
9
**
Mathieu Faverge's avatar
Mathieu Faverge committed
10 11 12 13 14
** As a counterpart to the access to the source code and rights to copy,
** modify and redistribute granted by the license, users are provided
** only with a limited warranty and the software's author, the holder of
** the economic rights, and the successive licensors have only limited
** liability.
15
**
Mathieu Faverge's avatar
Mathieu Faverge committed
16 17 18 19 20 21 22 23 24 25
** In this respect, the user's attention is drawn to the risks associated
** with loading, using, modifying and/or developing or reproducing the
** software by the user in light of its specific status of free software,
** that may mean that it is complicated to manipulate, and that also
** therefore means that it is reserved for developers and experienced
** professionals having in-depth computer knowledge. Users are therefore
** encouraged to load and test the software's suitability as regards
** their requirements in conditions enabling the security of their
** systems and/or data to be ensured and, more generally, to use and
** operate it in the same conditions as regards security.
26
**
Mathieu Faverge's avatar
Mathieu Faverge committed
27 28 29 30
** The fact that you are presently reading this means that you have had
** knowledge of the CeCILL-A license and that you accept its terms.
**
**
31
** ViTE developers are (for version 0.* to 1.0):
Mathieu Faverge's avatar
Mathieu Faverge committed
32 33 34 35 36 37 38 39
**
**        - COULOMB Kevin
**        - FAVERGE Mathieu
**        - JAZEIX Johnny
**        - LAGRASSE Olivier
**        - MARCOUEILLE Jule
**        - NOISETTE Pascal
**        - REDONDY Arthur
40
**        - VUCHENER Clément
Mathieu Faverge's avatar
Mathieu Faverge committed
41 42
**
*/
43
/*!
44
 *\file DrawVDiagram.hpp
45 46
 */

47 48
#ifndef DRAW_VDIAGRAM_HPP
#define DRAW_VDIAGRAM_HPP
49 50

/*!
51
 * \class DrawVDiagram
52 53 54
 * \brief Browse the stats and call back T drawing methods
 */
template<class T>
55
class DrawVDiagram : public DrawStats<T> {
56

57 58 59 60
public:
    /*
     * \brief The default constructor
     */
61
    DrawVDiagram() {
62
        this->_size_for_one_container = _HEIGHT_FOR_ONE_CONTAINER_DEFAULT;
63
        set_geometrical_informations();
64 65
    }

66

67 68 69
    /*!
     * \brief The destructor
     */
Mathieu Faverge's avatar
Mathieu Faverge committed
70
    virtual ~DrawVDiagram() = default;
71 72 73


    /*!
74
     * \fn build(T* draw_object, std::vector<Container *> containers_to_print)
75 76
     * \brief The trace building function.
     * \param draw_object the kind of object which will be drawn (OpenGL, SVG...).
77
     * \param containers_to_print the container's data
78 79 80 81 82 83 84 85 86 87 88 89 90 91
     */
    virtual void build(T* draw_object, std::vector<Container *> containers_to_print) {

        draw_object->clear();

        this->_size_for_one_container = draw_object->height();

        this->_containers_to_print = containers_to_print;
        const int number_of_containers = this->_containers_to_print.size();
        draw_object->start_draw();
        draw_object->set_total_height((number_of_containers-1)*this->_size_for_one_container);

        for(int i = 0 ; i < number_of_containers ; i ++) {
            draw_container_name(draw_object, i);
92

93
            draw_diagram(draw_object, i);
94

95 96
            draw_legend(draw_object, i);
        }
Johnny Jazeix's avatar
Johnny Jazeix committed
97 98
        this->set_geometrical_informations_object(draw_object);
        this->end_draw(draw_object);
99 100
    }

101 102 103 104 105 106
    /*!
     * \fn draw_container_name(T* draw_object, const int container_id) const
     * \brief Print the i-th container name
     * \param draw_object the kind of object which will be drawn (OpenGL, SVG...).
     * \param container_id the id of the container.
     */
107 108
    virtual void draw_container_name(T* draw_object, const int container_id) const {
        // Get the position for the i-th container name
109

110 111
        const Element_pos pos_x = this->_pos_x_container_name;
        const Element_pos pos_y = this->_size_for_one_container*(container_id+1)-this->_pos_y_container_name;
Mathieu Faverge's avatar
Mathieu Faverge committed
112
        const std::string name = this->_containers_to_print[container_id]->get_Name().to_string();
113 114


115 116 117
        draw_object->draw_text(pos_x, pos_y, name);
    }

118 119 120 121 122 123
    /*!
     * \fn draw_diagram(T* draw_object, const int container_id)
     * \brief Print the i-th diagram
     * \param draw_object the kind of object which will be drawn (OpenGL, SVG...).
     * \param container_id the id of the container.
     */
124 125 126 127 128 129 130 131
    virtual void draw_diagram(T* draw_object, const int container_id) {
        Statistic *stat_temp = new Statistic();
        this->_containers_to_print[container_id]->fill_stat(stat_temp, Interval(this->_start_time, this->_end_time));
        std::map<const EntityValue*, stats*> temp_states = stat_temp->get_states();
        this->_states.push_back(temp_states);

        // Printing of the trace

132 133 134 135 136
        int pos_x = _START_HISTOGRAM_X_DEFAULT;
        int pos_y = _START_HISTOGRAM_Y_DEFAULT - container_id*this->_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*(this->_states[container_id].size()+1), this->_percentage_height_default*100);
137

138
        draw_object->draw_text(pos_x-35,
139 140 141
                               this->_size_for_one_container-(pos_y+this->_percentage_height_default*100-5),
                               QString::number(max_percentage*100., 'g', 3).toStdString()+"%");

142 143 144 145 146 147 148 149 150 151 152 153 154 155
        draw_object->draw_horizontal_line(pos_x, pos_y+this->_percentage_height_default*100, _WIDTH_HISTOGRAM_DEFAULT*(this->_states[container_id].size()+1));


        // Draw the stats
        for (std::map<const EntityValue *, stats *>::iterator it = temp_states.begin();
             it != temp_states.end();
             it ++) {

            // We have to convert the percentage in a rectangle and print it
            const double length = (*it).second->_total_length;
            const double height = length*100.*this->_percentage_height_default/(this->_end_time-this->_start_time);

            // We search for a color
            if((*it).first->get_extra_fields()->find(std::string("Color")) != (*it).first->get_extra_fields()->end()) {
156 157
                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());
158 159
            }
            else {
160
                draw_object->draw_rect(pos_x, pos_y, _WIDTH_HISTOGRAM_DEFAULT, height/max_percentage, 0.7, 0.7, 0.75);
161 162 163 164
            }

            // We print the percentage above
            draw_object->draw_text(pos_x,
165 166
                                   this->_size_for_one_container-(pos_y+height/max_percentage+1),
                                   QString::number(length/(this->_end_time-this->_start_time)*100., 'f', 1).toStdString()+"%");
167 168 169

            pos_x += _WIDTH_HISTOGRAM_DEFAULT;
        }
170

171 172 173 174 175
        // We check for the width
        if(pos_x > this->_max_width){
            this->_max_width = pos_x;
        }

176 177 178
        delete stat_temp;
    }

179 180 181 182 183 184
    /*!
     * \fn draw_legend(T* draw_object, const int container_id)
     * \brief Print the legend for the i-th element (eg the color of each stats)
     * \param draw_object the kind of object which will be drawn (OpenGL, SVG...).
     * \param container_id the id of the container.
     */
185 186
    virtual void draw_legend(T* draw_object, const int container_id) {
        Element_pos pos_x = _POS_X_CONTAINER_NAME + _POS_X_LEGEND_DEFAULT;
187
        Element_pos pos_y = this->_size_for_one_container * (container_id+1) - _POS_Y_LEGEND_DEFAULT;
188 189 190 191 192 193
        const double w = this->_width_for_rect_legend;
        const double h = this->_height_for_rect_legend;

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

194
        for (std::map<const EntityValue *, stats *>::iterator it = this->_states[container_id].begin();
195 196
             it != this->_states[container_id].end();
             it ++, decalage ++) {
197 198 199

            std::string name = (*it).first->get_name();

200 201
            // We cut the name to don't exceed the place
            draw_object->draw_text(pos_x+w+_POS_X_LEGEND_DEFAULT, pos_y, name.substr(0, 10));
202 203 204

            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;
205
                draw_object->draw_rect(pos_x, this->_size_for_one_container-pos_y, w, h, color->get_red(), color->get_green(), color->get_blue());
206 207 208 209 210 211 212 213
            }
            else {
                draw_object->draw_rect(pos_x, pos_y, w, h, 0.7, 0.7, 0.75);
            }

            switch(decalage%3) {
            case 2:
                pos_x += 100;
214
                pos_y -= 40;
215 216
                break;
            default:
217
                pos_y += 20;
218 219 220
                break;
            }
        }
221 222 223 224 225

        // We check for the width
        if(pos_x > this->_max_width){
            this->_max_width = pos_x;
        }
226 227 228
    }


229
    /*!
230 231 232
     * \fn get_max_percentage(std::map<const EntityValue*, stats*> &temp_states) const
     * \brief Get the biggest percentage of times for all the stats
     * \param temp_states The stats where we want to get the longest
233 234 235 236 237 238 239
     *
     * \return a value between 0. and 1.
     *
     */
    virtual double get_max_percentage(std::map<const EntityValue*, stats*> &temp_states) const {
        double value;
        double max_length = 0.;
240
        for (std::map<const EntityValue *, stats *>::const_iterator it = temp_states.begin();
241 242 243 244 245 246 247 248 249 250 251
             it != temp_states.end();
             it ++) {
            if((*it).second->_total_length >= max_length) {
                max_length = (*it).second->_total_length;
            }
        }
        value = max_length/(this->_end_time-this->_start_time);

        return value;
    }

252

253
    /*!
254 255 256
     * \fn set_geometrical_informations()
     * \brief Set some infos for the displaying
     */
257 258
    void set_geometrical_informations() {
        this->_pos_x_container_name = _POS_X_CONTAINER_NAME;
259
        this->_pos_y_container_name = this->_size_for_one_container - 50;
260

261
        this->_percentage_height_default = (this->_size_for_one_container - _START_HISTOGRAM_Y_DEFAULT - 20) / 100.;
262

263 264 265 266 267 268
        /* Size for rectangles in the legend */
        this->_width_for_rect_legend = 20.;
        this->_height_for_rect_legend = 15.;
        this->_max_width = 0;
    }

269
};
270

271
#endif