ChartView wrapper
-
Hi all. I have wrapper for ChartView that looks like:
ChartWrapper.qml
:import QtQuick 2.9 import QtCharts 2.2 Item { property alias xAxisLabel: xAxisLabel.text property alias yAxisLabel: yAxisLabel.text Text { id: yAxisLabel y: parent.height - height text: "yAxis" color: "white" font { family: fontProvider.font pixelSize: 9 } transform: Rotation { angle: -90 } smooth: false antialiasing: false } Rectangle { id: clipRectangle anchors.top: parent.top anchors.bottom: parent.bottom anchors.left: yAxisLabel.right anchors.leftMargin: -5 anchors.right: xAxisLabel.left color: "red" clip: true ChartView { id: chart x: -34 y: -17 width: parent.width + 50 height: parent.height + 45 legend.visible: false backgroundColor: "black" ValueAxis { id: xAxis gridVisible: false minorGridVisible: false labelsVisible: false labelFormat: "" tickCount: 2 minorTickCount: 0 color: "white" } ValueAxis { id: yAxis gridVisible: false minorGridVisible: false labelsVisible: false labelFormat: "" tickCount: 2 minorTickCount: 0 color: "white" } // LineSeries { // axisX: xAxis // axisY: yAxis // color: "white" // XYPoint { x: 0; y: 0 } // XYPoint { x: 1.1; y: 2.1 } // XYPoint { x: 1.9; y: 3.3 } // XYPoint { x: 2.1; y: 2.1 } // XYPoint { x: 2.9; y: 4.9 } // XYPoint { x: 3.4; y: 3.0 } // XYPoint { x: 4.1; y: 3.3 } // } } } Text { id: xAxisLabel anchors.right: parent.right anchors.bottom: parent.bottom text: "xAxis" color: "white" font { family: fontProvider.font pixelSize: 9 } smooth: false antialiasing: false } }
and further i want to write something like:
main.qml
:Window { ChartWrapper { xAxisLabel: "x" yAxisLabel: "y" LineSeries { color: "white" XYPoint { x: 0; y: 0 } XYPoint { x: 1.1; y: 2.1 } XYPoint { x: 1.9; y: 3.3 } XYPoint { x: 2.1; y: 2.1 } XYPoint { x: 2.9; y: 4.9 } XYPoint { x: 3.4; y: 3.0 } XYPoint { x: 4.1; y: 3.3 } } } }
How can i achieve this?
-
@egor-utsov I understand the problem. If you want to do that, you must ensure that the ChartView component is the main component in your ChartWrapper.qml. I don't know if you are going to evaluate this kind of solution.
The other solution is about the data. I can see in this line:
XYPoint { x: 0; y: 0 } XYPoint { x: 1.1; y: 2.1 } XYPoint { x: 1.9; y: 3.3 } XYPoint { x: 2.1; y: 2.1 } XYPoint { x: 2.9; y: 4.9 } XYPoint { x: 3.4; y: 3.0 } XYPoint { x: 4.1; y: 3.3 }
that you are injecting data into your component with LineSeries component. Is it necessary for this structure? You can establish a new variant property in your ChartWrapper component and inject the data with this property. Or you can explore to apply the model-view-delegate paradigm to your solution. It's up to you. Good luck!
-
@egor.utsov said in ChartView wrapper:
How can i achieve this?
You can't. You must add/remove your series dynamically in that case.
The Qt graph examples are a bit useless because they mainly show statically defined series, as in your example. It is highly unlikely that anyone would ever write a Qt program to only show static data like that.In the end, you really need to generate and add the series dynamically, so you may as well start thinking dynamically from now on.
-
Hi @oria66, could you provide some examples for how to make ChartView main component of ChartWrapper and how to apply model-view-delegate here?
Hi @Diracsbracket . Yes, i tried to add series dynamically, but here another problem arise. After the series was changed, ChartView do not autoscale its area, like with statically added series. Is it possible to achieve same behaviour in dynamically case?
-
@egor.utsov said in ChartView wrapper:
ChartView do not autoscale its area, like with statically added series. Is it possible to achieve same behaviour in dynamically case
You may have to set the
min
andmax
properties of theaxisX
yourself (not sure whether it is required for theaxisY
too) at the time you add the series. -
@Diracsbracket Thank you for the answers. I will try it.
-
I ended up with the following solution
ClippedChart.qml
:Item { property alias xAxisLabel: xAxisLabel.text property alias yAxisLabel: yAxisLabel.text property var points // Add this property ... onPointsChanged: { chart.removeAllSeries(); var s = chart.createSeries(ChartView.SeriesTypeLine, "default", xAxis, yAxis); s.color = "white"; s.width = 1; var rightMost; var topMost; for (var i = 0; i < points.length; ++i) { var point = points[i]; s.append(points[i].x, points[i].y); if (!rightMost) { rightMost = point; } else { if (rightMost.x < point.x) rightMost = point; } if (!topMost) { topMost = point; } else { if (topMost.y < point.y) topMost = point; } } chart.axisX(s).min = 0.0; chart.axisX(s).max = rightMost.x; chart.axisY(s).min = 0.0; chart.axisY(s).max = topMost.y; } }
and then create instance of it like this
ClippedChart { id: fanSpeedGraph anchors.top: fanSwitch.bottom anchors.bottom: monitoringPane.bottom anchors.left: monitoringPane.left anchors.leftMargin: 2 anchors.right: monitoringPane.right anchors.rightMargin: 2 yAxisLabel: "speed" xAxisLabel: "t" points: [ Qt.point(0, 0), Qt.point(1.1, 2.1), Qt.point(1.9, 3.3), Qt.point(2.1, 2.1), Qt.point(2.9, 4.9), Qt.point(3.4, 3.0), Qt.point(4.1, 3.3) ] }