summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Gottfried <sebastian.gottfried@posteo.de>2016-11-01 09:58:44 (GMT)
committerSebastian Gottfried <sebastian.gottfried@posteo.de>2016-11-01 09:59:16 (GMT)
commit2cd0baf7eea44c9ee25f454b9ecced65346f987a (patch)
tree00976e806f02cc8e09c8c2a60056cdd4e8d20823
parent143e76a019ae52d57e3f448c7e3130cc53346506 (diff)
parent21f89e481c926de6e65e399d11f20931772c1715 (diff)
Merge Branch 'frameworks'v16.11.80
-rw-r--r--CMakeLists.txt92
-rw-r--r--README.md21
-rw-r--r--demo/dynamicdata/Chart.qml4
-rw-r--r--demo/dynamicdata/ChartTableView.qml (renamed from demo/dynamicdata/TableView.qml)6
-rw-r--r--demo/dynamicdata/ValueEdit.qml53
-rw-r--r--demo/dynamicdata/main.qml22
-rw-r--r--demo/minimal/main.qml2
-rw-r--r--demo/xy/main.qml88
-rw-r--r--src/CMakeLists.txt27
-rw-r--r--src/barchartcore.cpp4
-rw-r--r--src/barchartcore.h6
-rw-r--r--src/barchartsegment.cpp9
-rw-r--r--src/barchartsegment.h10
-rw-r--r--src/chartcore.cpp22
-rw-r--r--src/chartcore.h23
-rw-r--r--src/chartforegroundpainter.cpp8
-rw-r--r--src/chartforegroundpainter.h12
-rw-r--r--src/chartmodel.cpp19
-rw-r--r--src/chartmodel.h18
-rw-r--r--src/chartplugin.cpp12
-rw-r--r--src/chartplugin.h5
-rw-r--r--src/dimension.cpp44
-rw-r--r--src/dimension.h39
-rw-r--r--src/linechartbackgroundpainter.cpp13
-rw-r--r--src/linechartbackgroundpainter.h14
-rw-r--r--src/linechartcore.cpp4
-rw-r--r--src/linechartcore.h6
-rw-r--r--src/linechartpainter.cpp10
-rw-r--r--src/linechartpainter.h12
-rw-r--r--src/linechartpoint.cpp14
-rw-r--r--src/linechartpoint.h12
-rw-r--r--src/qml/BarChart.qml12
-rw-r--r--src/qml/Label.qml8
-rw-r--r--src/qml/LegendItem.qml10
-rw-r--r--src/qml/LineChart.qml14
-rw-r--r--src/qml/LineLabel.qml3
-rw-r--r--src/qml/XYChart.qml227
-rw-r--r--src/qml/qmldir6
-rw-r--r--src/record.cpp6
-rw-r--r--src/record.h2
-rw-r--r--src/xychartbackgroundpainter.cpp112
-rw-r--r--src/xychartbackgroundpainter.h50
-rw-r--r--src/xychartcore.cpp394
-rw-r--r--src/xychartcore.h104
-rw-r--r--src/xychartpainter.cpp126
-rw-r--r--src/xychartpainter.h54
-rw-r--r--src/xychartpoint.cpp199
-rw-r--r--src/xychartpoint.h66
48 files changed, 1803 insertions, 221 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e23b777..b6fa31c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,3 +1,91 @@
-find_package(KDE4 4.10 REQUIRED)
+cmake_minimum_required(VERSION 2.8.12)
-add_subdirectory(src/)
+project(KQtQuickCharts)
+
+# Dependencies
+find_package(ECM 1.1.0 REQUIRED NO_MODULE)
+set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
+
+set(REQUIRED_QT_VERSION "5.2.0")
+set(KF5_VERSION "5.1.0") # handled by release scripts
+set(KF5_DEP_VERSION "5.1.0") # handled by release scripts
+
+find_package(Qt5 ${REQUIRED_QT_VERSION} NO_MODULE REQUIRED Qml Quick Gui)
+include(KDEInstallDirs)
+include(KDEFrameworkCompilerSettings)
+include(KDECMakeSettings)
+
+#########################################################################
+
+add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0)
+
+#add_definitions(-Wno-deprecated)
+add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
+add_definitions(-DQT_NO_URL_CAST_FROM_STRING)
+
+remove_definitions(-DQT_NO_CAST_FROM_ASCII -DQT_STRICT_ITERATORS -DQT_NO_CAST_FROM_BYTEARRAY -DQT_NO_KEYWORDS)
+
+
+
+# Includes
+include(FeatureSummary)
+include(GenerateExportHeader)
+include(ECMSetupVersion)
+include(ECMGenerateHeaders)
+include(ECMPackageConfigHelpers)
+
+# ECM setup
+ecm_setup_version(
+ ${KF5_VERSION}
+ VARIABLE_PREFIX KQTQUICKCHARTS
+ VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kqtquickcharts_version.h"
+ PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KQtQuickChartsVersion.cmake"
+ SOVERSION 1)
+
+# Subdirectories
+add_definitions(-DTRANSLATION_DOMAIN=\"kqtquickcharts5\")
+if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po")
+ ki18n_install(po)
+endif()
+
+#add_subdirectory(autotests)
+
+add_subdirectory(src)
+
+# if(KF5Config_FOUND AND KF5I18n_FOUND AND KF5IconThemes_FOUND AND KF5KIO_FOUND)
+# add_subdirectory(tests)
+# endif()
+
+# Create a Config.cmake and a ConfigVersion.cmake file and install them
+set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KQtQuickCharts")
+
+# ecm_configure_package_config_file(
+# "${CMAKE_CURRENT_SOURCE_DIR}/KQtQuickChartsConfig.cmake.in"
+# "${CMAKE_CURRENT_BINARY_DIR}/KQtQuickChartsConfig.cmake"
+# INSTALL_DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+# )
+
+install(FILES
+# "${CMAKE_CURRENT_BINARY_DIR}/KQtQuickChartsConfig.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/KQtQuickChartsVersion.cmake"
+ DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+ COMPONENT Devel
+)
+
+# install(EXPORT
+# KQtQuickChartsTargets
+# DESTINATION "${CMAKECONFIG_INSTALL_DIR}"
+# FILE KQtQuickChartsTargets.cmake
+# NAMESPACE KF5::
+# COMPONENT Devel
+# )
+
+install(FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/kqtquickcharts_version.h"
+ DESTINATION "${KF5_INCLUDE_INSTALL_DIR}"
+ COMPONENT Devel
+)
+
+if ("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
+ feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
+endif()
diff --git a/README.md b/README.md
index 442d527..ec3bd0f 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
kqtquickcharts
==============
-Beautiful and interactive charts for Qt Quick 1.0
+Beautiful and interactive charts for Qt Quick
## Installation
@@ -9,10 +9,10 @@ Beautiful and interactive charts for Qt Quick 1.0
**kqtquicharts** depends on the following libaries:
- * KDElibs >= 4.10.0
- * Qt >= 4.8 (but not Qt 5.x)
- * CMake >= 2.8.9
-
+ * Qt >= 5.2
+ * CMake >= 2.8.12
+ * CMake Extra Modules >= 1.1
+
### Building
Once the required libaries are installed **kqtquickcharts** can be built with:
@@ -26,12 +26,6 @@ To be usable the components have to be installed:
# make install
-### Runtime dependencies
-
-At runtime, the following additional libaries have to be present:
-
- * KDE-runtime >= 4.10.0
-
## Try it out
There are a few example projects in the `demo` folder. They are directly
@@ -39,8 +33,5 @@ runable in **qmlviewer**. Make sure to pass the required import folders
to it:
$ cd demo/minimal
- $ qmlviewer -I /usr/lib64/kde4/imports/ main.qml
-
-Replace the last line on 32-bit systems with:
+ $ qml -I /usr/lib64/qt5/qml main.qml
- $ qmlviewer -I /usr/lib/kde4/imports/ main.qml
diff --git a/demo/dynamicdata/Chart.qml b/demo/dynamicdata/Chart.qml
index e9f137c..b27442b 100644
--- a/demo/dynamicdata/Chart.qml
+++ b/demo/dynamicdata/Chart.qml
@@ -17,10 +17,10 @@
* You should have received a copy of the GNU Lesser General Public
*/
-import QtQuick 1.1
+import QtQuick 2.2
import org.kde.charts 0.1
-BarChart {
+LineChart {
id: chart
model: ChartModel {
columns: chart.dimensions.length
diff --git a/demo/dynamicdata/TableView.qml b/demo/dynamicdata/ChartTableView.qml
index 20c7fbb..b3b659b 100644
--- a/demo/dynamicdata/TableView.qml
+++ b/demo/dynamicdata/ChartTableView.qml
@@ -17,12 +17,12 @@
* You should have received a copy of the GNU Lesser General Public
*/
-import QtQuick 1.1
+import QtQuick 2.2
import org.kde.charts 0.1
Rectangle {
id: root
- property variant chart
+ property Item chart
width: chart.model.columns * (listView.cellWidth + listView.spacing) + listView.spacing
@@ -39,7 +39,7 @@ Rectangle {
clip: true
model: root.chart.model.rows
- property real cellHeight: theme.defaultFont.mSize.height * 2
+ property real cellHeight: 30
property real cellWidth: 4 * cellHeight
spacing: 3
diff --git a/demo/dynamicdata/ValueEdit.qml b/demo/dynamicdata/ValueEdit.qml
index bbc45ff..0a003eb 100644
--- a/demo/dynamicdata/ValueEdit.qml
+++ b/demo/dynamicdata/ValueEdit.qml
@@ -17,16 +17,15 @@
* You should have received a copy of the GNU Lesser General Public
*/
-import QtQuick 1.1
-import org.kde.plasma.components 0.1 as PlasmaComponents
-import org.kde.plasma.extras 0.1 as PlasmaExtras
+import QtQuick 2.2
+import QtQuick.Controls 1.2
Rectangle {
color: "#ddd"
id: root
property real value: 0.0
property bool editing: false
- property real internalPadding: theme.defaultFont.mSize.height * 0.3
+ property real internalPadding: 3
Text {
anchors {
@@ -49,36 +48,40 @@ Rectangle {
if (loader.item) {
loader.item.forceActiveFocus()
}
+ else {
+ loader.sourceComponent = editorComponent
+ }
}
}
- PlasmaExtras.ConditionalLoader {
+ Loader {
id: loader
anchors.fill: parent
- when: editing
- source: Component {
- PlasmaComponents.TextField {
- anchors.fill: parent
- opacity: root.editing? 1: 0
- text: root.value
- Component.onCompleted: {
- forceActiveFocus()
- }
- onTextChanged: {
- var value = parseFloat(text)
- if (!isNaN(value)) {
- root.value = value
- }
- }
- onActiveFocusChanged: {
- if (!activeFocus) {
- root.editing = false
- }
+ }
+
+ Component {
+ id: editorComponent
+ TextField {
+ anchors.fill: parent
+ opacity: root.editing? 1: 0
+ text: root.value
+ Component.onCompleted: {
+ forceActiveFocus()
+ }
+ onTextChanged: {
+ var value = parseFloat(text)
+ if (!isNaN(value)) {
+ root.value = value
}
- onAccepted: {
+ }
+ onActiveFocusChanged: {
+ if (!activeFocus) {
root.editing = false
}
}
+ onAccepted: {
+ root.editing = false
+ }
}
}
}
diff --git a/demo/dynamicdata/main.qml b/demo/dynamicdata/main.qml
index e4b0e07..cd43f6c 100644
--- a/demo/dynamicdata/main.qml
+++ b/demo/dynamicdata/main.qml
@@ -17,8 +17,8 @@
* You should have received a copy of the GNU Lesser General Public
*/
-import QtQuick 1.1
-import org.kde.plasma.components 0.1 as PlasmaComponents
+import QtQuick 2.2
+import QtQuick.Controls 1.2
import org.kde.charts 0.1
Column {
@@ -57,25 +57,25 @@ Column {
}
}
- PlasmaComponents.ToolBar {
+ ToolBar {
id: toolbar
- tools: Row {
+ Row {
spacing: 4
- PlasmaComponents.ToolButton {
+ ToolButton {
anchors.verticalCenter: parent.verticalCenter
- iconSource: "edit-table-insert-row-below"
+ //iconSource: "edit-table-insert-row-below"
text: "Append record"
onClicked: appendRecord()
}
- PlasmaComponents.ToolButton {
+ ToolButton {
anchors.verticalCenter: parent.verticalCenter
- iconSource: "edit-table-insert-row-above"
+ //iconSource: "edit-table-insert-row-above"
text: "Insert record"
onClicked: insertRecord()
}
- PlasmaComponents.ToolButton {
+ ToolButton {
anchors.verticalCenter: parent.verticalCenter
- iconSource: "edit-table-delete-row"
+ //iconSource: "edit-table-delete-row"
text: "Remove record"
onClicked: removeRecord()
}
@@ -94,7 +94,7 @@ Column {
spacing: 40
- TableView {
+ ChartTableView {
id: tableView
height: parent.height
chart: chart
diff --git a/demo/minimal/main.qml b/demo/minimal/main.qml
index 3f4a63e..731881d 100644
--- a/demo/minimal/main.qml
+++ b/demo/minimal/main.qml
@@ -17,7 +17,7 @@
* You should have received a copy of the GNU Lesser General Public
*/
-import QtQuick 1.1
+import QtQuick 2.2
import org.kde.charts 0.1
Rectangle {
diff --git a/demo/xy/main.qml b/demo/xy/main.qml
new file mode 100644
index 0000000..cfc7c27
--- /dev/null
+++ b/demo/xy/main.qml
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2015 Jesper Hellesø Hansen <jesperhh@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ */
+
+import QtQuick 2.2
+import org.kde.charts 0.1
+
+Rectangle {
+ color: "white"
+ width: 800
+ height: 400
+
+ ChartModel {
+ id: chartModel
+ columns: 4
+
+ Record { values: [ 0, 3] }
+ Record { values: [ 1, 8, 6.5, 2] }
+ Record { values: [ 2, 5, NaN, 3] }
+ Record { values: [ 3, 10, NaN, 4] }
+ Record { values: [ 4, 8, NaN, 5] }
+ Record { values: [ 5, 4, 5.5, 6] }
+ Record { values: [ 6, 3] }
+ Record { values: [ 7, 0] }
+ Record { values: [ 8, 7, 5.5] }
+ Record { values: [ 9, 6] }
+ Record { values: [ 10, 10] }
+ }
+
+ XYChart {
+ model: chartModel
+ anchors.fill: parent
+ textColor: "black"
+ anchors.margins: 20
+ dimensions: [
+ Dimension {
+ color: "#ff0000"
+ dataColumn: 1
+ label: "A"
+ markerStyle: Dimension.MarkerStyleNone
+ },
+ Dimension {
+ color: "#0000FF"
+ dataColumn: 2
+ lineStyle: Dimension.LineStyleNone
+ markerStyle: Dimension.MarkerStyleCross
+ },
+ Dimension {
+ color: "#00FF00"
+ dataColumn: 3
+ label: "B"
+ }
+ ]
+
+ xAxis: Dimension {
+ dataColumn: 0
+ minimumValue: 0
+ maximumValue: 10
+ label: "X Label"
+ precision: 0
+ unit:"cm"
+ }
+
+ yAxis: Dimension {
+ dataColumn: 0
+ minimumValue: 0
+ maximumValue: 10
+ label: "Y Label"
+ precision: 0
+ unit:"hz"
+ }
+ }
+}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7168b05..96d620a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,10 +1,3 @@
-project(kqtquickcharts)
-
-include(KDE4Defaults)
-add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
-
-include_directories(${QT_INCLUDE} ${KDE4_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
-
set(kqtquickcharts_SRCS
dimension.cpp
chartplugin.cpp
@@ -18,12 +11,23 @@ set(kqtquickcharts_SRCS
linechartpoint.cpp
chartforegroundpainter.cpp
record.cpp
+ xychartcore.cpp
+ xychartbackgroundpainter.cpp
+ xychartpainter.cpp
+ xychartpoint.cpp
)
-automoc4_add_library(kqtquickcharts SHARED ${kqtquickcharts_SRCS})
-target_link_libraries(kqtquickcharts ${KDE4_PLASMA_LIBS} ${QT_QTSCRIPT_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY} ${KDECLARATIVE_LIBRARIES})
+add_library(kqtquickcharts SHARED ${kqtquickcharts_SRCS})
+
+
+target_link_libraries(kqtquickcharts
+ Qt5::Core
+ Qt5::Quick
+ Qt5::Qml
+ Qt5::Gui
+)
-install(TARGETS kqtquickcharts DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/charts)
+install(TARGETS kqtquickcharts DESTINATION ${QML_INSTALL_DIR}/org/kde/charts)
set(kqtquickcharts_files
qml/qmldir
@@ -33,6 +37,7 @@ set(kqtquickcharts_files
qml/LegendItem.qml
qml/LineLabel.qml
qml/Label.qml
+ qml/XYChart.qml
)
-install(FILES ${kqtquickcharts_files} DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/charts)
+install(FILES ${kqtquickcharts_files} DESTINATION ${QML_INSTALL_DIR}/org/kde/charts)
diff --git a/src/barchartcore.cpp b/src/barchartcore.cpp
index ffc4613..9424eea 100644
--- a/src/barchartcore.cpp
+++ b/src/barchartcore.cpp
@@ -19,7 +19,7 @@
#include "barchartcore.h"
-BarChartCore::BarChartCore(QDeclarativeItem* parent) :
+BarChartCore::BarChartCore(QQuickItem* parent) :
ChartCore(parent)
{
connect(this, SIGNAL(pitchChanged()), SIGNAL(barWidthChanged()));
@@ -30,7 +30,7 @@ qreal BarChartCore::barWidth() const
return qRound(pitch() / (dimensionsList().length() + 1));
}
-void BarChartCore::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
+void BarChartCore::paint(QPainter* painter)
{
paintAxisAndLines(painter, 0.0);
}
diff --git a/src/barchartcore.h b/src/barchartcore.h
index fdee9b3..d080102 100644
--- a/src/barchartcore.h
+++ b/src/barchartcore.h
@@ -27,10 +27,10 @@ class BarChartCore : public ChartCore
Q_OBJECT
Q_PROPERTY(qreal barWidth READ barWidth NOTIFY barWidthChanged)
public:
- explicit BarChartCore(QDeclarativeItem* parent = 0);
+ explicit BarChartCore(QQuickItem* parent = 0);
qreal barWidth() const;
- void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*);
-signals:
+ void paint(QPainter* painter);
+Q_SIGNALS:
void barWidthChanged();
};
diff --git a/src/barchartsegment.cpp b/src/barchartsegment.cpp
index bebc1a7..f1b5d3b 100644
--- a/src/barchartsegment.cpp
+++ b/src/barchartsegment.cpp
@@ -24,10 +24,8 @@
#include "dimension.h"
#include "barchartcore.h"
-#include <KDebug>
-
-BarChartSegment::BarChartSegment(QDeclarativeItem* parent) :
- QDeclarativeItem(parent),
+BarChartSegment::BarChartSegment(QQuickItem* parent) :
+ QQuickItem(parent),
m_barChartCore(0),
m_dimension(-1),
m_row(-1)
@@ -108,6 +106,9 @@ qreal BarChartSegment::barHeight() const
QString BarChartSegment::text() const
{
+ if (!m_barChartCore)
+ return QString();
+
const int role = m_barChartCore->textRole();
if (role == -1)
diff --git a/src/barchartsegment.h b/src/barchartsegment.h
index 83adb7e..2e4ecf3 100644
--- a/src/barchartsegment.h
+++ b/src/barchartsegment.h
@@ -20,11 +20,11 @@
#ifndef BARGRAPHSEGMENT_H
#define BARGRAPHSEGMENT_H
-#include <QDeclarativeItem>
+#include <QQuickItem>
class BarChartCore;
-class BarChartSegment : public QDeclarativeItem
+class BarChartSegment : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(BarChartCore* barChartCore READ barChartCore WRITE setBarChartCore NOTIFY barChartCoreChanged)
@@ -33,7 +33,7 @@ class BarChartSegment : public QDeclarativeItem
Q_PROPERTY(qreal barHeight READ barHeight NOTIFY barHeightChanged)
Q_PROPERTY(QString text READ text NOTIFY textChanged)
public:
- explicit BarChartSegment(QDeclarativeItem* parent = 0);
+ explicit BarChartSegment(QQuickItem* parent = 0);
BarChartCore* barChartCore() const;
void setBarChartCore(BarChartCore* barChartCore);
int dimension() const;
@@ -42,13 +42,13 @@ public:
void setRow(int row);
qreal barHeight() const;
QString text() const;
-signals:
+Q_SIGNALS:
void barChartCoreChanged();
void dimensionChanged();
void rowChanged();
void barHeightChanged();
void textChanged();
-private slots:
+private Q_SLOTS:
void triggerUpdate();
private:
bool valid() const;
diff --git a/src/chartcore.cpp b/src/chartcore.cpp
index 78a6ca0..b5c9865 100644
--- a/src/chartcore.cpp
+++ b/src/chartcore.cpp
@@ -22,13 +22,13 @@
#include <QAbstractTableModel>
#include <QPainter>
-ChartCore::ChartCore(QDeclarativeItem *parent) :
- QDeclarativeItem(parent),
+ChartCore::ChartCore(QQuickItem *parent) :
+ QQuickPaintedItem(parent),
m_model(0),
m_pitch(50.0),
m_textRole(-1)
{
- setFlag(QGraphicsItem::ItemHasNoContents, false);
+ setFlag(QQuickItem::ItemHasContents, true);
}
QAbstractTableModel* ChartCore::model() const
@@ -62,8 +62,8 @@ void ChartCore::setModel(QAbstractTableModel* model)
}
}
-QDeclarativeListProperty<Dimension> ChartCore::dimensions() {
- return QDeclarativeListProperty<Dimension>(this, 0, &ChartCore::appendDimension, &ChartCore::countDimensions, &ChartCore::dimensionAt, &ChartCore::clearDimensions);
+QQmlListProperty<Dimension> ChartCore::dimensions() {
+ return QQmlListProperty<Dimension>(this, 0, &ChartCore::appendDimension, &ChartCore::countDimensions, &ChartCore::dimensionAt, &ChartCore::clearDimensions);
}
QList<Dimension*> ChartCore::dimensionsList() const
@@ -109,6 +109,10 @@ void ChartCore::triggerUpdate()
update();
}
+void ChartCore::paint(QPainter*)
+{
+}
+
void ChartCore::paintAxisAndLines(QPainter* painter, qreal offset)
{
const int minY = qRound(offset);
@@ -130,7 +134,7 @@ void ChartCore::paintAxisAndLines(QPainter* painter, qreal offset)
painter->drawRect(QRectF(QPointF(x1, maxY), QPointF(x2, maxY + 1)));
}
-void ChartCore::appendDimension(QDeclarativeListProperty<Dimension>* list, Dimension *dimension) {
+void ChartCore::appendDimension(QQmlListProperty<Dimension>* list, Dimension *dimension) {
ChartCore* chartCore = qobject_cast<ChartCore*>(list->object);
if (chartCore) {
dimension->setParent(chartCore);
@@ -140,7 +144,7 @@ void ChartCore::appendDimension(QDeclarativeListProperty<Dimension>* list, Dimen
}
}
-int ChartCore::countDimensions(QDeclarativeListProperty<Dimension>* list) {
+int ChartCore::countDimensions(QQmlListProperty<Dimension>* list) {
ChartCore* chartCore = qobject_cast<ChartCore*>(list->object);
if (chartCore) {
return chartCore->m_dimensions.count();
@@ -148,7 +152,7 @@ int ChartCore::countDimensions(QDeclarativeListProperty<Dimension>* list) {
return -1;
}
-Dimension* ChartCore::dimensionAt(QDeclarativeListProperty<Dimension>* list, int index) {
+Dimension* ChartCore::dimensionAt(QQmlListProperty<Dimension>* list, int index) {
ChartCore* chartCore = qobject_cast<ChartCore*>(list->object);
if (chartCore) {
return chartCore->m_dimensions.at(index);
@@ -156,7 +160,7 @@ Dimension* ChartCore::dimensionAt(QDeclarativeListProperty<Dimension>* list, int
return 0;
}
-void ChartCore::clearDimensions(QDeclarativeListProperty<Dimension>* list) {
+void ChartCore::clearDimensions(QQmlListProperty<Dimension>* list) {
ChartCore* chartCore = qobject_cast<ChartCore*>(list->object);
if (chartCore) {
foreach (Dimension* dimension, chartCore->m_dimensions)
diff --git a/src/chartcore.h b/src/chartcore.h
index f792da7..8923e46 100644
--- a/src/chartcore.h
+++ b/src/chartcore.h
@@ -20,44 +20,45 @@
#ifndef GRAPHCORE_H
#define GRAPHCORE_H
-#include <QDeclarativeItem>
+#include <QQuickPaintedItem>
#include "dimension.h"
class QAbstractTableModel;
-class ChartCore : public QDeclarativeItem
+class ChartCore : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QAbstractTableModel* model READ model WRITE setModel NOTIFY modelChanged)
- Q_PROPERTY(QDeclarativeListProperty<Dimension> dimensions READ dimensions CONSTANT)
+ Q_PROPERTY(QQmlListProperty<Dimension> dimensions READ dimensions CONSTANT)
Q_PROPERTY(qreal pitch READ pitch WRITE setPitch NOTIFY pitchChanged)
Q_PROPERTY(int textRole READ textRole WRITE setTextRole NOTIFY textRoleChanged)
public:
- explicit ChartCore(QDeclarativeItem *parent = 0);
+ explicit ChartCore(QQuickItem *parent = 0);
QAbstractTableModel* model() const;
void setModel(QAbstractTableModel* model);
- QDeclarativeListProperty<Dimension> dimensions();
+ QQmlListProperty<Dimension> dimensions();
QList<Dimension*> dimensionsList() const;
qreal pitch() const;
void setPitch(qreal pitch);
int textRole() const;
void setTextRole(int textRole);
-signals:
+Q_SIGNALS:
void modelChanged();
void chartStyleChanged();
void pitchChanged();
void textRoleChanged();
void updated();
-protected slots:
+protected Q_SLOTS:
void triggerUpdate();
protected:
+ void paint(QPainter* painter);
void paintAxisAndLines(QPainter* painter, qreal offset);
private:
- static void appendDimension(QDeclarativeListProperty<Dimension>* list, Dimension* dimension);
- static int countDimensions(QDeclarativeListProperty<Dimension>* list);
- static Dimension* dimensionAt(QDeclarativeListProperty<Dimension>* list, int index);
- static void clearDimensions(QDeclarativeListProperty<Dimension>* list);
+ static void appendDimension(QQmlListProperty<Dimension>* list, Dimension* dimension);
+ static int countDimensions(QQmlListProperty<Dimension>* list);
+ static Dimension* dimensionAt(QQmlListProperty<Dimension>* list, int index);
+ static void clearDimensions(QQmlListProperty<Dimension>* list);
QAbstractTableModel* m_model;
QList<Dimension*> m_dimensions;
qreal m_pitch;
diff --git a/src/chartforegroundpainter.cpp b/src/chartforegroundpainter.cpp
index 590d3ca..a7c7153 100644
--- a/src/chartforegroundpainter.cpp
+++ b/src/chartforegroundpainter.cpp
@@ -23,11 +23,11 @@
#include "chartcore.h"
-ChartForegroundPainter::ChartForegroundPainter(QDeclarativeItem *parent) :
- QDeclarativeItem(parent),
+ChartForegroundPainter::ChartForegroundPainter(QQuickItem *parent) :
+ QQuickPaintedItem(parent),
m_chartCore(0)
{
- setFlag(QGraphicsItem::ItemHasNoContents, false);
+ setFlag(QQuickItem::ItemHasContents, true);
}
ChartCore* ChartForegroundPainter::chartCore() const
@@ -71,7 +71,7 @@ void ChartForegroundPainter::setBackgroundColor(const QColor& backgroundColor)
}
}
-void ChartForegroundPainter::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
+void ChartForegroundPainter::paint(QPainter* painter)
{
if (!m_chartCore)
return;
diff --git a/src/chartforegroundpainter.h b/src/chartforegroundpainter.h
index 344cd2c..75ec8f1 100644
--- a/src/chartforegroundpainter.h
+++ b/src/chartforegroundpainter.h
@@ -20,26 +20,26 @@
#ifndef LINEGRAPHFOREGROUNDPAINTER_H
#define LINEGRAPHFOREGROUNDPAINTER_H
-#include <QDeclarativeItem>
+#include <QQuickPaintedItem>
class ChartCore;
-class ChartForegroundPainter : public QDeclarativeItem
+class ChartForegroundPainter : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(ChartCore* chartCore READ chartCore WRITE setChartCore NOTIFY chartCoreChanged)
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged)
public:
- explicit ChartForegroundPainter(QDeclarativeItem* parent = 0);
+ explicit ChartForegroundPainter(QQuickItem* parent = 0);
ChartCore* chartCore() const;
void setChartCore(ChartCore* chartCore);
QColor backgroundColor() const;
void setBackgroundColor(const QColor& backgroundColor);
- void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*);
-signals:
+ void paint(QPainter* painter);
+Q_SIGNALS:
void chartCoreChanged();
void backgroundColorChanged();
-private slots:
+private Q_SLOTS:
void triggerUpdate();
private:
ChartCore* m_chartCore;
diff --git a/src/chartmodel.cpp b/src/chartmodel.cpp
index 4c7b6e9..331b7df 100644
--- a/src/chartmodel.cpp
+++ b/src/chartmodel.cpp
@@ -18,7 +18,7 @@
*/
#include "chartmodel.h"
-
+#include <limits.h>
#include "record.h"
ChartModel::ChartModel(QObject* parent) :
@@ -27,9 +27,9 @@ ChartModel::ChartModel(QObject* parent) :
{
}
-QDeclarativeListProperty<Record> ChartModel::records()
+QQmlListProperty<Record> ChartModel::records()
{
- return QDeclarativeListProperty<Record>(this, 0, &ChartModel::appendRecord, &ChartModel::countRecords, &ChartModel::recordAt, &ChartModel::clearRecords);
+ return QQmlListProperty<Record>(this, 0, &ChartModel::appendRecord, &ChartModel::countRecords, &ChartModel::recordAt, &ChartModel::clearRecords);
}
int ChartModel::columns() const
@@ -41,8 +41,9 @@ void ChartModel::setColumns(int columns)
{
if (columns != m_columns)
{
+ beginResetModel();
m_columns = columns;
- reset();
+ endResetModel();
emit columnsChanged();
}
}
@@ -55,7 +56,7 @@ int ChartModel::rows() const
qreal ChartModel::value(int row, int column) const
{
if (row >= m_records.count())
- return 0.0;
+ return std::numeric_limits<double>::quiet_NaN();;
return m_records.at(row)->value(column);
}
@@ -129,7 +130,7 @@ void ChartModel::insertRecord(int row, Record *record)
emit rowsChanged();
}
-void ChartModel::appendRecord(QDeclarativeListProperty<Record>* list, Record* record)
+void ChartModel::appendRecord(QQmlListProperty<Record>* list, Record* record)
{
ChartModel* chartModel = qobject_cast<ChartModel*>(list->object);
if (chartModel)
@@ -138,7 +139,7 @@ void ChartModel::appendRecord(QDeclarativeListProperty<Record>* list, Record* re
}
}
-int ChartModel::countRecords(QDeclarativeListProperty<Record>* list)
+int ChartModel::countRecords(QQmlListProperty<Record>* list)
{
ChartModel* chartModel = qobject_cast<ChartModel*>(list->object);
if (chartModel)
@@ -148,7 +149,7 @@ int ChartModel::countRecords(QDeclarativeListProperty<Record>* list)
return -1;
}
-Record* ChartModel::recordAt(QDeclarativeListProperty<Record>* list, int index)
+Record* ChartModel::recordAt(QQmlListProperty<Record>* list, int index)
{
ChartModel* chartModel = qobject_cast<ChartModel*>(list->object);
if (chartModel)
@@ -158,7 +159,7 @@ Record* ChartModel::recordAt(QDeclarativeListProperty<Record>* list, int index)
return 0;
}
-void ChartModel::clearRecords(QDeclarativeListProperty<Record>* list)
+void ChartModel::clearRecords(QQmlListProperty<Record>* list)
{
ChartModel* chartModel = qobject_cast<ChartModel*>(list->object);
if (chartModel)
diff --git a/src/chartmodel.h b/src/chartmodel.h
index 1d3373d..57bc1b6 100644
--- a/src/chartmodel.h
+++ b/src/chartmodel.h
@@ -22,19 +22,19 @@
#include <QAbstractTableModel>
-#include <QDeclarativeListProperty>
+#include <QQmlListProperty>
class Record;
class ChartModel : public QAbstractTableModel
{
Q_OBJECT
- Q_PROPERTY(QDeclarativeListProperty<Record> records READ records CONSTANT)
+ Q_PROPERTY(QQmlListProperty<Record> records READ records CONSTANT)
Q_PROPERTY(int columns READ columns WRITE setColumns NOTIFY columnsChanged)
Q_PROPERTY(int rows READ rows NOTIFY rowsChanged)
Q_CLASSINFO("DefaultProperty", "records")
public:
- QDeclarativeListProperty<Record> records();
+ QQmlListProperty<Record> records();
int columns() const;
void setColumns(int columns);
int rows() const;
@@ -47,18 +47,18 @@ public:
int rowCount(const QModelIndex& parent) const;
int columnCount(const QModelIndex& parent) const;
QVariant data(const QModelIndex& index, int role) const;
-signals:
+Q_SIGNALS:
void columnsChanged();
void rowsChanged();
void recordChanged(int row);
-private slots:
+private Q_SLOTS:
void onRecordChanged(Record* record);
private:
void insertRecord(int row, Record* record);
- static void appendRecord(QDeclarativeListProperty<Record>* list, Record* record);
- static int countRecords(QDeclarativeListProperty<Record>* list);
- static Record* recordAt(QDeclarativeListProperty<Record>* list, int index);
- static void clearRecords(QDeclarativeListProperty<Record>* list);
+ static void appendRecord(QQmlListProperty<Record>* list, Record* record);
+ static int countRecords(QQmlListProperty<Record>* list);
+ static Record* recordAt(QQmlListProperty<Record>* list, int index);
+ static void clearRecords(QQmlListProperty<Record>* list);
QList<Record*> m_records;
int m_columns;
};
diff --git a/src/chartplugin.cpp b/src/chartplugin.cpp
index b3d7813..129c034 100644
--- a/src/chartplugin.cpp
+++ b/src/chartplugin.cpp
@@ -19,7 +19,7 @@
#include "chartplugin.h"
-#include <qdeclarative.h>
+#include <QQmlEngine>
#include <QAbstractTableModel>
#include "barchartcore.h"
@@ -32,6 +32,10 @@
#include "linechartbackgroundpainter.h"
#include "linechartpainter.h"
#include "linechartpoint.h"
+#include "xychartcore.h"
+#include "xychartbackgroundpainter.h"
+#include "xychartpainter.h"
+#include "xychartpoint.h"
#include "record.h"
void ChartPlugin::registerTypes(const char *uri)
@@ -47,10 +51,12 @@ void ChartPlugin::registerTypes(const char *uri)
qmlRegisterType<LineChartBackgroundPainter>(uri, 0, 1, "LineChartBackgroundPainter");
qmlRegisterType<LineChartPainter>(uri, 0, 1, "LineChartPainter");
qmlRegisterType<LineChartPoint>(uri, 0, 1, "LineChartPoint");
+ qmlRegisterType<XYChartCore>(uri, 0, 1, "XYChartCore");
+ qmlRegisterType<XYChartBackgroundPainter>(uri, 0, 1, "XYChartBackgroundPainter");
+ qmlRegisterType<XYChartPainter>(uri, 0, 1, "XYChartPainter");
+ qmlRegisterType<XYChartPoint>(uri, 0, 1, "XYChartPoint");
qmlRegisterType<ChartModel>(uri, 0, 1, "ChartModel");
qmlRegisterType<Record>(uri, 0, 1, "Record");
qmlRegisterUncreatableType<QAbstractTableModel>(uri, 0, 1, "QAbstractTableModel", "abstract class");
}
-
-Q_EXPORT_PLUGIN2(chartplugin, ChartPlugin)
diff --git a/src/chartplugin.h b/src/chartplugin.h
index 5dd7099..61ae712 100644
--- a/src/chartplugin.h
+++ b/src/chartplugin.h
@@ -20,11 +20,12 @@
#ifndef GRAPHPLUGIN_H
#define GRAPHPLUGIN_H
-#include <QDeclarativeExtensionPlugin>
+#include <QQmlExtensionPlugin>
-class ChartPlugin : public QDeclarativeExtensionPlugin
+class ChartPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
public:
void registerTypes(const char *uri);
};
diff --git a/src/dimension.cpp b/src/dimension.cpp
index 13f2138..94d1ae7 100644
--- a/src/dimension.cpp
+++ b/src/dimension.cpp
@@ -19,17 +19,18 @@
#include "dimension.h"
-#include <KGlobal>
-#include <KLocale>
+#include <QLocale>
-Dimension::Dimension(QDeclarativeItem* parent) :
- QDeclarativeItem(parent),
+Dimension::Dimension(QObject* parent) :
+ QObject(parent),
m_color(Qt::black),
m_dataColumn(0),
m_minimumValue(0),
m_maximumValue(256),
m_precision(0),
- m_unitFactor(1)
+ m_unitFactor(1),
+ m_markerStyle(MarkerStyleRound),
+ m_lineStyle(LineStyleSolid)
{
}
@@ -155,5 +156,36 @@ void Dimension::setUnitFactor(qreal unitFactor)
QString Dimension::formatValue(qreal value)
{
- return KGlobal::locale()->formatNumber(value * m_unitFactor, m_precision) + m_unit;
+ QLocale locale;
+ return locale.toString(value * m_unitFactor, 'f', m_precision);
+}
+
+Dimension::MarkerStyle Dimension::markerStyle() const
+{
+ return m_markerStyle;
+}
+
+void Dimension::setMarkerStyle(MarkerStyle markerstyle)
+{
+ if (m_markerStyle != markerstyle)
+ {
+ m_markerStyle = markerstyle;
+ emit updated();
+ emit markerStyleChanged();
+ }
+}
+
+Dimension::LineStyle Dimension::lineStyle() const
+{
+ return m_lineStyle;
+}
+
+void Dimension::setLineStyle(LineStyle lineStyle)
+{
+ if (m_lineStyle != lineStyle)
+ {
+ m_lineStyle = lineStyle;
+ emit updated();
+ emit lineStyleChanged();
+ }
}
diff --git a/src/dimension.h b/src/dimension.h
index da0d2c3..1743c29 100644
--- a/src/dimension.h
+++ b/src/dimension.h
@@ -20,14 +20,29 @@
#ifndef DIMENSION_H
#define DIMENSION_H
-#include <QDeclarativeItem>
+#include <QObject>
#include <QColor>
-#include <QDeclarativeListProperty>
-class Dimension : public QDeclarativeItem
+class Dimension : public QObject
{
- Q_OBJECT
+Q_OBJECT
+public:
+ enum MarkerStyle
+ {
+ MarkerStyleNone,
+ MarkerStyleRound,
+ MarkerStyleCross
+ };
+ Q_ENUMS(MarkerStyle);
+ enum LineStyle
+ {
+ LineStyleNone,
+ LineStyleSolid,
+ LineStyleDash
+ };
+ Q_ENUMS(LineStyle);
+
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
Q_PROPERTY(int dataColumn READ dataColumn WRITE setDataColumn NOTIFY dataColumnChanged)
Q_PROPERTY(qreal minimumValue READ minimumValue WRITE setMinimumValue NOTIFY minimumValueChanged)
@@ -36,9 +51,10 @@ class Dimension : public QDeclarativeItem
Q_PROPERTY(int precision READ precision WRITE setPrecision NOTIFY precisionChanged)
Q_PROPERTY(QString unit READ unit WRITE setUnit NOTIFY unitChanged)
Q_PROPERTY(qreal unitFactor READ unitFactor WRITE setUnitFactor NOTIFY unitFactorChanged)
+ Q_PROPERTY(MarkerStyle markerStyle READ markerStyle WRITE setMarkerStyle NOTIFY markerStyleChanged)
+ Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle NOTIFY lineStyleChanged)
-public:
- explicit Dimension(QDeclarativeItem* parent = 0);
+ explicit Dimension(QObject* parent = 0);
QColor color() const;
void setColor(const QColor& color);
int dataColumn() const;
@@ -55,8 +71,13 @@ public:
void setUnit(const QString& unit);
qreal unitFactor() const;
void setUnitFactor(qreal unitFactor);
+ MarkerStyle markerStyle() const;
+ void setMarkerStyle(MarkerStyle markerstyle);
+ LineStyle lineStyle() const;
+ void setLineStyle(LineStyle lineStyle);
Q_INVOKABLE QString formatValue(qreal value);
-signals:
+
+Q_SIGNALS:
void colorChanged();
void dataColumnChanged();
void minimumValueChanged();
@@ -66,6 +87,8 @@ signals:
void unitChanged();
void unitFactorChanged();
void updated();
+ void markerStyleChanged();
+ void lineStyleChanged();
private:
QColor m_color;
int m_dataColumn;
@@ -75,6 +98,8 @@ private:
int m_precision;
QString m_unit;
qreal m_unitFactor;
+ MarkerStyle m_markerStyle;
+ LineStyle m_lineStyle;
};
#endif // DIMENSION_H
diff --git a/src/linechartbackgroundpainter.cpp b/src/linechartbackgroundpainter.cpp
index 0a2e148..f4f6627 100644
--- a/src/linechartbackgroundpainter.cpp
+++ b/src/linechartbackgroundpainter.cpp
@@ -25,13 +25,11 @@
#include "linechartcore.h"
#include "dimension.h"
-#include <KDebug>
-
-LineChartBackgroundPainter::LineChartBackgroundPainter(QDeclarativeItem* parent) :
- QDeclarativeItem(parent),
+LineChartBackgroundPainter::LineChartBackgroundPainter(QQuickItem* parent) :
+ QQuickPaintedItem(parent),
m_lineChartCore(0)
{
- setFlag(QGraphicsItem::ItemHasNoContents, false);
+ setFlag(QQuickItem::ItemHasContents, true);
connect(this, SIGNAL(heightChanged()), SLOT(triggerUpdate()));
}
@@ -67,7 +65,7 @@ const QList<QPolygonF>& LineChartBackgroundPainter::linePolygons() const
return m_linePolygons;
}
-void LineChartBackgroundPainter::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
+void LineChartBackgroundPainter::paint(QPainter* painter)
{
if (m_lineChartCore->model()->rowCount() == 0)
return;
@@ -137,6 +135,9 @@ void LineChartBackgroundPainter::updateLinePolygons()
for (int row = 0; row < model->rowCount(); row++)
{
const qreal value = model->data(model->index(row, column)).toReal();
+ if (qIsNaN(value))
+ continue;
+
const qreal x = (qreal(row) + 0.5) * pitch;
const qreal y = maxY - ((maxY - 2 * radius) * (value - minValue) / (maxValue - minValue)) - radius;
line << QPointF(x, y);
diff --git a/src/linechartbackgroundpainter.h b/src/linechartbackgroundpainter.h
index adadd48..5cef06b 100644
--- a/src/linechartbackgroundpainter.h
+++ b/src/linechartbackgroundpainter.h
@@ -20,24 +20,26 @@
#ifndef LINEGRAPHBACKGROUNDPAINTER_H
#define LINEGRAPHBACKGROUNDPAINTER_H
-#include <QDeclarativeItem>
+#include <QQuickPaintedItem>
+
+#include <QPolygonF>
class LineChartCore;
-class LineChartBackgroundPainter : public QDeclarativeItem
+class LineChartBackgroundPainter : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(LineChartCore* lineChartCore READ lineChartCore WRITE setLineChartCore NOTIFY lineChartCoreChanged)
public:
- explicit LineChartBackgroundPainter(QDeclarativeItem* parent = 0);
+ explicit LineChartBackgroundPainter(QQuickItem* parent = 0);
LineChartCore* lineChartCore() const;
void setLineChartCore(LineChartCore* lineChartCore);
- void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*);
+ void paint(QPainter* painter);
const QList<QPolygonF>& linePolygons() const;
-signals:
+Q_SIGNALS:
void lineChartCoreChanged();
void linePolygonsUpdated();
-private slots:
+private Q_SLOTS:
void triggerUpdate();
private:
void updateWidth();
diff --git a/src/linechartcore.cpp b/src/linechartcore.cpp
index 886c3b1..1308c0d 100644
--- a/src/linechartcore.cpp
+++ b/src/linechartcore.cpp
@@ -19,7 +19,7 @@
#include "linechartcore.h"
-LineChartCore::LineChartCore(QDeclarativeItem* parent) :
+LineChartCore::LineChartCore(QQuickItem* parent) :
ChartCore(parent),
m_pointRadius(5.0)
{
@@ -40,7 +40,7 @@ void LineChartCore::setPointRadius(qreal pointRadius)
}
}
-void LineChartCore::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
+void LineChartCore::paint(QPainter* painter)
{
paintAxisAndLines(painter, m_pointRadius);
}
diff --git a/src/linechartcore.h b/src/linechartcore.h
index 4d99ede..546c4c5 100644
--- a/src/linechartcore.h
+++ b/src/linechartcore.h
@@ -27,11 +27,11 @@ class LineChartCore : public ChartCore
Q_OBJECT
Q_PROPERTY(qreal pointRadius READ pointRadius WRITE setPointRadius NOTIFY pointRadiusChanged)
public:
- explicit LineChartCore(QDeclarativeItem* parent = 0);
+ explicit LineChartCore(QQuickItem* parent = 0);
qreal pointRadius() const;
void setPointRadius(qreal pointRadius);
- void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*);
-signals:
+ void paint(QPainter* painter);
+Q_SIGNALS:
void pointRadiusChanged();
private:
qreal m_pointRadius;
diff --git a/src/linechartpainter.cpp b/src/linechartpainter.cpp
index 1912fc1..922fa41 100644
--- a/src/linechartpainter.cpp
+++ b/src/linechartpainter.cpp
@@ -25,15 +25,13 @@
#include "dimension.h"
#include "linechartbackgroundpainter.h"
-#include <KDebug>
-
-LineChartPainter::LineChartPainter(QDeclarativeItem* parent) :
- QDeclarativeItem(parent),
+LineChartPainter::LineChartPainter(QQuickItem* parent) :
+ QQuickPaintedItem(parent),
m_lineChartCore(0),
m_backgroundPainter(0),
m_dimension(-1)
{
- setFlag(QGraphicsItem::ItemHasNoContents, false);
+ setFlag(QQuickItem::ItemHasContents, true);
}
LineChartCore* LineChartPainter::lineChartCore() const
@@ -92,7 +90,7 @@ void LineChartPainter::setDimension(int dimension)
}
}
-void LineChartPainter::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
+void LineChartPainter::paint(QPainter* painter)
{
if (!m_lineChartCore || !m_backgroundPainter || m_dimension == -1)
return;
diff --git a/src/linechartpainter.h b/src/linechartpainter.h
index 7fed82c..3222f1b 100644
--- a/src/linechartpainter.h
+++ b/src/linechartpainter.h
@@ -19,31 +19,31 @@
#ifndef LINEGRAPHPAINTER_H
#define LINEGRAPHPAINTER_H
-#include <QDeclarativeItem>
+#include <QQuickPaintedItem>
class LineChartCore;
class LineChartBackgroundPainter;
-class LineChartPainter : public QDeclarativeItem
+class LineChartPainter : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(LineChartCore* lineChartCore READ lineChartCore WRITE setLineChartCore NOTIFY lineChartCoreChanged)
Q_PROPERTY(LineChartBackgroundPainter* backgroundPainter READ backgroundPainter WRITE setBackgroundPainter NOTIFY backgroundPainterChanged)
Q_PROPERTY(int dimension READ dimension WRITE setDimension NOTIFY dimensionChanged)
public:
- explicit LineChartPainter(QDeclarativeItem* parent = 0);
+ explicit LineChartPainter(QQuickItem* parent = 0);
LineChartCore* lineChartCore() const;
void setLineChartCore(LineChartCore* lineChartCore);
LineChartBackgroundPainter* backgroundPainter() const;
void setBackgroundPainter(LineChartBackgroundPainter* backgroundPainter);
int dimension() const;
void setDimension(int dimension);
- void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*);
-signals:
+ void paint(QPainter* painter);
+Q_SIGNALS:
void lineChartCoreChanged();
void backgroundPainterChanged();
void dimensionChanged();
-private slots:
+private Q_SLOTS:
void triggerUpdate();
private:
void updateWidth();
diff --git a/src/linechartpoint.cpp b/src/linechartpoint.cpp
index 80591d3..562ad4e 100644
--- a/src/linechartpoint.cpp
+++ b/src/linechartpoint.cpp
@@ -26,14 +26,14 @@
#include "dimension.h"
#include "linechartbackgroundpainter.h"
-LineChartPoint::LineChartPoint(QDeclarativeItem* parent) :
- QDeclarativeItem(parent),
+LineChartPoint::LineChartPoint(QQuickItem* parent) :
+ QQuickPaintedItem(parent),
m_lineChartCore(0),
m_backgroundPainter(0),
m_dimension(-1),
m_row(-1)
{
- setFlag(QGraphicsItem::ItemHasNoContents, false);
+ setFlag(QQuickItem::ItemHasContents, true);
}
LineChartCore* LineChartPoint::lineChartCore() const
@@ -120,6 +120,9 @@ void LineChartPoint::setRow(int row)
QString LineChartPoint::text() const
{
+ if (!m_lineChartCore)
+ return QString();
+
const int role = m_lineChartCore->textRole();
if (role == -1)
@@ -132,7 +135,7 @@ QString LineChartPoint::text() const
return model->data(model->index(m_row, column), role).toString();
}
-void LineChartPoint::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*)
+void LineChartPoint::paint(QPainter* painter)
{
if (!valid())
return;
@@ -161,7 +164,8 @@ void LineChartPoint::updateGeometry()
setHeight(2 * radius);
QPointF center = m_backgroundPainter->linePolygons().at(m_dimension).at(m_row);
- setPos(center - QPointF(radius, radius));
+ setX(center.x() - radius);
+ setY(center.y() - radius);
}
bool LineChartPoint::valid() const
diff --git a/src/linechartpoint.h b/src/linechartpoint.h
index ddde219..0a54a24 100644
--- a/src/linechartpoint.h
+++ b/src/linechartpoint.h
@@ -20,12 +20,12 @@
#ifndef LINEGRAPHPOINT_H
#define LINEGRAPHPOINT_H
-#include <QDeclarativeItem>
+#include <QQuickPaintedItem>
class LineChartCore;
class LineChartBackgroundPainter;
-class LineChartPoint : public QDeclarativeItem
+class LineChartPoint : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(LineChartCore* lineChartCore READ lineChartCore WRITE setLineChartCore NOTIFY lineChartCoreChanged)
@@ -34,7 +34,7 @@ class LineChartPoint : public QDeclarativeItem
Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged)
Q_PROPERTY(QString text READ text NOTIFY textChanged)
public:
- explicit LineChartPoint(QDeclarativeItem* parent = 0);
+ explicit LineChartPoint(QQuickItem* parent = 0);
LineChartCore* lineChartCore() const;
void setLineChartCore(LineChartCore* lineChartCore);
LineChartBackgroundPainter* backgroundPainter() const;
@@ -44,15 +44,15 @@ public:
int row() const;
void setRow(int row);
QString text() const;
- void paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*);
-signals:
+ void paint(QPainter* painter);
+Q_SIGNALS:
void lineChartCoreChanged();
void backgroundPainterChanged();
void dimensionChanged();
void rowChanged();
void textChanged();
void maxYChanged();
-private slots:
+private Q_SLOTS:
void triggerUpdate();
private:
void updateGeometry();
diff --git a/src/qml/BarChart.qml b/src/qml/BarChart.qml
index 29ef6b8..4039d8d 100644
--- a/src/qml/BarChart.qml
+++ b/src/qml/BarChart.qml
@@ -17,8 +17,8 @@
* You should have received a copy of the GNU Lesser General Public
*/
-import QtQuick 1.1
-import org.kde.plasma.components 0.1 as PlasmaComponents
+import QtQuick 2.2
+import org.kde.charts 0.1
/**
* An interactive bar chart.
@@ -74,7 +74,7 @@ Item {
* @warn colors with an non-zero alpha component aren't supported yet
* and result in an visual defiencies.
*
- * Default value is the theme's background color.
+ * Default value is white.
*/
property alias backgroundColor: bg.color
@@ -84,9 +84,9 @@ Item {
*
* Used for pitch line and date element labels.
*
- * Default value is the theme's text color.
+ * Default value is black.
*/
- property color textColor: theme.textColor
+ property color textColor: "#000"
/**
* The amount of space between the outline of the chart background
@@ -126,7 +126,7 @@ Item {
Rectangle {
id: bg
anchors.fill: parent
- color: theme.backgroundColor
+ color: "#fff"
}
BarChartCore {
diff --git a/src/qml/Label.qml b/src/qml/Label.qml
index 7702aac..4ee1856 100644
--- a/src/qml/Label.qml
+++ b/src/qml/Label.qml
@@ -17,13 +17,11 @@
* You should have received a copy of the GNU Lesser General Public
*/
-import QtQuick 1.1
-import org.kde.plasma.components 0.1 as PlasmaComponents
+import QtQuick 2.2
+import org.kde.charts 0.1
-PlasmaComponents.Label {
+Text {
property Rectangle backgroundItem
- height: paintedHeight
- font.pointSize: theme.smallestFont.pointSize
style: Text.Outline;
styleColor: backgroundItem.color
}
diff --git a/src/qml/LegendItem.qml b/src/qml/LegendItem.qml
index 0e1d9f4..5ca724b 100644
--- a/src/qml/LegendItem.qml
+++ b/src/qml/LegendItem.qml
@@ -17,9 +17,8 @@
* You should have received a copy of the GNU Lesser General Public
*/
-import QtQuick 1.1
-import org.kde.plasma.components 0.1 as PlasmaComponents
-
+import QtQuick 2.0
+import org.kde.charts 0.1
/**
* An item to compose the legend for a chart of.
@@ -35,7 +34,7 @@ Item {
/**
* The text color for the legend label.
*
- * Default value is the theme's text color
+ * Default value is black.
*/
property alias textColor: label.color
@@ -54,13 +53,12 @@ Item {
radius: 4
}
- PlasmaComponents.Label {
+ Text {
id: label
anchors {
top: parent.top
right: parent.right
}
text: dimension.label
- height: paintedHeight
}
}
diff --git a/src/qml/LineChart.qml b/src/qml/LineChart.qml
index 7228d93..90d87db 100644
--- a/src/qml/LineChart.qml
+++ b/src/qml/LineChart.qml
@@ -17,8 +17,8 @@
* You should have received a copy of the GNU Lesser General Public
*/
-import QtQuick 1.1
-import org.kde.plasma.components 0.1 as PlasmaComponents
+import QtQuick 2.2
+import org.kde.charts 0.1
/**
* An interactive line chart.
@@ -74,7 +74,7 @@ Item {
* @warn colors with an non-zero alpha component aren't supported yet
* and result in an visual defiencies.
*
- * Default value is the theme's background color.
+ * Default value is white.
*/
property alias backgroundColor: bg.color
@@ -82,11 +82,11 @@ Item {
* type:color
* The text color used for the chart
*
- * Used for pitch line and date element labels.
+ * Used for pitch lines and date element labels.
*
- * Default value is the theme's text color.
+ * Default value is black.
*/
- property color textColor: theme.textColor
+ property color textColor: "#000"
/**
* The amount of space between the outline of the chart background
@@ -129,7 +129,7 @@ Item {
Rectangle {
id: bg
anchors.fill: parent
- color: theme.backgroundColor
+ color: "#fff"
}
LineChartCore {
diff --git a/src/qml/LineLabel.qml b/src/qml/LineLabel.qml
index e61be64..52216eb 100644
--- a/src/qml/LineLabel.qml
+++ b/src/qml/LineLabel.qml
@@ -17,7 +17,8 @@
* You should have received a copy of the GNU Lesser General Public
*/
-import QtQuick 1.1
+import QtQuick 2.2
+import org.kde.charts 0.1
Label {
property Dimension dimension
diff --git a/src/qml/XYChart.qml b/src/qml/XYChart.qml
new file mode 100644
index 0000000..2ed74c2
--- /dev/null
+++ b/src/qml/XYChart.qml
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2015 Jesper Hellesø Hansen <jesperhh@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ */
+
+import QtQuick 2.2
+import org.kde.charts 0.1
+
+/**
+ * An interactive xy chart.
+ *
+ * At the minimum, set the 'model' and 'dimensions' properties to use
+ * this component.
+ */
+Item {
+ id: root
+
+ /**
+ * type:QAbstractTableModel
+ * The source model the data for the chart is taken from.
+ *
+ * One row represents a record in the chart. Use the 'dimensions'
+ * property to define which columns carry the relevant data.
+ */
+ property alias model: core.model
+
+ /**
+ * type:list<Dimension>
+ * The list of dimensions for the graph.
+ *
+ * Each dimension defines the appearance of the data from one
+ * column in the source model. See the documentation for Dimension
+ * for details.
+ */
+ property alias dimensions: core.dimensions
+
+ /**
+ * type:Dimension
+ * The x axis description for the graph.
+ *
+ * Defines the dimension used for the x axis. The x axis is shared between
+ * all dimensions (for now). See the documentation for Dimension
+ * for details.
+ */
+ property alias xAxis: core.xAxis
+
+ /**
+ * type:Dimension
+ * The y axis description for the graph.
+ *
+ * Defines the dimension used for the y axis. The y axis is shared between
+ * all dimensions (for now). See the documentation for Dimension
+ * for details.
+ */
+ property alias yAxis: core.yAxis
+
+ /**
+ * type:int
+ * The role to query text from the model for data indices.
+ *
+ * If set there will be text labels with the data fetched with the
+ * specified role next to the point elements.
+ *
+ * Default value is -1 (unset).
+ */
+ property alias textRole: core.textRole
+
+ /**
+ * type:color
+ * The background color used for the chart.
+ *
+ * @warn colors with an non-zero alpha component aren't supported yet
+ * and result in an visual defiencies.
+ *
+ * Default value is white.
+ */
+ property alias backgroundColor: bg.color
+
+ /**
+ * type:color
+ * The text color used for the chart
+ *
+ * Used for pitch lines and date element labels.
+ *
+ * Default value is black.
+ */
+ property alias textColor: core.textColor
+
+ /**
+ * type:real
+ * The size of markers on the lines
+ *
+ * Default value is 5.0.
+ */
+ property alias pointRadius: core.pointRadius
+
+ /**
+ * type:real
+ * The width of the lines between data points as well as axis and
+ * grid lines.
+ *
+ * Default value is 2.0.
+ */
+ property alias lineWidth: core.lineWidth
+
+ /**
+ * Fires when the user has clicked on a data element.
+ *
+ * @param dimension The dimension the data element belongs to.
+ * @param row The row in the source model the data element represents.
+ * @param elem The QML item for data element itself.
+ */
+ signal elemClicked(variant dimension, int row, variant elem)
+
+
+ /**
+ * Fires when the mouse cursor touches a data element.
+ *
+ * @param dimension The dimension the data element belongs to.
+ * @param row The row in the source model the data element represents.
+ * @param elem The QML item for data element itself.
+ */
+ signal elemEntered(variant dimension, int row, variant elem)
+
+ /**
+ * Fires when the mouse cursor leaves a data element.
+ *
+ * @param dimension The dimension the data element belongs to.
+ * @param row The row in the source model the data element represents.
+ * @param elem The QML item for data element itself.
+ */
+ signal elemExited(variant dimension, int row, variant elem)
+
+ Rectangle {
+ id: bg
+ anchors.fill: parent
+ color: "transparent"
+ }
+
+ Text {
+ id: yLabel
+ font: core.font
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ horizontalAlignment: Text.AlignHCenter
+ text: core.yAxis.label + "\n(" + core.yAxis.unit + ")"
+ color: core.textColor
+ }
+
+ Text {
+ id: xLabel
+ font: core.font
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ text: core.xAxis.label + " (" + core.xAxis.unit + ")"
+ color: core.textColor
+ }
+
+ XYChartCore {
+ id: core
+
+ anchors.left: yLabel.right
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.bottom: xLabel.top
+
+ XYChartBackgroundPainter {
+ id: xyBg
+ xyChartCore: core
+ anchors.fill: parent
+ }
+
+ Repeater {
+ id: dimensionsRepeater
+
+ model: core.dimensions.length
+
+ delegate: XYChartPainter {
+ id: xyChart
+ xyChartCore: core
+ backgroundPainter: xyBg
+ dimension: index
+ anchors.fill: parent
+
+ Repeater {
+ model: core.model
+ delegate: XYChartPoint {
+ id: point
+ xyChartCore: core
+ backgroundPainter: xyBg
+ dimension: xyChart.dimension
+ row: index
+
+ Label {
+ anchors.top: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ backgroundItem: bg
+ text: parent.text
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: root.elemClicked(core.dimensions[xyChart.dimension], parent.row, parent)
+ onEntered: root.elemEntered(core.dimensions[xyChart.dimension], parent.row, parent)
+ onExited: root.elemExited(core.dimensions[xyChart.dimension], parent.row, parent)
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/qml/qmldir b/src/qml/qmldir
index 9bd1c6c..41359d9 100644
--- a/src/qml/qmldir
+++ b/src/qml/qmldir
@@ -1,6 +1,6 @@
-plugin kqtquickcharts
-
+module org.kde.charts
BarChart 0.1 BarChart.qml
LineChart 0.1 LineChart.qml
LegendItem 0.1 LegendItem.qml
-
+XYChart 0.1 XYChart.qml
+plugin kqtquickcharts
diff --git a/src/record.cpp b/src/record.cpp
index f677d61..71abfb6 100644
--- a/src/record.cpp
+++ b/src/record.cpp
@@ -18,6 +18,7 @@
*/
#include "record.h"
+#include <limits>
Record::Record(QObject* parent) :
QObject(parent)
@@ -41,14 +42,15 @@ void Record::setValues(const QVariantList& values)
qreal Record::value(int column) const
{
if (column >= m_values.count())
- return 0.0;
+ return std::numeric_limits<double>::quiet_NaN();
+
return m_values.at(column).toReal();
}
void Record::setValue(int column, qreal value)
{
while(column >= m_values.count()) {
- m_values.append(0.0);
+ m_values.append(std::numeric_limits<double>::quiet_NaN());
}
m_values[column] = value;
emit valuesChanged(this);
diff --git a/src/record.h b/src/record.h
index a6cfd44..5589f65 100644
--- a/src/record.h
+++ b/src/record.h
@@ -34,7 +34,7 @@ public:
void setValues(const QVariantList& values);
Q_INVOKABLE qreal value(int column) const;
Q_INVOKABLE void setValue(int column, qreal value);
-signals:
+Q_SIGNALS:
void valuesChanged(Record* record);
private:
QVariantList m_values;
diff --git a/src/xychartbackgroundpainter.cpp b/src/xychartbackgroundpainter.cpp
new file mode 100644
index 0000000..05a0696
--- /dev/null
+++ b/src/xychartbackgroundpainter.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2015 Jesper Hellesø Hansen <jesperhh@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ */
+
+#include "xychartbackgroundpainter.h"
+
+#include <QAbstractTableModel>
+#include <QPainter>
+
+#include "xychartcore.h"
+#include "dimension.h"
+
+XYChartBackgroundPainter::XYChartBackgroundPainter(QQuickItem* parent) :
+ QQuickPaintedItem(parent),
+ m_xyChartCore(0)
+{
+ setFlag(QQuickItem::ItemHasContents, true);
+
+ connect(this, SIGNAL(widthChanged()), SLOT(triggerUpdate()));
+ connect(this, SIGNAL(heightChanged()), SLOT(triggerUpdate()));
+}
+
+XYChartCore* XYChartBackgroundPainter::xyChartCore() const
+{
+ return m_xyChartCore;
+}
+
+void XYChartBackgroundPainter::setXYChartCore(XYChartCore* xyChartCore)
+{
+ if (xyChartCore != m_xyChartCore)
+ {
+ if (m_xyChartCore)
+ {
+ m_xyChartCore->disconnect(this);
+ }
+
+ m_xyChartCore = xyChartCore;
+
+ if (m_xyChartCore)
+ {
+ connect(m_xyChartCore, SIGNAL(updated()), SLOT(triggerUpdate()));
+ }
+
+ update();
+ emit xyChartCoreChanged();
+ }
+}
+
+const QList<QPolygonF>& XYChartBackgroundPainter::linePolygons() const
+{
+ return m_linePolygons;
+}
+
+void XYChartBackgroundPainter::paint(QPainter* painter)
+{
+ Q_UNUSED(painter);
+}
+
+void XYChartBackgroundPainter::triggerUpdate()
+{
+ if (!m_xyChartCore->model())
+ return;
+
+ updateLinePolygons();
+ update();
+}
+
+void XYChartBackgroundPainter::updateLinePolygons()
+{
+ m_linePolygons.clear();
+
+ Dimension* xAxis = m_xyChartCore->xAxis();
+ QList<Dimension*> dimensions = m_xyChartCore->dimensionsList();
+ QAbstractTableModel* model = m_xyChartCore->model();
+
+ const int xAxisColumn = xAxis->dataColumn();
+
+ foreach(Dimension* dimension, dimensions)
+ {
+ const int column = dimension->dataColumn();
+ QPolygonF line;
+ for (int row = 0; row < model->rowCount(); row++)
+ {
+ const qreal key = model->data(model->index(row, xAxisColumn)).toReal();
+ const qreal value = model->data(model->index(row, column)).toReal();
+ // Skip "NULL" values
+ if (qIsNaN(value))
+ continue;
+
+ line << m_xyChartCore->translatePoint(QPointF(key, value));
+ }
+
+ m_linePolygons << line;
+ }
+
+ emit linePolygonsUpdated();
+}
diff --git a/src/xychartbackgroundpainter.h b/src/xychartbackgroundpainter.h
new file mode 100644
index 0000000..9c96be8
--- /dev/null
+++ b/src/xychartbackgroundpainter.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2015 Jesper Hellesø Hansen <jesperhh@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ */
+
+#ifndef XYGRAPHBACKGROUNDPAINTER_H
+#define XYGRAPHBACKGROUNDPAINTER_H
+
+#include <QQuickPaintedItem>
+
+#include <QPolygonF>
+
+class XYChartCore;
+
+class XYChartBackgroundPainter : public QQuickPaintedItem
+{
+ Q_OBJECT
+ Q_PROPERTY(XYChartCore* xyChartCore READ xyChartCore WRITE setXYChartCore NOTIFY xyChartCoreChanged)
+public:
+ explicit XYChartBackgroundPainter(QQuickItem* parent = 0);
+ XYChartCore* xyChartCore() const;
+ void setXYChartCore(XYChartCore* lineChartCore);
+ void paint(QPainter* painter);
+ const QList<QPolygonF>& linePolygons() const;
+Q_SIGNALS:
+ void xyChartCoreChanged();
+ void linePolygonsUpdated();
+private Q_SLOTS:
+ void triggerUpdate();
+private:
+ void updateLinePolygons();
+ XYChartCore* m_xyChartCore;
+ QList<QPolygonF> m_linePolygons;
+};
+
+#endif // XYGRAPHBACKGROUNDPAINTER_H
diff --git a/src/xychartcore.cpp b/src/xychartcore.cpp
new file mode 100644
index 0000000..f6fe57f
--- /dev/null
+++ b/src/xychartcore.cpp
@@ -0,0 +1,394 @@
+/*
+ * Copyright 2015 Jesper Hellesø Hansen <jesperhh@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ */
+
+#include "xychartcore.h"
+#include <QPainter>
+#include <QAbstractTableModel>
+#include <assert.h>
+#include <cmath>
+
+const qreal divisors[] = { 1, 2, 5};
+const int ndivisors = sizeof(divisors) / sizeof(divisors[0]);
+
+XYChartCore::XYChartCore(QQuickItem* parent) :
+ ChartCore(parent),
+ m_pointRadius(5.0),
+ m_lineWidth(2.0),
+ m_xAxis(0),
+ m_yAxis(0),
+ m_labelFont(),
+ m_labelFontMetrics(m_labelFont),
+ m_minorTickSize(2),
+ m_majorTickSize(4),
+ m_margin(m_majorTickSize + 4),
+ m_gridLines(false),
+ m_axisLabelCountGoal(6)
+{
+ m_labelFont.setPointSize(18);
+ m_labelFontMetrics = QFontMetrics(m_labelFont);
+ connect(this, &QQuickItem::widthChanged, this, &XYChartCore::triggerUpdate);
+ connect(this, &QQuickItem::heightChanged, this, &XYChartCore::triggerUpdate);
+ connect(this, &XYChartCore::fontChanged, this, &XYChartCore::triggerUpdate);
+ connect(this, &XYChartCore::textColorChanged, this, &XYChartCore::triggerUpdate);
+ connect(this, &XYChartCore::pointRadiusChanged, this, &XYChartCore::triggerUpdate);
+ connect(this, &XYChartCore::lineWidthChanged, this, &XYChartCore::triggerUpdate);
+ connect(this, &XYChartCore::xAxisChanged, this, &XYChartCore::triggerUpdate);
+ connect(this, &XYChartCore::yAxisChanged, this, &XYChartCore::triggerUpdate);
+ connect(this, &XYChartCore::gridLinesChanged, this, &XYChartCore::triggerUpdate);
+ connect(this, &XYChartCore::axisLabelCountGoalChanged, this, &XYChartCore::triggerUpdate);
+ connect(this, &ChartCore::updated, this, &XYChartCore::updateAxis);
+}
+
+qreal XYChartCore::pointRadius() const
+{
+ return m_pointRadius;
+}
+
+void XYChartCore::setPointRadius(qreal pointRadius)
+{
+ if (pointRadius != m_pointRadius)
+ {
+ m_pointRadius = pointRadius;
+ emit pointRadiusChanged();
+ }
+}
+
+qreal XYChartCore::lineWidth() const
+{
+ return m_lineWidth;
+}
+
+void XYChartCore::setLineWidth(qreal lineWidth)
+{
+ if (lineWidth != m_lineWidth)
+ {
+ m_lineWidth = lineWidth;
+ emit lineWidthChanged();
+ }
+}
+
+void XYChartCore::paint(QPainter* painter)
+{
+ painter->setRenderHint(QPainter::Antialiasing, true);
+ painter->setFont(m_labelFont);
+ QPen pen(m_textColor);
+ pen.setWidthF(m_lineWidth);
+ painter->setPen(pen);
+
+ if (m_gridLines)
+ paintGrid(painter);
+
+ paintAxis(painter);
+ paintTicks(painter);
+ paintAxisLabels(painter);
+ paintDimensionLabels(painter);
+}
+
+void XYChartCore::paintAxis(QPainter* painter)
+{
+ const qreal minKey = xAxis()->minimumValue();
+ const qreal maxKey = xAxis()->maximumValue();
+ const qreal minValue = yAxis()->minimumValue();
+ const qreal maxValue = yAxis()->maximumValue();
+
+ const QPointF origo = translatePoint(QPointF(0.0, 0.0));
+ const QPointF p1 = translatePoint(QPointF(minKey, 0.0));
+ const QPointF p2 = translatePoint(QPointF(maxKey, 0.0));
+ const QPointF p3 = translatePoint(QPointF(0.0, minValue));
+ const QPointF p4 = translatePoint(QPointF(0.0, maxValue));
+
+ if (origo != p1)
+ painter->drawLine(origo, p1);
+
+ if (origo != p2)
+ painter->drawLine(origo, p2);
+
+ if (origo != p3)
+ painter->drawLine(origo, p3);
+
+ if (origo != p4)
+ painter->drawLine(origo, p4);
+}
+
+void XYChartCore::paintGrid(QPainter* painter)
+{
+ foreach(qreal label, m_xAxisLabels)
+ {
+ const qreal x = translatePoint(QPointF(label, 0.0)).x();
+ painter->drawLine(x, m_lowerLeftCorner.y(), x, m_lowerLeftCorner.y() - m_graphHeight);
+ }
+
+ foreach(qreal label, m_yAxisLabels)
+ {
+ const qreal y = translatePoint(QPointF(0.0, label)).y();
+ painter->drawLine(m_lowerLeftCorner.x(), y, m_lowerLeftCorner.x() + m_graphWidth, y);
+ }
+}
+
+void XYChartCore::paintTicks(QPainter* painter)
+{
+ int tick = 2, tock = 4;
+
+ qreal label;
+ QPointF point;
+ for (int i = 0; i < m_xAxisLabels.size(); i++)
+ {
+ label = m_xAxisLabels[i];
+ point = translatePoint(QPointF(label, 0.0));
+ painter->drawLine(point.x(), point.y() - tock, point.x(), point.y() + tock);
+
+ if (i < m_xAxisLabels.size() - 1)
+ {
+ label = (m_xAxisLabels[i] + m_xAxisLabels[i + 1]) / 2.0;
+ point = translatePoint(QPointF(label, 0.0));
+ painter->drawLine(point.x(), point.y() - tick, point.x(), point.y() + tick);
+ }
+ }
+
+ for (int i = 0; i < m_yAxisLabels.size(); i++)
+ {
+ label = m_yAxisLabels[i];
+ point = translatePoint(QPointF(0.0, label));
+ painter->drawLine(point.x() - tock, point.y(), point.x() + tock, point.y());
+
+ if (i < m_yAxisLabels.size() - 1)
+ {
+ label = (m_yAxisLabels[i] + m_yAxisLabels[i + 1]) / 2.0;
+ point = translatePoint(QPointF(0.0, label));
+ painter->drawLine(point.x() - tick, point.y(), point.x() + tick, point.y());
+ }
+ }
+}
+
+void XYChartCore::paintAxisLabels(QPainter* painter)
+{
+ int labelHeight = painter->fontMetrics().tightBoundingRect("0123456789").height();
+ foreach(qreal label, m_xAxisLabels)
+ {
+ QString strLabel = formatLabel(label, xAxis());
+ int labelWidth = painter->fontMetrics().width(strLabel);
+ const QPointF point = translatePoint(QPointF(label, 0.0));
+ painter->drawText(point.x() - labelWidth / 2, point.y() + labelHeight + m_margin, strLabel);
+ }
+
+ foreach(qreal label, m_yAxisLabels)
+ {
+ QString strLabel = formatLabel(label, yAxis());
+ int labelWidth = painter->fontMetrics().width(strLabel);
+ const QPointF point = translatePoint(QPointF(0.0, label));
+ painter->drawText(point.x() - labelWidth - m_margin, point.y() + (labelHeight / 2), strLabel);
+ }
+}
+
+void XYChartCore::paintDimensionLabels(QPainter* painter)
+{
+ QList<QPair<qreal, QString>> labels;
+ const int row = model()->rowCount() - 1;
+ if (row == -1)
+ return;
+
+ const qreal maxKey = model()->data(model()->index(row, xAxis()->dataColumn())).toReal();
+ const qreal x = translatePoint(QPointF(maxKey, 0.0)).x();
+ foreach(Dimension* dimension, dimensionsList())
+ {
+ const QString label = dimension->label();
+ if (label.isEmpty())
+ continue;
+
+ const int column = dimension->dataColumn();
+ const qreal value = model()->data(model()->index(row, column)).toReal();
+
+ // We do not label dimensions that miss values for the last point
+ // Use point text for labels inside the chart
+ if (qIsNaN(value))
+ continue;
+
+ const qreal y = translatePoint(QPointF(maxKey, value)).y();
+ labels.append(QPair<qreal, QString>(y, label));
+ }
+
+ if (labels.empty())
+ return;
+
+ for (const auto& iter : labels)
+ {
+ int labelheight = m_labelFontMetrics.tightBoundingRect(iter.second).height();
+ painter->drawText(x + m_margin, iter.first + (labelheight / 2.0), iter.second);
+ }
+}
+
+void XYChartCore::updateAxis()
+{
+ if (!xAxis() || !yAxis())
+ return;
+
+ const qreal minKey = xAxis()->minimumValue();
+ const qreal maxKey = xAxis()->maximumValue();
+ m_xAxisLabels = generateAxisLabels(minKey, maxKey);
+
+ const qreal minValue = yAxis()->minimumValue();
+ const qreal maxValue = yAxis()->maximumValue();
+ m_yAxisLabels = generateAxisLabels(minValue, maxValue);
+
+ const int minValueStringLength = formatLabel(minValue, yAxis()).length();
+ const int maxValueStringLength = formatLabel(maxValue, yAxis()).length();
+ const int minKeyStringLength = formatLabel(minKey, xAxis()).length();
+ const int maxKeyStringLength = formatLabel(maxKey, xAxis()).length();
+
+ int maxYLabelWidth = m_labelFontMetrics.width("W") * std::max(minValueStringLength, maxValueStringLength);
+ int maxXLabelWidth = m_labelFontMetrics.width("W") * std::max(minKeyStringLength, maxKeyStringLength);
+
+ m_lowerLeftCorner.setX(maxYLabelWidth + m_margin);
+ m_lowerLeftCorner.setY(height() - m_labelFontMetrics.height() - m_margin);
+ m_graphWidth = width() - m_lowerLeftCorner.x() - (maxXLabelWidth / 2);
+ m_graphHeight = m_lowerLeftCorner.y() - (m_labelFontMetrics.height() / 2);
+}
+
+QString XYChartCore::formatLabel(const qreal label, const Dimension* dimension) const
+{
+ QLocale locale;
+ return locale.toString(label, 'f', dimension->precision());
+}
+
+QPointF XYChartCore::translatePoint(QPointF point)
+{
+ const qreal minKey = xAxis()->minimumValue();
+ const qreal maxKey = xAxis()->maximumValue();
+ const qreal minVal = yAxis()->minimumValue();
+ const qreal maxVal = yAxis()->maximumValue();
+
+ const qreal x = m_lowerLeftCorner.x() + (m_graphWidth * (point.x() - minKey) / (maxKey - minKey));
+ const qreal y = m_lowerLeftCorner.y() - (m_graphHeight * (point.y() - minVal) / (maxVal - minVal));
+ return QPointF(x, y);
+}
+
+
+QList<qreal> XYChartCore::generateAxisLabels(const qreal minValue, const qreal maxValue)
+{
+ // Distance between labels with preferred number of labels
+ qreal div = fabs(maxValue - minValue) / m_axisLabelCountGoal;
+ // Find power of 10 to scale preferred increments to
+ qreal scale = std::pow(10, floor(std::log10(div)));
+
+ // Find closest increment that has at maximum div distance between labels
+ qreal increment = divisors[0] * scale;
+ for (int i = 0; i < ndivisors; i++)
+ {
+ if ((divisors[i] * scale) > div)
+ break;
+
+ increment = divisors[i] * scale;
+ }
+
+ increment *= (maxValue - minValue) < 0.0 ? -1.0 : 1.0;
+
+ qreal label = minValue;
+ QList<qreal> result;
+ while (label <= maxValue)
+ {
+ result << label;
+ label += increment;
+ }
+
+ return result;
+}
+
+Dimension* XYChartCore::xAxis() const
+{
+ return m_xAxis;
+}
+
+void XYChartCore::setXAxis(Dimension* xAxis)
+{
+ if (m_xAxis != xAxis)
+ {
+ m_xAxis = xAxis;
+ xAxisChanged();
+ }
+}
+
+QColor XYChartCore::textColor() const
+{
+ return m_textColor;
+}
+
+void XYChartCore::setTextColor(QColor color)
+{
+ if (m_textColor != color)
+ {
+ m_textColor = color;
+ emit textColorChanged();
+ }
+}
+
+QFont XYChartCore::font() const
+{
+ return m_labelFont;
+}
+
+void XYChartCore::setFont(QFont font)
+{
+ if (font != m_labelFont)
+ {
+ m_labelFont = font;
+ emit fontChanged();
+ }
+}
+
+bool XYChartCore::gridLines() const
+{
+ return m_gridLines;
+}
+
+void XYChartCore::setGridLines(bool gridLines)
+{
+ if (m_gridLines != gridLines)
+ {
+ m_gridLines = gridLines;
+ emit gridLinesChanged();
+ }
+}
+
+Dimension* XYChartCore::yAxis() const
+{
+ return m_yAxis;
+}
+
+void XYChartCore::setYAxis(Dimension* yAxis)
+{
+ if (m_yAxis != yAxis)
+ {
+ m_yAxis = yAxis;
+ yAxisChanged();
+ }
+}
+
+unsigned int XYChartCore::axisLabelCountGoal() const
+{
+ return m_axisLabelCountGoal;
+}
+
+void XYChartCore::setAxisLabelCountGoal(unsigned int axisLabelCountGoal)
+{
+ if (m_axisLabelCountGoal != axisLabelCountGoal)
+ {
+ m_axisLabelCountGoal = axisLabelCountGoal;
+ axisLabelCountGoalChanged();
+ }
+}
diff --git a/src/xychartcore.h b/src/xychartcore.h
new file mode 100644
index 0000000..b3b17d7
--- /dev/null
+++ b/src/xychartcore.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2015 Jesper Hellesø Hansen <jesperhh@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ */
+
+#ifndef XYGRAPHCORE_H
+#define XYGRAPHCORE_H
+
+#include "chartcore.h"
+#include <QFont>
+#include <QFontMetrics>
+
+class Dimension;
+
+class XYChartCore : public ChartCore
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal pointRadius READ pointRadius WRITE setPointRadius NOTIFY pointRadiusChanged)
+ Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth NOTIFY lineWidthChanged)
+ Q_PROPERTY(Dimension* xAxis READ xAxis WRITE setXAxis NOTIFY xAxisChanged)
+ Q_PROPERTY(Dimension* yAxis READ yAxis WRITE setYAxis NOTIFY yAxisChanged)
+ Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor NOTIFY textColorChanged)
+ Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)
+ Q_PROPERTY(bool gridLines READ gridLines WRITE setGridLines NOTIFY gridLinesChanged)
+ Q_PROPERTY(unsigned int axisLabelCountGoal READ axisLabelCountGoal WRITE setAxisLabelCountGoal NOTIFY axisLabelCountGoalChanged)
+public:
+ explicit XYChartCore(QQuickItem* parent = 0);
+ qreal pointRadius() const;
+ void setPointRadius(qreal pointRadius);
+ qreal lineWidth() const;
+ void setLineWidth(qreal lineWidth);
+ Dimension* xAxis() const;
+ void setXAxis(Dimension* xAxis);
+ Dimension* yAxis() const;
+ void setYAxis(Dimension* yAxis);
+ QColor textColor() const;
+ void setTextColor(QColor color);
+ QFont font() const;
+ void setFont(QFont font);
+ bool gridLines() const;
+ void setGridLines(bool gridLines);
+ unsigned int axisLabelCountGoal() const;
+ void setAxisLabelCountGoal(unsigned int axisLabelCountGoal);
+ QList<qreal> generateAxisLabels(const qreal minValue, const qreal maxValue);
+ void paint(QPainter* painter);
+ QPointF translatePoint(QPointF point);
+
+Q_SIGNALS:
+ void pointRadiusChanged();
+ void lineWidthChanged();
+ void xAxisChanged();
+ void yAxisChanged();
+ void textColorChanged();
+ void fontChanged();
+ void gridLinesChanged();
+ void axisLabelCountGoalChanged();
+
+protected Q_SLOTS:
+ void updateAxis();
+
+protected:
+ void paintAxis(QPainter* painter);
+ void paintAxisLabels(QPainter* painter);
+ void paintTicks(QPainter* painter);
+ void paintGrid(QPainter* painter);
+ void paintDimensionLabels(QPainter* painter);
+
+private:
+ QString formatLabel(const qreal label, const Dimension* dimension) const;
+
+ QList<qreal> m_xAxisLabels;
+ QList<qreal> m_yAxisLabels;
+ qreal m_pointRadius;
+ qreal m_lineWidth;
+ QPointF m_lowerLeftCorner;
+ Dimension* m_xAxis;
+ Dimension* m_yAxis;
+ QFont m_labelFont;
+ QFontMetrics m_labelFontMetrics;
+ QColor m_textColor;
+ qreal m_graphHeight;
+ qreal m_graphWidth;
+ int m_minorTickSize;
+ int m_majorTickSize;
+ int m_margin;
+ bool m_gridLines;
+ unsigned int m_axisLabelCountGoal;
+};
+
+#endif // XYGRAPHCORE_H
diff --git a/src/xychartpainter.cpp b/src/xychartpainter.cpp
new file mode 100644
index 0000000..2eb6e8f
--- /dev/null
+++ b/src/xychartpainter.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2015 Jesper Hellesø Hansen <jesperhh@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ */
+#include "xychartpainter.h"
+
+#include <QAbstractTableModel>
+#include <QPainter>
+
+#include "xychartcore.h"
+#include "dimension.h"
+#include "xychartbackgroundpainter.h"
+
+XYChartPainter::XYChartPainter(QQuickItem* parent) :
+ QQuickPaintedItem(parent),
+ m_xyChartCore(0),
+ m_backgroundPainter(0),
+ m_dimension(-1)
+{
+ setFlag(QQuickItem::ItemHasContents, true);
+}
+
+XYChartCore* XYChartPainter::xyChartCore() const
+{
+ return m_xyChartCore;
+}
+
+void XYChartPainter::setXYChartCore(XYChartCore* lineChartCore)
+{
+ if (lineChartCore != m_xyChartCore)
+ {
+ if (m_xyChartCore)
+ {
+ m_xyChartCore->disconnect(this);
+ }
+
+ m_xyChartCore = lineChartCore;
+
+ if (m_xyChartCore)
+ {
+ connect(m_xyChartCore, SIGNAL(updated()), SLOT(triggerUpdate()));
+ }
+
+ update();
+ emit xyChartCoreChanged();
+ }
+}
+
+XYChartBackgroundPainter* XYChartPainter::backgroundPainter() const
+{
+ return m_backgroundPainter;
+}
+
+void XYChartPainter::setBackgroundPainter(XYChartBackgroundPainter* backgroundPainter)
+{
+ if (backgroundPainter != m_backgroundPainter)
+ {
+ m_backgroundPainter = backgroundPainter;
+ triggerUpdate();
+ emit backgroundPainterChanged();
+ }
+}
+
+int XYChartPainter::dimension() const
+{
+ return m_dimension;
+}
+
+void XYChartPainter::setDimension(int dimension)
+{
+ if (dimension != m_dimension)
+ {
+ m_dimension = dimension;
+ triggerUpdate();
+ emit dimensionChanged();
+ }
+}
+
+void XYChartPainter::paint(QPainter* painter)
+{
+ if (!m_xyChartCore || !m_backgroundPainter || m_dimension == -1)
+ return;
+
+ painter->setRenderHints(QPainter::Antialiasing, true);
+
+ Dimension* dimension = m_xyChartCore->dimensionsList().at(m_dimension);
+
+ QPolygonF line = m_backgroundPainter->linePolygons().at(m_dimension);
+
+ switch (dimension->lineStyle())
+ {
+ case Dimension::LineStyleSolid:
+ painter->setPen(QPen(QBrush(dimension->color()), m_xyChartCore->lineWidth()));
+ painter->drawPolyline(line);
+ break;
+ case Dimension::LineStyleDash:
+ painter->setPen(QPen(QBrush(dimension->color()), m_xyChartCore->lineWidth(), Qt::DashLine));
+ painter->drawPolyline(line);
+ break;
+ case Dimension::LineStyleNone:
+ // do nothing
+ break;
+ }
+}
+
+void XYChartPainter::triggerUpdate()
+{
+ if (!m_xyChartCore || !m_backgroundPainter || m_dimension == -1)
+ return;
+
+ update();
+}
diff --git a/src/xychartpainter.h b/src/xychartpainter.h
new file mode 100644
index 0000000..5fd7931
--- /dev/null
+++ b/src/xychartpainter.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2015 Jesper Hellesø Hansen <jesperhh@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ */
+#ifndef XYGRAPHPAINTER_H
+#define XYGRAPHPAINTER_H
+
+#include <QQuickPaintedItem>
+
+class XYChartCore;
+class XYChartBackgroundPainter;
+
+class XYChartPainter : public QQuickPaintedItem
+{
+ Q_OBJECT
+ Q_PROPERTY(XYChartCore* xyChartCore READ xyChartCore WRITE setXYChartCore NOTIFY xyChartCoreChanged)
+ Q_PROPERTY(XYChartBackgroundPainter* backgroundPainter READ backgroundPainter WRITE setBackgroundPainter NOTIFY backgroundPainterChanged)
+ Q_PROPERTY(int dimension READ dimension WRITE setDimension NOTIFY dimensionChanged)
+public:
+ explicit XYChartPainter(QQuickItem* parent = 0);
+ XYChartCore* xyChartCore() const;
+ void setXYChartCore(XYChartCore* xyChartCore);
+ XYChartBackgroundPainter* backgroundPainter() const;
+ void setBackgroundPainter(XYChartBackgroundPainter* backgroundPainter);
+ int dimension() const;
+ void setDimension(int dimension);
+ void paint(QPainter* painter);
+Q_SIGNALS:
+ void xyChartCoreChanged();
+ void backgroundPainterChanged();
+ void dimensionChanged();
+private Q_SLOTS:
+ void triggerUpdate();
+private:
+ XYChartCore* m_xyChartCore;
+ XYChartBackgroundPainter* m_backgroundPainter;
+ int m_dimension;
+};
+
+#endif // XYGRAPHPAINTER_H
diff --git a/src/xychartpoint.cpp b/src/xychartpoint.cpp
new file mode 100644
index 0000000..c15ea51
--- /dev/null
+++ b/src/xychartpoint.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2015 Jesper Hellesø Hansen <jesperhh@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ */
+
+#include "xychartpoint.h"
+
+#include <QAbstractTableModel>
+#include <QPainter>
+
+#include "xychartcore.h"
+#include "dimension.h"
+#include "xychartbackgroundpainter.h"
+
+XYChartPoint::XYChartPoint(QQuickItem* parent) :
+ QQuickPaintedItem(parent),
+ m_xyChartCore(0),
+ m_backgroundPainter(0),
+ m_dimension(-1),
+ m_row(-1)
+{
+ setFlag(QQuickItem::ItemHasContents, true);
+}
+
+XYChartCore* XYChartPoint::xyChartCore() const
+{
+ return m_xyChartCore;
+}
+
+void XYChartPoint::setXYChartCore(XYChartCore* xyChartCore)
+{
+ if (xyChartCore != m_xyChartCore)
+ {
+ if (m_xyChartCore)
+ {
+ m_xyChartCore->disconnect(this);
+ }
+
+ m_xyChartCore = xyChartCore;
+
+ if (m_xyChartCore)
+ {
+ connect(m_xyChartCore, SIGNAL(updated()), SLOT(triggerUpdate()));
+ }
+
+ triggerUpdate();
+ emit xyChartCoreChanged();
+ }
+}
+
+XYChartBackgroundPainter* XYChartPoint::backgroundPainter() const
+{
+ return m_backgroundPainter;
+}
+
+void XYChartPoint::setBackgroundPainter(XYChartBackgroundPainter* backgroundPainter)
+{
+ if (backgroundPainter != m_backgroundPainter)
+ {
+ if (m_backgroundPainter)
+ {
+ m_backgroundPainter->disconnect(this);
+ }
+
+ m_backgroundPainter = backgroundPainter;
+
+ if (m_backgroundPainter)
+ {
+ connect(m_backgroundPainter, SIGNAL(linePolygonsUpdated()), SLOT(triggerUpdate()));
+ }
+
+ triggerUpdate();
+ emit backgroundPainterChanged();
+ }
+}
+
+int XYChartPoint::dimension() const
+{
+ return m_dimension;
+}
+
+void XYChartPoint::setDimension(int dimension)
+{
+ if (dimension != m_dimension)
+ {
+ m_dimension = dimension;
+ triggerUpdate();
+ emit dimensionChanged();
+ }
+}
+
+int XYChartPoint::row() const
+{
+ return m_row;
+}
+
+void XYChartPoint::setRow(int row)
+{
+ if (row != m_row)
+ {
+ m_row = row;
+ triggerUpdate();
+ emit rowChanged();
+ }
+}
+
+QString XYChartPoint::text() const
+{
+ if (!m_xyChartCore)
+ return QString();
+
+ const int role = m_xyChartCore->textRole();
+
+ if (role == -1)
+ return QString();
+
+ QAbstractTableModel* model = m_xyChartCore->model();
+ Dimension* dimension = m_xyChartCore->dimensionsList().at(m_dimension);
+ const int column = dimension->dataColumn();
+
+ return model->data(model->index(m_row, column), role).toString();
+}
+
+void XYChartPoint::paint(QPainter* painter)
+{
+ if (!valid())
+ return;
+
+ const Dimension* dimension = m_xyChartCore->dimensionsList().at(m_dimension);
+ const qreal radius = m_xyChartCore->pointRadius();
+ painter->setRenderHints(QPainter::Antialiasing, true);
+
+
+ switch (dimension->markerStyle())
+ {
+ case Dimension::MarkerStyleNone:
+ // Do nothing
+ break;
+ case Dimension::MarkerStyleRound:
+ painter->setBrush(QBrush(dimension->color()));
+ painter->setPen(Qt::NoPen);
+ painter->drawEllipse(QPointF(radius, radius), radius, radius);
+ break;
+ case Dimension::MarkerStyleCross:
+ painter->setBrush(Qt::NoBrush);
+ QPen pen(dimension->color());
+ pen.setWidthF(m_xyChartCore->lineWidth());
+ painter->setPen(pen);
+ painter->drawLine(0.0, 0.0, radius * 2.0, radius * 2.0);
+ painter->drawLine(0.0, radius * 2.0, radius * 2.0, 0.0);
+ break;
+ }
+}
+
+void XYChartPoint::triggerUpdate()
+{
+ if (!valid())
+ return;
+ updateGeometry();
+ update();
+}
+
+void XYChartPoint::updateGeometry()
+{
+ const qreal radius = m_xyChartCore->pointRadius();
+ setWidth(2 * radius);
+ setHeight(2 * radius);
+ QPointF center = m_backgroundPainter->linePolygons().at(m_dimension).at(m_row);
+
+ setX(center.x() - radius);
+ setY(center.y() - radius);
+}
+
+bool XYChartPoint::valid() const
+{
+ if (!m_xyChartCore || !m_backgroundPainter || m_row == -1 || m_dimension == -1)
+ return false;
+ if (m_xyChartCore->dimensionsList().at(m_dimension)->markerStyle() == Dimension::MarkerStyleNone)
+ return false;
+ if (m_dimension >= m_backgroundPainter->linePolygons().count())
+ return false;
+ if (m_row >= m_backgroundPainter->linePolygons().at(m_dimension).count())
+ return false;
+ return true;
+}
diff --git a/src/xychartpoint.h b/src/xychartpoint.h
new file mode 100644
index 0000000..2d3f323
--- /dev/null
+++ b/src/xychartpoint.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015 Jesper Hellesø Hansen <jesperhh@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ */
+
+#ifndef XYGRAPHPOINT_H
+#define XYGRAPHPOINT_H
+
+#include <QQuickPaintedItem>
+
+class XYChartCore;
+class XYChartBackgroundPainter;
+
+class XYChartPoint : public QQuickPaintedItem
+{
+ Q_OBJECT
+ Q_PROPERTY(XYChartCore* xyChartCore READ xyChartCore WRITE setXYChartCore NOTIFY xyChartCoreChanged)
+ Q_PROPERTY(XYChartBackgroundPainter* backgroundPainter READ backgroundPainter WRITE setBackgroundPainter NOTIFY backgroundPainterChanged)
+ Q_PROPERTY(int dimension READ dimension WRITE setDimension NOTIFY dimensionChanged)
+ Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged)
+ Q_PROPERTY(QString text READ text NOTIFY textChanged)
+public:
+ explicit XYChartPoint(QQuickItem* parent = 0);
+ XYChartCore* xyChartCore() const;
+ void setXYChartCore(XYChartCore* xyChartCore);
+ XYChartBackgroundPainter* backgroundPainter() const;
+ void setBackgroundPainter(XYChartBackgroundPainter* backgroundPainter);
+ int dimension() const;
+ void setDimension(int dimension);
+ int row() const;
+ void setRow(int row);
+ QString text() const;
+ void paint(QPainter* painter);
+Q_SIGNALS:
+ void xyChartCoreChanged();
+ void backgroundPainterChanged();
+ void dimensionChanged();
+ void rowChanged();
+ void textChanged();
+ void maxYChanged();
+private Q_SLOTS:
+ void triggerUpdate();
+private:
+ void updateGeometry();
+ bool valid() const;
+ XYChartCore* m_xyChartCore;
+ XYChartBackgroundPainter* m_backgroundPainter;
+ int m_dimension;
+ int m_row;
+};
+
+#endif // XYGRAPHPOINT_H