/* ** 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". ** ** 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. ** ** 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. ** ** 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. ** ** ** ViTE developers are (for version 0.* to 1.0): ** ** - COULOMB Kevin ** - FAVERGE Mathieu ** - JAZEIX Johnny ** - LAGRASSE Olivier ** - MARCOUEILLE Jule ** - NOISETTE Pascal ** - REDONDY Arthur ** - VUCHENER Clément ** */ /*! *\file DrawHDiagram.hpp */ #ifndef DRAW_HDIAGRAM_HPP #define DRAW_HDIAGRAM_HPP /*! * \class DrawHDiagram * \brief Browse the stats and call back T drawing methods */ template class DrawHDiagram : public DrawStats { protected: double _startx; double _starty; double _graph_width; double _draw_width; double _draw_height; double _legend_width; double _legend_height; std::set _setstates; public: /* * \brief The default constructor */ DrawHDiagram() { _startx = _START_HISTOGRAM_X_DEFAULT; _starty = 100.0f; this->_size_for_one_container = _HEIGHT_FOR_ONE_CONTAINER_DEFAULT; this->_percentage_height_default = (this->_size_for_one_container - _START_HISTOGRAM_Y_DEFAULT) / 100.; this->_pos_x_container_name = _POS_X_CONTAINER_NAME; this->_pos_y_container_name = _POS_Y_CONTAINER_NAME; /* Size for rectangles in the legend */ this->_width_for_rect_legend = 20.; this->_height_for_rect_legend = 15.; } /*! * \brief The destructor */ virtual ~DrawHDiagram() = default; /*! * \fn build(T* draw_object, std::vector containers_to_print) * \brief The trace building function. * \param draw_object the kind of object which will be drawn (OpenGL, SVG...). * \param containers_to_print the container's data. */ void build(T* draw_object, std::vector containers_to_print) { int nbcont; draw_object->clear(); _draw_height = draw_object->height(); _draw_width = draw_object->width(); _legend_height = draw_object->height(); _legend_width = draw_object->width(); _graph_width = _draw_width - _startx - 30.; this->_containers_to_print = containers_to_print; nbcont = this->_containers_to_print.size(); draw_object->start_draw(); draw_object->set_total_height( (nbcont+1) * _WIDTH_HISTOGRAM_DEFAULT + 10. ); draw_object->set_total_width( draw_object->width() ); draw_object->draw_axis(_startx, _starty - (nbcont-1)*_WIDTH_HISTOGRAM_DEFAULT, _graph_width + 10., (nbcont+1)*_WIDTH_HISTOGRAM_DEFAULT); draw_object->draw_horizontal_line(_startx, _starty + _WIDTH_HISTOGRAM_DEFAULT, _graph_width + 10.); for (int i=25; i < 101; i+=25) { // Draw Up Scale draw_object->draw_vertical_line(_startx + i*_graph_width/100., _starty + _WIDTH_HISTOGRAM_DEFAULT - 2.5, 5.); draw_object->draw_text(_startx + i*_graph_width/100 - 10., this->_size_for_one_container-(_starty + _WIDTH_HISTOGRAM_DEFAULT + 15.), QString::number(i, 'd', 1).toStdString()+"%"); // Draw Down Scale draw_object->draw_vertical_line(_startx + i*_graph_width/100., _starty - (nbcont-1)*_WIDTH_HISTOGRAM_DEFAULT - 2.5, 5.); draw_object->draw_text(_startx + i*_graph_width/100 - 10., this->_size_for_one_container-(_starty - (nbcont-1)*_WIDTH_HISTOGRAM_DEFAULT - 15.), QString::number(i, 'd', 1).toStdString()+"%"); } for(int i = 0 ; i < nbcont ; i ++) { draw_diagram(draw_object, i); } draw_legend(draw_object, _POS_X_LEGEND_DEFAULT + _startx, _POS_Y_LEGEND_DEFAULT + _starty - (nbcont+3)*_WIDTH_HISTOGRAM_DEFAULT); this->end_draw(draw_object); } /*! * \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. */ void draw_diagram(T* draw_object, const int container_id) { Statistic *stat_temp; std::map temp_states; double duration; int pos_x, pos_y; std::string ctname; stat_temp = new Statistic(); this->_containers_to_print[container_id]->fill_stat(stat_temp, Interval(this->_start_time, this->_end_time)); temp_states = stat_temp->get_states(); duration = this->_end_time - this->_start_time; // Printing of the trace //std::cout << "nb states " << temp_states.size() << std::endl; // Depending on the kind of diagram... pos_x = _startx; pos_y = _starty - container_id * _WIDTH_HISTOGRAM_DEFAULT; // Draw the container name ctname = this->_containers_to_print[container_id]->get_Name().to_string(); draw_object->draw_text(_POS_X_CONTAINER_NAME, this->_size_for_one_container-(pos_y + _WIDTH_HISTOGRAM_DEFAULT / 2. - 5.), ctname); // Draw the stats for (std::map::iterator it = temp_states.begin(); it != temp_states.end(); it ++) { double length = (*it).second->_total_length; double percent = length / duration ; double width = percent * _graph_width; double red = 0.7; double green = 0.7; double blue = 0.75; // 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; red = color->get_red(); green = color->get_green(); blue = color->get_blue(); } draw_object->draw_rect(pos_x, pos_y, width, _WIDTH_HISTOGRAM_DEFAULT, red, green, blue); if ( width > 30. ) draw_object->draw_text(pos_x + width / 2 - 10., this->_size_for_one_container-(pos_y + _WIDTH_HISTOGRAM_DEFAULT / 2. - 5.), QString::number(percent*100., 'f', 1).toStdString()+"%"); pos_x += width; this->_setstates.insert((*it).first); } delete stat_temp; } /*! * \fn draw_legend(T* draw_object, int pos_x, int pos_y) * \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 pos_x the x position of the legend. * \param pos_y the y position of the legend. */ void draw_legend(T* draw_object, int pos_x, int pos_y) { std::set::const_iterator it; std::set::const_iterator end; 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; end = this->_setstates.end(); for (it = this->_setstates.begin(); it != end; it ++, decalage ++) { std::string name = (*it)->get_name(); draw_object->draw_text(pos_x+w+_POS_X_LEGEND_DEFAULT, this->_size_for_one_container-pos_y, name.substr(0, 10)); if((*it)->get_extra_fields()->find(std::string("Color")) != (*it)->get_extra_fields()->end()) { const Color *color = (const Color *)(*it)->get_extra_fields()->find(std::string("Color"))->second; draw_object->draw_rect(pos_x, pos_y, w, h, color->get_red(), color->get_green(), color->get_blue()); } 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; pos_y += 40; break; default: pos_y -= 20; break; } } this->_max_width = pos_x + w + _POS_X_LEGEND_DEFAULT; this->set_geometrical_informations_object(draw_object); } }; #endif