0

Item是否可以在 Qt 图表或其他 3rd 方库中为可拖动点(即s、图标、Rectangles 等)使用自定义委托,MapItemView例如在 Qt Location forMapQuickItem及其delegate属性中很容易实现?或者可以使用 和 的一些组合来PathView达到ChartView这个目的?PathViewinsideChartView可能是一个解决方案,但可能需要将图表坐标转换为屏幕坐标:也不确定是否ChartView有方法。需要制作一些模型来检查这一点。没有找到任何有关的文档或样本。应该是显而易见的和简单的,就像它在 Qt Location 中实现的一样,但是由于某些原因它没有为 Qt Charts 实现。

理想的方式可能是Map使用来自 Qt Location 的元素,我有我需要的所有内容:MapItemViewMapQuickItem或者用于图形MapPolygonMapPolyline因为我有制图信息要绘制。但又是两个问题:

  • 如何绘制轴:X - 距离公里,Y - 高度
  • 如何绘制图表网格
  • 如何绘制自定义 2D BarSeries 模仿地形高程(MapPolygon但是可能)。

是否可以在这里动态绘制一些自定义地图?有任何想法吗?

示例图表/地形海拔

4

1 回答 1

0

ChartView找到了具有Repeater内部和ChartView映射功能的简单而优雅的解决方案:mapToPositionmapToValue轻松映射图表<->屏幕坐标。

小样:

import QtQuick 2.12
import QtCharts 2.3

Item {
    visible: true
    width: 640
    height: 480

    ChartView {
        id: chart
        anchors.fill: parent
        antialiasing: true

        ValueAxis {
            id: xAxis
            min: 0
            max: 1100
            tickCount: 12
            labelFormat: "%.0f"
        }

        ValueAxis {
            id: yAxis
            min: -50
            max: 200
            tickInterval: 50
            labelFormat: "%.0f"
        }

        ListModel {
            id: lineModel
            ListElement { x: 50; y: 155; }
            ListElement { x: 138; y: 175 }
            ListElement { x: 193; y: 50 }
            ListElement { x: 271; y: 90 }
            ListElement { x: 295; y: 90 }
            ListElement { x: 383; y: 150 }
            ListElement { x: 529; y: 100 }
            ListElement { x: 665; y: 150 }
            ListElement { x: 768; y: 90 }
            ListElement { x: 794; y: 90 }
            ListElement { x: 851; y: 50 }
            ListElement { x: 875; y: 50 }
            ListElement { x: 925; y: 175 }
            ListElement { x: 1060; y: 125 }
        }

        ListModel {
            id: areaModel
            ListElement { x: 0; y: 100 }
            ListElement { x: 138; y: 125 }
            ListElement { x: 193; y: 0 }
            ListElement { x: 271; y: 40 }
            ListElement { x: 295; y: 40 }
            ListElement { x: 383; y: 100 }
            ListElement { x: 529; y: 50 }
            ListElement { x: 665; y: 100 }
            ListElement { x: 768; y: 40 }
            ListElement { x: 794; y: 40 }
            ListElement { x: 851; y: 0 }
            ListElement { x: 875; y: 0 }
            ListElement { x: 925; y: 125 }
            ListElement { x: 1060; y: 75 }
            ListElement { x: 1100; y: 60 }
        }

        AreaSeries {
            name: "Terrain"
            axisX: xAxis
            axisY: yAxis
            borderColor: color
            upperSeries: LineSeries {
                id: areaSeries
            }
        }

        LineSeries {
            id: lineSeries
            name: "Flying path"
            axisX: xAxis
            axisY: yAxis
        }

        function adjustPosition(item, index) {
            let point = Qt.point(lineModel.get(index).x, lineModel.get(index).y)
            let position = chart.mapToPosition(point, lineSeries)
            item.x = position.x - item.width / 2
            item.y = position.y - item.height / 2
        }

        function adjustValue(item, index) {
            let position = Qt.point(item.x + item.width / 2, item.y + item.height / 2)
            let point = chart.mapToValue(position, lineSeries)
            lineModel.setProperty(index, "y", point.y)  // Change only Y-coordinate
            lineSeries.replace(lineSeries.at(index).x, lineSeries.at(index).y, // old
                               lineSeries.at(index).x, point.y)                // new
        }

        Repeater {
            model: lineModel

            Rectangle {
                id: indicator
                radius: 100
                width: radius / 2
                height: width
                color: "red"

                property real parentWidth: chart.width
                property real parentHeight: chart.height

                onParentWidthChanged: chart.adjustPosition(this, index)
                onParentHeightChanged: chart.adjustPosition(this, index)

                onYChanged: {
                    if(mouseArea.drag.active) {
                        chart.adjustValue(this, index)
                    }
                }

                Image {
                    id: waypoint
                    anchors.centerIn: parent
                    source: index ? "qrc:/waypoint.svg" : "qrc:/home.svg"
                }

                MouseArea {
                    id: mouseArea
                    anchors.fill: parent
                    drag.target: indicator
                    drag.axis: Drag.YAxis
                    preventStealing: true
                }
            }
        }

        Component.onCompleted: {
            lineSeries.clear()
            areaSeries.clear()
            for(let i = 0; i < lineModel.count; i++) {
                lineSeries.append(lineModel.get(i).x, lineModel.get(i).y)
            }

            for(let j = 0; j < areaModel.count; j++) {
                areaSeries.append(areaModel.get(j).x, areaModel.get(j).y)
            }
        }
    }
}

HXYModelMapper欢迎任何改进、优化和建议,例如通过/VXYModelMapper而不是 JS 模型填充的模型绑定。将修复答案。

结果截图:

在此处输入图像描述

于 2020-02-20T02:15:11.113 回答