##// END OF EJS Templates
improvements in execution time, colorbar ok, more work to do on axes,
improvements in execution time, colorbar ok, more work to do on axes,

File last commit:

r3:ab1c9ba54a31 default
r3:ab1c9ba54a31 default
Show More
qcolormapseries.cpp
631 lines | 16.6 KiB | text/x-c | CppLexer
winter
first init : ColorMapChart added to QtCharts
r0 #include "qcolormapseries.h"
#include <private/qcolormapseries_p.h>
#include <private/abstractdomain_p.h>
#include <QtCharts/QValueAxis>
#include <private/colormapchart_p.h>
#include <QtCharts/QColorMapLegendMarker>
#include <private/charthelpers_p.h>
#include <private/qchart_p.h>
#include <QtGui/QPainter>
//#include <algorithm>
#include <cmath>
winter
more work on colorbar axis, stuck with qtchart mecanism
r2 #include "qcolorbaraxis.h"
winter
first init : ColorMapChart added to QtCharts
r0 QT_CHARTS_BEGIN_NAMESPACE
/*!
\internal
Constructs empty series object which is a child of \a parent.
When series object is added to QChart instance ownerships is transferred.
*/
QColorMapSeries::QColorMapSeries(QObject *parent)
: QAbstractSeries(*new QColorMapSeriesPrivate(this), parent)
{
}
/*!
\internal
Constructs empty series object which is a child of \a parent.
When series object is added to QChart instance ownerships is transferred.
*/
QColorMapSeries::QColorMapSeries(QColorMapSeriesPrivate &d, QObject *parent)
: QAbstractSeries(d, parent)
{
}
/*!
Destroys the object. Series added to QChart instances are owned by those,
and are destroyed when QChart instances are destroyed.
*/
QColorMapSeries::~QColorMapSeries()
{
}
/*!
\fn virtual SeriesType QBoxPlotSeries::type() const
\brief Returns type of series.
\sa QAbstractSeries, SeriesType
*/
QAbstractSeries::SeriesType QColorMapSeries::type() const
{
return QAbstractSeries::SeriesTypeColorMap;
}
/*!
Adds data part \a dataPart to the series.\n
If \a copy is true, adds a copy of the data part instead.
*/
void QColorMapSeries::append(ColorMapDataPart* dataPart, bool copy)
{
Q_D(QColorMapSeries);
if(copy)
d->m_dataParts << new ColorMapDataPart(dataPart);
else
d->m_dataParts << dataPart;
d->recomputeDataRange();
emit dataPartAdded(d->m_dataParts.count() - 1);
}
/*!
This is an overloaded function.\n
Adds data parts \a dataParts to the series.\n
If \a copy is true, adds a copy of the data part instead.
*/
void QColorMapSeries::append(const QList<ColorMapDataPart*> &dataParts, bool copy)
{
foreach (ColorMapDataPart* dataPart , dataParts)
append(dataPart,copy);
}
/*!
Returns number of data parts within series.
*/
int QColorMapSeries::count() const
{
Q_D(const QColorMapSeries);
return d->m_dataParts.count();
}
/*!
Stream operator for adding a data part \a point to the series.
\sa append()
*/
QColorMapSeries &QColorMapSeries::operator <<(const ColorMapDataPart &dataPart)
{
append(new ColorMapDataPart(dataPart));
return *this;
}
/*!
Stream operator for adding a vector of data parts \a dataParts to the series.
\sa append()
*/
QColorMapSeries &QColorMapSeries::operator <<(const QList<ColorMapDataPart*> &dataParts)
{
append(dataParts);
return *this;
}
/*!
Returns a ColorMapData part containing a uniform grid of data points to be mapped in a ColorMapChart.\n
The rectangle of data returned is determined by \a width and \height,\n
from the position \a xpos , \a ypos (starting at the top left corner of the plot area).\n
When there are more points than pixels, \a strategy is applied to determine which to choose.
*/
winter
improvements in execution time, colorbar ok, more work to do on axes,
r3 QVector<double> *QColorMapSeries::getUniformGrid(int xpos, int ypos,int width, int height, QColorMapSeries::Strategy strategy)
winter
first init : ColorMapChart added to QtCharts
r0 {
Q_D(QColorMapSeries);
return d->getUniformGrid(xpos, ypos,width,height, strategy);
}
winter
more work on colorbar axis, stuck with qtchart mecanism
r2 //void QColorMapSeries::attachAxis(QAbstractAxis *axis)
//{
// axis = static_cast<QColorBarAxis*>();
// if(axis)
// {
// }
// else
// {
// QAbstractSeries::attachAxis(axis);
// }
//}
winter
first init : ColorMapChart added to QtCharts
r0 /*!
Sets \a pen used for drawing points on the chart. If the pen is not defined, the
pen from chart theme is used.
\sa QChart::setTheme()
*/
void QColorMapSeries::setPen(const QPen &pen)
{
Q_D(QColorMapSeries);
if (d->m_pen != pen)
{
winter
more work on colorbar axis, stuck with qtchart mecanism
r2 //bool emitColorChanged = d->m_pen.color() != pen.color();
winter
first init : ColorMapChart added to QtCharts
r0 d->m_pen = pen;
emit d->updated();
winter
more work on colorbar axis, stuck with qtchart mecanism
r2 // if (emitColorChanged)
// emit colorChanged(pen.color());
winter
first init : ColorMapChart added to QtCharts
r0 emit penChanged(pen);
}
}
QPen QColorMapSeries::pen() const
{
Q_D(const QColorMapSeries);
if (d->m_pen == QChartPrivate::defaultPen())
return QPen();
else
return d->m_pen;
}
/*!
Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
from chart theme setting is used.
\sa QChart::setTheme()
*/
void QColorMapSeries::setBrush(const QBrush &brush)
{
Q_D(QColorMapSeries);
if (d->m_brush != brush)
{
d->m_brush = brush;
emit d->updated();
}
}
QBrush QColorMapSeries::brush() const
{
Q_D(const QColorMapSeries);
if (d->m_brush == QChartPrivate::defaultBrush())
return QBrush();
else
return d->m_brush;
}
//void QColorMapSeries::setColor(const QColor &color)
//{
// QPen p = pen();
// if (p.color() != color)
// {
// p.setColor(color);
// setPen(p);
// }
//}
//QColor QColorMapSeries::color() const
//{
// return pen().color();
//}
//void QColorMapSeries::setPointsVisible(bool visible)
//{
// Q_D(QColorMapSeries);
// if (d->m_pointsVisible != visible)
// {
// d->m_pointsVisible = visible;
// emit d->updated();
// }
//}
//bool QColorMapSeries::pointsVisible() const
//{
// Q_D(const QColorMapSeries);
// return d->m_pointsVisible;
//}
//void QColorMapSeries::setPointLabelsFormat(const QString &format)
//{
// Q_D(QColorMapSeries);
// if (d->m_pointLabelsFormat != format)
// {
// d->m_pointLabelsFormat = format;
// emit pointLabelsFormatChanged(format);
// }
//}
//QString QColorMapSeries::pointLabelsFormat() const
//{
// Q_D(const QColorMapSeries);
// return d->m_pointLabelsFormat;
//}
//void QColorMapSeries::setPointLabelsVisible(bool visible)
//{
// Q_D(QColorMapSeries);
// if (d->m_pointLabelsVisible != visible)
// {
// d->m_pointLabelsVisible = visible;
// emit pointLabelsVisibilityChanged(visible);
// }
//}
//bool QColorMapSeries::pointLabelsVisible() const
//{
// Q_D(const QColorMapSeries);
// return d->m_pointLabelsVisible;
//}
//void QColorMapSeries::setPointLabelsFont(const QFont &font)
//{
// Q_D(QColorMapSeries);
// if (d->m_pointLabelsFont != font) {
// d->m_pointLabelsFont = font;
// emit pointLabelsFontChanged(font);
// }
//}
//QFont QColorMapSeries::pointLabelsFont() const
//{
// Q_D(const QColorMapSeries);
// return d->m_pointLabelsFont;
//}
//void QColorMapSeries::setPointLabelsColor(const QColor &color)
//{
// Q_D(QColorMapSeries);
// if (d->m_pointLabelsColor != color) {
// d->m_pointLabelsColor = color;
// emit pointLabelsColorChanged(color);
// }
//}
//QColor QColorMapSeries::pointLabelsColor() const
//{
// Q_D(const QColorMapSeries);
// if (d->m_pointLabelsColor == QChartPrivate::defaultPen().color())
// return QPen().color();
// else
// return d->m_pointLabelsColor;
//}
//void QColorMapSeries::setPointLabelsClipping(bool enabled)
//{
// Q_D(QColorMapSeries);
// if (d->m_pointLabelsClipping != enabled) {
// d->m_pointLabelsClipping = enabled;
// emit pointLabelsClippingChanged(enabled);
// }
//}
//bool QColorMapSeries::pointLabelsClipping() const
//{
// Q_D(const QColorMapSeries);
// return d->m_pointLabelsClipping;
//}
/*!
Returns the minimum value of the series on the X axis.
*/
double QColorMapSeries::minX()
{
Q_D(QColorMapSeries);
return d->m_minX;
}
/*!
Returns the minimum value of the series on the Y axis.
*/
double QColorMapSeries::minY()
{
Q_D(QColorMapSeries);
return d->m_minY;
}
/*!
Returns the minimum value of the series on the Z axis.
*/
double QColorMapSeries::minZ()
{
Q_D(QColorMapSeries);
return d->m_minZ;
}
/*!
Returns the maximum value of the series on the X axis.
*/
double QColorMapSeries::maxX()
{
Q_D(QColorMapSeries);
return d->m_maxX;
}
/*!
Returns the maximum value of the series on the Y axis.
*/
double QColorMapSeries::maxY()
{
Q_D(QColorMapSeries);
return d->m_maxY;
}
/*!
Returns the maximum value of the series on the Z axis.
*/
double QColorMapSeries::maxZ()
{
Q_D(QColorMapSeries);
return d->m_maxZ;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QColorMapSeriesPrivate::QColorMapSeriesPrivate(QColorMapSeries *q)
: QAbstractSeriesPrivate(q),
m_pen(QChartPrivate::defaultPen()),
m_brush(QChartPrivate::defaultBrush()),
m_pointsVisible(false),
m_pointLabelsFormat(QLatin1String("@xPoint, @yPoint")), //TODO : change
m_pointLabelsVisible(false),
m_pointLabelsFont(QChartPrivate::defaultFont()),
m_pointLabelsColor(QChartPrivate::defaultPen().color()),
m_pointLabelsClipping(true)
{
}
void QColorMapSeriesPrivate::initializeGraphics(QGraphicsItem* parent)
{
Q_Q(QColorMapSeries);
ColorMapChart *colormap = new ColorMapChart(q,parent);
m_item.reset(colormap);
QAbstractSeriesPrivate::initializeGraphics(parent);
}
void QColorMapSeriesPrivate::initializeDomain()
{
domain()->setRange(m_minX, m_maxX, m_minY, m_maxY);
}
void QColorMapSeriesPrivate::initializeTheme(int index, ChartTheme* theme, bool forced)
{
// Q_Q(QColorMapSeries);
// const QList<QGradient> gradients = theme->seriesGradients();
// const QList<QColor> colors = theme->seriesColors();
// if (forced || QChartPrivate::defaultPen() == m_pen) {
// QPen pen;
// pen.setColor(ChartThemeManager::colorAt(gradients.at(index % gradients.size()), 0.0));
// pen.setWidthF(2);
// q->setPen(pen);
// }
// if (forced || QChartPrivate::defaultBrush() == m_brush) {
// QBrush brush(colors.at(index % colors.size()));
// q->setBrush(brush);
// }
// if (forced || QChartPrivate::defaultPen().color() == m_pointLabelsColor) {
// QColor color = theme->labelBrush().color();
// q->setPointLabelsColor(color);
// }
}
QList<QLegendMarker*> QColorMapSeriesPrivate::createLegendMarkers(QLegend* legend)
{
Q_Q(QColorMapSeries);
QList<QLegendMarker*> list;
return list << new QColorMapLegendMarker(q,legend);
}
void QColorMapSeriesPrivate::initializeAxes()
{
}
QAbstractAxis::AxisType QColorMapSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
{
Q_UNUSED(orientation);
return QAbstractAxis::AxisTypeValue;
}
QAbstractAxis* QColorMapSeriesPrivate::createDefaultAxis(Qt::Orientation orientation) const
{
Q_UNUSED(orientation);
return new QValueAxis;
}
winter
improvements in execution time, colorbar ok, more work to do on axes,
r3 QVector<double> *QColorMapSeriesPrivate::getUniformGrid(int xpos, int ypos, int width, int height, QColorMapSeries::Strategy strategy)
winter
first init : ColorMapChart added to QtCharts
r0 {
winter
improvements in execution time, colorbar ok, more work to do on axes,
r3 QVector<double> *grid = new QVector<double>(width*height);
winter
first init : ColorMapChart added to QtCharts
r0
double dx = (m_maxX - m_minX)/(double)width;
double dy = (m_maxY - m_minY)/(double)height;
int x=0;
int y=0;
winter
improvements in execution time, colorbar ok, more work to do on axes,
r3 QVector<Point3D> cluster;
cluster.reserve(height*width/1000);
winter
first init : ColorMapChart added to QtCharts
r0
winter
improvements in execution time, colorbar ok, more work to do on axes,
r3 for (auto cell= grid->begin();cell<grid->end();++cell)
winter
first init : ColorMapChart added to QtCharts
r0 {
winter
improvements in execution time, colorbar ok, more work to do on axes,
r3 cluster.resize(0);
winter
first init : ColorMapChart added to QtCharts
r0 this->buildCluster(x,y,dx,dy,cluster);
if(strategy == QColorMapSeries::LastPixel)
*cell=this->clusterStrategyLast(cluster);
else if(strategy == QColorMapSeries::MeanPixel)
*cell=this->clusterStrategyMean(cluster);
else if(strategy == QColorMapSeries::MedianPixel)
*cell=this->clusterStrategyMedian(cluster);
if(x<width-1)
{
x++;
}
else
{
x=0;
y++;
}
}
winter
improvements in execution time, colorbar ok, more work to do on axes,
r3
winter
first init : ColorMapChart added to QtCharts
r0 return grid;
}
/*!
Recompute the data range on X, Y and Z axes each time a ColorMapDataPart is added to the series.\n
The minimum distance between 2 adjacent values on X and Y axis is added to the maximum on X and Y respectively\n
in order to take account of the width of the last element.
*/
void QColorMapSeriesPrivate::recomputeDataRange()
{
//TODO : if non empty
m_minX = m_dataParts.first()->timesSeries().first();
m_maxX = m_dataParts.last()->timesSeries().last();
m_minY = m_dataParts.last()->ySeries().last();
m_maxY = m_dataParts.last()->ySeries().first();
m_minZ = m_dataParts.first()->dataSeries().first();
m_maxZ = m_dataParts.last()->dataSeries().last();
double minDeltaX=m_maxX-m_minX;
double minDeltaY=m_minY-m_maxY;
foreach(ColorMapDataPart* datapart, m_dataParts)
{
m_minY = qMin(datapart->ySeries().first(),m_minY);
m_maxY = qMax(datapart->ySeries().last(),m_maxY);
for(int i=1;i<datapart->timesSeries().size();i++)
{
double newDeltaX=datapart->timesSeries()[i]-datapart->timesSeries()[i-1];
minDeltaX=qMin(minDeltaX,newDeltaX);
}
for(int i=1;i<datapart->ySeries().size();i++)
{
double newDeltaY=datapart->ySeries()[i]-datapart->ySeries()[i-1];
minDeltaY=qMin(minDeltaY,newDeltaY);
}
for (int i = 0; i < datapart->dataSeries().count(); i++)
{
double z = datapart->dataSeries().at(i);
m_minZ = qMin(m_minZ, z);
m_maxZ = qMax(m_maxZ, z);
}
}
m_maxX+=minDeltaX;
m_maxY+=minDeltaY;
}
/*!
Returns the last value (bottom right Z value) of a \a cluster of points passed as argument.
*/
double QColorMapSeriesPrivate::clusterStrategyLast(QVector<Point3D>& cluster)
{
if(!cluster.isEmpty())
return cluster.last().value();
return 0;
}
/*!
Returns the mean value (mean Z value) of a \a cluster of points passed as argument.
*/
double QColorMapSeriesPrivate::clusterStrategyMean(QVector<Point3D>& cluster)
{
if(!cluster.isEmpty())
{
double sum=0;
int count =0;
for(int i =0;i<cluster.size();i++)
{
if(!isnan(Point3D(cluster.at(i)).value()))
{
sum+= Point3D(cluster.at(i)).value();
count++;
}
}
return (sum/count);
}
return 0;
}
/*!
Returns the median value (median Z value) of a \a cluster of points passed as argument.
*/
double QColorMapSeriesPrivate::clusterStrategyMedian(QVector<Point3D>& cluster)
{
if(!cluster.isEmpty())
{
QVector<double> *copy = new QVector<double>();
for(int i =0;i<cluster.size();i++)
{
if(!isnan(Point3D(cluster.at(i)).value()))
copy->append(Point3D(cluster.at(i)).value());
}
if(!copy->isEmpty())
{
std::sort(copy->begin(), copy->end());
if(copy->count() & 1) // odd
{
int middle = (copy->count()+1)/2;
return copy->at(middle-1);
}
else //even
{
int middle = copy->count()/2;
return (copy->at(middle-1)+copy->at(middle))/2;
}
}
}
return 0;
}
/*!
Computes which data points correspond to the given position and returns the in a \a cluster.
*/
winter
work on color bar axis
r1 void QColorMapSeriesPrivate::buildCluster(int xpos, int ypos, double dx, double dy, QVector<Point3D>& cluster)
{
foreach(ColorMapDataPart *dataPart, m_dataParts)
winter
first init : ColorMapChart added to QtCharts
r0 {
winter
work on color bar axis
r1 QPair<int,int> xRange = dataPart->getRange(dataPart->timesSeries(),m_minX+xpos*dx,m_minX+(xpos+1)*dx);
QPair<int,int> yRange = dataPart->getRange(dataPart->ySeries(),m_maxY-(ypos+1)*dy,m_maxY-ypos*dy);
winter
improvements in execution time, colorbar ok, more work to do on axes,
r3 int timeSeriesSize = dataPart->timesSeries().size();
winter
work on color bar axis
r1 if(xRange.first != xRange.second && yRange.first != yRange.second)
winter
first init : ColorMapChart added to QtCharts
r0 {
winter
work on color bar axis
r1 for(int i =xRange.first+1;i<xRange.second;i++)
winter
first init : ColorMapChart added to QtCharts
r0 {
winter
work on color bar axis
r1 qreal xval=dataPart->timesSeries()[i];
for(int j=yRange.first+1;j<yRange.second;j++)
winter
first init : ColorMapChart added to QtCharts
r0 {
winter
work on color bar axis
r1 qreal yval=dataPart->ySeries()[j];
winter
improvements in execution time, colorbar ok, more work to do on axes,
r3 qreal val=dataPart->dataSeries()[ i + (timeSeriesSize * j)];
winter
work on color bar axis
r1 cluster.append(Point3D(xval,yval,val));
winter
first init : ColorMapChart added to QtCharts
r0 }
}
}
}
winter
work on color bar axis
r1 }
winter
first init : ColorMapChart added to QtCharts
r0
winter
work on color bar axis
r1 void QColorMapSeriesPrivate::initializeAnimations(QtCharts::QChart::AnimationOptions options,
int duration, QEasingCurve &curve)
{
// ColorMapChart *item = static_cast<ColorMapChart *>(m_item.data());
// Q_ASSERT(item);
// if (item->animation())
// item->animation()->stopAndDestroyLater();
winter
first init : ColorMapChart added to QtCharts
r0
winter
work on color bar axis
r1 // if (options.testFlag(QChart::SeriesAnimations))
// item->setAnimation(new XYAnimation(item, duration, curve));
// else
// item->setAnimation(0);
QAbstractSeriesPrivate::initializeAnimations(options, duration, curve);
}
winter
first init : ColorMapChart added to QtCharts
r0
#include "moc_qcolormapseries.cpp"
#include "moc_qcolormapseries_p.cpp"
winter
work on color bar axis
r1 QT_CHARTS_END_NAMESPACE