diff --git a/src/qchart.cpp b/src/qchart.cpp index 1179bb9..4ba4f6f 100644 --- a/src/qchart.cpp +++ b/src/qchart.cpp @@ -18,12 +18,14 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE QChart::QChart(QGraphicsObject* parent) : QGraphicsObject(parent), - m_axisX(new Axis(this)), - m_axisY(new Axis(this)), - m_grid(new XYGrid(this)), - m_plotDataIndex(0), - m_marginSize(0) + m_axisX(new Axis(this)), + m_axisY(new Axis(this)), + m_grid(new XYGrid(this)), + m_plotDataIndex(0), + m_marginSize(0) { + // TODO: the default theme? + setTheme(QChart::ChartThemeVanilla); // setFlags(QGraphicsItem::ItemClipsChildrenToShape); // set axis m_axisY->rotate(90); @@ -47,6 +49,9 @@ void QChart::addSeries(QChartSeries* series) case QChartSeries::SeriesTypeLine: { QXYChartSeries* xyseries = static_cast(series); + // Use color defined by theme in case the series does not define a custom color + if (!xyseries->color().isValid() && m_themeColors.count()) + xyseries->setColor(m_themeColors.takeFirst()); XYPlotDomain domain; //TODO "nice numbers algorithm" @@ -69,16 +74,6 @@ void QChart::addSeries(QChartSeries* series) m_xyLineChartItems<(series); -// if (scatter) { -// scatter->d->setParentItem(this); -// scene()->addItem(scatter->d); -// } -// break; -// } - case QChartSeries::SeriesTypeBar: { qDebug() << "barSeries added"; @@ -90,6 +85,23 @@ void QChart::addSeries(QChartSeries* series) m_BarGroupItems.append(group); // If we need to access group later break; } + case QChartSeries::SeriesTypeScatter: { + QScatterSeries *scatterSeries = qobject_cast(series); + connect(this, SIGNAL(sizeChanged(QRectF)), + scatterSeries, SLOT(chartSizeChanged(QRectF))); + scatterSeries->d->setParentItem(this); + QColor nextColor = m_themeColors.takeFirst(); + nextColor.setAlpha(150); // TODO: default opacity? + scatterSeries->setMarkerColor(nextColor); + } + case QChartSeries::SeriesTypePie: { + // TODO: we now have also a list of y values as a parameter, it is ignored + // we should use a generic data class instead of list of x and y values + QPieSeries *pieSeries = qobject_cast(series); + connect(this, SIGNAL(sizeChanged(QRectF)), + pieSeries, SLOT(chartSizeChanged(QRectF))); + // TODO: how to define the color for all the slices of a pie? + } } } @@ -97,28 +109,32 @@ QChartSeries* QChart::createSeries(QChartSeries::QChartSeriesType type) { // TODO: support also other types; not only scatter and pie + QChartSeries *series(0); + switch (type) { + case QChartSeries::SeriesTypeLine: { + series = QXYChartSeries::create(); + break; + } + case QChartSeries::SeriesTypeBar: { + series = new BarChartSeries(this); + break; + } case QChartSeries::SeriesTypeScatter: { - QScatterSeries *scatterSeries = new QScatterSeries(this); - connect(this, SIGNAL(sizeChanged(QRectF)), - scatterSeries, SLOT(chartSizeChanged(QRectF))); - scatterSeries->d->setParentItem(this); - return scatterSeries; + series = new QScatterSeries(this); + break; } case QChartSeries::SeriesTypePie: { - // TODO: we now have also a list of y values as a parameter, it is ignored - // we should use a generic data class instead of list of x and y values - QPieSeries *pieSeries = new QPieSeries(this); - connect(this, SIGNAL(sizeChanged(QRectF)), - pieSeries, SLOT(chartSizeChanged(QRectF))); - return pieSeries; + series = new QPieSeries(this); + break; } default: Q_ASSERT(false); break; } - return 0; + addSeries(series); + return series; } void QChart::setSize(const QSizeF& size) @@ -159,7 +175,39 @@ void QChart::setMargin(int margin) m_marginSize = margin; } -#include "moc_qchart.cpp" +void QChart::setTheme(QChart::ChartTheme theme) +{ + // TODO: define color themes + switch (theme) { + case ChartThemeVanilla: + m_themeColors.append(QColor(255, 238, 174)); + m_themeColors.append(QColor(228, 228, 160)); + m_themeColors.append(QColor(228, 179, 160)); + m_themeColors.append(QColor(180, 151, 18)); + m_themeColors.append(QColor(252, 252, 37)); + break; + case ChartThemeIcy: + m_themeColors.append(QColor(255, 238, 174)); + m_themeColors.append(QColor(228, 228, 160)); + m_themeColors.append(QColor(228, 179, 160)); + m_themeColors.append(QColor(180, 151, 18)); + m_themeColors.append(QColor(252, 252, 37)); + break; + case ChartThemeGrayscale: + m_themeColors.append(QColor(255, 238, 174)); + m_themeColors.append(QColor(228, 228, 160)); + m_themeColors.append(QColor(228, 179, 160)); + m_themeColors.append(QColor(180, 151, 18)); + m_themeColors.append(QColor(252, 252, 37)); + break; + default: + Q_ASSERT(false); + break; + } + // TODO: update coloring of different elements to match the selected theme +} + +#include "moc_qchart.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qchart.h b/src/qchart.h index e1d0856..9a70953 100644 --- a/src/qchart.h +++ b/src/qchart.h @@ -26,6 +26,13 @@ class QTCOMMERCIALCHART_EXPORT QChart : public QGraphicsObject { Q_OBJECT public: + enum ChartTheme { + ChartThemeVanilla = 0, + ChartThemeIcy, + ChartThemeGrayscale + }; + +public: QChart(QGraphicsObject* parent = 0); ~QChart(); @@ -41,6 +48,7 @@ public: virtual void setSize(const QSizeF& rect); void setMargin(int margin); int margin() const; + void setTheme(QChart::ChartTheme theme); signals: void sizeChanged(QRectF rect); @@ -58,6 +66,7 @@ private: QList m_items; int m_plotDataIndex; int m_marginSize; + QList m_themeColors; QList m_BarGroupItems; }; diff --git a/src/qchartwidget.cpp b/src/qchartwidget.cpp index 299e191..ecd3f1b 100644 --- a/src/qchartwidget.cpp +++ b/src/qchartwidget.cpp @@ -46,6 +46,12 @@ QChartSeries* QChartWidget::createSeries(QChartSeries::QChartSeriesType type) { return m_chart->createSeries(type); } + +void QChartWidget::setTheme(QChart::ChartTheme theme) +{ + m_chart->setTheme(theme); +} + #include "moc_qchartwidget.cpp" QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/qchartwidget.h b/src/qchartwidget.h index 8f5ea76..b5d2347 100644 --- a/src/qchartwidget.h +++ b/src/qchartwidget.h @@ -28,6 +28,12 @@ public: void addSeries(QChartSeries* series); QChartSeries* createSeries(QChartSeries::QChartSeriesType type); + /*! + * Set color theme for the chart. Themes define harmonic colors for the graphical elements of + * the chart. + */ + void setTheme(QChart::ChartTheme theme); + private: Q_DISABLE_COPY(QChartWidget) QGraphicsScene *m_scene; diff --git a/src/qscatterseries.cpp b/src/qscatterseries.cpp index 75b2ea7..471da73 100644 --- a/src/qscatterseries.cpp +++ b/src/qscatterseries.cpp @@ -12,7 +12,8 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE QScatterSeriesPrivate::QScatterSeriesPrivate(QGraphicsItem *parent) : QGraphicsItem(parent), m_scalex(100), // TODO: let the use define the scale (or autoscaled) - m_scaley(100) + m_scaley(100), + m_markerColor(QColor()) { } @@ -41,7 +42,8 @@ void QScatterSeriesPrivate::paint(QPainter *painter, const QStyleOptionGraphicsI QPen pen = painter->pen(); QBrush brush = pen.brush(); // TODO: The opacity should be user definable... - brush.setColor(QColor(255, 82, 0, 100)); + //brush.setColor(QColor(255, 82, 0, 100)); + brush.setColor(m_markerColor); pen.setBrush(brush); pen.setWidth(4); painter->setPen(pen); @@ -80,6 +82,11 @@ void QScatterSeries::chartSizeChanged(QRectF rect) d->resize(rect); } +void QScatterSeries::setMarkerColor(QColor color) +{ + d->m_markerColor = color; +} + // TODO: //void QScatterSeries::chartScaleChanged(qreal xscale, qreal yscale) //{ diff --git a/src/qscatterseries.h b/src/qscatterseries.h index 83e3a77..a134b1e 100644 --- a/src/qscatterseries.h +++ b/src/qscatterseries.h @@ -3,6 +3,7 @@ #include "qchartseries.h" #include +#include QTCOMMERCIALCHART_BEGIN_NAMESPACE class QScatterSeriesPrivate; @@ -21,6 +22,7 @@ public: // from QChartSeries public Q_SLOTS: void chartSizeChanged(QRectF rect); + void setMarkerColor(QColor color); //void chartScaleChanged(qreal xscale, qreal yscale); private: diff --git a/src/qscatterseries_p.h b/src/qscatterseries_p.h index ef8b71e..e39c4af 100644 --- a/src/qscatterseries_p.h +++ b/src/qscatterseries_p.h @@ -26,6 +26,7 @@ public: // from QGraphicsItem qreal m_scaley; QList m_scenex; QList m_sceney; + QColor m_markerColor; }; QTCOMMERCIALCHART_END_NAMESPACE diff --git a/src/xylinechart/qxychartseries.cpp b/src/xylinechart/qxychartseries.cpp index 21ba0d9..8811aa4 100644 --- a/src/xylinechart/qxychartseries.cpp +++ b/src/xylinechart/qxychartseries.cpp @@ -3,7 +3,7 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE QXYChartSeries::QXYChartSeries(QObject* parent):QChartSeries(parent), - m_color(Qt::black) + m_color() { } diff --git a/test/chartwidgettest/mainwidget.cpp b/test/chartwidgettest/mainwidget.cpp index 9811372..4b327e2 100644 --- a/test/chartwidgettest/mainwidget.cpp +++ b/test/chartwidgettest/mainwidget.cpp @@ -58,6 +58,14 @@ MainWidget::MainWidget(QWidget *parent) : m_yMaxSpin->setValue(10); connect(m_yMaxSpin, SIGNAL(valueChanged(int)), this, SLOT(yMaxChanged(int))); + QComboBox *chartTheme = new QComboBox(); + chartTheme->addItem("Vanilla"); + chartTheme->addItem("Icy"); + chartTheme->addItem("Grayscale"); + chartTheme->addItem("Tobedefined"); + connect(chartTheme, SIGNAL(currentIndexChanged(int)), + this, SLOT(changeChartTheme(int))); + QGridLayout *grid = new QGridLayout(); QGridLayout *mainLayout = new QGridLayout(); //grid->addWidget(new QLabel("Add series:"), 0, 0); @@ -73,9 +81,11 @@ MainWidget::MainWidget(QWidget *parent) : grid->addWidget(m_yMinSpin, 6, 1); grid->addWidget(new QLabel("y max:"), 7, 0); grid->addWidget(m_yMaxSpin, 7, 1); + grid->addWidget(new QLabel("Chart theme:"), 8, 0); + grid->addWidget(chartTheme, 8, 1); // add row with empty label to make all the other rows static - grid->addWidget(new QLabel(""), 8, 0); - grid->setRowStretch(8, 1); + grid->addWidget(new QLabel(""), 9, 0); + grid->setRowStretch(9, 1); mainLayout->addLayout(grid, 0, 0); @@ -160,8 +170,19 @@ void MainWidget::addSeries(QString series, QString data) newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie); Q_ASSERT(newSeries->setData(y)); } else if (series == "Line") { - newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypePie); - Q_ASSERT(newSeries->setData(x, y)); + // TODO: adding data to an existing line series does not give any visuals for some reason +// newSeries = m_chartWidget->createSeries(QChartSeries::SeriesTypeLine); +// QXYChartSeries *lineSeries = static_cast(newSeries); +// lineSeries->setColor(Qt::blue); +// for (int i(0); i < x.count() && i < y.count(); i++) { +// lineSeries->add(x.at(i), y.at(i)); +// } + //Q_ASSERT(newSeries->setData(x, y)); + QXYChartSeries* series0 = QXYChartSeries::create(); + for (int i(0); i < x.count() && i < y.count(); i++) + series0->add(x.at(i), y.at(i)); + m_chartWidget->addSeries(series0); + newSeries = series0; } else { // TODO } @@ -279,6 +300,12 @@ void MainWidget::yMaxChanged(int value) qDebug() << "yMaxChanged: " << value; } +void MainWidget::changeChartTheme(int themeIndex) +{ + qDebug() << "changeChartTheme: " << themeIndex; + m_chartWidget->setTheme((QChart::ChartTheme) themeIndex); +} + void MainWidget::setPieSizeFactor(double size) { QPieSeries *pie = qobject_cast(m_currentSeries); diff --git a/test/chartwidgettest/mainwidget.h b/test/chartwidgettest/mainwidget.h index 3e5fc39..21cf670 100644 --- a/test/chartwidgettest/mainwidget.h +++ b/test/chartwidgettest/mainwidget.h @@ -30,6 +30,7 @@ private slots: void yMinChanged(int value); void yMaxChanged(int value); void setCurrentSeries(QChartSeries *series); + void changeChartTheme(int themeIndex); void setPieSizeFactor(double margin); private: