diff --git a/demos/qmloscilloscope/datasource.cpp b/demos/qmloscilloscope/datasource.cpp index 25362d6..c5af232 100644 --- a/demos/qmloscilloscope/datasource.cpp +++ b/demos/qmloscilloscope/datasource.cpp @@ -20,36 +20,76 @@ #include "datasource.h" #include +#include +#include +#include #include QTCOMMERCIALCHART_USE_NAMESPACE -DataSource::DataSource(QObject *parent) : +DataSource::DataSource(QAbstractScrollArea *appViewer, QObject *parent) : + m_appViewer(appViewer), QObject(parent), - m_index(0) + m_index(-1) { - const int rowCount = 5; - const int colCount = 1024; + // generate + generateData(0, 5, 1024); +} + +void DataSource::update(QAbstractSeries *series) +{ + QXYSeries *xySeries = qobject_cast(series); + Q_ASSERT(xySeries); + + m_index++; + if (m_index > m_data.count() - 1) + m_index = 0; + + QList points = m_data.at(m_index); + // Use replace instead of clear + append, it's optimized for performance + xySeries->replace(points); +} + +void DataSource::generateData(int type, int rowCount, int colCount) +{ + qDebug() << "DataSource::generateData:" << type << rowCount << colCount; + // Remove previous data + foreach (QList row, m_data) + row.clear(); + m_data.clear(); + + // Append the new data depending on the type for (int i(0); i < rowCount; i++) { QList points; for (int j(0); j < colCount; j++) { - qreal x = j; - qreal y = sin(3.14159265358979 / 50 * x) + 0.5 + (qreal) rand() / (qreal) RAND_MAX; + qreal x(0); + qreal y(0); + switch (type) { + case 0: + // data with sin + random component + y = sin(3.14159265358979 / 50 * j) + 0.5 + (qreal) rand() / (qreal) RAND_MAX; + x = j; + break; + case 1: + // linear data + x = j; + y = (qreal) i / 10; + break; + default: + // unknown, do nothing + break; + } points.append(QPointF(x, y)); } m_data.append(points); } } -void DataSource::update(QAbstractSeries *series) +void DataSource::setOpenGL(bool enabled) { - QXYSeries *xySeries = qobject_cast(series); - Q_ASSERT(xySeries); - - QList points = m_data.at(m_index); -//xySeries->clear(); -//xySeries->append(points); - xySeries->replace(points); - m_index = (m_index + 1) % m_data.count(); + if (enabled) + m_appViewer->setViewport(new QGLWidget()); + else + m_appViewer->setViewport(0); } diff --git a/demos/qmloscilloscope/datasource.h b/demos/qmloscilloscope/datasource.h index f39bcfe..1a51815 100644 --- a/demos/qmloscilloscope/datasource.h +++ b/demos/qmloscilloscope/datasource.h @@ -24,20 +24,25 @@ #include #include +class QAbstractScrollArea; + QTCOMMERCIALCHART_USE_NAMESPACE class DataSource : public QObject { Q_OBJECT public: - explicit DataSource(QObject *parent = 0); + explicit DataSource(QAbstractScrollArea *appViewer, QObject *parent = 0); signals: public slots: + void generateData(int type, int rowCount, int colCount); void update(QAbstractSeries *series); + void setOpenGL(bool enabled); private: + QAbstractScrollArea *m_appViewer; QList > m_data; int m_index; }; diff --git a/demos/qmloscilloscope/main.cpp b/demos/qmloscilloscope/main.cpp index a9687f9..62b78c4 100644 --- a/demos/qmloscilloscope/main.cpp +++ b/demos/qmloscilloscope/main.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include "qmlapplicationviewer.h" #include "datasource.h" @@ -30,12 +29,11 @@ Q_DECL_EXPORT int main(int argc, char *argv[]) QScopedPointer app(createApplication(argc, argv)); QScopedPointer viewer(QmlApplicationViewer::create()); - DataSource dataSource; + DataSource dataSource(viewer.data()); viewer->rootContext()->setContextProperty("dataSource", &dataSource); viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto); viewer->setSource(QUrl("qrc:/qml/qmloscilloscope/main.qml")); - viewer->setViewport(new QGLWidget()); viewer->showExpanded(); return app->exec(); diff --git a/demos/qmloscilloscope/qml/qmloscilloscope/ControlPanel.qml b/demos/qmloscilloscope/qml/qmloscilloscope/ControlPanel.qml new file mode 100644 index 0000000..5fb6e34 --- /dev/null +++ b/demos/qmloscilloscope/qml/qmloscilloscope/ControlPanel.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +import QtQuick 1.0 + +Column { + spacing: 5 + signal openGLEnabled(bool enabled) + signal animationsEnabled(bool enabled) + signal seriesTypeChanged(string type) + signal refreshRateChanged(variant rate); + signal signalSourceChanged(string source, int signalCount, int sampleCount); + + Text { + text: "Oscilloscope" + font.pointSize: 18 + } + + MultiButton { + id: signalSourceButton + text: "Signal source: " + items: ["sin", "linear"] + currentSelection: 0 + onSelectionChanged: signalSourceChanged( + selection, + 5, + sampleCountButton.items[sampleCountButton.currentSelection]); + } + + MultiButton { + id: sampleCountButton + text: "Samples: " + items: [6, 128, 1024, 10000] + currentSelection: 2 + onSelectionChanged: signalSourceChanged( + signalSourceButton.items[signalSourceButton.currentSelection], + 5, + selection); + } + + MultiButton { + text: "Graph: " + items: ["line", "spline", "scatter"] + currentSelection: 0 + onSelectionChanged: seriesTypeChanged(items[currentSelection]); + } + + MultiButton { + text: "Refresh rate: " + items: [1, 24, 60, 100] + currentSelection: 2 + onSelectionChanged: refreshRateChanged(items[currentSelection]); + } + + MultiButton { + text: "OpenGL: " + items: ["OFF", "ON"] + currentSelection: 0 + onSelectionChanged: openGLEnabled(currentSelection == 1); + } + + MultiButton { + text: "Animations: " + items: ["OFF", "ON"] + currentSelection: 0 + onSelectionChanged: animationsEnabled(currentSelection == 1); + } +} diff --git a/demos/qmloscilloscope/qml/qmloscilloscope/MultiButton.qml b/demos/qmloscilloscope/qml/qmloscilloscope/MultiButton.qml new file mode 100644 index 0000000..3c5d3e1 --- /dev/null +++ b/demos/qmloscilloscope/qml/qmloscilloscope/MultiButton.qml @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +import QtQuick 1.0 + +Rectangle { + id: button + width: 105 + height: 33 + border.color: "gray" + radius: 5 + property string text: "Option: " + property variant items: ["first"] + property int currentSelection: 0 + signal selectionChanged(variant selection) + + Text { + id: buttonText + anchors.centerIn: parent + text: button.text + button.items[currentSelection] + } + + MouseArea { + anchors.fill: parent + onClicked: { + currentSelection = (currentSelection + 1) % items.length; + selectionChanged(button.items[currentSelection]); + } + } +} diff --git a/demos/qmloscilloscope/qml/qmloscilloscope/ScopeView.qml b/demos/qmloscilloscope/qml/qmloscilloscope/ScopeView.qml new file mode 100644 index 0000000..a84708f --- /dev/null +++ b/demos/qmloscilloscope/qml/qmloscilloscope/ScopeView.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +import QtQuick 1.0 +import QtCommercial.Chart 1.0 + +ChartView { + id: chartView + animationOptions: ChartView.NoAnimation + + ValuesAxis { + id: axisY + min: -1 + max: 3 + } + + ValuesAxis { + id: axisX + min: 0 + max: 1000 + } + + LineSeries { + id: lineSeries1 + name: "signal 1" + } + LineSeries { + id: lineSeries2 + name: "signal 2" + } + + Component.onCompleted: { + chartView.setAxisX(axisX, lineSeries1); + chartView.setAxisY(axisY, lineSeries1); + chartView.setAxisX(axisX, lineSeries2); + chartView.setAxisY(axisY, lineSeries2); + } + + Timer { + id: refreshTimer + interval: 1 / 60 * 1000 // 60 Hz + running: true + repeat: true + onTriggered: { + dataSource.update(chartView.series(0)); + dataSource.update(chartView.series(1)); + } + } + + function changeSeriesType(type) { + chartView.series(1).destroy(); + chartView.series(0).destroy(); + var seriesCount = 2; + for (var i = 0; i < seriesCount; i++) { + var series; + if (type == "line") { + series = scopeView.createSeries(ChartView.SeriesTypeLine, "signal " + (i + 1)); + } else if (type == "spline") { + series = chartView.createSeries(ChartView.SeriesTypeSpline, "signal " + (i + 1)); + } else { + series = chartView.createSeries(ChartView.SeriesTypeScatter, "signal " + (i + 1)); + series.markerSize = 3; + series.borderColor = "transparent"; + } + chartView.setAxisX(axisX, series); + chartView.setAxisY(axisY, series); + } + } + + function setAnimations(enabled) { + if (enabled) + scopeView.animationOptions = ChartView.SeriesAnimations; + else + scopeView.animationOptions = ChartView.NoAnimation; + } + + function changeRefreshRate(rate) { + console.log("rate " + rate); + refreshTimer.interval = 1 / Number(rate) * 1000; + } +} diff --git a/demos/qmloscilloscope/qml/qmloscilloscope/main.qml b/demos/qmloscilloscope/qml/qmloscilloscope/main.qml index 0a17e98..913e955 100644 --- a/demos/qmloscilloscope/qml/qmloscilloscope/main.qml +++ b/demos/qmloscilloscope/qml/qmloscilloscope/main.qml @@ -19,54 +19,38 @@ ****************************************************************************/ import QtQuick 1.0 -import QtCommercial.Chart 1.0 Rectangle { + id: main width: 400 height: 300 - ChartView { - id: chartView - anchors.fill: parent - title: "Oscilloscope" - animationOptions: ChartView.NoAnimation - - ValuesAxis { - id: axisY - min: -1 - max: 3 - } - - ValuesAxis { - id: axisX - min: 0 - max: 1000 - } - - LineSeries { - id: lineSeries1 - name: "signal 1" - } - LineSeries { - id: lineSeries2 - name: "signal 2" - } - } - - Timer { - interval: 16 // 60 Hz - running: true - repeat: true - onTriggered: { - dataSource.update(lineSeries1); - dataSource.update(lineSeries2); + ControlPanel { + id: controlPanel + anchors.top: parent.top + anchors.topMargin: 10 + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.leftMargin: 10 + + onSignalSourceChanged: { + if (source == "sin") + dataSource.generateData(0, signalCount, sampleCount); + else + dataSource.generateData(1, signalCount, sampleCount); } + onOpenGLEnabled: dataSource.setOpenGL(enabled); + onAnimationsEnabled: scopeView.setAnimations(enabled); + onSeriesTypeChanged: scopeView.changeSeriesType(type); + onRefreshRateChanged: scopeView.changeRefreshRate(rate); } - Component.onCompleted: { - chartView.setAxisX(axisX, lineSeries1); - chartView.setAxisY(axisY, lineSeries1); - chartView.setAxisX(axisX, lineSeries2); - chartView.setAxisY(axisY, lineSeries2); + ScopeView { + id: scopeView + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.left: controlPanel.right + height: main.height } } diff --git a/demos/qmloscilloscope/resources.qrc b/demos/qmloscilloscope/resources.qrc index 52678b7..e2aadae 100644 --- a/demos/qmloscilloscope/resources.qrc +++ b/demos/qmloscilloscope/resources.qrc @@ -1,5 +1,8 @@ qml/qmloscilloscope/main.qml + qml/qmloscilloscope/ControlPanel.qml + qml/qmloscilloscope/ScopeView.qml + qml/qmloscilloscope/MultiButton.qml