Dynamically create DateTimeAxis QML chart SplineSeries



  • I am using the below example to display date in the XAxis.
    ChartView {
    title: "Accurate Historical Data"
    anchors.fill: parent
    legend.visible: false
    antialiasing: true

    LineSeries {
        axisX: DateTimeAxis {
            format: "yyyy MMM"
            tickCount: 5
        }
        axisY: ValueAxis {
            min: 0
            max: 150
        }
    
        // Please note that month in JavaScript months are zero based, so 2 means March
        XYPoint { x: toMsecsSinceEpoch(new Date(1950, 2, 15)); y: 5 }
        XYPoint { x: toMsecsSinceEpoch(new Date(1970, 0, 1)); y: 50 }
        XYPoint { x: toMsecsSinceEpoch(new Date(1987, 12, 31)); y: 102 }
        XYPoint { x: toMsecsSinceEpoch(new Date(1998, 7, 1)); y: 100 }
        XYPoint { x: toMsecsSinceEpoch(new Date(2012, 8, 2)); y: 110 }
    }
    

    }

    // DateTimeAxis is based on QDateTimes so we must convert our JavaScript dates to
    // milliseconds since epoch to make them match the DateTimeAxis values
    function toMsecsSinceEpoch(date) {
    var msecs = date.getTime();
    return msecs;
    }

    Its worked fine.

    But i need to append the XYPoints from outside for chartview its not working.

    It will be very helpful, to give the solution.
    I have date format like 2018-01-04 and need to draw graph based on Date in the XAxis. How can i draw the Graph.



  • How you solved this ?Any Idea?



  • @Refi
    Apparently, the standard example shown above from the QML documentation does not work for dynamically populated LineSeries because the append(x,y) method of LineSeries seems to convert x and y to real values (even if you dynamically create an XYPoint e.g. as xypoint and then use something like lineSeries1.append(xypoint.x, xypoint.y)), while DateTimeAxis probably requires 64bit integer values which is not supported by JavaScript.

    You can use the append method if the X axis is also a ValueAxis of course.

    The only workaround for dynamically populating a LineSeries with a DateTimeAxis seems to be to do it via C++, e.g. as in this example:
    https://stackoverflow.com/questions/38467769/add-c-qabstractseries-to-qml-chartview



  • @Diracsbracket
    I tried with C++ based on the link you shared , But getting a graph like in the photo . X axis is repeatedly showing the same value with 1970. I used to take values from a QMap and appends to chart with code

        splineseries->append(i.key().toMSecsSinceEpoch(),i.value());
    

    sample value of i.key() is QDateTime(2018-07-15 22:00:16.000 India Standard Time Qt::TimeSpec(LocalTime)).

    0_1533392105803_35619ceb-a2b3-47b6-90c5-1edc53629f27-image.png


  • Lifetime Qt Champion

    Hi,

    Are you sure your QDateTime objects are valid ? How are you building them ?



  • This post is deleted!


  • @Refi
    Your post got me really confused now about why append() would not work in QML for dates in the first place. Reading more about how JavaScript represents numbers (which JS internally stores as 64-bit floating point numbers anyway, regardless of the number type) and the max. range of JS Date object, this conversion should pose no problem for the date ranges we are talking about.

    So I'm affraid that my poor attempt earlier to explain why append did not work was complete bullocks.

    It turns out that append does work, and that in my initial trial, I forgot one thing: to set the range of the Date axis to a correct value: failing to do that plots all "0" values, i.e. all 01 January, 1970 UTC values. I suspect that this is also why your C++ version does only show these 0 dates.

    Here is a working example in QML:

    0_1533443615867_6eaf264e-cb29-4687-8048-52527f8c7181-image.png

    Column {
            id: column
            Button {
                id: button
                text: "Add data"
                onClicked: {
                    series1.append(column.toMsecsSinceEpoch(new Date(1950, 2, 15)), 5)
                    series1.append(column.toMsecsSinceEpoch(new Date(1970, 0, 1)), 50)
                    series1.append(column.toMsecsSinceEpoch(new Date(1987, 12, 31)), 200)
                    series1.append(column.toMsecsSinceEpoch(new Date(1998, 7, 1)), 100)
                    series1.append(column.toMsecsSinceEpoch(new Date(2012, 8, 2)), 30)
    
                    series1.axisX.min = new Date(1950, 2, 15)
                    series1.axisX.max = new Date(2012, 8, 2)
                    series1.axisY.max = 250
                }
            }
    
    
            ChartView {
                title: "Accurate Historical Data"
                height: window.height - button.height
                width: window.width
                antialiasing: true
    
                LineSeries {
                    id: series1
    
                    axisX: DateTimeAxis {
                        format: "yyyy MMM"
                    }
                    axisY: ValueAxis {
                        min: 0
                        max: 150
                    }
                }
            }
    
            function toMsecsSinceEpoch(date) {
                var msecs = date.getTime();
                return msecs;
            }
        }
    

    Not setting the X range, gives the following plot which, before, led me to prematurely conclude that append did not work.

    0_1533443941576_7c282adf-f9d1-494a-94f8-5b1ff991ce40-image.png

    My apologies for unnecessarily misleading you onto the C++ path!



  • This post is deleted!


  • @SGaist
    @Diracsbracket
    Thank you for your consideration. Issue solved by setting min and max values



  • @Refi
    Great to hear. Don't forget to mark this topic as solved then!
    Edit: just realized that you didn't start this thread... :0



  • This post is deleted!

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.