0
votes

I have the following code to draw a doughnut chart and it works perfectly as it stands with a static dataset. (Here is the static chart: http://jsfiddle.net/2gapedks/71/) I am using socket.io and am testing the addData function for updating the chart on a certain condition, currently for testing I am keeping the addData static as well:

Add Data:

myChart.addData({value: 2000, color:"#F7464A", url:"http://cdn.akamai.steamstatic.com/steamcommunity/public/images/avatars/cc/cc4cafa5e36c3333ffece4a19debe52ff693e4ab_full.jpg"});

ChartJS

var data = [
    {value: 500, color:"#F7464A", url:"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d8/d85a3b326846fa2b0f6e59acdbaa0cfef307bd87_full.jpg"},
    {value: 500, color:"#F7464A", url:"http://cdn.akamai.steamstatic.com/steamcommunity/public/images/avatars/c3/c342f1e1590c5adb1040b3f8fedfebd060b1b839_full.jpg"}
    ];
var total = 0;

var options = {
    segmentShowStroke : true,
    segmentStrokeColor : "#fff",
    segmentStrokeWidth : 2,
    percentageInnerCutout : 30, // This is 0 for Pie charts
    animationSteps : 100,
    animationEasing : "easeOutBounce",
    animateRotate : true,
    animateScale : false,
    legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>",
    showTooltips: false,
    onAnimationProgress: drawSegmentValues,
    onAnimationComplete: drawTotalValues
}

var canvas = document.getElementById("wheel");
var ctx = canvas.getContext("2d");
var midX = canvas.width/2;
var midY = canvas.height/2;

// Create a pie chart
var myChart = new Chart(ctx).Doughnut(data, options);

var radius = myChart.outerRadius;

function drawSegmentValues()
{
    for(var i=0; i<myChart.segments.length; i++) 
    {
        var image = new Image();
        image.src = data[i].url;

        ctx.fillStyle="white";
        var textSize = canvas.width/30;
        ctx.font= textSize+"px Verdana";

        var value = myChart.segments[i].value;
        var startAngle = myChart.segments[i].startAngle;
        var endAngle = myChart.segments[i].endAngle;
        var middleAngle = startAngle + ((endAngle - startAngle)/2);

        if (data[i].value > 100) {
            var posX = (3*radius)/4.5 * Math.cos(middleAngle) + midX;
            var posY = (3*radius)/4.5 * Math.sin(middleAngle) + midY;
        }
        else {
            var posX = (3*radius)/4.5 * Math.cos(middleAngle) + midX;
            var posY = (3*radius)/4.5 * Math.sin(middleAngle) + midY;
        }

        // Text offside by middle
        var w_offset = 32;
        var h_offset = 32;

        ctx.drawImage(image, posX - w_offset, posY - h_offset, 64, 64);
    }
}
function drawTotalValues()
{
    console.log("I am Here drawing");
    for(var i=0; i<myChart.segments.length; i++) 
    {
            total += myChart.segments[i].value;
    }
    ctx.fillStyle="black";
    var textSize = canvas.width/30;
    ctx.font= textSize+"px Verdana";

    // Text offside by middle
    var w_offset = ctx.measureText(total+"\ud83c\udf53").width/2;
    var h_offset = textSize/4;

    ctx.fillText(total+"\ud83c\udf53", midX - w_offset, midY + h_offset);
}

I have noticed that when I add the data, the drawSegmentValues breaks and chromes inspector comes up with the following error:

Uncaught TypeError: Cannot read property 'url' of undefined

which is the following line:

function drawSegmentValues()
{
    for(var i=0; i<myChart.segments.length; i++) 
    {
        var image = new Image();
        image.src = data[i].url; // Here

what could be causing the function to break?

1

1 Answers

0
votes

I misunderstood how the addData function worked.

My drawSegmentValues uses an external array rather than an array that is used by chart.js itself.

When addData increased the length of myChart.segments, the data array did not increase and thus there was no index in data at mychart.segments max index.

I changed my adding of the data to include an array.push so both arrays are updated and kept aligned.

Data.push({value: 500, color:"#F7464A", url:"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d8/d85a3b326846fa2b0f6e59acdbaa0cfef307bd87_full.jpg"});
myChart.addData({value: 500, color:"#F7464A", url:"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d8/d85a3b326846fa2b0f6e59acdbaa0cfef307bd87_full.jpg"});