Use repeater inside chartview
-
wrote on 18 Jun 2020, 12:53 last edited by
Hi, can anyone help me on the following?
In a qml file trying to dynamically create AreaSeries objects. Try to get this working but the only result is an empty window, without any significant application output or debugging error information what is going wrong. No chartobject or graphics are shown.
The data in the ListModel defined is a first step. Second step (after this concept appears to be working) will be removing the ListModel out of the qml, and placing it in the C++ environment. Code:
ChartView {
id: chartid
antialiasing: true//Valueaxis ValueAxis{ id:xAxis; min: 0; max: 40000; tickCount: 9 } ValueAxis{ id:yAxis; min: -200; max: 1400; tickCount: 17 } //Listmodel only for testing AreaSeries/Repeater concept ListModel{ id: listModel ListElement { x1: 18000; x2: 18200 ; y1: -100; y2: 400 } ListElement { x1: 25000; x2: 25200 ; y1: -100; y2: 1000 } ListElement { x1: 31000; x2: 31200 ; y1: -100; y2: 1200 } ListElement { x1: 39500; x2: 39700 ; y1: -100; y2: 1250 } } Repeater{ id: areaSeriesRepeater model: listModel delegate: Item{ AreaSeries { axisX: xAxis axisY: yAxis color: "grey" borderColor: "black" borderWidth: 2 upperSeries: LineSeries { XYPoint { x: model.x1 ; y: model.y2 } XYPoint { x: model.x2 ; y: model.y2 } } lowerSeries: LineSeries { XYPoint { x: model.x1 ; y: model.y1 } XYPoint { x: model.x2 ; y: model.y1 } } } } } }
-
wrote on 22 Jun 2020, 10:47 last edited by
Hereby a solution that works for me. Instead of using a repeater, this codesample works with the ChartView's onCompleted signal handler. In the onCompleted handler first three LineSeries are dynamically created, then an AreaSeries is created.
ChartView { id: chartid anchors.fill: parent antialiasing: true //Valueaxis ValueAxis{ id:xAxis; min: 0; max: 40000; tickCount: 9 } ValueAxis{ id:yAxis; min: -200; max: 1400; tickCount: 17 } //Listmodel only for testing Area- and LineSeries concept ListModel{ id: listModel ListElement { x1: 18000; y1: -100; x2: 18000 ; y2: 400 } ListElement { x1: 25000; y1: -100; x2: 25000 ; y2: 1000 } ListElement { x1: 31000; y1: -100; x2: 31000 ; y2: 1200 } ListElement { x1: 36500; y1: -100; x2: 39700 ; y2: 1250 } } Component.onCompleted: { var count = listModel.count; for(var i = 0;i < count;i ++) { if (i < count - 1) // add LineSeries { var lineTypeSeries = chartid.createSeries(ChartView.SeriesTypeLine, "line" + i, xAxis, yAxis); lineTypeSeries.color = "black"; lineTypeSeries.width = 2; lineTypeSeries.borderWidth = 0; lineTypeSeries.append(listModel.get(i).x1, listModel.get(i).y1); lineTypeSeries.append(listModel.get(i).x2, listModel.get(i).y2); } else { var areaTypeSeries = chartid.createSeries(ChartView.SeriesTypeArea, "area" + i, xAxis, yAxis); areaTypeSeries.pointsVisible = true; areaTypeSeries.color = "lightgrey"; areaTypeSeries.borderColor = "black"; areaTypeSeries.borderWidth = 2; areaTypeSeries.lowerSeries = chartid.createSeries(ChartView.SeriesTypeLine, "lowerSerie"); areaTypeSeries.lowerSeries.width = 0; areaTypeSeries.lowerSeries.borderWidth = 0; areaTypeSeries.lowerSeries.color = areaTypeSeries.borderColor; areaTypeSeries.lowerSeries.capStyle = 0x00; areaTypeSeries.lowerSeries.append(listModel.get(i).x1, listModel.get(i).y1); areaTypeSeries.lowerSeries.append(listModel.get(i).x2, listModel.get(i).y1); areaTypeSeries.upperSeries.append(listModel.get(i).x1, listModel.get(i).y2); areaTypeSeries.upperSeries.append(listModel.get(i).x2, listModel.get(i).y2); } } } }
-
wrote on 18 Jun 2020, 14:52 last edited by
Why is AreaSeries inside an Item?
-
wrote on 19 Jun 2020, 08:00 last edited by
If you don't place it inside an item object you get run time error: popup messagebox reporting a "Read access violation" and the application output windows says "QML Component: Delegate must be of Item type".
When using the Item object, no errors are reported, looks good, but application window (chartview) stays completely empty.
-
wrote on 19 Jun 2020, 15:55 last edited by
I think you will have to find another way to do this.
I tried this:
ChartView { id: chartid antialiasing: true width: parent.width height: 500 //Valueaxis ValueAxis{ id:xAxis; min: 0; max: 40000; tickCount: 9 } ValueAxis{ id:yAxis; min: -200; max: 1400; tickCount: 17 } //Listmodel only for testing AreaSeries/Repeater concept ListModel{ id: listModel ListElement { x1: 18000; x2: 18200 ; y1: -100; y2: 400 } ListElement { x1: 25000; x2: 25200 ; y1: -100; y2: 1000 } ListElement { x1: 31000; x2: 31200 ; y1: -100; y2: 1200 } ListElement { x1: 39500; x2: 39700 ; y1: -100; y2: 1250 } } Repeater{ id: areaSeriesRepeater model: listModel delegate: Item{ AreaSeries { id: areaseries axisX: xAxis axisY: yAxis color: "grey" borderColor: "black" borderWidth: 2 upperSeries: LineSeries { XYPoint { x: model.x1 ; y: model.y2 } XYPoint { x: model.x2 ; y: model.y2 } } lowerSeries: LineSeries { XYPoint { x: model.x1 ; y: model.y1 } XYPoint { x: model.x2 ; y: model.y1 } } Component.onCompleted: { chartid.children.push(areaseries) } } } } }
But this causes a segfault. I think the problem is that AreaSeries is not a direct child of ChartView.
-
wrote on 22 Jun 2020, 05:56 last edited by
Thnx for your idea's. I'm also working on a solution via the onCompleted signal handler. First result looks promising. I'll work it out some further, and when usefull I'll post it here. In the meantime if anyone has any idea's how handle this in a proper way, please share it.
-
wrote on 22 Jun 2020, 10:47 last edited by
Hereby a solution that works for me. Instead of using a repeater, this codesample works with the ChartView's onCompleted signal handler. In the onCompleted handler first three LineSeries are dynamically created, then an AreaSeries is created.
ChartView { id: chartid anchors.fill: parent antialiasing: true //Valueaxis ValueAxis{ id:xAxis; min: 0; max: 40000; tickCount: 9 } ValueAxis{ id:yAxis; min: -200; max: 1400; tickCount: 17 } //Listmodel only for testing Area- and LineSeries concept ListModel{ id: listModel ListElement { x1: 18000; y1: -100; x2: 18000 ; y2: 400 } ListElement { x1: 25000; y1: -100; x2: 25000 ; y2: 1000 } ListElement { x1: 31000; y1: -100; x2: 31000 ; y2: 1200 } ListElement { x1: 36500; y1: -100; x2: 39700 ; y2: 1250 } } Component.onCompleted: { var count = listModel.count; for(var i = 0;i < count;i ++) { if (i < count - 1) // add LineSeries { var lineTypeSeries = chartid.createSeries(ChartView.SeriesTypeLine, "line" + i, xAxis, yAxis); lineTypeSeries.color = "black"; lineTypeSeries.width = 2; lineTypeSeries.borderWidth = 0; lineTypeSeries.append(listModel.get(i).x1, listModel.get(i).y1); lineTypeSeries.append(listModel.get(i).x2, listModel.get(i).y2); } else { var areaTypeSeries = chartid.createSeries(ChartView.SeriesTypeArea, "area" + i, xAxis, yAxis); areaTypeSeries.pointsVisible = true; areaTypeSeries.color = "lightgrey"; areaTypeSeries.borderColor = "black"; areaTypeSeries.borderWidth = 2; areaTypeSeries.lowerSeries = chartid.createSeries(ChartView.SeriesTypeLine, "lowerSerie"); areaTypeSeries.lowerSeries.width = 0; areaTypeSeries.lowerSeries.borderWidth = 0; areaTypeSeries.lowerSeries.color = areaTypeSeries.borderColor; areaTypeSeries.lowerSeries.capStyle = 0x00; areaTypeSeries.lowerSeries.append(listModel.get(i).x1, listModel.get(i).y1); areaTypeSeries.lowerSeries.append(listModel.get(i).x2, listModel.get(i).y1); areaTypeSeries.upperSeries.append(listModel.get(i).x1, listModel.get(i).y2); areaTypeSeries.upperSeries.append(listModel.get(i).x2, listModel.get(i).y2); } } } }
6/6