Commit 2e30bf2f authored by Mathieu Faverge's avatar Mathieu Faverge
Browse files

First version of Horizontal diagramm, legend needs to be completed, and first...

First version of Horizontal diagramm, legend needs to be completed, and first drawing method should be exported in an other class
parent 5598d54f
......@@ -83,8 +83,13 @@
</property>
</widget>
</item>
<item row="2" column="1" >
<item row="3" column="1" >
<widget class="QComboBox" name="_kind_of_diagram_box" >
<item>
<property name="text" >
<string>Horizontal Histogram</string>
</property>
</item>
<item>
<property name="text" >
<string>Histogram</string>
......
......@@ -90,6 +90,14 @@ public:
*/
void draw_horizontal_line(const Element_pos x, const Element_pos y, const Element_pos size_x);
/*!
* \brief Draw a line.
* \param x the x position of the text.
* \param y the y position of the text.
* \param value the string value of the text.
*/
void draw_vertical_line(const Element_pos x, const Element_pos y, const Element_pos size_x);
void draw_axis(const Element_pos x, const Element_pos y, const Element_pos size_x, const Element_pos size_y);
/*!
* \brief Draw a rectangle.
......@@ -147,6 +155,16 @@ inline void Render_stats_opengl::draw_horizontal_line(const Element_pos x, const
glEnd();
}
inline void Render_stats_opengl::draw_vertical_line(const Element_pos x, const Element_pos y, const Element_pos size_y){
glBegin(GL_LINES);
{
glColor3ub(0, 0, 0);
glVertex2i(x, y);
glVertex2i(x, y+size_y);
}
glEnd();
}
inline void Render_stats_opengl::draw_axis(const Element_pos x, const Element_pos y, const Element_pos size_x, const Element_pos size_y){
glBegin(GL_LINES);
{
......
/*!
*\file DrawStats.hpp
*/
#ifndef DRAW_HDIAGRAM_HPP
#define DRAW_HDIAGRAM_HPP
#include <string>
#include <vector>
#include <map>
#include "../message/Message.hpp"
#include "../trace/Trace.hpp"
#include "../trace/tree/Interval.hpp"
#include "Statistic.hpp"
#include "DrawStats.hpp"
template<class T>
class DrawHDiagram : public DrawStats<T> {
protected:
double _startx;
double _starty;
double _graph_width;
double _draw_width;
double _draw_height;
double _legend_width;
double _legend_height;
public:
/*
* \brief The default constructor
*/
DrawHDiagram() {
_startx = _START_HISTOGRAM_X_DEFAULT;
_starty = 200.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() {
}
/*!
* \fn build(T* draw_object, Trace* trace)
* \brief The trace building function.
* \param draw_object the kind of object which will be drawn (OpenGL, SVG...).
* \param trace the trace data.
*/
void build(T* draw_object, std::vector<Container *> 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.,
_starty + _WIDTH_HISTOGRAM_DEFAULT + 15.,
QString::number(i, 'd', 1).toStdString()+"%");
// Dra 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.,
_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);
end_draw(draw_object);
}
void draw_diagram(T* draw_object, const int container_id) {
Statistic *stat_temp;
std::map<const EntityValue*, stats*> 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();
this->_states.push_back(temp_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,
pos_y + _WIDTH_HISTOGRAM_DEFAULT / 2. - 5.,
ctname);
// Draw the stats
for (map<const EntityValue *, stats *>::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;
std::string name = (*it).first->get_name().to_string();
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., pos_y + _WIDTH_HISTOGRAM_DEFAULT / 2. - 5.,
QString::number(percent*100., 'f', 1).toStdString()+"%");
pos_x += width;
}
delete stat_temp;
}
void draw_legend(T* draw_object, int pos_x, int pos_y) {
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;
for (map<const EntityValue *, stats *>::iterator it = this->_states[0].begin();
it != this->_states[0].end();
it ++, decalage ++) {
std::string name = (*it).first->get_name().to_string();
draw_object->draw_text(pos_x+w+_POS_X_LEGEND_DEFAULT, pos_y, name);
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, 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;
}
}
}
};
#endif
......@@ -124,13 +124,12 @@ public:
/*!
* \fn build(T* draw_object, Trace* trace, std::string kind_of_diagram)
* \fn build(T* draw_object, Trace* trace)
* \brief The trace building function.
* \param draw_object the kind of object which will be drawn (OpenGL, SVG...).
* \param trace the trace data.
* \param kind_of_diagram the kind of diagram (histogram, chart...)
*/
void build(T* draw_object, std::vector<Container *> containers_to_print, std::string kind_of_diagram) {
virtual void build(T* draw_object, std::vector<Container *> containers_to_print) {
draw_object->clear();
......@@ -145,14 +144,14 @@ public:
for(int i = 0 ; i < number_of_containers ; i ++) {
draw_container_name(draw_object, i);
draw_diagram(draw_object, i, kind_of_diagram);
draw_diagram(draw_object, i);
draw_legend(draw_object, i);
}
end_draw(draw_object);
}
void draw_container_name(T* draw_object, const int container_id) const {
virtual void draw_container_name(T* draw_object, const int container_id) const {
// Get the position for the i-th container name
Element_pos pos_x = _pos_x_container_name;
......@@ -163,7 +162,7 @@ public:
draw_object->draw_text(pos_x, pos_y, name);
}
void draw_diagram(T* draw_object, const int container_id, std::string kind_of_diagram) {
virtual void draw_diagram(T* draw_object, const int container_id) {
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();
......@@ -171,53 +170,46 @@ public:
// Printing of the trace
// Depending on the kind of diagram...
if(kind_of_diagram == "Histogram") {
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;
}
}
else {
*Message::get_instance() << kind_of_diagram << " not yet implemented" << Message::endw;
}
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;
}
delete stat_temp;
}
void draw_legend(T* draw_object, const int container_id) {
virtual void draw_legend(T* draw_object, const int container_id) {
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;
......@@ -269,7 +261,7 @@ public:
* \return a value between 0. and 1.
*
*/
double get_max_percentage(std::map<const EntityValue*, stats*> &temp_states) const {
virtual double get_max_percentage(std::map<const EntityValue*, stats*> &temp_states) const {
double value;
double max_length = 0.;
for (map<const EntityValue *, stats *>::iterator it = temp_states.begin();
......@@ -285,7 +277,7 @@ public:
return value;
}
void updateGL(T* draw_object) const {
virtual void updateGL(T* draw_object) const {
draw_object->updateGL();
}
......
......@@ -79,7 +79,7 @@ void Stats_window::init_window() {
void Stats_window::on_reload_button_clicked() {
std::string kind_of_diagram = _kind_of_diagram_box->currentText ().toStdString();
// We delete the previous selected containers
if(!_selected_containers.empty()) {
_selected_containers.clear();
......@@ -105,12 +105,30 @@ void Stats_window::on_reload_button_clicked() {
// We get the times
_start_time = _start_time_widget->text().toDouble();
_end_time = _end_time_widget->text().toDouble();
_end_time = _end_time_widget->text().toDouble();
// We create a drawer
DrawStats<Render_stats_opengl> drawer;
drawer.set_times(_start_time, _end_time);
drawer.build(_ui_stats_area, _selected_containers, _kind_of_diagram_box->currentText ().toStdString());
DrawStats<Render_stats_opengl> *drawer;
if(kind_of_diagram == "Horizontal Histogram")
{
drawer = new DrawHDiagram<Render_stats_opengl>();
}
else if (kind_of_diagram == "Histogram")
{
drawer = new DrawStats<Render_stats_opengl>();
}
else if (kind_of_diagram == "Chart")
{
*Message::get_instance() << kind_of_diagram << " not yet implemented" << Message::endw;
drawer = new DrawStats<Render_stats_opengl>();
}
else
{
*Message::get_instance() << kind_of_diagram << " not yet implemented" << Message::endw;
drawer = new DrawStats<Render_stats_opengl>();
}
drawer->set_times(_start_time, _end_time);
drawer->build(_ui_stats_area, _selected_containers);
_ui_stats_area->updateGL();
}
......
......@@ -20,6 +20,7 @@ class Stats_window;
#include "../message/Message.hpp"
#include "../render/render_stats_opengl.hpp"
#include "DrawStats.hpp"
#include "DrawHDiagram.hpp"
/*!
* \brief Class used to display statistics of containers.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment