QML QtCharts CandlestickSeries.append() returns false

Viewed 126

Trying to populate a CandlestickSeries via JavaScript (data comes from a custom QObject dataProvider):

Connections {
    target: dataProvider
    function onDataChanged() {
        for(var i = 0; i < dataProvider.data.length; i++) {
            var x = dataProvider.data[i]
            var jsobj = {timestamp: x.timestamp, open: x.open, high: x.high, low: x.low, close: x.close}
            if(!serie1.append(jsobj))
                console.log('append failed:', JSON.stringify(jsobj))
        }
    }
}

ChartView {
    title: "Candlestick Series"
    width: 400
    height: 300

    CandlestickSeries {
        id: serie1
        name: "Acme Ltd."
        increasingColor: "green"
        decreasingColor: "red"
    }
}

The call to .append() fails for every data point:

qml: append failed: {"timestamp":1514764800,"open":11993.6,"high":11995.2,"low":11676,"close":11807.6}
qml: append failed: {"timestamp":1514768400,"open":11807.5,"high":11908.4,"low":11501,"close":11561.1}
qml: append failed: {"timestamp":1514772000,"open":11561.1,"high":11700,"low":11423.5,"close":11648.6}
qml: append failed: {"timestamp":1514775600,"open":11620.6,"high":11843.4,"low":11519.3,"close":11567.5}
qml: append failed: {"timestamp":1514779200,"open":11596.5,"high":11809.7,"low":11505.9,"close":11790.7}
qml: append failed: {"timestamp":1514782800,"open":11790.6,"high":11809.9,"low":11699.5,"close":11699.6}
qml: append failed: {"timestamp":1514786400,"open":11699.1,"high":11890.3,"low":11639.6,"close":11886.6}
qml: append failed: {"timestamp":1514790000,"open":11867.4,"high":11949.9,"low":11770.2,"close":11830.3}
qml: append failed: {"timestamp":1514793600,"open":11807.5,"high":11822.5,"low":11461.9,"close":11559.6}
qml: append failed: {"timestamp":1514797200,"open":11582.6,"high":11807.2,"low":11543.5,"close":11743.6}
qml: append failed: {"timestamp":1514800800,"open":11710.8,"high":11777,"low":11582.2,"close":11592.9}
qml: append failed: {"timestamp":1514804400,"open":11592.9,"high":11598,"low":11250,"close":11400.1}
qml: append failed: {"timestamp":1514808000,"open":11412.1,"high":11440,"low":11376.2,"close":11414.7}
qml: append failed: {"timestamp":1514811600,"open":11413.6,"high":11434.4,"low":11180.3,"close":11217.5}
qml: append failed: {"timestamp":1514815200,"open":11210.1,"high":11457.4,"low":11090,"close":11410}
qml: append failed: {"timestamp":1514818800,"open":11457.2,"high":11470,"low":11300.1,"close":11437.9}
qml: append failed: {"timestamp":1514822400,"open":11426.5,"high":11426.6,"low":11257.5,"close":11310.8}
qml: append failed: {"timestamp":1514826000,"open":11310.5,"high":11439.9,"low":11300,"close":11378.1}
qml: append failed: {"timestamp":1514829600,"open":11378,"high":11470,"low":11300,"close":11391.6}
qml: append failed: {"timestamp":1514833200,"open":11391.6,"high":11469.9,"low":11335,"close":11455.8}
qml: append failed: {"timestamp":1514836800,"open":11455.8,"high":11639,"low":11360,"close":11434.1}
qml: append failed: {"timestamp":1514840400,"open":11455,"high":11588,"low":11434,"close":11498.9}
qml: append failed: {"timestamp":1514844000,"open":11495.6,"high":11508,"low":11346.2,"close":11448.3}
qml: append failed: {"timestamp":1514847600,"open":11448.1,"high":11460,"low":11300,"close":11359}

How to populate the CandlestickSeries dynamically?

Note: I also tried an alternative approach using Repeater, and that failed too.

2 Answers

Tried to generate the whole QML code for the data I want to show and then use Qt.createQmlObject() to dynamically create it (yeah, I know, horrible solution):

function onDataChanged() {
    var qml = 'import QtQuick 2.15\nimport QtCharts 2.15\n\nCandlestickSeries {\n    name: "HelloWorld Ltd."\n    increasingColor: "green"\n    decreasingColor: "red"\n\n'
    for(var i = 0; i < dataProvider.data.length; i++) {
        var x = dataProvider.data[i]
        qml += '    CandlestickSet { timestamp: ' + (x.timestamp * 1000) + '; open: ' + x.open + '; high: ' + x.high + '; low: ' + x.low + '; close: ' + x.close + ' }\n'
    }
    qml += '}\n'
    var series = Qt.createQmlObject(qml, chart, 'dyn')
    if(series == null) {
        console.log("Error creating series")
        return
    }
}

and it doesn't work (no error).

But if I print the generated QML code, and then I modify my static QML code to add the generated QML, it works.

Really weird

You probably don't need this anymore but I have found a solution. What you need to do is create the entire object of CandlestickSet with Qt.createQmlObject, append it to CandlstickSeries and create and assign axes. The following code will work:

    var newObject = Qt.createQmlObject(
                "import QtQuick 2.0; " +
                "import QtCharts 2.2; " +
                "CandlestickSet {" + 
                    "timestamp: " + timestamp +
                    "; open: " + open +
                    "; high: " + high +
                    "; low: " + low +
                    "; close: " + close +
                "}", candlestickSeries);
    qmlObjects.push(newObject); //Array holding created objects to destroy them when not needed anymore to prevent a memory leak
    candlestickSeries.append(newObject);
    candlestickSeries.axisX = Qt.createQmlObject(
        "import QtQuick 2.0; " +
        "import QtCharts 2.2; " +
        "DateTimeAxis {" + 
            "min: new Date(" + x_min + ")" +
            "; max: new Date(" + x_max + ")" +
        "}", candlestickSeries);
    candlestickSeries.axisY = Qt.createQmlObject(
        "import QtQuick 2.0; " +
        "import QtCharts 2.2; " +
        "ValueAxis {" + 
            "min: " + y_min +
            "; max: " + y_max +
        "}", candlestickSeries);
Related