/**************************************************************************** ** ** Copyright (C) 2014 Digia Plc ** All rights reserved. ** For any questions to Digia, please use contact form at http://qt.io ** ** This file is part of the Qt Charts module. ** ** Licensees holding valid commercial license for Qt may use this file in ** accordance with the Qt License Agreement provided with the Software ** or, alternatively, in accordance with the terms contained in a written ** agreement between you and Digia. ** ** If you have questions regarding the use of this file, please use ** contact form at http://qt.io ** ****************************************************************************/ #include "engine.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include const qint32 MAGIC_NUMBER = 0x66666666; Engine::Engine(QObject* parent) : QObject(parent), m_count(10), m_chart(new QChart()), m_model(0), m_selection(0) { createModels(); } Engine::~Engine() { delete m_chart; delete m_selection; delete m_model; } void Engine::createModels() { m_model = new QStandardItemModel(m_count, m_count); m_model->setHorizontalHeaderLabels( QStringList() << "A" << "B" << "C" << "D" << "E" << "F" << "G" << "H" << "I" << "J"); m_model->setVerticalHeaderLabels( QStringList() << "1" << "2" << "3" << "4" << "5" << "6" << "7" << "8" << "9" << "10"); m_selection = new QItemSelectionModel(m_model); } QList Engine::addSeries(QAbstractSeries::SeriesType type) { const QModelIndexList& list = m_selection->selectedIndexes(); QMap columns; foreach (const QModelIndex& index, list) { columns.insertMulti(index.column(), index); } QList keys = columns.uniqueKeys(); QModelIndexList rows = columns.values(keys.first()); int minRow = m_count + 1; int maxRow = -1; foreach (const QModelIndex& index, rows) { minRow = qMin(index.row(), minRow); maxRow = qMax(index.row(), maxRow); } QList result; QColor color; switch (type) { case QAbstractSeries::SeriesTypeLine: { for (int i = 1; i < keys.count(); ++i) { QLineSeries *line = new QLineSeries(); setupXYSeries(line, keys, i, minRow, maxRow); result << line; } break; } case QAbstractSeries::SeriesTypeSpline: { for (int i = 1; i < keys.count(); ++i) { QSplineSeries *line = new QSplineSeries(); setupXYSeries(line, keys, i, minRow, maxRow); result << line; } break; } case QAbstractSeries::SeriesTypeScatter: { for (int i = 1; i < keys.count(); ++i) { QScatterSeries *line = new QScatterSeries(); setupXYSeries(line, keys, i, minRow, maxRow); result << line; } break; } case QAbstractSeries::SeriesTypeBar: { QBarSeries *bar = new QBarSeries(); setupBarSeries(bar,keys,minRow,maxRow); result << bar; break; } case QAbstractSeries::SeriesTypePercentBar: { QPercentBarSeries *bar = new QPercentBarSeries(); setupBarSeries(bar,keys,minRow,maxRow); result << bar; break; } case QAbstractSeries::SeriesTypeStackedBar: { QStackedBarSeries *bar = new QStackedBarSeries(); setupBarSeries(bar,keys,minRow,maxRow); result << bar; break; } case QAbstractSeries::SeriesTypePie: { QPieSeries *pie = new QPieSeries(); setupPieSeries(pie,keys,minRow,maxRow); result << pie; break; } case QAbstractSeries::SeriesTypeArea: { QAreaSeries *area = new QAreaSeries( new QLineSeries(), new QLineSeries()); setupAreaSeries(area,keys,minRow,maxRow); result << area; break; } } m_chart->createDefaultAxes(); return result; } void Engine::removeSeries(QAbstractSeries* series) { m_chart->removeSeries(series); foreach (const QModelIndex& index, m_seriesModelIndex.value(series)) { m_model->setData(index, QColor(Qt::white), Qt::BackgroundRole); } } void Engine::clearModels() { delete m_selection; m_selection = 0; delete m_model; m_model = 0; createModels(); } bool Engine::save(const QString &filename) const { if (filename.isEmpty()) return false; QFile file(filename); if (!file.open(QIODevice::WriteOnly)) { return false; } QDataStream out(&file); out << MAGIC_NUMBER; out.setVersion(QDataStream::Qt_4_8); out << m_model->rowCount(); out << m_model->columnCount(); for (int row = 0; row < m_model->rowCount(); ++row) { for (int column = 0; column < m_model->columnCount(); ++column) { QStandardItem *item = m_model->item(row, column); if (item) { out << row; out << column; out << item->data(Qt::EditRole).toString(); } } } return true; } bool Engine::load(const QString &filename) { clearModels(); if (filename.isEmpty()) return false; QFile file(filename); if (!file.open(QIODevice::ReadOnly)) { return false; } QDataStream in(&file); qint32 magicNumber; in >> magicNumber; if (magicNumber != MAGIC_NUMBER) return false; in.setVersion(QDataStream::Qt_4_8); int rowCount; in >> rowCount; int columnCount; in >> columnCount; while (!in.atEnd()) { int row; int column; QString value; in >> row >> column >> value; QStandardItem *item = new QStandardItem(); bool ok; double result = value.toDouble(&ok); if(ok) item->setData(result, Qt::EditRole); else item->setData(value, Qt::EditRole); m_model->setItem(row, column, item); } return true; } void Engine::setupXYSeries(QXYSeries *xyseries, const QList& columns, int column, int minRow, int maxRow) { QVXYModelMapper* mapper = new QVXYModelMapper(xyseries); mapper->setSeries(xyseries); mapper->setModel(m_model); mapper->setXColumn(columns.first()); mapper->setYColumn(columns.at(column)); mapper->setFirstRow(minRow); mapper->setRowCount(maxRow - minRow + 1); m_chart->addSeries(xyseries); xyseries->setName(QString("Series %1").arg(m_chart->series().count())); QObject::connect(xyseries,SIGNAL(clicked(QPointF)),this,SIGNAL(selected())); const QModelIndexList& list = m_selection->selectedIndexes(); QModelIndexList result; foreach (const QModelIndex& index, list) { if (index.column() ==columns.at(column)){ m_model->setData(index, xyseries->pen().color(), Qt::BackgroundRole); result << index; } } m_seriesModelIndex.insert(xyseries,result); } void Engine::setupBarSeries(QAbstractBarSeries *bar, const QList& columns, int minRow, int maxRow) { QHBarModelMapper* mapper = new QHBarModelMapper(bar); mapper->setSeries(bar); mapper->setModel(m_model); mapper->setFirstColumn(minRow); mapper->setColumnCount(maxRow - minRow + 1); mapper->setFirstBarSetRow(columns.at(1)); mapper->setLastBarSetRow(columns.last()); m_chart->addSeries(bar); bar->setName(QString("Series %1").arg(m_chart->series().count())); const QModelIndexList& list = m_selection->selectedIndexes(); foreach (const QModelIndex& index, list) { if (index.column() >= columns.at(1) && index.column()<= columns.last()) { //m_model->setData(index, bar->barSets().at(index.column())->brush().color(), Qt::BackgroundRole); } } } void Engine::setupPieSeries(QPieSeries *pie, const QList& columns, int minRow, int maxRow) { QVPieModelMapper* mapper = new QVPieModelMapper(pie); mapper->setSeries(pie); mapper->setModel(m_model); mapper->setValuesColumn(columns.at(1)); mapper->setLabelsColumn(columns.first()); mapper->setFirstRow(minRow); mapper->setRowCount(maxRow - minRow + 1); m_chart->addSeries(pie); pie->setName(QString("Series %1").arg(m_chart->series().count())); const QModelIndexList& list = m_selection->selectedIndexes(); foreach (const QModelIndex& index, list) { // m_model->setData(index, bar->barSets()pen().color(), Qt::BackgroundRole); } } void Engine::setupAreaSeries(QAreaSeries *series, const QList& columns, int minRow, int maxRow) { QVXYModelMapper* umapper = new QVXYModelMapper(series); umapper->setSeries(series->upperSeries()); umapper->setModel(m_model); umapper->setXColumn(columns.first()); umapper->setYColumn(columns.at(1)); umapper->setFirstRow(minRow); umapper->setRowCount(maxRow - minRow + 1); QVXYModelMapper* lmapper = new QVXYModelMapper(series); lmapper->setSeries(series->lowerSeries()); lmapper->setModel(m_model); lmapper->setXColumn(columns.first()); lmapper->setYColumn(columns.at(2)); lmapper->setFirstRow(minRow); lmapper->setRowCount(maxRow - minRow + 1); m_chart->addSeries(series); series->setName(QString("Series %1").arg(m_chart->series().count())); const QModelIndexList& list = m_selection->selectedIndexes(); foreach (const QModelIndex& index, list) { //if (index.column() ==columns.at(column)) // m_model->setData(index, xyseries->pen().color(), Qt::BackgroundRole); } }