Search code examples
qtqmlqt5qtcharts

Is it possible to create a sliding x-axis using QtCharts as done in Qwt?


I'm migrating a project that is using Qwt for plotting to QtCharts. I started testing QtCharts and see that I am not able to create an x-axis that's "sliding" like in Qwt. From the documentation I'm not able to see that this is supported in any way.

Does anyone know how this can be done with Qt Charts? Is it possible? How would one go about creating this from scratch?

I attached two videos of how this looks like in Qwt and what I did so far in QtCharts.

Code for the QtCharts example is shown below

import QtQuick 2.12
import QtCharts 2.3
import QtQuick.Controls 2.12
import QtQml 2.12

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Chart test")

    ChartView {
        id: chartView

        readonly property var startDate: new Date('1995-12-17T03:20:00')

        anchors.fill: parent
        antialiasing: true

        // The number of vertical tick lines to scroll to the right
        function scrollTicksRight(ticks) {
            chartView.scrollRight(axisX.tickDistance() * ticks)
        }

        Timer {
            property real hz: 25
            property real period: 1 / hz
            property real periodMs: period * 1000
            property int counter: 0
            property real sinusStep: 0

            function generateAndAppendPoint() {
                let x = chartView.startDate.getTime() + counter
                let y = 5 * Math.cos(sinusStep) + 5
                splineSeries.append(x, y)
                counter += periodMs
                sinusStep += 0.1

                if (x > axisX.max)
                    chartView.scrollRight(10)
            }

            interval: periodMs
            running: true
            repeat: true
            onTriggered: generateAndAppendPoint()
        }

        SplineSeries {
            id: splineSeries

            name: "Example Series"
            useOpenGL: true

            function newestPoint() {
                return splineSeries.at(splineSeries.count - 1)
            }

            axisX: DateTimeAxis {
                id: axisX

                // The distance between two vertical tick lines
                function tickDistance() {
                    return (chartView.plotArea.width / (axisX.tickCount - 1))
                }

                // Remove points that are no longer visible
                function removeOldPoints() {
                    let pointsToRemove = 0
                    let size = splineSeries.count
                    for (let i = 0; i < size; i++) {
                        if (splineSeries.at(i).x < min)
                            pointsToRemove++
                        else
                            break
                    }

                    splineSeries.removePoints(0, pointsToRemove)
                }

                tickCount: 11
                format: "yyyy-MM-dd hh:mm:ss"
                min: chartView.startDate
                max: new Date(chartView.startDate.getTime() + 10000)
                onMinChanged: removeOldPoints()
            }

            axisY: ValueAxis {
                min: 0
                max: 10
            }
        }
    }
}

Solution

  • It is possible. Have a look at the dynamic spline example The axis is adapted over time there.

    You can find it via Qt Creator > Welcome > Examples... Type in the filter "chart" and you will find it, next to other interesting ones.