From 0d50fe03d2e8e2b555b4ff21feb5a36b8322dfad 2012-02-01 11:04:02 From: Tero Ahola Date: 2012-02-01 11:04:02 Subject: [PATCH] Scaling for scatter series --- diff --git a/src/qchart.cpp b/src/qchart.cpp index f00866d..357bfaf 100644 --- a/src/qchart.cpp +++ b/src/qchart.cpp @@ -54,15 +54,15 @@ void QChart::addSeries(QChartSeries* series) m_chartSeries << series; + m_plotDataIndex = 0 ; + m_plotDomainList.resize(1); + PlotDomain& domain = m_plotDomainList[m_plotDataIndex]; + switch(series->type()) { case QChartSeries::SeriesTypeLine: { QXYChartSeries* xyseries = static_cast(series); - m_plotDataIndex = 0 ; - m_plotDomainList.resize(1); - - PlotDomain& domain = m_plotDomainList[m_plotDataIndex]; for (int i = 0 ; i < xyseries->count() ; i++) { qreal x = xyseries->x(i); @@ -97,15 +97,8 @@ void QChart::addSeries(QChartSeries* series) m_chartItems << barGroup; childItems().append(barGroup); - // TODO: setting of domain should this be somewhere else. - m_plotDataIndex = 0 ; - m_plotDomainList.resize(1); - qreal x = barSeries->countColumns(); qreal y = barSeries->max(); - - PlotDomain& domain = m_plotDomainList[m_plotDataIndex]; - domain.m_minX = qMin(domain.m_minX,x); domain.m_minY = qMin(domain.m_minY,y); domain.m_maxX = qMax(domain.m_maxX,x); @@ -128,15 +121,8 @@ void QChart::addSeries(QChartSeries* series) m_chartItems << stackedBarGroup; childItems().append(stackedBarGroup); - // TODO: setting of domain should this be somewhere else. - m_plotDataIndex = 0 ; - m_plotDomainList.resize(1); - qreal x = stackedBarSeries->countColumns(); qreal y = stackedBarSeries->maxColumnSum(); - - PlotDomain& domain = m_plotDomainList[m_plotDataIndex]; - domain.m_minX = qMin(domain.m_minX,x); domain.m_minY = qMin(domain.m_minY,y); domain.m_maxX = qMax(domain.m_maxX,x); @@ -159,14 +145,7 @@ void QChart::addSeries(QChartSeries* series) m_chartItems << percentBarGroup; childItems().append(percentBarGroup); - // TODO: setting of domain should this be somewhere else. - m_plotDataIndex = 0 ; - m_plotDomainList.resize(1); - qreal x = percentBarSeries->countColumns(); - - PlotDomain& domain = m_plotDomainList[m_plotDataIndex]; - domain.m_minX = qMin(domain.m_minX,x); domain.m_minY = 0; domain.m_maxX = qMax(domain.m_maxX,x); @@ -177,8 +156,19 @@ void QChart::addSeries(QChartSeries* series) QScatterSeries *scatterSeries = qobject_cast(series); scatterSeries->d->m_theme = m_chartTheme->themeForSeries(); scatterSeries->d->setParentItem(this); + scatterSeries->d->m_boundingRect = m_rect.adjusted(margin(),margin(), -margin(), -margin()); m_chartItems << scatterSeries->d; m_chartTheme->addObserver(scatterSeries->d); + + foreach (qreal x, scatterSeries->d->m_x) { + domain.m_minX = qMin(domain.m_minX, x); + domain.m_maxX = qMax(domain.m_maxX, x); + } + foreach (qreal y, scatterSeries->d->m_y) { + domain.m_minY = qMin(domain.m_minY, y); + domain.m_maxY = qMax(domain.m_maxY, y); + } + break; } case QChartSeries::SeriesTypePie: { diff --git a/src/qchartwidget.cpp b/src/qchartwidget.cpp index c601b89..a3f7dd8 100644 --- a/src/qchartwidget.cpp +++ b/src/qchartwidget.cpp @@ -18,6 +18,8 @@ QChartWidget::QChartWidget(QWidget *parent) : setScene(m_scene); m_chart = new QChart(); + // TODO: currently setting the margins explicitly is required, if you wish to have axis labels visible + m_chart->setMargin(25); m_scene->addItem(m_chart); m_rubberBand.setEnabled(true); // TODO: should zoom be enabled by default? show(); diff --git a/src/qscatterseries.cpp b/src/qscatterseries.cpp index d3cff7f..1300d51 100644 --- a/src/qscatterseries.cpp +++ b/src/qscatterseries.cpp @@ -12,31 +12,36 @@ QTCOMMERCIALCHART_BEGIN_NAMESPACE QScatterSeriesPrivate::QScatterSeriesPrivate(QGraphicsItem *parent) : ChartItem(parent), m_markerColor(QColor()), - m_visibleChartArea() + m_visibleChartArea(), + m_boundingRect() { + if (parent) + m_boundingRect = parent->boundingRect(); } -void QScatterSeriesPrivate::resize(QRectF rect) +void QScatterSeriesPrivate::changeGeometry() { - qreal scalex = rect.width() / m_visibleChartArea.spanX(); - qreal scaley = rect.height() / m_visibleChartArea.spanY(); - - m_scenex.clear(); - m_sceney.clear(); - - // Convert relative coordinates to absolute pixel coordinates that can be used for drawing - foreach(qreal x, m_x) - m_scenex.append(rect.left() + x * scalex - m_visibleChartArea.m_minX * scalex); - - foreach(qreal y, m_y) - m_sceney.append(rect.bottom() - y * scaley - m_visibleChartArea.m_minY * scaley); + if (m_boundingRect.isValid()) { + prepareGeometryChange(); + qreal scalex = m_boundingRect.width() / m_visibleChartArea.spanX(); + qreal scaley = m_boundingRect.height() / m_visibleChartArea.spanY(); + m_scenex.clear(); + m_sceney.clear(); + + // Convert relative coordinates to absolute pixel coordinates that can be used for drawing + foreach(qreal x, m_x) + m_scenex.append(m_boundingRect.left() + x * scalex - m_visibleChartArea.m_minX * scalex); + + foreach(qreal y, m_y) + m_sceney.append(m_boundingRect.bottom() - y * scaley + m_visibleChartArea.m_minY * scaley); + } } void QScatterSeriesPrivate::setSize(const QSize &size) { - QGraphicsItem *parent = this->parentItem(); - if (parent) - resize(QRectF(parent->pos(), size)); +// m_boundingRect = QRectF(pos().x(), pos().y(), size.width(), size.height()); + m_boundingRect = QRectF(0, 0, size.width(), size.height()); + changeGeometry(); } void QScatterSeriesPrivate::themeChanged(ChartTheme *theme) @@ -47,12 +52,12 @@ void QScatterSeriesPrivate::themeChanged(ChartTheme *theme) void QScatterSeriesPrivate::setPlotDomain(const PlotDomain& plotDomain) { m_visibleChartArea = plotDomain; - resize(parentItem()->boundingRect()); + changeGeometry(); } QRectF QScatterSeriesPrivate::boundingRect() const { - return QRectF(0, 0, 55, 100); + return m_boundingRect; } void QScatterSeriesPrivate::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/) @@ -86,16 +91,26 @@ QScatterSeries::QScatterSeries(QObject *parent) : { } -bool QScatterSeries::setData(QList x, QList y) +bool QScatterSeries::setData(QList xlist, QList ylist) { // TODO: validate data - d->m_x = x; - d->m_y = y; - QGraphicsItem *parentItem = qobject_cast(parent()); - Q_ASSERT(parentItem); -// d->setPos(parentItem->pos()); -// d->setSize(parentItem->boundingRect().size().toSize()); - d->resize(parentItem->boundingRect()); + d->m_x = xlist; + d->m_y = ylist; + + // TODO: the following updates the visible chart area setting of the series, we would instead + // need to update the _chart's_ visible area... this would require a callback or + // similar to the parenting QChart object... + foreach (qreal x, d->m_x) { + d->m_visibleChartArea.m_minX = qMin(d->m_visibleChartArea.m_minX, x); + d->m_visibleChartArea.m_maxX = qMax(d->m_visibleChartArea.m_maxX, x); + } + foreach (qreal y, d->m_y) { + d->m_visibleChartArea.m_minY = qMin(d->m_visibleChartArea.m_minY, y); + d->m_visibleChartArea.m_maxY = qMax(d->m_visibleChartArea.m_maxY, y); + } + + d->changeGeometry(); + return true; } diff --git a/src/qscatterseries_p.h b/src/qscatterseries_p.h index 4e573e3..0eeee39 100644 --- a/src/qscatterseries_p.h +++ b/src/qscatterseries_p.h @@ -29,13 +29,12 @@ public: // from QGraphicsItem void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); public: - void resize(QRectF rect); // TODO: replace with setSize + void changeGeometry(); + QRectF m_boundingRect; // TODO: use the chart data class instead of list of x and y values? QList m_x; QList m_y; - qreal m_scalex; - qreal m_scaley; QList m_scenex; QList m_sceney; QColor m_markerColor; diff --git a/test/chartwidgettest/mainwidget.cpp b/test/chartwidgettest/mainwidget.cpp index 4f45923..703ebac 100644 --- a/test/chartwidgettest/mainwidget.cpp +++ b/test/chartwidgettest/mainwidget.cpp @@ -25,22 +25,24 @@ MainWidget::MainWidget(QWidget *parent) : { m_chartWidget = new QChartWidget(this); - // GridLayout for the controls for configuring the chart widget + // Grid layout for the controls for configuring the chart widget QGridLayout *grid = new QGridLayout(); - QGridLayout *mainLayout = new QGridLayout(); QPushButton *addSeriesButton = new QPushButton("Add series"); connect(addSeriesButton, SIGNAL(clicked()), this, SLOT(addSeries())); grid->addWidget(addSeriesButton, 0, 1); initBackroundCombo(grid); initScaleControls(grid); initThemeCombo(grid); - QCheckBox *zoomCheckBox = new QCheckBox("Zoom enabled"); + QCheckBox *zoomCheckBox = new QCheckBox("Drag'n drop Zoom"); connect(zoomCheckBox, SIGNAL(toggled(bool)), m_chartWidget, SLOT(setZoomEnabled(bool))); zoomCheckBox->setChecked(true); grid->addWidget(zoomCheckBox, grid->rowCount(), 0); // add row with empty label to make all the other rows static grid->addWidget(new QLabel(""), grid->rowCount(), 0); grid->setRowStretch(grid->rowCount() - 1, 1); + + // Another grid layout as a main layout + QGridLayout *mainLayout = new QGridLayout(); mainLayout->addLayout(grid, 0, 0); // Init series type specific controls