diff --git a/examples/piechart/FpsItem.qml b/examples/piechart/FpsItem.qml new file mode 100644 index 0000000..bc5018b --- /dev/null +++ b/examples/piechart/FpsItem.qml @@ -0,0 +1,56 @@ +import QtQuick 2.0 + +Item { + id: root + property int frameCounter: 0 + property int frameCounterAvg: 0 + property int counter: 0 + property int fps: 0 + property int fpsAvg: 0 + width: 140 * dp + height: Math.floor(48 * dp) + + Image { + id: spinnerImage + anchors.verticalCenter: parent.verticalCenter + x: 4 * dp + width: 36 * dp + height: width + source: "images/spinner.png" + NumberAnimation on rotation { + from:0 + to: 360 + duration: 800 + loops: Animation.Infinite + } + onRotationChanged: frameCounter++; + } + + Text { + anchors.left: spinnerImage.right + anchors.leftMargin: 8 * dp + anchors.verticalCenter: spinnerImage.verticalCenter + color: "#c0c0c0" + //style: Text.Outline + //styleColor: "#606060" + font.pixelSize: 18 * dp + text: "Ø " + root.fpsAvg + " | " + root.fps + " fps" + } + + Timer { + interval: 2000 + repeat: true + running: true + onTriggered: { + frameCounterAvg += frameCounter; + root.fps = frameCounter/2; + counter++; + frameCounter = 0; + if (counter >= 3) { + root.fpsAvg = frameCounterAvg/(2*counter) + frameCounterAvg = 0; + counter = 0; + } + } + } +} diff --git a/examples/piechart/deployment.pri b/examples/piechart/deployment.pri new file mode 100644 index 0000000..5441b63 --- /dev/null +++ b/examples/piechart/deployment.pri @@ -0,0 +1,27 @@ +android-no-sdk { + target.path = /data/user/qt + export(target.path) + INSTALLS += target +} else:android { + x86 { + target.path = /libs/x86 + } else: armeabi-v7a { + target.path = /libs/armeabi-v7a + } else { + target.path = /libs/armeabi + } + export(target.path) + INSTALLS += target +} else:unix { + isEmpty(target.path) { + qnx { + target.path = /tmp/$${TARGET}/bin + } else { + target.path = /opt/$${TARGET}/bin + } + export(target.path) + } + INSTALLS += target +} + +export(INSTALLS) diff --git a/examples/piechart/images/spinner.png b/examples/piechart/images/spinner.png new file mode 100644 index 0000000..5c6eefd Binary files /dev/null and b/examples/piechart/images/spinner.png differ diff --git a/examples/piechart/main.cpp b/examples/piechart/main.cpp new file mode 100644 index 0000000..a9427a7 --- /dev/null +++ b/examples/piechart/main.cpp @@ -0,0 +1,16 @@ +#include +#include +#include "piechart.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); + + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + qmlRegisterType("PieChart", 1, 0, "PieChart"); + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + + return app.exec(); +} diff --git a/examples/piechart/main.qml b/examples/piechart/main.qml new file mode 100644 index 0000000..c94f9e7 --- /dev/null +++ b/examples/piechart/main.qml @@ -0,0 +1,1586 @@ +import QtQuick 2.4 +import QtQuick.Window 2.2 +import PieChart 1.0 +import "." +Window { + id: root + property real dp: Screen.pixelDensity * 25.4/160 + // This will be 1 on most platforms, 2 on iOS double retina, 3 on iPhone6 plus + property int dPRatio: Screen.devicePixelRatio + + visible: true + width: Screen.primaryOrientation === Qt.LandscapeOrientation ? 800:480 + height: Screen.primaryOrientation === Qt.LandscapeOrientation ? 480:800 + color: "#404040" + + Text { + id: textItem + anchors.horizontalCenter: parent.horizontalCenter + y: parent.height * 0.01 + font.pixelSize: parent.width * 0.015 + color: "lightgray" + text: "Here are some piecharts" + } + + ListModel { + id: pieModel1 + + ListElement { + color: "#99e600" + value: 21 + } + ListElement { + color: "#99cc00" + value: 18 + } + ListElement { + color: "#99b300" + value: 14 + } + ListElement { + color: "#9f991a" + value: 13 + } + ListElement { + color: "#a48033" + value: 13 + } + ListElement { + color: "#a9664d" + value: 13 + } + ListElement { + color: "ae4d66" + value: 12 + } + ListElement { + color: "#b33380" + value: 11 + } + ListElement { + color: "#a64086" + value: 9 + } + ListElement { + color: "#994d8d" + value: 9 + } + ListElement { + color: "#8d5a93" + value: 7 + } + ListElement { + color: "806699" + value: 6 + } + ListElement { + color: "#8073a6" + value: 4 + } + ListElement { + color: "#8080b3" + value:38 + } + } + ListModel { + id: pieModel2 + + ListElement { + color: "black" + value: 5 + } + ListElement { + color: "red" + value: 15 + } + ListElement { + color: "blue" + value: 10 + } + ListElement { + color: "gray" + value: 15 + } + ListElement { + color: "green" + value: 20 + } + ListElement { + color: "lightcyan" + value: 25 + } + ListElement { + color: "lemonchiffon" + value: 30 + } + ListElement { + color: "limegreen" + value: 35 + } + ListElement { + color: "salmon" + value: 15 + } + } + ListModel { + id: pieModel3 + + ListElement { + color: "navy" + value: 1 + } + ListElement { + color: "oldlace" + value: 2 + } + ListElement { + color: "orchid" + value: 3 + } + ListElement { + color: "royalblue" + value: 4 + } + ListElement { + color: "firebrick" + value: 5 + } + ListElement { + color: "darkseagreen" + value: 6 + } + ListElement { + color: "cornsilk" + value: 7 + } + ListElement { + color: "cadetblue" + value: 8 + } + ListElement { + color: "burlywood" + value: 9 + } + } + Flickable { + anchors.top: textItem.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + contentWidth: grid.width; contentHeight: grid.height + Grid { + id: grid + columns: width / 80 + spacing: 0 + width: root.width + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + segmentStrokeWidth: 4 + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1200 + easing.type: Easing.Linear + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + easing.type: Easing.Linear + duration: 1200 + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: false + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 3000 + easing.type: Easing.Linear + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 550 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 500 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 250 + easing.type: Easing.InSine + to: 100 + } + PauseAnimation { + duration: 100 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 3000 + easing.type: Easing.Linear + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + duration: 1750 + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + segmentStrokeColor: "lightgray" + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: false + animateScale: true + segmentShowStroke:false + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutSine + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + segmentStrokeWidth:3 + segmentStrokeColor: "black" + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 250 + easing.type: Easing.InSine + to: 100 + } + PauseAnimation { + duration: 100 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + segmentShowStroke:false + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 3000 + easing.type: Easing.Linear + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + duration: 1750 + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + segmentStrokeColor:"darkblue" + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: false + animateScale: true + segmentShowStroke:false + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutSine + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 250 + easing.type: Easing.InSine + to: 100 + } + PauseAnimation { + duration: 100 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 3000 + easing.type: Easing.Linear + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + duration: 1750 + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: false + animateScale: true + + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutSine + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + segmentStrokeWidth: 4 + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1200 + easing.type: Easing.Linear + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + easing.type: Easing.Linear + duration: 1200 + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: false + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 3000 + easing.type: Easing.Linear + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 550 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 500 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 250 + easing.type: Easing.InSine + to: 100 + } + PauseAnimation { + duration: 100 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 3000 + easing.type: Easing.Linear + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + duration: 1750 + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + segmentStrokeColor: "lightgray" + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: false + animateScale: true + segmentShowStroke:false + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutSine + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + segmentStrokeWidth:3 + segmentStrokeColor: "black" + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 250 + easing.type: Easing.InSine + to: 100 + } + PauseAnimation { + duration: 100 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + segmentShowStroke:false + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 3000 + easing.type: Easing.Linear + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + duration: 1750 + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + segmentStrokeColor:"darkblue" + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: false + animateScale: true + segmentShowStroke:false + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutSine + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 250 + easing.type: Easing.InSine + to: 100 + } + PauseAnimation { + duration: 100 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 3000 + easing.type: Easing.Linear + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + duration: 1750 + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: false + animateScale: true + segmentShowStroke:false + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutSine + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 250 + easing.type: Easing.InSine + to: 100 + } + PauseAnimation { + duration: 100 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + + PieChart { + model: pieModel3 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: true + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 750 + easing.type: Easing.OutBounce + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + PieChart { + model: pieModel1 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: true + animateScale: false + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutElastic + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + + PieChart { + model: pieModel2 + width:(parent.width - 2*parent.spacing)/parent.columns + height: width + animation: true + animateRotate: false + animateScale: true + + + SequentialAnimation on animationProgress { + loops: Animation.Infinite + PropertyAnimation { + duration: 1500 + easing.type: Easing.OutSine + to: 100 + } + PauseAnimation { + duration: 1000 + } + PropertyAnimation { + to: 0 + } + } + } + } + } + FpsItem { + id: fpsItem + } + +} diff --git a/examples/piechart/piechart.cpp b/examples/piechart/piechart.cpp new file mode 100644 index 0000000..e979a75 --- /dev/null +++ b/examples/piechart/piechart.cpp @@ -0,0 +1,167 @@ +#include "piechart.h" +#include + +void PieChartPainter::synchronize(QNanoQuickItem *item) +{ + // Setting values here synchronized + PieChart *realItem = static_cast(item); + if (realItem) { + m_animation = realItem->animation(); + m_animationProgress = realItem->animationProgress()/100.0; + m_animateScale = realItem->animateScale(); + m_animateRotate = realItem->animateRotate(); + m_segmentShowStroke = realItem->segmentShowStroke(); + m_segmentStrokeColor = QNanoColor::fromQColor(realItem->segmentStrokeColor()); + m_segmentStrokeWidth = realItem->segmentStrokeWidth(); + m_percentageInnerCutout = realItem->percentageInnerCutout(); + m_data = realItem->data(&m_totalValue); + + } +} + + +void PieChartPainter::paint(QNanoPainter *p) +{ + qreal pieRadius = qMin(height()/2,width()/2) - 5; + + qreal cumulativeAngle = -M_PI_2; + + qreal scaleAnimation = 1; + qreal rotateAnimation = 1; + + if (m_animation) { + if (m_animateScale) { + scaleAnimation = m_animationProgress; + } + if (m_animateRotate) { + rotateAnimation = m_animationProgress; + } + } + + for (auto it = m_data.cbegin(); it != m_data.cend(); ++it) { + qreal segmentAngle = rotateAnimation * ((it->m_value/m_totalValue) * (M_PI*2)); + p->beginPath(); + p->arc(width()/2,height()/2,scaleAnimation * pieRadius,cumulativeAngle,cumulativeAngle + segmentAngle); + p->lineTo(width()/2,height()/2); + p->closePath(); + p->setFillStyle(it->m_color); + p->fill(); + if(m_segmentShowStroke) { + p->setLineJoin(QNanoPainter::JOIN_ROUND); + p->setLineWidth(m_segmentStrokeWidth); + p->setStrokeStyle(m_segmentStrokeColor); + p->stroke(); + } + cumulativeAngle += segmentAngle; + } + + QLatin1String text("PieChart"); + QRectF box = p->textBoundingBox(text,0,0); + p->setTextAlign(QNanoPainter::ALIGN_CENTER); + box.setWidth(width()); + box.setY(box.height()); + QNanoFont f; + f.setPixelSize(25); + f.setBlur(2); + p->setFont(f); + p->setFillStyle(0xFFf8f8f8); + p->fillText(text,box); + f.setBlur(0); + p->setFont(f); + p->setFillStyle(0xFF000000); + p->fillText(text,box); + + +} + + +PieChart::PieChart(QQuickItem *parent) + : QNanoQuickItem(parent) + ,m_segmentShowStroke(true) + ,m_animation(false) + ,m_animateScale(false) + ,m_animateRotate(false) + ,m_animationProgress(0) + ,m_segmentStrokeColor("#fff") + ,m_segmentStrokeWidth(2.0) + ,m_percentageInnerCutout(50.0) + ,m_model(0) + ,m_dataSourceIsObject(false) + +{ + m_data.push_back(PieChartPainter::Data(10,QNanoColor::fromQColor(Qt::green))); + m_data.push_back(PieChartPainter::Data(20,QNanoColor::fromQColor(Qt::darkBlue))); + m_data.push_back(PieChartPainter::Data(40,QNanoColor::fromQColor(Qt::magenta))); + m_data.push_back(PieChartPainter::Data(50,QNanoColor::fromQColor(Qt::darkGray))); + m_data.push_back(PieChartPainter::Data(30,QNanoColor::fromQColor(Qt::red))); + m_data.push_back(PieChartPainter::Data(90,QNanoColor::fromQColor(Qt::blue))); + m_data.push_back(PieChartPainter::Data(70,QNanoColor::fromQColor(Qt::darkYellow))); + updateTotalValue(); +} + +PieChart::~PieChart() +{ +} +QVariant PieChart::model() const +{ + + if (m_dataSourceIsObject) { + QObject *o = m_model; + return QVariant::fromValue(o); + } + + return m_dataSource; +} + +void PieChart::setModel(const QVariant &m) +{ + QVariant model = m; + if (model.userType() == qMetaTypeId()) + model = model.value().toVariant(); + + if (m_dataSource == model) + return; + + if (m_model) { + disconnect(m_model.data(), &QAbstractListModel::dataChanged, + this, &PieChart::dataChanged); + } + m_dataSource = model; + QObject *object = qvariant_cast(model); + m_dataSourceIsObject = object != 0; + QAbstractListModel *alm = 0; + if (object && (alm = qobject_cast(object))) { + m_model = alm; + } + if (m_model) { + connect(m_model.data(), &QAbstractListModel::dataChanged, + this, &PieChart::dataChanged); + updateData(); + } + emit modelChanged(); +} + +void PieChart::updateData() { + QVariant m = model(); + QObject *object = qvariant_cast(m); + QAbstractListModel *alm = 0; + if (object && (alm = qobject_cast(object))) { + m_data.clear(); + int roleValue = alm->roleNames().key(QByteArray("value")); + int roleColor = alm->roleNames().key(QByteArray("color")); + + for (int row = 0; row < alm->rowCount(); ++row) { + QModelIndex index = alm->index(row); + QString color = alm->data(index,roleColor).value(); + double value = alm->data(index,roleValue).toDouble(); + m_data.push_back(PieChartPainter::Data(value,QNanoColor::fromQColor(QColor(color)))); + } + } + updateTotalValue(); + update(); +} + +void PieChart::dataChanged(const QModelIndex & /*topLeft*/, const QModelIndex & /*bottomRight*/, const QVector & /*roles*/) +{ + updateData(); +} diff --git a/examples/piechart/piechart.h b/examples/piechart/piechart.h new file mode 100644 index 0000000..9af2f9e --- /dev/null +++ b/examples/piechart/piechart.h @@ -0,0 +1,108 @@ +#ifndef PIECHART +#define PIECHART + +#include "qnanoquickitem.h" +#include "qnanoquickitempainter.h" +#include +#include + +// PieChartPainter contains the painting code +class PieChartPainter : public QNanoQuickItemPainter +{ +public: + PieChartPainter() + { + + } + void synchronize(QNanoQuickItem *item); + void paint(QNanoPainter *p); + + class Data { + public: + Data() + :m_value(0) + {} + Data(qreal v,const QNanoColor & c) + :m_value(v) + ,m_color(c) + {} + + public: + qreal m_value; + QNanoColor m_color; + }; +private: + qreal m_animationProgress; + bool m_animation; + bool m_animateScale; + bool m_animateRotate; + bool m_segmentShowStroke; + QNanoColor m_segmentStrokeColor; + qreal m_segmentStrokeWidth; + qreal m_percentageInnerCutout; + QVector m_data; + qreal m_totalValue; +}; +#define PIE_PROPERTY(type,name) QNANO_PROPERTY(type, m_##name, name, set##name) + +// PieChart provides the API towards QML + +class PieChart : public QNanoQuickItem +{ + Q_OBJECT + PIE_PROPERTY(bool,segmentShowStroke) + PIE_PROPERTY(bool,animation) + PIE_PROPERTY(bool,animateScale) + PIE_PROPERTY(bool,animateRotate) + PIE_PROPERTY(int,animationProgress) + PIE_PROPERTY(QColor,segmentStrokeColor) + PIE_PROPERTY(qreal,segmentStrokeWidth) + PIE_PROPERTY(qreal,percentageInnerCutout) + + Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged) + + QVector m_data; + qreal m_totalValue; + QPointer m_model; + QVariant m_dataSource; + bool m_dataSourceIsObject : 1; + +public: + PieChart(QQuickItem *parent = 0); + ~PieChart(); + // Reimplement + QNanoQuickItemPainter *createItemPainter() const + { + // Create painter for this item + return new PieChartPainter(); + } + + QVariant model() const; + void setModel(const QVariant &); + + QVector data(qreal * ptotalValue) { + *ptotalValue = m_totalValue; + return m_data; + } +protected: + + void updateData(); + void updateTotalValue() { + m_totalValue = 0.0; + for (auto it = m_data.cbegin(); it != m_data.cend(); ++it) { + m_totalValue += it->m_value; + } + + } + +Q_SIGNALS: + void modelChanged(); + +private Q_SLOTS: + void dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector & roles ); + + +}; + +#endif // PIECHART + diff --git a/examples/piechart/piechart.pro b/examples/piechart/piechart.pro new file mode 100644 index 0000000..2306246 --- /dev/null +++ b/examples/piechart/piechart.pro @@ -0,0 +1,19 @@ +TEMPLATE = app +QT += qml quick + +SOURCES += main.cpp \ + piechart.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Include QNanoPainter +include(../../libqnanopainter/include.pri) + +# Default rules for deployment. +include(deployment.pri) + +HEADERS += \ + piechart.h diff --git a/examples/piechart/qml.qrc b/examples/piechart/qml.qrc new file mode 100644 index 0000000..ce1633c --- /dev/null +++ b/examples/piechart/qml.qrc @@ -0,0 +1,7 @@ + + + main.qml + FpsItem.qml + images/spinner.png + + diff --git a/qnanopainter.pro b/qnanopainter.pro index baf6900..eb522ec 100644 --- a/qnanopainter.pro +++ b/qnanopainter.pro @@ -3,6 +3,7 @@ TEMPLATE = subdirs SUBDIRS += \ examples/qnanopainter_vs_qpainter_demo \ examples/gallery \ + examples/piechart \ examples/helloitem \ examples/hellowindow \ examples/hellowidget