[SalesForce] Chart.js with Locker Service – Failed to create chart: can’t acquire context from the given item

Any help appreciated, I have seen a few post on this subject, but none with a conclusive answer that solves the issue. I have followed all advice in these posts.

I am using ChartJS within a Lightning component. All works fine until I enable Locker Service. I then get the following message in Console and a blank component on the page:

Failed to create chart: can't acquire context from the given item

I am using the latest version of ChartJS: Version: 2.5.0.
I'll Post code below:

Component:

<aura:component controller="SentimentChartData" implements="force:appHostable,flexipage:availableForAllPageTypes,force:hasRecordId,force:hasSObjectName" access="global">
<aura:attribute name="recordId" type="String"/>
<ltng:require scripts="{!$Resource.chart_js}" afterScriptsLoaded="{!c.init}"/>  
<ui:outputText class="form-control" aura:id="recid" value="{!v.recId}" />        
<div>  
    <canvas aura:id="radarChart" id="radarChart" width="200" height="200"/>
</div>

Controller:

({
    init : function(component, event, helper) { 
    helper.setupRadarChart(component);
}
})

Helper:

({
setupRadarChart : function(component) {
    var jsonRetVal;
    var rId = component.get("v.recordId");
    var action = component.get("c.buildRadarData");
    action.setParams({
        "rId": rId
    });

    action.setCallback(this, function(a){
        jsonRetVal = JSON.parse(a.getReturnValue()); 

        var data =  jsonRetVal; 

        var ctx = document.getElementById("radarChart");            
            var myRadar = new Chart(ctx, {
                type: "radar",
                data: data,
                options: {
                    scale: {
                        reverse: false,
                        ticks: {
                            beginAtZero: true
                        }
                    }
                }
            }); 
    });
    $A.enqueueAction(action);              
}   
})

Best Answer

I would imagine that document.getElementById("radarChart") is failing. Try printing it out to the console to confirm.

You should use component.find("radarChart").getElement() instead.

And then, there is also a potential timing issue. During the init action, the DOM won't have been created yet. By the time your server action runs its callback, the DOM will probably will be there. But, it might not be. To be on the safe side, I'd create the chart in a custom renderer, on the afterRender event.