Commit fef11c8a authored by Sylvain Thery's avatar Sylvain Thery

add histogram algo & qt drawer

parent 01ff9703
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __HISTOGRAM__
#define __HISTOGRAM__
#include "Topology/generic/attributeHandler.h"
#include "Geometry/vector_gen.h"
#include "Utils/colorMaps.h"
#include "Utils/vbo.h"
namespace CGoGN
{
namespace Algo
{
namespace Histogram
{
class HistoColorMap
{
protected:
double m_min;
double m_max;
double m_w;
unsigned int m_nb;
public:
virtual ~HistoColorMap() {}
/// set min value (for update from Histogram)
void setMin(double m) {m_min = m; m_w = (m_max -m_min)/double(m_nb);}
/// set max value (for update from Histogram)
void setMax(double m) {m_max = m; m_w = (m_max -m_min)/double(m_nb);}
/// set nb value (for update from Histogram)
void setNb(unsigned int n) {m_nb = n; m_w = (m_max -m_min)/double(m_nb);}
/**
* get color from param: To implement (with call to colormap functions for examples)
*/
virtual Geom::Vec3f color(double v) const = 0 ;
/**
* get color from index (can be overload)
* compute a [0,1[ value from an index [0,nb[
* and call color with it
* Used by Histogram::colorize && Qt::DrawHistogram
*/
virtual Geom::Vec3f colorIndex(unsigned int i) const
{
double v = double(i)/double(m_nb-1) + double(1)/double(m_nb+m_nb);
return color(v);
}
};
/**
* inherits this class by:
* - add xxAttribute& in data (& constructor)
* - overload begin/end/next/nbElements (by calling xxxAttribute.yyy)
* - overload operator [] to return the [i] converted in double with necessary computations.
*/
class AttributeConvertGen
{
public:
virtual unsigned int begin() const = 0;
virtual unsigned int end() const = 0;
virtual void next(unsigned int& i) const = 0;
virtual unsigned int nbElements() const = 0;
virtual double operator[](unsigned int i) const = 0;
virtual ~AttributeConvertGen() {}
};
/**
* Helper class templated by Attribute
* Avoid the writing of begin/end/next/nbElements
*/
template <typename ATT>
class AttributeConvert: public AttributeConvertGen
{
protected:
ATT& attrib;
public:
AttributeConvert(ATT &att): attrib(att) {}
virtual unsigned int begin() const { return attrib.begin();}
virtual unsigned int end() const { return attrib.end();}
virtual void next(unsigned int& i) const { attrib.next(i);}
virtual unsigned int nbElements() const { return attrib.nbElements();}
virtual double operator[](unsigned int i) const = 0;
virtual ~AttributeConvert() {}
};
/**
* Histogram class
* T must have operators -, / ,< ,>
*/
class Histogram
{
// std::vector<double> m_data;
std::vector< std::pair<double, unsigned int> > m_dataIdx;
/// number of classes in attribute
unsigned int m_nbclasses;
/// vector of population
std::vector<unsigned int> m_populations;
/// vector of intervals of quantilles
std::vector<double> m_interv;
/// vector of population for quantilles
std::vector<double> m_pop_quantilles;
/// min value
double m_min;
/// max value
double m_max;
/// interval width (in regular case)
double m_interWidth;
/// max number of population in a class
unsigned int m_nbMin;
/// max values in histo population
unsigned int m_maxBar;
/// max value in quantille population
double m_maxQBar;
HistoColorMap& m_hcolmap;
bool m_sorted;
/// get data
double data(unsigned int i) const;
/// get idx of data in attribute
unsigned int idx(unsigned int i) const;
// comparison function for sorting data
static bool dataComp( const std::pair<double, unsigned int>& a, const std::pair<double, unsigned int>& b);
public:
/**
* create an histogram from attribute handler
*/
Histogram(HistoColorMap& hcm);
/**
* init data
* @param conv a attribute convertor
*/
void initDataConvert(const AttributeConvertGen& conv);
/**
* init data
* @param attr the attribute to copy from
* @param sortForQuantilles sort data vector for quantille generation
*/
template <typename ATTR>
void initData(const ATTR& attr);
/**
* get min value of attribute (perhaps modified by user)
*/
double getMin() const;
/**
* get max value of attribute (perhaps modified by user)
*/
double getMax() const;
/**
* get real min value of attribute
*/
double getQMin() const;
/**
* get real max value of attribute
*/
double getQMax() const;
/**
* set min value of attribute
*/
void setMin(double m);
/**
* set max value of attribute
*/
void setMax(double m);
/**
* get max population value of all bars of histo
*/
unsigned int getMaxBar() const;
/**
* get max population value of all bars of quantilles
*/
double getMaxQBar() const;
/**
* modify min/max values to center Histogram on zero if necessary
*/
void centerOnZero();
/**
* compute the histogram with given numbre of classes
*/
void populateHisto(unsigned int nbclasses=0);
/**
* compute the histogram with given number of classes
*/
void populateQuantilles(unsigned int nbclasses=10);
/**
* which class belong a value
*/
unsigned int whichClass(double val) const;
/**
* which class belong a value
*/
unsigned int whichQuantille(double val) const;
/**
* fill a color attribute
* @param colors attribute to fill
*/
template <typename ATTC>
void histoColorize(ATTC& colors);
/**
* colorize the VBO (RGB)
* @warning GL context must be accessible
* @param vbo the vbo to fill with colors
*/
void histoColorizeVBO(Utils::VBO& vbo);
/**
* fill a color attribute
* @param colors attribute to fill
* @param tc table of color
*/
template<typename ATTC>
void quantillesColorize(ATTC& colors, const std::vector<Geom::Vec3f>& tc);
/**
* fill a color attribute
* @param colors attribute to fill
* @param func colormap function (Geom::Vec3f func(float x)
*/
template<typename ATTC, typename COLORMAP>
void quantillesColorizeFunc(ATTC& colors, COLORMAP func);
/**
* get the vector of class population
*/
const std::vector<unsigned int>& getPopulation() const;
/**
* get the vector of height of quantilles
*/
const std::vector<double>& getQuantillesHeights() const;
/**
* get the vector of intervals bounaries for quantilles
*/
const std::vector<double>& getQuantillesIntervals() const;
/**
* get the colorMap
*/
const HistoColorMap& colorMap() const;
};
}
}
}
#include "Algo/Histogram/histogram.hpp"
#endif
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
// forward
namespace CGoGN
{
namespace Algo
{
namespace Histogram
{
inline Histogram::Histogram( HistoColorMap& hcm):
m_hcolmap(hcm),m_sorted(false)
{
}
inline const std::vector<unsigned int>& Histogram::getPopulation() const
{
return m_populations;
}
inline const std::vector<double>& Histogram::getQuantillesHeights() const
{
return m_pop_quantilles;
}
inline const std::vector<double>& Histogram::getQuantillesIntervals() const
{
return m_interv;
}
inline const HistoColorMap& Histogram::colorMap() const
{
return m_hcolmap;
}
inline double Histogram::getMin() const
{
return m_min;
}
inline double Histogram::getMax() const
{
return m_max;
}
inline double Histogram::getQMin() const
{
return m_dataIdx.front().first;
}
inline double Histogram::getQMax() const
{
return m_dataIdx.back().first;
}
inline unsigned int Histogram::getMaxBar() const
{
return m_maxBar;
}
inline double Histogram::getMaxQBar() const
{
return m_maxQBar;
}
inline void Histogram::setMin(double m)
{
m_min = m;
m_hcolmap.setMin(m);
}
inline void Histogram::setMax(double m)
{
m_max = m;
m_hcolmap.setMax(m);
}
inline void Histogram::centerOnZero()
{
if ((m_min <0.0) && (m_max > 0.0))
{
if ((-m_min) > m_max)
m_max = -m_min;
else
m_min = -m_max;
}
}
template <typename ATTR>
inline void Histogram::initData(const ATTR& attr)
{
unsigned int beg = attr.begin();
m_min = attr[beg];
m_max = m_min;
m_dataIdx.reserve(attr.nbElements());
for (unsigned int i = beg; i!= attr.end(); attr.next(i))
{
double val = attr[i];
m_dataIdx.push_back(std::make_pair(val ,i));
if (val < m_min)
m_min = val;
if (val > m_max)
m_max = val;
}
m_hcolmap.setMin(m_min);
m_hcolmap.setMax(m_max);
}
inline unsigned int Histogram::whichClass(double val) const
{
if (val == m_max)
return m_populations.size()-1;
double x = (val - m_min)/m_interWidth;
if ((x<0) || (val>=m_max))
return -1;
return (unsigned int)(x);
}
inline unsigned int Histogram::whichQuantille(double val) const
{
unsigned int i=1;
while (val > m_interv[i])
++i;
return i-1;
}
template<typename ATTC>
void Histogram::histoColorize(ATTC& colors)
{
unsigned int nb = m_dataIdx.size();
for (unsigned int i = 0; i<nb; ++i)
{
unsigned int j = idx(i);
unsigned int c = whichClass(data(i));
if (c != 0xffffffff)
colors[j] = m_hcolmap.colorIndex(c);
}
}
template<typename ATTC>
void Histogram::quantillesColorize(ATTC& colors, const std::vector<Geom::Vec3f>& tc)
{
unsigned int nb = m_dataIdx.size();
unsigned int nbi = m_interv.size()-1;
assert(tc.size() >= nbi);
unsigned int i=0;
unsigned int j=0;
while ((i<nb) && (j<nbi))
{
while ((i<nb) && (data(i) <= m_interv[j+1]))
colors[ idx(i++) ] = tc[j];
++j;
}
}
/// get data
inline double Histogram::data(unsigned int i) const
{
return m_dataIdx[i].first;
}
/// get idx of data in attribute
inline unsigned int Histogram::idx(unsigned int i) const
{
return m_dataIdx[i].second;
}
// comparison function for sorting data
inline bool Histogram::dataComp( const std::pair<double, unsigned int>& a, const std::pair<double, unsigned int>& b)
{
return a.first < b.first;
}
}
}
}
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __QT_HISTO_DRAW__
#define __QT_HISTO_DRAW__
#include <QWidget>
#include <QPainter>
#include <QMouseEvent>
#include "Utils/Qt/qtpopup.h"
#include "Algo/Histogram/histogram.h"
namespace CGoGN
{
namespace Utils
{
namespace QT
{
class RenderHistogram : public QWidget
{
Q_OBJECT
static const int m_frameWidth = 10;
const Algo::Histogram::Histogram& m_histo;
std::vector<Geom::Vec3f> m_qcolors;
unsigned int m_max;
int m_h;
int m_w;
unsigned int m_l;
std::vector<int> m_vals_ax_left;
int m_axl_nbd;
bool m_drawHisto;
bool m_drawQuantilles;
bool m_histoFront;
float m_opacity;
bool m_drawAxis;
/// draw all in painter
void draw(QPainter& painter);
/// compute left axis value
void axeVals();
public:
/**
* constructor
* @param parent parent widget
* @param histo histogram to draw
*/
RenderHistogram(QWidget* parent, Algo::Histogram::Histogram& histo, bool drawAxis=true );
/// minimum size
virtual QSize minimumSizeHint() const;
/// size at launch
virtual QSize sizeHint() const;
/**
* set color table for quantilles drawing
* @param colors vector of colors
*/
void setQuantillesColors(const std::vector<Geom::Vec3f>& colors);
/***
* svg export
* @param filename file name of svg file
*/
void svgExport(const std::string& filename);
/**
* set histo position (front or back)
* @param hf if true histo is in front of the quantille
*/
void setHistoPosition(bool hf);
/**
* define if histogram is drawn
*/
void setHistoDraw(bool d);
/**
* define if quantille is drawn
*/
void setQuantillesDraw(bool d);
/**
* get bool value that indicate drawing of histogram
*/
bool getHistoDraw();
/**
* get bool value that indicate drawing of quantille
*/
bool getQuantillesDraw();
/**
* get opacity value
*/
float getOpacity();
/**
* define the opacity if the two graphs are drawn
*/
void setOpacity(float op);
/**
* update drawing
*/
void update();
signals:
/**
* emitted signal when a column of histogram is clicked
*/
void clicked(unsigned int, unsigned int);
protected:
/// draw the histogram in painter widget
void drawHisto(QPainter& painter);
/// draw the quatilles in painter widget
void drawQuantilles(QPainter& painter);
/// functinn calles when widget need to be redraw
void paintEvent(QPaintEvent *event);
/// draw the histogram in painter widget
void mousePressEvent(QMouseEvent* event);
};
}
}
}
#endif
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *