简体   繁体   中英

CanvasJS not properly rendering chart

I am using the following code to render an OHLC chart in CanvasJS:

<script>

var candleData = [];
var chart = new CanvasJS.Chart("chartContainer", {
    title: {
        text: 'Demo Stacker Candlestick Chart (Realtime)'
    },
    zoomEnabled: true,
    axisY: {
        includeZero: false,
        title: 'Price',
        prefix: '$'
    },
    axisX: {
        interval: 1,
    },
    data: [{
            type: 'ohlc',
            dataPoints: candleData
        }
    ]
});

function mapDataToPointObject(data) {
    var dataPoints = [];
    for(var i = 0; i < data.length; i++) {
        var obj = data[i];
        var newObj = {
            x: new Date(obj.time),
            y: [
                obj.open,
                obj.high,
                obj.low,
                obj.close
            ]
        }
        dataPoints.push(newObj);
    }
    return dataPoints;
}

function updateChart() {
    $.ajax({
        url: 'http://localhost:8080',
        success: function(data) {
            candleData = JSON.parse(data);
            candleData = mapDataToPointObject(candleData);
            chart.render();
        }
    });
}

$(function(){
    setInterval(() => {
        updateChart();
    }, 500);
});

The data properly loads, parses into the correct format, and render() is called on the interval like it should. The problem is, while the chart axes and titles all render properly, no data shows up. The chart is empty.

What DOES work is setting the data directly to the chart using

chart.options.data[0].dataPoints = candleData;

Why does my above solution not work then? Is there a way I can update the chart's dataPoints without having to hardcode a direct accessor to the chart's dataPoints?

It's related to JavaScript pass by value and pass by reference.

After execution of the following line.

dataPoints: candleData

dataPoints will refer to the current value of candleData. ie. dataPoints = [];

Now if you redefine candleData to any other value.

        candleData = JSON.parse(data);
        candleData = mapDataToPointObject(candleData);

Then dataPoints won't be aware of this update and will still refer to the empty array (that you pointed earlier).

The following snippet will make it easy to understand

 //pass by value var a = "string1"; var b = a; a = "string2"; alert("b is: " + b); //this will alert "string1" //pass by reference var c = { s: "string1" }; var d = c; cs = "string2"; alert("ds is: " + ds); //this will alert "string2" 

For more, you can read about pass by value and pass by reference.

Javascript by reference vs. by value

Explaining Value vs. Reference in Javascript

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM