From 9e99014de1f1e4b30d2227391bce17fb6e988e3c 2012-08-15 10:03:42 From: Tero Ahola Date: 2012-08-15 10:03:42 Subject: [PATCH] Switched the z-order of axis to be below series The axis was changed to be below series to make it possible to get clicked signals from series when a data point is overlapping an axis. If the axis is on top of series, you cannot get clicked events from such data points at all. It should not be a problem if you don't get a clicked event from the axis in this case; you can always click on other position on top of the axis (except in the rare use case that the axis is fully covered by data points of a series). --- diff --git a/demos/chartinteractions/chart.cpp b/demos/chartinteractions/chart.cpp new file mode 100644 index 0000000..986f5ae --- /dev/null +++ b/demos/chartinteractions/chart.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Commercial Charts Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial 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.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include "chart.h" + +Chart::Chart(QGraphicsItem *parent, Qt::WindowFlags wFlags, QLineSeries *series) + : QChart(parent, wFlags), m_series(series) +{ + m_clicked = false; +} + +Chart::~Chart() +{ +} + +void Chart::clickPoint(const QPointF &point) +{ + //Get all points from the series. + QList points = m_series->points(); + //Construct a small rectangle around the clicked point + //to identify the real point clicked from the series. + QRectF clickRect(point.x() - 0.5, point.y() - 0.5, 1.0, 1.0); + + //Find the clicked point to be moved. + foreach (QPointF p, points) { + if (clickRect.contains(p)) { + m_movingPoint = p; + m_clicked = true; + return; + } + } +} + +void Chart::setPointClicked(bool clicked) +{ + m_clicked = clicked; +} + +void Chart::handlePointMove(const QPoint &point) +{ + if (m_clicked) { + //Map the point clicked from the ChartView + //to the area occupied by the chart. + QPoint mappedPoint = point; + mappedPoint.setX(point.x()-this->plotArea().x()); + mappedPoint.setY(point.y()-this->plotArea().y()); + + //Get the x- and y axis to be able to convert the mapped + //coordinate point to the charts scale. + QAbstractAxis * axisx = this->axisX(); + QValuesAxis* haxis = 0; + if (axisx->type() == QAbstractAxis::AxisTypeValues) + haxis = qobject_cast(axisx); + + QAbstractAxis * axisy = this->axisY(); + QValuesAxis* vaxis = 0; + if (axisy->type() == QAbstractAxis::AxisTypeValues) + vaxis = qobject_cast(axisy); + + if (haxis && vaxis) { + //Calculate the "unit" between points on the x + //y axis. + double xUnit = this->plotArea().width()/haxis->max(); + double yUnit = this->plotArea().height()/vaxis->max(); + + //Convert the mappedPoint to the actual chart scale. + double x = mappedPoint.x()/xUnit; + double y = vaxis->max() - mappedPoint.y()/yUnit; + + //Replace the old point with the new one. + m_series->replace(m_movingPoint, QPointF(x, y)); + + //Update the m_movingPoint so we are able to + //do the replace also during mousemoveEvent. + m_movingPoint.setX(x); + m_movingPoint.setY(y); + } + } +} + diff --git a/demos/chartinteractions/chart.h b/demos/chartinteractions/chart.h new file mode 100644 index 0000000..f9e021a --- /dev/null +++ b/demos/chartinteractions/chart.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Commercial Charts Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial 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.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CHART_H +#define CHART_H + +#include +#include + +QTCOMMERCIALCHART_USE_NAMESPACE + +class Chart : public QChart +{ + Q_OBJECT +public: + explicit Chart(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0, QLineSeries *series = 0); + ~Chart(); + +public slots: + void clickPoint(const QPointF &point); + +public: + void handlePointMove(const QPoint &point); + void setPointClicked(bool clicked); + +private: + QLineSeries *m_series; + QPointF m_movingPoint; + + //Boolean value to determine if an actual point in the + //series is clicked. + bool m_clicked; +}; + +#endif // CHART_H diff --git a/demos/chartinteractions/chartinteractions.pro b/demos/chartinteractions/chartinteractions.pro new file mode 100644 index 0000000..b00f2f4 --- /dev/null +++ b/demos/chartinteractions/chartinteractions.pro @@ -0,0 +1,9 @@ +!include( ../demos.pri ):error( "Couldn't find the demos.pri file!" ) + +QT += core gui + +TARGET = chartinteractions +TEMPLATE = app + +HEADERS += chart.h chartview.h +SOURCES += main.cpp chart.cpp chartview.cpp diff --git a/demos/chartinteractions/chartview.cpp b/demos/chartinteractions/chartview.cpp new file mode 100644 index 0000000..b8ec429 --- /dev/null +++ b/demos/chartinteractions/chartview.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Commercial Charts Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial 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.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "chartview.h" +#include "chart.h" + +ChartView::ChartView(Chart *chart, QWidget *parent) : + QChartView(chart, parent) +{ + m_chart = chart; +} + +void ChartView::mousePressEvent(QMouseEvent *event) +{ + m_mousePos = event->pos(); + QChartView::mousePressEvent(event); +} + +void ChartView::mouseMoveEvent(QMouseEvent *event) +{ + m_chart->handlePointMove(event->pos()); + QChartView::mouseMoveEvent(event); +} + +void ChartView::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->pos() != m_mousePos) { + m_chart->handlePointMove(event->pos()); + m_chart->setPointClicked(false); + } + QChartView::mouseReleaseEvent(event); +} diff --git a/demos/chartinteractions/chartview.h b/demos/chartinteractions/chartview.h new file mode 100644 index 0000000..216461d --- /dev/null +++ b/demos/chartinteractions/chartview.h @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Commercial Charts Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial 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.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CHARTVIEW_H +#define CHARTVIEW_H + +#include + +class Chart; + +QTCOMMERCIALCHART_USE_NAMESPACE + +class ChartView : public QChartView +{ +public: + ChartView(Chart *chart, QWidget *parent = 0); + +protected: + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + +private: + Chart *m_chart; + QPoint m_mousePos; +}; + +#endif diff --git a/demos/chartinteractions/main.cpp b/demos/chartinteractions/main.cpp new file mode 100644 index 0000000..22ab027 --- /dev/null +++ b/demos/chartinteractions/main.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the Qt Commercial Charts Add-on. +** +** $QT_BEGIN_LICENSE$ +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial 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.digia.com +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include + +#include "chart.h" +#include "chartview.h" + +QTCOMMERCIALCHART_USE_NAMESPACE + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + QLineSeries* series = new QLineSeries(); + + series->append(0, 6); + series->append(1, 3); + series->append(2, 4); + series->append(3, 8); + series->append(7, 13); + series->append(10, 5); + *series << QPointF(11, 1) << QPointF(13, 3) << QPointF(17, 6) << QPointF(18, 3) << QPointF(20, 2); + + Chart* chart = new Chart(0, 0, series); + chart->legend()->hide(); + chart->addSeries(series); + chart->createDefaultAxes(); + chart->setTitle("Drag'n drop to move data points"); + + QValuesAxis *axisX = new QValuesAxis(); + chart->setAxisX(axisX, series); + axisX->setRange(0, 20); + + QValuesAxis *axisY = new QValuesAxis(); + chart->setAxisY(axisY, series); + axisY->setRange(0, 13); + + QObject::connect(series, SIGNAL(clicked(QPointF)), chart, SLOT(clickPoint(QPointF))); + + ChartView* chartView = new ChartView(chart); + chartView->setRenderHint(QPainter::Antialiasing); + + QMainWindow window; + window.setCentralWidget(chartView); + window.resize(400, 300); + window.show(); + + return a.exec(); +} diff --git a/demos/demos.pro b/demos/demos.pro index 3660c4d..b080f2d 100644 --- a/demos/demos.pro +++ b/demos/demos.pro @@ -13,4 +13,5 @@ SUBDIRS += chartthemes \ qmlcustomizations \ qmlcustommodel \ qmloscilloscope \ - chartviewer + chartviewer \ + chartinteractions diff --git a/src/axis/qabstractaxis.h b/src/axis/qabstractaxis.h index a74bb68..4dff600 100644 --- a/src/axis/qabstractaxis.h +++ b/src/axis/qabstractaxis.h @@ -133,7 +133,7 @@ Q_SIGNALS: protected: QScopedPointer d_ptr; - Q_DISABLE_COPY(QAbstractAxis); + Q_DISABLE_COPY(QAbstractAxis) friend class ChartDataSet; friend class ChartAxis; friend class ChartPresenter; diff --git a/src/chartpresenter_p.h b/src/chartpresenter_p.h index 896be25..0a08977 100644 --- a/src/chartpresenter_p.h +++ b/src/chartpresenter_p.h @@ -55,13 +55,13 @@ public: BackgroundZValue = -1, ShadesZValue , GridZValue, + AxisZValue, SeriesZValue, LineChartZValue = SeriesZValue, SplineChartZValue = SeriesZValue, BarSeriesZValue = SeriesZValue, ScatterSeriesZValue = SeriesZValue, PieSeriesZValue = SeriesZValue, - AxisZValue, LegendZValue, TopMostZValue };