##// END OF EJS Templates
Merge remote-tracking branch 'origin/5.6' into 5.7...
Merge remote-tracking branch 'origin/5.6' into 5.7 Conflicts: src/charts/doc/qtcharts.qdocconf Change-Id: If6160b2f643e7df8c32400b97afac229b95b78de

File last commit:

r2863:15eed6371853
r2893:0464d42b101e merge 5.7.0
Show More
glxyseriesdata.cpp
233 lines | 8.1 KiB | text/x-c | CppLexer
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Charts module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "private/glxyseriesdata_p.h"
#include "private/abstractdomain_p.h"
#include <QtCharts/QScatterSeries>
QT_CHARTS_BEGIN_NAMESPACE
GLXYSeriesDataManager::GLXYSeriesDataManager(QObject *parent)
: QObject(parent),
m_mapDirty(false)
{
}
GLXYSeriesDataManager::~GLXYSeriesDataManager()
{
cleanup();
}
void GLXYSeriesDataManager::setPoints(QXYSeries *series, const AbstractDomain *domain)
{
GLXYSeriesData *data = m_seriesDataMap.value(series);
if (!data) {
data = new GLXYSeriesData;
data->type = series->type();
QColor sc;
if (data->type == QAbstractSeries::SeriesTypeScatter) {
QScatterSeries *scatter = static_cast<QScatterSeries *>(series);
data->width = float(scatter->markerSize());
sc = scatter->color(); // Scatter overwrites color property
connect(scatter, &QScatterSeries::colorChanged, this,
&GLXYSeriesDataManager::handleScatterColorChange);
connect(scatter, &QScatterSeries::markerSizeChanged, this,
&GLXYSeriesDataManager::handleScatterMarkerSizeChange);
} else {
data->width = float(series->pen().widthF());
sc = series->color();
connect(series, &QXYSeries::penChanged, this,
&GLXYSeriesDataManager::handleSeriesPenChange);
}
data->color = QVector3D(float(sc.redF()), float(sc.greenF()), float(sc.blueF()));
connect(series, &QXYSeries::useOpenGLChanged, this,
&GLXYSeriesDataManager::handleSeriesOpenGLChange);
m_seriesDataMap.insert(series, data);
m_mapDirty = true;
}
QVector<float> &array = data->array;
bool logAxis = false;
bool reverseX = false;
bool reverseY = false;
foreach (QAbstractAxis* axis, series->attachedAxes()) {
if (axis->type() == QAbstractAxis::AxisTypeLogValue) {
logAxis = true;
}
if (axis->isReverse()) {
if (axis->orientation() == Qt::Horizontal)
reverseX = true;
else
reverseY = true;
if (reverseX && reverseY)
break;
}
}
int count = series->count();
int index = 0;
array.resize(count * 2);
QMatrix4x4 matrix;
if (reverseX)
matrix.scale(-1.0, 1.0);
if (reverseY)
matrix.scale(1.0, -1.0);
data->matrix = matrix;
if (logAxis) {
// Use domain to resolve geometry points. Not as fast as shaders, but simpler that way
QVector<QPointF> geometryPoints = domain->calculateGeometryPoints(series->pointsVector());
const float height = domain->size().height();
if (geometryPoints.size()) {
for (int i = 0; i < count; i++) {
const QPointF &point = geometryPoints.at(i);
array[index++] = float(point.x());
array[index++] = float(height - point.y());
}
} else {
// If there are invalid log values, geometry points generation fails
for (int i = 0; i < count; i++) {
array[index++] = 0.0f;
array[index++] = 0.0f;
}
}
data->min = QVector2D(0, 0);
data->delta = QVector2D(domain->size().width() / 2.0f, domain->size().height() / 2.0f);
} else {
// Regular value axes, so we can do the math easily on shaders.
QVector<QPointF> seriesPoints = series->pointsVector();
for (int i = 0; i < count; i++) {
const QPointF &point = seriesPoints.at(i);
array[index++] = float(point.x());
array[index++] = float(point.y());
}
data->min = QVector2D(domain->minX(), domain->minY());
data->delta = QVector2D((domain->maxX() - domain->minX()) / 2.0f,
(domain->maxY() - domain->minY()) / 2.0f);
}
data->dirty = true;
}
void GLXYSeriesDataManager::removeSeries(const QXYSeries *series)
{
GLXYSeriesData *data = m_seriesDataMap.take(series);
if (data) {
disconnect(series, 0, this, 0);
delete data;
emit seriesRemoved(series);
m_mapDirty = true;
}
}
void GLXYSeriesDataManager::cleanup()
{
foreach (GLXYSeriesData *data, m_seriesDataMap.values())
delete data;
m_seriesDataMap.clear();
m_mapDirty = true;
// Signal all series removal by using zero as parameter
emit seriesRemoved(0);
}
void GLXYSeriesDataManager::handleSeriesPenChange()
{
QXYSeries *series = qobject_cast<QXYSeries *>(sender());
if (series) {
GLXYSeriesData *data = m_seriesDataMap.value(series);
if (data) {
QColor sc = series->color();
data->color = QVector3D(float(sc.redF()), float(sc.greenF()), float(sc.blueF()));
data->width = float(series->pen().widthF());
data->dirty = true;
}
}
}
void GLXYSeriesDataManager::handleSeriesOpenGLChange()
{
QXYSeries *series = qobject_cast<QXYSeries *>(sender());
if (!series->useOpenGL())
removeSeries(series);
}
void GLXYSeriesDataManager::handleScatterColorChange()
{
QScatterSeries *series = qobject_cast<QScatterSeries *>(sender());
if (series) {
GLXYSeriesData *data = m_seriesDataMap.value(series);
if (data) {
QColor sc = series->color();
data->color = QVector3D(float(sc.redF()), float(sc.greenF()), float(sc.blueF()));
data->dirty = true;
}
}
}
void GLXYSeriesDataManager::handleScatterMarkerSizeChange()
{
QScatterSeries *series = qobject_cast<QScatterSeries *>(sender());
if (series) {
GLXYSeriesData *data = m_seriesDataMap.value(series);
if (data) {
data->width =float(series->markerSize());
data->dirty = true;
}
}
}
void GLXYSeriesDataManager::handleAxisReverseChanged(const QList<QAbstractSeries *> &seriesList)
{
bool reverseX = false;
bool reverseY = false;
foreach (QAbstractSeries *series, seriesList) {
if (QXYSeries *xyseries = qobject_cast<QXYSeries *>(series)) {
GLXYSeriesData *data = m_seriesDataMap.value(xyseries);
if (data) {
foreach (QAbstractAxis* axis, xyseries->attachedAxes()) {
if (axis->isReverse()) {
if (axis->orientation() == Qt::Horizontal)
reverseX = true;
else
reverseY = true;
}
if (reverseX && reverseY)
break;
}
QMatrix4x4 matrix;
if (reverseX)
matrix.scale(-1.0, 1.0);
if (reverseY)
matrix.scale(1.0, -1.0);
data->matrix = matrix;
data->dirty = true;
}
}
}
}
QT_CHARTS_END_NAMESPACE