web-dev-qa-db-fra.com

Impossible de lire la propriété 'canvas' de indéfini

J'essaye d'utiliser des diagrammes pour faire un camembert. J'ai suivi les étapes de la documentation de chartjs et j'ai inclus chart.js et l'élément canvas. J'ai ajouté le script qui devrait créer le graphique comme exemple fourni dans la documentation de chartjs. Je reçois le message d'erreur suivant: Uncaught TypeError: Impossible de lire la propriété 'canvas' d'undefined Quelqu'un sait-il comment résoudre ce problème? Qu'est-ce que je fais mal? Merci d'avance!

ICI IS LE CODE:

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="<?php echo base_url(); ?>media/js/chart.js"></script>


<script type="text/javascript" src="<?php echo base_url(); ?>media/js/jquery.js"></script>

    </head>



    <canvas id="myChart" width="400" height="400"></canvas>
        <script  type="text/javascript">

        $(function() {
             options = {
                //Boolean - Show a backdrop to the scale label
                scaleShowLabelBackdrop: true,
                //String - The colour of the label backdrop
                scaleBackdropColor: "rgba(255,255,255,0.75)",
                // Boolean - Whether the scale should begin at zero
                scaleBeginAtZero: true,
                //Number - The backdrop padding above & below the label in pixels
                scaleBackdropPaddingY: 2,
                //Number - The backdrop padding to the side of the label in pixels
                scaleBackdropPaddingX: 2,
                //Boolean - Show line for each value in the scale
                scaleShowLine: true,
                //Boolean - Stroke a line around each segment in the chart
                segmentShowStroke: true,
                //String - The colour of the stroke on each segement.
                segmentStrokeColor: "#fff",
                //Number - The width of the stroke value in pixels
                segmentStrokeWidth: 2,
                //Number - Amount of animation steps
                animationSteps: 100,
                //String - Animation easing effect.
                animationEasing: "easeOutBounce",
                //Boolean - Whether to animate the rotation of the chart
                animateRotate: true,
                //Boolean - Whether to animate scaling the chart from the centre
                animateScale: false,
                //String - A legend template
                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>"

            };
             data = [
                {
                    value: 300,
                    color: "#F7464A",
                    highlight: "#FF5A5E",
                    label: "Red"
                },
                {
                    value: 50,
                    color: "#46BFBD",
                    highlight: "#5AD3D1",
                    label: "Green"
                },
                {
                    value: 100,
                    color: "#FDB45C",
                    highlight: "#FFC870",
                    label: "Yellow"
                }
            ];
             ctx = $("#myChart").get(0).getContext("2d");
             myNewChart = new Chart(ctx[0]).Pie(data, options);
        });
    </script>
</html>
10
Unfinished

Le problème réside sur cette ligne ici:

myNewChart = new Chart(ctx[0]).Pie(data, options);

Et en particulier ctx[0]. Lorsque vous avez défini ctx ici:

ctx = $("#myChart").get(0).getContext("2d");

ctx est un objet appelé CanvasRenderingContext2D, qui possède des propriétés. Vous essayez de le traiter comme un Array alors que ce n'est pas le cas. ctx[0] est donc undefined. La solution est donc simple, comme vous l’avez découvert. 

Remplacez ctx[0] par ctx et vous obtenez votre diagramme à secteurs animé de Nice.

ctx = $("#myChart").get(0).getContext("2d");
myNewChart = new Chart(ctx).Pie(data, options);

Fiddle Ici

24
Spencer Wieczorek

Ma solution est un peu différente, car je souhaitais que le graphique change de façon dynamique (dans mon application, il se déplace avec un curseur) mais évite le scintillement affreux. 

Après l'instanciation standard, je mets à jour le curseur comme suit:

var chartData = getChartData();

for(var i=0; i<chartData.length; i++)
{
    barChart.datasets[0].bars[i].value = chartData[i];
}

barChart.update();

Cela anime bien le changement, mais une fois l'animation terminée, afin d'éviter que le scintillement étrange ne se produise lorsque l'utilisateur survole la souris (l'info-bulle est également essentielle pour moi), je détruis et recrée le graphique sur la souris vers le haut comme suit :

if(barChart) {
    barChart.clear();
    barChart.destroy();
}

chartDataObject = getChartData();

var chartData = {
    labels: getChartLabels(),
    datasets: [
        {
            label: "label",
            fillColor: "rgba(151,187,205,0.5)",
            strokeColor: "rgba(151,187,205,0.8)",
            highlightFill: "rgba(151,187,205,0.75)",
            highlightStroke: "rgba(151,187,205,1)",
            data: chartDataObject
        }
    ]
};

var chartContext = $("#visualizeEfficacyBar").get(0).getContext("2d");
barChart = new Chart(chartContext).Bar(chartData, { tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>", responsive : true , animate : false, animationSteps : 1 });

La chose importante ici est de ne pas animer la récréation car cela conduit à un effet visuel très gênant, le réglage de animate : false n'a pas fait l'affaire, mais animationSteps : 1 l'a fait. Maintenant, pas de scintillement, le graphique est recréé et l'utilisateur n'en est pas plus sage. 

0
Frank Conry