From 905c34fe48adaf94c782a27cece33e9bba5fb162 2016-06-29 21:57:04 From: jeandet Date: 2016-06-29 21:57:04 Subject: [PATCH] Initial ColorMap Chart implementation. Signed-off-by: jeandet --- diff --git a/src/charts/axis/axis.pri b/src/charts/axis/axis.pri index 340f5b3..541f175 100644 --- a/src/charts/axis/axis.pri +++ b/src/charts/axis/axis.pri @@ -4,7 +4,8 @@ INCLUDEPATH += $$PWD \ $$PWD/valueaxis \ $$PWD/barcategoryaxis \ $$PWD/categoryaxis \ - $$PWD/logvalueaxis + $$PWD/logvalueaxis \ + $$PWD/colorbaraxis SOURCES += \ $$PWD/chartaxiselement.cpp \ @@ -23,7 +24,9 @@ SOURCES += \ $$PWD/categoryaxis/qcategoryaxis.cpp \ $$PWD/logvalueaxis/chartlogvalueaxisx.cpp \ $$PWD/logvalueaxis/chartlogvalueaxisy.cpp \ - $$PWD/logvalueaxis/qlogvalueaxis.cpp + $$PWD/logvalueaxis/qlogvalueaxis.cpp \ + $$PWD/colorbaraxis/qcolorbaraxis.cpp \ + $$PWD/colorbaraxis/chartcolorbaraxisy.cpp PRIVATE_HEADERS += \ $$PWD/chartaxiselement_p.h \ @@ -43,7 +46,9 @@ PRIVATE_HEADERS += \ $$PWD/categoryaxis/qcategoryaxis_p.h \ $$PWD/logvalueaxis/chartlogvalueaxisx_p.h \ $$PWD/logvalueaxis/chartlogvalueaxisy_p.h \ - $$PWD/logvalueaxis/qlogvalueaxis_p.h + $$PWD/logvalueaxis/qlogvalueaxis_p.h \ + $$PWD/colorbaraxis/qcolorbaraxis_p.h \ + $$PWD/colorbaraxis/chartcolorbaraxisy_p.h PUBLIC_HEADERS += \ $$PWD/qabstractaxis.h \ @@ -51,6 +56,7 @@ PUBLIC_HEADERS += \ $$PWD/barcategoryaxis/qbarcategoryaxis.h \ $$PWD/categoryaxis/qcategoryaxis.h \ $$PWD/logvalueaxis/qlogvalueaxis.h \ + $$PWD/colorbaraxis/qcolorbaraxis.h # polar SOURCES += \ diff --git a/src/charts/axis/colorbaraxis/chartcolorbaraxisy.cpp b/src/charts/axis/colorbaraxis/chartcolorbaraxisy.cpp new file mode 100644 index 0000000..64bd4f4 --- /dev/null +++ b/src/charts/axis/colorbaraxis/chartcolorbaraxisy.cpp @@ -0,0 +1,179 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#include "chartcolorbaraxisy_p.h" +#include +#include +//#include +#include "colorbaraxis/qcolorbaraxis.h" +#include +#include +#include +#include + +QT_CHARTS_BEGIN_NAMESPACE + +ChartColorBarAxisY::ChartColorBarAxisY(QColorBarAxis *axis, QPoint pos, qreal height, QLinearGradient gradient, QGraphicsItem *item) + : VerticalAxis(axis, item), + m_axis(axis), + m_gradient(gradient), + m_position(pos), + m_height(height) +{ + QObject::connect(m_axis, SIGNAL(tickCountChanged(int)), this, SLOT(handleTickCountChanged(int))); + QObject::connect(m_axis, SIGNAL(minorTickCountChanged(int)), + this, SLOT(handleMinorTickCountChanged(int))); + QObject::connect(m_axis, SIGNAL(labelFormatChanged(QString)), this, SLOT(handleLabelFormatChanged(QString))); + + createColorBar(); + +} + +ChartColorBarAxisY::~ChartColorBarAxisY() +{ +} + +QVector ChartColorBarAxisY::calculateLayout() const +{ + int tickCount = m_axis->tickCount(); + + Q_ASSERT(tickCount >= 2); + + QVector points; + points.resize(tickCount); + + const QRectF &gridRect = gridGeometry(); + + const qreal deltaY = gridRect.height() / (qreal(tickCount) - 1.0); + for (int i = 0; i < tickCount; ++i) + points[i] = qreal(i) * -deltaY + gridRect.bottom(); + + return points; +} + +void ChartColorBarAxisY::updateGeometry() +{ + const QVector &layout = ChartAxisElement::layout(); + if (layout.isEmpty()) + return; + setLabels(createValueLabels(min(),max(),layout.size(),m_axis->labelFormat())); + VerticalAxis::updateGeometry(); +} + +void ChartColorBarAxisY::handleTickCountChanged(int tick) +{ + Q_UNUSED(tick); + QGraphicsLayoutItem::updateGeometry(); + if (presenter()) presenter()->layout()->invalidate(); +} + +void ChartColorBarAxisY::handleMinorTickCountChanged(int tick) +{ + Q_UNUSED(tick); + QGraphicsLayoutItem::updateGeometry(); + if (presenter()) + presenter()->layout()->invalidate(); +} + +void ChartColorBarAxisY::handleLabelFormatChanged(const QString &format) +{ + Q_UNUSED(format); + QGraphicsLayoutItem::updateGeometry(); + if(presenter()) presenter()->layout()->invalidate(); +} + +QSizeF ChartColorBarAxisY::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const +{ + Q_UNUSED(constraint) + + QSizeF sh; + QSizeF base = VerticalAxis::sizeHint(which, constraint); + QStringList ticksList = createValueLabels(min(),max(),m_axis->tickCount(),m_axis->labelFormat()); + qreal width = 0; + // Height of vertical axis sizeHint indicates the maximum distance labels can extend past + // first and last ticks. Base height is irrelevant. + qreal height = 0; + + switch (which) + { + case Qt::MinimumSize: { + QRectF boundingRect = ChartPresenter::textBoundingRect(axis()->labelsFont(), + QStringLiteral("..."), + axis()->labelsAngle()); + width = boundingRect.width() + labelPadding() + base.width() + 61.0; //TODO : hint changed 1.0 to 61.0 + height = boundingRect.height() / 2.0; + sh = QSizeF(width, height); + break; + } + case Qt::PreferredSize: { + qreal labelWidth = 0.0; + qreal firstHeight = -1.0; + foreach (const QString& s, ticksList) { + QRectF rect = ChartPresenter::textBoundingRect(axis()->labelsFont(), s, axis()->labelsAngle()); + labelWidth = qMax(rect.width(), labelWidth); + height = rect.height(); + if (firstHeight < 0.0) + firstHeight = height; + } + width = labelWidth + labelPadding() + base.width() + 62.0; //two pixels of tolerance //TODO : hint changed 2.0 to 62.0 + height = qMax(height, firstHeight) / 2.0; + sh = QSizeF(width, height); + break; + } + default: + break; + } + return sh; +} + +void ChartColorBarAxisY::createColorBar() +{ + m_axis->setLabelsColor(QColor(0,0,255,0)); //make automatic labels disappear without changing layout (as it would be the case with setlabelVisible(false)) + + //gradient + QGradientStops stops = m_gradient.stops(); + QLinearGradient gradient(0,m_position.y(),1,m_height); + foreach(QGradientStop stop, stops) + { + gradient.setColorAt(1-stop.first,stop.second); + } + + //colorbar + QRectF rect(m_position.x()+10,m_position.y(),m_height/20,m_height); //remove +10 if needed + + QGraphicsRectItem *colorbar = new QGraphicsRectItem(rect, this); + colorbar->setZValue(ChartPresenter::AxisZValue); + colorbar->setBrush(gradient); + + //colorbar labels + for(int i=0;itickCount();i++) + { + qreal value = m_axis->max() - (i * (m_axis->max() - m_axis->min()) / (m_axis->tickCount() - 1)); + QGraphicsTextItem *label = new QGraphicsTextItem(this); + label->setPlainText(QString::number(value)); + label->setPos((m_position.x()+10+m_height/20+1),(m_position.y()*0.85+i*(m_height/(m_axis->tickCount()-1)))); //remove +10 if needed + } +} + +#include "moc_chartcolorbaraxisy_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/axis/colorbaraxis/chartcolorbaraxisy_p.h b/src/charts/axis/colorbaraxis/chartcolorbaraxisy_p.h new file mode 100644 index 0000000..3bd8456 --- /dev/null +++ b/src/charts/axis/colorbaraxis/chartcolorbaraxisy_p.h @@ -0,0 +1,63 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#ifndef CHARTCOLORBARAXISY_H +#define CHARTCOLORBARAXISY_H + +#include +#include + +QT_CHARTS_BEGIN_NAMESPACE + +class QColorBarAxis; + +class ChartColorBarAxisY : public VerticalAxis +{ + Q_OBJECT +public: + ChartColorBarAxisY(QColorBarAxis *axis, QPoint pos, qreal height, QLinearGradient gradient, QGraphicsItem *item = 0); + ~ChartColorBarAxisY(); + + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const; + + + +protected: + QVector calculateLayout() const; + void updateGeometry(); +private Q_SLOTS: + void handleTickCountChanged(int tick); + void handleMinorTickCountChanged(int tick); + void handleLabelFormatChanged(const QString &format); + void createColorBar(); + + +private: + QColorBarAxis *m_axis; + QLinearGradient m_gradient; + QPoint m_position; + qreal m_height; +}; + +QT_CHARTS_END_NAMESPACE + +#endif // CHARTCOLORBARAXISY_H diff --git a/src/charts/axis/colorbaraxis/qcolorbaraxis.cpp b/src/charts/axis/colorbaraxis/qcolorbaraxis.cpp new file mode 100644 index 0000000..ed9e6a3 --- /dev/null +++ b/src/charts/axis/colorbaraxis/qcolorbaraxis.cpp @@ -0,0 +1,277 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +//#include // TODO : fix this +#include "colorbaraxis/qcolorbaraxis.h" +//#include +#include "colorbaraxis/qcolorbaraxis_p.h" +#include +#include +#include +#include + +//#include +#include + +#include + +QT_CHARTS_BEGIN_NAMESPACE + + +/*! + Constructs an axis object which is a child of \a parent. +*/ +QColorBarAxis::QColorBarAxis(QRectF plotArea, QLinearGradient gradient, qreal min, qreal max, QObject *parent) : + QAbstractAxis(*new QColorBarAxisPrivate(plotArea, gradient, min, max, this), parent) +{ +setGridLineVisible(false); +} + +/*! + \internal +*/ +QColorBarAxis::QColorBarAxis(QColorBarAxisPrivate &d, QObject *parent) + : QAbstractAxis(d, parent) +{ + +} + +/*! + Destroys the object +*/ +QColorBarAxis::~QColorBarAxis() +{ + Q_D(QColorBarAxis); + if (d->m_chart) + d->m_chart->removeAxis(this); +} + +void QColorBarAxis::setMin(qreal min) +{ + Q_D(QColorBarAxis); + setRange(min, qMax(d->m_max, min)); +} + +qreal QColorBarAxis::min() const +{ + Q_D(const QColorBarAxis); + return d->m_min; +} + +void QColorBarAxis::setMax(qreal max) +{ + Q_D(QColorBarAxis); + setRange(qMin(d->m_min, max), max); +} + +qreal QColorBarAxis::max() const +{ + Q_D(const QColorBarAxis); + return d->m_max; +} + +void QColorBarAxis::setRange(qreal min, qreal max) +{ + Q_D(QColorBarAxis); + d->setRange(min,max); +} + + +void QColorBarAxis::setTickCount(int count) +{ + Q_D(QColorBarAxis); + if (d->m_tickCount != count && count >= 2) { + d->m_tickCount = count; + emit tickCountChanged(count); + } +} + +int QColorBarAxis::tickCount() const +{ + Q_D(const QColorBarAxis); + return d->m_tickCount; +} + +void QColorBarAxis::setMinorTickCount(int count) +{ + Q_D(QColorBarAxis); + if (d->m_minorTickCount != count && count >= 0) { + d->m_minorTickCount = count; + emit minorTickCountChanged(count); + } +} + +int QColorBarAxis::minorTickCount() const +{ + Q_D(const QColorBarAxis); + return d->m_minorTickCount; +} + +void QColorBarAxis::setLabelFormat(const QString &format) +{ + Q_D(QColorBarAxis); + d->m_format = format; + emit labelFormatChanged(format); +} + +QString QColorBarAxis::labelFormat() const +{ + Q_D(const QColorBarAxis); + return d->m_format; +} + +/*! + Returns the type of the axis +*/ +QAbstractAxis::AxisType QColorBarAxis::type() const +{ + return AxisTypeValue; + //TODO : AxisTypeColorBar +} + + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QColorBarAxisPrivate::QColorBarAxisPrivate(QRectF plotArea, QLinearGradient gradient, qreal min, qreal max, QColorBarAxis *q) + : QAbstractAxisPrivate(q), + m_plotArea(plotArea), + m_min(min), + m_max(max), + m_tickCount(5), + m_minorTickCount(0), + m_format(QString::null), + // m_applying(false) + m_gradient(gradient) +{ + +} + +QColorBarAxisPrivate::~QColorBarAxisPrivate() +{ + +} + +void QColorBarAxisPrivate::initializeGraphics(QGraphicsItem *parent) +{ + Q_Q(QColorBarAxis); + ChartAxisElement *axis(0); + + setAlignment(Qt::AlignRight); //also set orientation (Vertical in this case) + + //TODO : change this position + qreal x1; + qreal y1; + qreal x2; + qreal y2; + m_plotArea.getCoords(&x1,&y1,&x2,&y2); + QPoint pos(x2+5,y1); + axis = new ChartColorBarAxisY(q, pos, m_plotArea.height(),m_gradient, parent); + + m_item.reset(axis); + QAbstractAxisPrivate::initializeGraphics(parent); +} + +void QColorBarAxisPrivate::initializeDomain(AbstractDomain *domain) +{ + //domain is not supposed to have a rangeZ + + // if (orientation() == Qt::Vertical) { + // if (!qFuzzyIsNull(m_max - m_min)) + // domain->setRangeY(m_min, m_max); + // else + // setRange(domain->minY(), domain->maxY()); + // } +} + +void QColorBarAxisPrivate::setMin(const QVariant &min) +{ + Q_Q(QColorBarAxis); + bool ok; + qreal value = min.toReal(&ok); + if (ok) + q->setMin(value); +} + +void QColorBarAxisPrivate::setMax(const QVariant &max) +{ + Q_Q(QColorBarAxis); + bool ok; + qreal value = max.toReal(&ok); + if (ok) + q->setMax(value); +} + +void QColorBarAxisPrivate::setRange(const QVariant &min, const QVariant &max) +{ + Q_Q(QColorBarAxis); + bool ok1; + bool ok2; + qreal value1 = min.toReal(&ok1); + qreal value2 = max.toReal(&ok2); + if (ok1 && ok2) + q->setRange(value1, value2); +} + +void QColorBarAxisPrivate::setRange(qreal min,qreal max) +{ + Q_Q(QColorBarAxis); + bool changed = false; + + if (min > max) + return; + + bool changeMin = false; + if (m_min == 0 || min == 0) + changeMin = !qFuzzyCompare(1 + m_min, 1 + min); + else + changeMin = !qFuzzyCompare(m_min, min); + + bool changeMax = false; + if (m_max == 0 || max == 0) + changeMax = !qFuzzyCompare(1 + m_max, 1 + max); + else + changeMax = !qFuzzyCompare(m_max, max); + + if (changeMin) { + m_min = min; + changed = true; + emit q->minChanged(min); + } + + if (changeMax) { + m_max = max; + changed = true; + emit q->maxChanged(max); + } + + if (changed) { + emit rangeChanged(min,max); + emit q->rangeChanged(min, max); + } +} + + +#include "moc_qcolorbaraxis.cpp" +#include "moc_qcolorbaraxis_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/axis/colorbaraxis/qcolorbaraxis.h b/src/charts/axis/colorbaraxis/qcolorbaraxis.h new file mode 100644 index 0000000..eec5acc --- /dev/null +++ b/src/charts/axis/colorbaraxis/qcolorbaraxis.h @@ -0,0 +1,76 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#ifndef QCOLORBARAXIS_H +#define QCOLORBARAXIS_H + +#include + +QT_CHARTS_BEGIN_NAMESPACE + +class QColorBarAxisPrivate; + +class QT_CHARTS_EXPORT QColorBarAxis : public QAbstractAxis +{ + Q_OBJECT +public: + explicit QColorBarAxis(QRectF plotArea,QLinearGradient gradient, qreal min, qreal max,QObject *parent = 0); + ~QColorBarAxis(); + +protected: + QColorBarAxis(QColorBarAxisPrivate &d, QObject *parent = 0); + +public: + AxisType type() const; + + //range handling + void setMin(qreal min); + qreal min() const; + void setMax(qreal max); + qreal max() const; + void setRange(qreal min, qreal max); + + //ticks handling + void setTickCount(int count); + int tickCount() const; + void setMinorTickCount(int count); + int minorTickCount() const; + + void setLabelFormat(const QString &format); + QString labelFormat() const; + +Q_SIGNALS: + void minChanged(qreal min); + void maxChanged(qreal max); + void rangeChanged(qreal min, qreal max); + void tickCountChanged(int tickCount); + void minorTickCountChanged(int tickCount); + void labelFormatChanged(const QString &format); + +private: + Q_DECLARE_PRIVATE(QColorBarAxis) + Q_DISABLE_COPY(QColorBarAxis) +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QCOLORBARAXIS_H diff --git a/src/charts/axis/colorbaraxis/qcolorbaraxis_p.h b/src/charts/axis/colorbaraxis/qcolorbaraxis_p.h new file mode 100644 index 0000000..eaf4480 --- /dev/null +++ b/src/charts/axis/colorbaraxis/qcolorbaraxis_p.h @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#ifndef QCOLORBARAXIS_P_H +#define QCOLORBARAXIS_P_H + +//#include //TODO : fix this +#include "colorbaraxis/qcolorbaraxis.h" +#include + +QT_CHARTS_BEGIN_NAMESPACE + +class QColorBarAxisPrivate : public QAbstractAxisPrivate +{ + Q_OBJECT +public: + QColorBarAxisPrivate(QRectF plotArea, QLinearGradient gradient, qreal min, qreal max,QColorBarAxis *q); + ~QColorBarAxisPrivate(); + +public: + void initializeGraphics(QGraphicsItem* parent); + void initializeDomain(AbstractDomain *domain); + + qreal min() { return m_min; } + qreal max() { return m_max; } + void setRange(qreal min,qreal max); + +protected: + void setMin(const QVariant &min); + void setMax(const QVariant &max); + void setRange(const QVariant &min, const QVariant &max); + +private: + qreal m_min; + qreal m_max; + int m_tickCount; + int m_minorTickCount; + QString m_format; + // bool m_applying; + QLinearGradient m_gradient; + QRectF m_plotArea; + Q_DECLARE_PUBLIC(QColorBarAxis) +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QCOLORBARAXIS_P_H diff --git a/src/charts/charts.pro b/src/charts/charts.pro index 0867f0f..9b171c2 100644 --- a/src/charts/charts.pro +++ b/src/charts/charts.pro @@ -67,6 +67,7 @@ include($$PWD/themes/themes.pri) include($$PWD/xychart/xychart.pri) include($$PWD/layout/layout.pri) include($$PWD/boxplotchart/boxplotchart.pri) +include($$PWD/colormapchart/colormapchart.pri) HEADERS += $$PUBLIC_HEADERS HEADERS += $$PRIVATE_HEADERS diff --git a/src/charts/colormapchart/colormapchart.cpp b/src/charts/colormapchart/colormapchart.cpp new file mode 100644 index 0000000..fea0845 --- /dev/null +++ b/src/charts/colormapchart/colormapchart.cpp @@ -0,0 +1,299 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define nbOfColors 65000 + +QT_CHARTS_BEGIN_NAMESPACE + +ColorMapChart::ColorMapChart(QColorMapSeries *series, QGraphicsItem *item) + : ChartItem(series->d_func(), item), + m_series(series), + m_dirty(true), + m_gradientType(Rainbow), + m_colorbar(Q_NULLPTR), + m_isColorBarDrawn(false), + m_currentClipRect(QRectF()) +{ + // QObject::connect(series, SIGNAL(pointReplaced(int)), this, SLOT(handlePointReplaced(int))); + // QObject::connect(series, SIGNAL(pointsReplaced()), this, SLOT(handlePointsReplaced())); + // QObject::connect(series, SIGNAL(pointAdded(int)), this, SLOT(handlePointAdded(int))); + // QObject::connect(series, SIGNAL(pointRemoved(int)), this, SLOT(handlePointRemoved(int))); + // QObject::connect(series, SIGNAL(pointsRemoved(int, int)), this, SLOT(handlePointsRemoved(int, int))); + // QObject::connect(this, SIGNAL(clicked(Point3D)), series, SIGNAL(clicked(Point3D))); + // QObject::connect(this, SIGNAL(hovered(Point3D,bool)), series, SIGNAL(hovered(Point3D,bool))); + // QObject::connect(this, SIGNAL(pressed(Point3D)), series, SIGNAL(pressed(Point3D))); + // QObject::connect(this, SIGNAL(released(Point3D)), series, SIGNAL(released(Point3D))); + // QObject::connect(this, SIGNAL(doubleClicked(Point3D)), series, SIGNAL(doubleClicked(Point3D))); + + connect(this,SIGNAL(gradientTypeChanged()), this, SLOT(populateColorTable())); + + m_colorTable = new QVector(); + m_colorTable->reserve(nbOfColors); + populateColorTable(); +} + +ColorMapChart::~ColorMapChart() +{ + delete m_colorTable; + delete m_colorbar; +} + +void ColorMapChart::setDirty(bool dirty) +{ + m_dirty = dirty; +} + +QRectF ColorMapChart::boundingRect() const +{ + return m_rect; +} + +void ColorMapChart::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(widget) + Q_UNUSED(option) + + painter->save(); + //m_series->setUseOpenGL(); + + QRectF plotAreaRect = m_series->chart()->plotArea(); + QRectF clipRect = mapColorMapToPlotArea(); + painter->setClipRect(clipRect); + + if(m_currentClipRect !=clipRect) + { + m_currentClipRect = clipRect; + m_grid.reserve(clipRect.width()*clipRect.height()); + m_grid.resize(clipRect.width()*clipRect.height()); + + m_series->getUniformGrid(qMax(m_series->minX(),domain()->minX()),qMin(m_series->maxX(),domain()->maxX()),qMax(m_series->minY(),domain()->minY()),qMin(m_series->maxY(),domain()->maxY()), clipRect.width(),clipRect.height(),m_grid, QColorMapSeries::LastPixel); + addColorBar(plotAreaRect); + } + + QImage colorMapImage(clipRect.width(),clipRect.height(),QImage::Format_RGB32); + //http://doc.qt.io/qt-4.8/qimage.html#details :Warning: This will create a QImage with uninitialized data. Call fill() to fill the image with an appropriate pixel value before drawing onto it with QPainter. + colorMapImage.fill(QColor(Qt::white).rgb()); + + fillColorMapImage(colorMapImage); + + painter->drawImage(clipRect,colorMapImage); + painter->restore(); +} + +void ColorMapChart::addColorBar(QRectF plotAreaRect) +{ + double maxZ = m_series->maxZ(); + double minZ = m_series->minZ(); + + if(m_isColorBarDrawn) + m_series->chart()->removeAxis(m_colorbar); + + m_colorbar = new QColorBarAxis(plotAreaRect,createColorMapGradient(m_gradientType),minZ, maxZ,this); + m_series->chart()->addAxis(m_colorbar, Qt::AlignRight); + m_isColorBarDrawn = true; +} + +QRectF ColorMapChart::mapColorMapToPlotArea() +{ + QRectF plotAreaRect = m_series->chart()->plotArea(); + + double seriesMinX = m_series->minX(); + double seriesMaxX = m_series->maxX(); + double seriesMinY = m_series->minY(); + double seriesMaxY = m_series->maxY(); + + double domainMinX = domain()->minX(); + double domainMaxX = domain()->maxX(); + double domainMinY = domain()->minY(); + double domainMaxY = domain()->maxY(); + + double widthToPaint = (qMin(seriesMaxX, domainMaxX)-qMax(seriesMinX, domainMinX))*plotAreaRect.width()/(domainMaxX-domainMinX); + double heightTopaint= (qMin(seriesMaxY, domainMaxY)-qMax(seriesMinY, domainMinY))*plotAreaRect.height()/(domainMaxY-domainMinY); + + QSizeF size = QSize(widthToPaint,heightTopaint); + + double pointX = (qMax(seriesMinX,domainMinX)-domainMinX)*plotAreaRect.width()/(domainMaxX-domainMinX); + double pointY = (domainMaxY-qMin(seriesMaxY,domainMaxY))*plotAreaRect.height()/(domainMaxY-domainMinY); + + return QRectF(QPointF(pointX,pointY) ,size); +} + +void ColorMapChart::fillColorMapImage(QImage &colorMapImage) +{ + double maxZ = m_series->maxZ(); + double minZ = m_series->minZ(); + double rangeZ = maxZ - minZ; + + int imageWidth = colorMapImage.width(); + int imageHeight = colorMapImage.height(); + + for(int i=0;iat(indexInColorTable)); + } + } +} + +/*! + Returns the predefined QLinearGradient corresponding to the \a gradientType passed as argument. +*/ +QLinearGradient ColorMapChart::createColorMapGradient(GradientType gradientType) +{ + QLinearGradient gradient(0,0,1,100); + switch(gradientType) + { + case Rainbow : + gradient.setColorAt(1.0,Qt::darkRed); + gradient.setColorAt(0.8,Qt::red); + gradient.setColorAt(0.6,Qt::yellow); + gradient.setColorAt(0.4,Qt::green); + gradient.setColorAt(0.2,Qt::cyan); + gradient.setColorAt(0.0,Qt::blue); + break; + case CyclingRainbow : + gradient.setColorAt(1.0,Qt::red); + gradient.setColorAt(0.8,Qt::yellow); + gradient.setColorAt(0.6,Qt::green); + gradient.setColorAt(0.4,Qt::cyan); + gradient.setColorAt(0.2,Qt::blue); + gradient.setColorAt(0.0,Qt::magenta); + break; + case BlackAndWhite : + gradient.setColorAt(1.0, Qt::black); + gradient.setColorAt(0.0, Qt::white); + break; + case ReverseBlackAndWhite : + gradient.setColorAt(1.0, Qt::white); + gradient.setColorAt(0.0, Qt::black); + break; + default: + break; + } + return gradient; +} + +/*! + Changes the type of gradient used to paint the ColorMap. +*/ +void ColorMapChart::changeGradient(GradientType gradientType) +{ + if(m_gradientType == gradientType) + return; + else + m_gradientType = gradientType; + emit gradientTypeChanged(); +} + +/*! + Creates a color table corresponding to the gradient type currently selected. +*/ +void ColorMapChart::populateColorTable() +{ + QLinearGradient gradient = createColorMapGradient(m_gradientType); + QGradientStops colorStops = gradient.stops(); + + for(int i=0;i= lowerBound.first && colorIndex < upperBound.first) + { + double ratio = (colorIndex-lowerBound.first)/(upperBound.first - lowerBound.first); + int red = (int)((1-ratio)*lowerBound.second.red() + ratio*upperBound.second.red()); + int green = (int)((1-ratio)*lowerBound.second.green() + ratio*upperBound.second.green()); + int blue = (int)((1-ratio)*lowerBound.second.blue() + ratio*upperBound.second.blue()); + m_colorTable->append(qRgb(red, green, blue)); + break; + } + else + { + if(k==colorStops.size()-2) + { + m_colorTable->append(qRgb(colorStops.at(colorStops.size()-1).second.red(), colorStops.at(colorStops.size()-1).second.green(), colorStops.at(colorStops.size()-1).second.blue())); + } + } + } + } +} + + +//handlers + +void ColorMapChart::handlePointAdded(int index) +{ + +} + +void ColorMapChart::handlePointRemoved(int index) +{ + +} + +void ColorMapChart::handlePointsRemoved(int index, int count) +{ + +} + +void ColorMapChart::handlePointReplaced(int index) +{ + +} + +void ColorMapChart::handlePointsReplaced() +{ + +} + +void ColorMapChart::handleDomainUpdated() +{ + +} + +bool ColorMapChart::isEmpty() +{ + +} + + +#include "moc_colormapchart_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/colormapchart/colormapchart.pri b/src/charts/colormapchart/colormapchart.pri new file mode 100644 index 0000000..d8d3680 --- /dev/null +++ b/src/charts/colormapchart/colormapchart.pri @@ -0,0 +1,21 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD +QT+=concurrent +#QMAKE_CXXFLAGS+= -fopenmp +#QMAKE_LFLAGS += -fopenmp + +SOURCES += \ + $$PWD/qcolormapseries.cpp \ + $$PWD/colormapchart.cpp \ + $$PWD/colormapdatapart.cpp \ + $$PWD/point3d.cpp + +PRIVATE_HEADERS += \ + $$PWD/qcolormapseries_p.h \ + $$PWD/colormapchart_p.h + +PUBLIC_HEADERS += \ + $$PWD/qcolormapseries.h \ + $$PWD/point3d.h \ + $$PWD/colormapdatapart.h + diff --git a/src/charts/colormapchart/colormapchart_p.h b/src/charts/colormapchart/colormapchart_p.h new file mode 100644 index 0000000..9426ee6 --- /dev/null +++ b/src/charts/colormapchart/colormapchart_p.h @@ -0,0 +1,154 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#ifndef COLORMAPCHART_H +#define COLORMAPCHART_H + +#include "point3d.h" +#include +#include +#include +#include + +//#include TODO : fix this +#include "qcolorbaraxis.h" + +QT_CHARTS_BEGIN_NAMESPACE + +class ChartPresenter; +class QColorMapSeries; + +class ColorMapChart : public ChartItem +{ + Q_OBJECT +public: + + enum GradientType + { + Rainbow, + CyclingRainbow, + BlackAndWhite, + ReverseBlackAndWhite + }; + + explicit ColorMapChart(QColorMapSeries *series,QGraphicsItem *item = 0); + ~ColorMapChart(); + + bool isDirty() const { return m_dirty; } + void setDirty(bool dirty); + + // from QGraphicsItem + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +public Q_SLOTS: + void handlePointAdded(int index); + void handlePointRemoved(int index); + void handlePointsRemoved(int index, int count); + void handlePointReplaced(int index); + void handlePointsReplaced(); + void handleDomainUpdated(); + +private slots : + void populateColorTable(); + +Q_SIGNALS: + void clicked(const Point3D &point); + void hovered(const Point3D &point, bool state); + void pressed(const Point3D &point); + void released(const Point3D &point); + void doubleClicked(const Point3D &point); + void gradientTypeChanged(); + +private: + inline bool isEmpty(); + void addColorBar(QRectF plotAreaRect); + + QRectF mapColorMapToPlotArea(); + void fillColorMapImage(QImage &colorMapImage); + QLinearGradient createColorMapGradient(GradientType gradientType); + void changeGradient(GradientType gradientType); + +protected: + QColorMapSeries *m_series; + QVector m_points; + QRectF m_rect; + bool m_dirty; + QVector *m_colorTable; + GradientType m_gradientType; + bool m_isColorBarDrawn; + QColorBarAxis *m_colorbar; + QRectF m_currentClipRect; + QVector m_grid; +}; + +//class PixmapMarker: public QGraphicsRectItem +//{ + +//public: +// PixmapMarker(qreal x, qreal y, qreal w, qreal h, ColorMapChart *parent) +// : QGraphicsRectItem(x, y, w, h, parent), +// m_parent(parent) +// { +// setAcceptHoverEvents(true); +// setFlag(QGraphicsItem::ItemIsSelectable); +// } + +//protected: +// void mousePressEvent(QGraphicsSceneMouseEvent *event) +// { +// QGraphicsRectItem::mousePressEvent(event); +// m_parent->markerPressed(this); +// m_parent->setMousePressed(); +// } +// void hoverEnterEvent(QGraphicsSceneHoverEvent *event) +// { +// QGraphicsRectItem::hoverEnterEvent(event); +// m_parent->markerHovered(this, true); +// } +// void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +// { +// QGraphicsRectItem::hoverLeaveEvent(event); +// m_parent->markerHovered(this, false); +// } +// void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +// { +// QGraphicsRectItem::mouseReleaseEvent(event); +// m_parent->markerReleased(this); +// if (m_parent->mousePressed()) +// m_parent->markerSelected(this); +// m_parent->setMousePressed(false); +// } +// void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +// { +// QGraphicsRectItem::mouseDoubleClickEvent(event); +// m_parent->markerDoubleClicked(this); +// } + +//private: +// ColorMapChart *m_parent; +//}; + + +QT_CHARTS_END_NAMESPACE + +#endif // COLORMAPCHART_H diff --git a/src/charts/colormapchart/colormapdatapart.cpp b/src/charts/colormapchart/colormapdatapart.cpp new file mode 100644 index 0000000..9d9ddd8 --- /dev/null +++ b/src/charts/colormapchart/colormapdatapart.cpp @@ -0,0 +1,78 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#include "colormapdatapart.h" + +QT_CHARTS_BEGIN_NAMESPACE + +ColorMapDataPart::ColorMapDataPart() +{ + +} + +ColorMapDataPart::ColorMapDataPart(ColorMapDataPart *dataPart) +{/* + QVector *m_timeSeries; + QVector *m_ySeries; + QVector *m_dataSeries;*/ + this->m_dataSeries = new QVector(dataPart->dataSeries()); + this->m_ySeries = new QVector(dataPart->ySeries()); + this->m_timeSeries = new QVector(dataPart->timesSeries()); +} + +ColorMapDataPart::ColorMapDataPart(QVector *timeSeries, QVector *ySeries, QVector *dataSeries) + : m_timeSeries(timeSeries),m_ySeries(ySeries),m_dataSeries(dataSeries) +{ + +} + +ColorMapDataPart::~ColorMapDataPart() +{ + delete m_dataSeries; + delete m_ySeries; + delete m_timeSeries; +} + +int ColorMapDataPart::find(double val, const QVector &vect, bool more) +{ + if(val >=vect.last() && more) + return vect.count(); + if(val <= vect.first() && !more) + return -1; + + int guessedIndex = (val-vect.first())*vect.count()/(vect.last()-vect.first()); + if(guessedIndex>(vect.count()-1))guessedIndex=vect.count()-1; + + if(more) + while(vect[guessedIndex]val){} + return guessedIndex; +} + +QPair ColorMapDataPart::getRange(const QVector &vect, double start, double stop) +{ + return QPair(find(start,vect, false),find(stop,vect, true)); +} + + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/colormapchart/colormapdatapart.h b/src/charts/colormapchart/colormapdatapart.h new file mode 100644 index 0000000..c67f9bd --- /dev/null +++ b/src/charts/colormapchart/colormapdatapart.h @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#ifndef COLORMAPDATAPART_H +#define COLORMAPDATAPART_H + +#include +#include + +QT_CHARTS_BEGIN_NAMESPACE + +class QT_CHARTS_EXPORT ColorMapDataPart +{ +public: + explicit ColorMapDataPart(); + ColorMapDataPart(ColorMapDataPart* dataPart); + explicit ColorMapDataPart(QVector *timeSeries, QVector *ySeries, QVector *dataSeries); + ~ColorMapDataPart(); + inline const QVector& timesSeries(){return *this->m_timeSeries;} + inline const QVector& ySeries(){return *this->m_ySeries;} + inline const QVector& dataSeries(){return *this->m_dataSeries;} + inline void setTimeSeries(QVector *timeSeries){this->m_timeSeries =timeSeries;} + inline void setYSeries(QVector *ySeries){this->m_ySeries =ySeries;} + inline void setDataSeries(QVector *dataSeries){this->m_dataSeries =dataSeries;} + QPair getRange(const QVector &vect, double start, double stop); +protected: + QVector *m_timeSeries; + QVector *m_ySeries; + QVector *m_dataSeries; +private: + int find(double val, const QVector &vect, bool more); +}; + +QT_CHARTS_END_NAMESPACE + +#endif // COLORMAPDATAPART_H diff --git a/src/charts/colormapchart/point3d.cpp b/src/charts/colormapchart/point3d.cpp new file mode 100644 index 0000000..1197323 --- /dev/null +++ b/src/charts/colormapchart/point3d.cpp @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#include "point3d.h" + + +Point3D::Point3D() + : QPointF() +{ +} + +Point3D::Point3D(qreal x, qreal y, qreal value) + : QPointF(x,y), + m_value(value) +{ +} diff --git a/src/charts/colormapchart/point3d.h b/src/charts/colormapchart/point3d.h new file mode 100644 index 0000000..b23701c --- /dev/null +++ b/src/charts/colormapchart/point3d.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#ifndef POINT3D_H +#define POINT3D_H + +#include + +class Point3D : public QPointF +{ +public: + Point3D(); + Point3D(qreal x, qreal y, qreal value); + inline void setValue(qreal value){this->m_value = value;} + inline qreal value(){return this->m_value;} +private: + qreal m_value; +}; +#endif // POINT3D_H diff --git a/src/charts/colormapchart/qcolormaplegendmarker.h b/src/charts/colormapchart/qcolormaplegendmarker.h new file mode 100644 index 0000000..bccfedf --- /dev/null +++ b/src/charts/colormapchart/qcolormaplegendmarker.h @@ -0,0 +1 @@ +#include "../../src/charts/legend/qcolormaplegendmarker.h" diff --git a/src/charts/colormapchart/qcolormaplegendmarker_p.h b/src/charts/colormapchart/qcolormaplegendmarker_p.h new file mode 100644 index 0000000..c48992a --- /dev/null +++ b/src/charts/colormapchart/qcolormaplegendmarker_p.h @@ -0,0 +1 @@ +#include "../../../../../src/charts/legend/qcolormaplegendmarker_p.h" diff --git a/src/charts/colormapchart/qcolormapseries.cpp b/src/charts/colormapchart/qcolormapseries.cpp new file mode 100644 index 0000000..9b69b88 --- /dev/null +++ b/src/charts/colormapchart/qcolormapseries.cpp @@ -0,0 +1,658 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#include "qcolormapseries.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "qcolorbaraxis.h" + +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 &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 &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. +*/ +void QColorMapSeries::getUniformGrid(double minX, double maxX, double minY, double maxY, int width, int height, QVector &grid, QColorMapSeries::Strategy strategy) +{ + Q_D(QColorMapSeries); + d->getUniformGrid(minX, maxX,minY,maxY,width,height, grid, strategy); +} + +//void QColorMapSeries::attachAxis(QAbstractAxis *axis) +//{ +// axis = static_cast(); +// if(axis) +// { + +// } +// else +// { +// QAbstractSeries::attachAxis(axis); +// } +//} + +/*! + 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) + { + //bool emitColorChanged = d->m_pen.color() != pen.color(); + d->m_pen = pen; + emit d->updated(); + // if (emitColorChanged) + // emit colorChanged(pen.color()); + 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 gradients = theme->seriesGradients(); + // const QList 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 QColorMapSeriesPrivate::createLegendMarkers(QLegend* legend) +{ + Q_Q(QColorMapSeries); + QList 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; +} + + +void QColorMapSeriesPrivate::getUniformGrid(double minX, double maxX, double minY, double maxY, int width, int height, QVector &grid, QColorMapSeries::Strategy strategy) +{ + m_imageHeight = height; + m_imageWidth = width; + m_strategy = strategy; + + m_requestedMinX = minX; + m_requestedMaxX = maxX; + m_requestedMinY = minY; + m_requestedMaxY = maxY; + + int index=0; + std::generate(grid.begin(),grid.end(),[&index]{return index++;}); + + QFuture futureWatcher = QtConcurrent::map(grid,[this] (double &index) { return computePixelValue(index); }); + + futureWatcher.waitForFinished(); +} + +double QColorMapSeriesPrivate::computePixelValue(double &index) +{ + QVector cluster; + cluster.reserve(m_imageHeight*m_imageWidth/1000); + cluster.resize(0); + + double dx = (m_requestedMaxX - m_requestedMinX)/m_imageWidth; + double dy = (m_requestedMaxY - m_requestedMinY)/m_imageHeight; + + int x = (int)index%m_imageWidth; + int y = (int)index/m_imageWidth; + this->buildCluster(x,y,dx,dy,cluster); + if(m_strategy == QColorMapSeries::LastPixel) + index = this->clusterStrategyLast(cluster); + else if(m_strategy == QColorMapSeries::MeanPixel) + index = this->clusterStrategyMean(cluster); + else if(m_strategy == QColorMapSeries::MedianPixel) + index = this->clusterStrategyMedian(cluster); + + return index;//not used +} + +/*! + 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;itimesSeries().size();i++) + { + double newDeltaX=datapart->timesSeries()[i]-datapart->timesSeries()[i-1]; + minDeltaX=qMin(minDeltaX,newDeltaX); + } + for(int i=1;iySeries().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& 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& cluster) +{ + if(!cluster.isEmpty()) + { + double sum=0; + int count =0; + for(int i =0;i& cluster) +{ + if(!cluster.isEmpty()) + { + QVector *copy = new QVector(); + + for(int i =0;iappend(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. +*/ +void QColorMapSeriesPrivate::buildCluster(int xpos, int ypos, double dx, double dy, QVector& cluster) +{ + foreach(ColorMapDataPart *dataPart, m_dataParts) + { + QPair xRange = dataPart->getRange(dataPart->timesSeries(),m_requestedMinX+xpos*dx,m_requestedMinX+(xpos+1)*dx); + QPair yRange = dataPart->getRange(dataPart->ySeries(),m_requestedMaxY-(ypos+1)*dy,m_requestedMaxY-ypos*dy); + + int timeSeriesSize = dataPart->timesSeries().size(); + + if(xRange.first != xRange.second && yRange.first != yRange.second) + { + for(int i =xRange.first+1;itimesSeries()[i]; + for(int j=yRange.first+1;jySeries()[j]; + qreal val=dataPart->dataSeries()[ i + (timeSeriesSize * j)]; + cluster.append(Point3D(xval,yval,val)); + } + } + } + } +} + + +void QColorMapSeriesPrivate::initializeAnimations(QtCharts::QChart::AnimationOptions options, + int duration, QEasingCurve &curve) +{ + // ColorMapChart *item = static_cast(m_item.data()); + // Q_ASSERT(item); + // if (item->animation()) + // item->animation()->stopAndDestroyLater(); + + // if (options.testFlag(QChart::SeriesAnimations)) + // item->setAnimation(new XYAnimation(item, duration, curve)); + // else + // item->setAnimation(0); + QAbstractSeriesPrivate::initializeAnimations(options, duration, curve); +} + + + +#include "moc_qcolormapseries.cpp" +#include "moc_qcolormapseries_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/colormapchart/qcolormapseries.h b/src/charts/colormapchart/qcolormapseries.h new file mode 100644 index 0000000..656718d --- /dev/null +++ b/src/charts/colormapchart/qcolormapseries.h @@ -0,0 +1,144 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#ifndef QCOLORMAPSERIES_H +#define QCOLORMAPSERIES_H + +#include +#include +#include +#include +#include "colormapdatapart.h" + +QT_CHARTS_BEGIN_NAMESPACE +class QColorMapSeriesPrivate; + + +class QT_CHARTS_EXPORT QColorMapSeries : public QAbstractSeries +{ + Q_OBJECT +// Q_PROPERTY(bool pointsVisible READ pointsVisible WRITE setPointsVisible) +// Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) +// Q_PROPERTY(QString pointLabelsFormat READ pointLabelsFormat WRITE setPointLabelsFormat NOTIFY pointLabelsFormatChanged) +// Q_PROPERTY(bool pointLabelsVisible READ pointLabelsVisible WRITE setPointLabelsVisible NOTIFY pointLabelsVisibilityChanged) +// Q_PROPERTY(QFont pointLabelsFont READ pointLabelsFont WRITE setPointLabelsFont NOTIFY pointLabelsFontChanged) +// Q_PROPERTY(QColor pointLabelsColor READ pointLabelsColor WRITE setPointLabelsColor NOTIFY pointLabelsColorChanged) +// Q_PROPERTY(bool pointLabelsClipping READ pointLabelsClipping WRITE setPointLabelsClipping NOTIFY pointLabelsClippingChanged) + +protected: + explicit QColorMapSeries(QColorMapSeriesPrivate &d, QObject *parent =0); + + +public : + + enum Strategy + { + LastPixel, + MeanPixel, + MedianPixel + }; + + + explicit QColorMapSeries(QObject *parent =0); + ~QColorMapSeries(); + QAbstractSeries::SeriesType type() const; + void append(ColorMapDataPart* dataPart, bool copy=true); + void append(const QList &dataParts, bool copy=true); + + int count() const; + QVector dataParts() const; + + QColorMapSeries &operator << (const ColorMapDataPart &dataPart); + QColorMapSeries &operator << (const QList &dataParts); + + void getUniformGrid(double minX, double maxX, double minY, double maxY, int width, int height, QVector &grid, QColorMapSeries::Strategy strategy); + // QVector *getUniformGrid(int width, int height, QVector &grid, Strategy lambda); + + // virtual void attachAxis(QAbstractAxis *axis); + + virtual void setPen(const QPen &pen); + QPen pen() const; + + virtual void setBrush(const QBrush &brush); + QBrush brush() const; + +// virtual void setColor(const QColor &color); +// QColor color() const; + +// void setPointsVisible(bool visible = true); +// bool pointsVisible() const; + +// void setPointLabelsFormat(const QString &format); +// QString pointLabelsFormat() const; + +// void setPointLabelsVisible(bool visible = true); +// bool pointLabelsVisible() const; + +// void setPointLabelsFont(const QFont &font); +// QFont pointLabelsFont() const; + +// void setPointLabelsColor(const QColor &color); +// QColor pointLabelsColor() const; + +// void setPointLabelsClipping(bool enabled = true); +// bool pointLabelsClipping() const; + + double minX(); + double minY(); + double minZ(); + double maxX(); + double maxY(); + double maxZ(); + + + +Q_SIGNALS: +// void clicked(const Point3D &point); +// void hovered(const Point3D &point, bool state); +// void pressed(const Point3D &point); +// void released(const Point3D &point); +// void doubleClicked(const Point3D &point); +// void pointReplaced(int index); +// void pointRemoved(int index); + void dataPartAdded(int index); +// void colorChanged(QColor color); +// void pointsReplaced(); +// void pointLabelsFormatChanged(const QString &format); +// void pointLabelsVisibilityChanged(bool visible); +// void pointLabelsFontChanged(const QFont &font); +// void pointLabelsColorChanged(const QColor &color); +// void pointLabelsClippingChanged(bool clipping); +// void pointsRemoved(int index, int count); + void penChanged(const QPen &pen); + +private: + Q_DECLARE_PRIVATE(QColorMapSeries) + Q_DISABLE_COPY(QColorMapSeries) + friend class ColorMapLegendMarker; + friend class ColorMapChart; + friend class QColorMapLegendMarkerPrivate; + +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QCOLORMAPSERIES_H diff --git a/src/charts/colormapchart/qcolormapseries_p.h b/src/charts/colormapchart/qcolormapseries_p.h new file mode 100644 index 0000000..aa7e3ec --- /dev/null +++ b/src/charts/colormapchart/qcolormapseries_p.h @@ -0,0 +1,100 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#ifndef QCOLORMAPSERIES_P_H +#define QCOLORMAPSERIES_P_H + +#include +#include "colormapdatapart.h" +#include + +QT_CHARTS_BEGIN_NAMESPACE + +#include "qcolormapseries.h" + +class QAbstractAxis; + +class QColorMapSeriesPrivate : public QAbstractSeriesPrivate +{ + Q_OBJECT + +public : + + QColorMapSeriesPrivate(QColorMapSeries *q); + + void initializeDomain(); + void initializeAxes(); + void initializeGraphics(QGraphicsItem* parent); + void initializeTheme(int index, ChartTheme* theme, bool forced = false); + void initializeAnimations(QChart::AnimationOptions options, int duration, + QEasingCurve &curve); + + QList createLegendMarkers(QLegend *legend); + + QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const; + QAbstractAxis* createDefaultAxis(Qt::Orientation) const; + + void getUniformGrid(double minX, double maxX, double minY, double maxY, int width, int height, QVector &grid, QColorMapSeries::Strategy strategy); + +Q_SIGNALS: + void updated(); + +protected: + QList m_dataParts; + QPen m_pen; + QBrush m_brush; + bool m_pointsVisible; + QString m_pointLabelsFormat; + bool m_pointLabelsVisible; + QFont m_pointLabelsFont; + QColor m_pointLabelsColor; + bool m_pointLabelsClipping; + +private: + double m_minX; + double m_maxX; + double m_minY; + double m_maxY; + double m_minZ; + double m_maxZ; + int m_imageHeight; + int m_imageWidth; + QColorMapSeries::Strategy m_strategy; + + double m_requestedMinX; + double m_requestedMaxX; + double m_requestedMinY; + double m_requestedMaxY; + + void recomputeDataRange(); + double computePixelValue(double &index); + double clusterStrategyLast(QVector& cluster); + double clusterStrategyMean(QVector &cluster); + double clusterStrategyMedian(QVector& cluster); + void buildCluster(int xpos,int ypos, double dx,double dy,QVector& cluster); + Q_DECLARE_PUBLIC(QColorMapSeries) +}; + +QT_CHARTS_END_NAMESPACE + + +#endif // QCOLORMAPSERIES_P_H diff --git a/src/charts/legend/legend.pri b/src/charts/legend/legend.pri index 73ff719..9b4e2d9 100644 --- a/src/charts/legend/legend.pri +++ b/src/charts/legend/legend.pri @@ -10,7 +10,8 @@ SOURCES += \ $$PWD/qxylegendmarker.cpp \ $$PWD/qarealegendmarker.cpp \ $$PWD/legendscroller.cpp \ - $$PWD/qboxplotlegendmarker.cpp + $$PWD/qboxplotlegendmarker.cpp \ + $$PWD/qcolormaplegendmarker.cpp PRIVATE_HEADERS += \ $$PWD/legendscroller_p.h \ @@ -22,7 +23,8 @@ PRIVATE_HEADERS += \ $$PWD/qbarlegendmarker_p.h \ $$PWD/qxylegendmarker_p.h \ $$PWD/qarealegendmarker_p.h \ - $$PWD/qboxplotlegendmarker_p.h + $$PWD/qboxplotlegendmarker_p.h \ + $$PWD/qcolormaplegendmarker_p.h PUBLIC_HEADERS += \ @@ -32,4 +34,5 @@ PUBLIC_HEADERS += \ $$PWD/qbarlegendmarker.h \ $$PWD/qxylegendmarker.h \ $$PWD/qarealegendmarker.h \ - $$PWD/qboxplotlegendmarker.h + $$PWD/qboxplotlegendmarker.h \ + $$PWD/qcolormaplegendmarker.h diff --git a/src/charts/legend/qcolormaplegendmarker.cpp b/src/charts/legend/qcolormaplegendmarker.cpp new file mode 100644 index 0000000..a40250b --- /dev/null +++ b/src/charts/legend/qcolormaplegendmarker.cpp @@ -0,0 +1,105 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ + +#include +#include +#include +#include + +QT_CHARTS_BEGIN_NAMESPACE + +QColorMapLegendMarker::QColorMapLegendMarker(QColorMapSeries *series, QLegend *legend, QObject *parent) + : QLegendMarker(*new QColorMapLegendMarkerPrivate(this,series,legend), parent) +{ + d_ptr->updated(); +} + +QColorMapLegendMarker::~QColorMapLegendMarker() +{ +} + +QColorMapLegendMarker::QColorMapLegendMarker(QColorMapLegendMarkerPrivate &d, QObject *parent) : + QLegendMarker(d, parent) +{ +} + +QColorMapSeries* QColorMapLegendMarker::series() +{ + Q_D(QColorMapLegendMarker); + return d->m_series; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +QColorMapLegendMarkerPrivate::QColorMapLegendMarkerPrivate(QColorMapLegendMarker *q, QColorMapSeries *series, QLegend *legend) : + QLegendMarkerPrivate(q,legend), + q_ptr(q), + m_series(series) +{ + QObject::connect(m_series, SIGNAL(nameChanged()), this, SLOT(updated())); + QObject::connect(m_series->d_func(), SIGNAL(updated()), this, SLOT(updated())); +} + +QColorMapLegendMarkerPrivate::~QColorMapLegendMarkerPrivate() +{ +} + +QAbstractSeries* QColorMapLegendMarkerPrivate::series() +{ + return m_series; +} + +QObject* QColorMapLegendMarkerPrivate::relatedObject() +{ + return m_series; +} + +void QColorMapLegendMarkerPrivate::updated() +{ + bool labelChanged = false; + bool brushChanged = false; + + if (!m_customLabel && (m_item->label() != m_series->name())) { + m_item->setLabel(m_series->name()); + labelChanged = true; + } + + QBrush emptyBrush; + if (!m_customBrush + && (m_item->brush() == emptyBrush + || m_item->brush().color() != m_series->pen().color())) { + m_item->setBrush(QBrush(m_series->pen().color())); + brushChanged = true; + } + + invalidateLegend(); + + if (labelChanged) + emit q_ptr->labelChanged(); + if (brushChanged) + emit q_ptr->brushChanged(); +} + +//#include "moc_qcolormaplegendmarker.cpp" +//#include "moc_qcolormaplegendmarker_p.cpp" + +QT_CHARTS_END_NAMESPACE diff --git a/src/charts/legend/qcolormaplegendmarker.h b/src/charts/legend/qcolormaplegendmarker.h new file mode 100644 index 0000000..c8b0e5e --- /dev/null +++ b/src/charts/legend/qcolormaplegendmarker.h @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------------ +-- This file is a part of the ColorMapChart API +-- Copyright (C) 2016, Plasma Physics Laboratory - CNRS +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program 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 General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-------------------------------------------------------------------------------*/ +/*-- Author : Hugo Winter +-- Mail : hugo.winter@lpp.polytechnique.fr +----------------------------------------------------------------------------*/ +#ifndef QCOLORMAPLEGENDMARKER_H +#define QCOLORMAPLEGENDMARKER_H + +#include +#include +#include + +QT_CHARTS_BEGIN_NAMESPACE + +class QColorMapLegendMarkerPrivate; + +class QColorMapLegendMarker : public QLegendMarker +{ + Q_OBJECT +public: + explicit QColorMapLegendMarker(QColorMapSeries *series, QLegend *legend, QObject *parent = 0); + virtual ~QColorMapLegendMarker(); + + virtual LegendMarkerType type() { return LegendMarkerTypeColorMap; } + + // Related series + virtual QColorMapSeries* series(); + +protected: + QColorMapLegendMarker(QColorMapLegendMarkerPrivate &d, QObject *parent = 0); + +private: + Q_DECLARE_PRIVATE(QColorMapLegendMarker) + Q_DISABLE_COPY(QColorMapLegendMarker) +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QCOLORMAPLEGENDMARKER_H diff --git a/src/charts/legend/qcolormaplegendmarker_p.h b/src/charts/legend/qcolormaplegendmarker_p.h new file mode 100644 index 0000000..002861a --- /dev/null +++ b/src/charts/legend/qcolormaplegendmarker_p.h @@ -0,0 +1,35 @@ +#ifndef QCOLORMAPLEGENDMARKER_P_H +#define QCOLORMAPLEGENDMARKER_P_H + +#include +#include +#include +#include + +QT_CHARTS_BEGIN_NAMESPACE + +class QColorMapLegendMarker; + +class QColorMapLegendMarkerPrivate : public QLegendMarkerPrivate +{ + Q_OBJECT +public: + explicit QColorMapLegendMarkerPrivate(QColorMapLegendMarker *q, QColorMapSeries *series, QLegend *legend); + virtual ~QColorMapLegendMarkerPrivate(); + + virtual QAbstractSeries* series(); + virtual QObject* relatedObject(); + +public Q_SLOTS: + virtual void updated(); + +private: + QColorMapLegendMarker *q_ptr; + QColorMapSeries *m_series; + + Q_DECLARE_PUBLIC(QColorMapLegendMarker) +}; + +QT_CHARTS_END_NAMESPACE + +#endif // QCOLORMAPLEGENDMARKER_P_H diff --git a/src/charts/legend/qlegendmarker.h b/src/charts/legend/qlegendmarker.h index 142b7e4..dbd6b8f 100644 --- a/src/charts/legend/qlegendmarker.h +++ b/src/charts/legend/qlegendmarker.h @@ -52,7 +52,8 @@ public: LegendMarkerTypeBar, LegendMarkerTypePie, LegendMarkerTypeXY, - LegendMarkerTypeBoxPlot + LegendMarkerTypeBoxPlot, + LegendMarkerTypeColorMap }; Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged) diff --git a/src/charts/qabstractseries.h b/src/charts/qabstractseries.h index 8fedf5c..6e472bd 100644 --- a/src/charts/qabstractseries.h +++ b/src/charts/qabstractseries.h @@ -63,7 +63,8 @@ public: SeriesTypeHorizontalBar, SeriesTypeHorizontalStackedBar, SeriesTypeHorizontalPercentBar, - SeriesTypeBoxPlot + SeriesTypeBoxPlot, + SeriesTypeColorMap }; protected: