Klicken Sie in Chart.js auf Ereignisse in Kreisdiagrammen

72

Ich habe eine Frage zu Chart.js.

Ich habe anhand der bereitgestellten Dokumentation mehrere Kreisdiagramme gezeichnet. Ich habe mich gefragt, ob ich beim Klicken auf ein bestimmtes Slice eines der Diagramme je nach Wert dieses Slice einen Ajax-Aufruf tätigen kann.

Zum Beispiel, wenn dies mein ist data

var 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"
    }
], 

Kann ich auf das Redbeschriftete Slice klicken und eine URL des folgenden Formulars aufrufen : example.com?label=red&value=300? Wenn ja, wie gehe ich vor?

Newtt
quelle

Antworten:

86

Update: Wie @Soham Shetty kommentiert, getSegmentsAtEvent(event)funktioniert nur für 1.x und für 2.x getElementsAtEventsollte verwendet werden.

.getElementsAtEvent (e)

Sucht nach dem Element unter dem Ereignispunkt und gibt dann alle Elemente mit demselben Datenindex zurück. Dies wird intern für die Hervorhebung des Etikettenmodus verwendet.

Wenn Sie getElementsAtEvent(event)Ihre Chart-Instanz aufrufen und ein Argument eines Ereignisses oder eines jQuery-Ereignisses übergeben, werden die Punktelemente zurückgegeben, die sich an derselben Position wie dieses Ereignis befinden.

canvas.onclick = function(evt){
    var activePoints = myLineChart.getElementsAtEvent(evt);
    // => activePoints is an array of points on the canvas that are at the same position as the click event.
};

Beispiel: https://jsfiddle.net/u1szh96g/208/


Ursprüngliche Antwort (gültig für die Version Chart.js 1.x):

Sie können dies mit erreichen getSegmentsAtEvent(event)

Wenn Sie getSegmentsAtEvent(event)Ihre Chart-Instanz aufrufen und ein Argument eines Ereignisses oder eines jQuery-Ereignisses übergeben, werden die Segmentelemente zurückgegeben, die sich an derselben Position wie dieses Ereignis befinden.

Aus: Prototypmethoden

So können Sie tun:

$("#myChart").click( 
    function(evt){
        var activePoints = myNewChart.getSegmentsAtEvent(evt);           
        /* do something */
    }
);  

Hier ist ein voll funktionsfähiges Beispiel:

<html>
    <head>
        <script type="text/javascript" src="http://code.jquery.com/jquery-2.0.2.js"></script>
        <script type="text/javascript" src="Chart.js"></script>
        <script type="text/javascript">
            var 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"
                }
            ];

            $(document).ready( 
                function () {
                    var ctx = document.getElementById("myChart").getContext("2d");
                    var myNewChart = new Chart(ctx).Pie(data);

                    $("#myChart").click( 
                        function(evt){
                            var activePoints = myNewChart.getSegmentsAtEvent(evt);
                            var url = "http://example.com/?label=" + activePoints[0].label + "&value=" + activePoints[0].value;
                            alert(url);
                        }
                    );                  
                }
            );
        </script>
    </head>
    <body>
        <canvas id="myChart" width="400" height="400"></canvas>
    </body>
</html>
Tobías
quelle
6
Es funktioniert für die 1.x-Version. Für mehr als 2.x müssen Sie die getElementsAtEventMethode verwenden.
@SohamShetty, vielen Dank für Ihr Feedback. Ich habe die Antwort basierend auf Ihrem Kommentar aktualisiert.
Tobías
1
Vielen Dank für diese Antwort. Ich habe festgestellt, dass beim Klicken auf das Diagramm (kein Segment) eine Fehlermeldung in der Konsole angezeigt wird: Nicht erfasster Typfehler: Die Eigenschaft '_chart' von undefined kann bei HTMLCanvasElement.canvas.onclick
Matt Saunders
@MattSaunders Sie haben Recht, ein Häkchen wie if (activePoints[0])fehlt, um sicherzustellen, dass es ein Element gibt. Vielen Dank für den Hinweis. Ich habe das Beispiel aktualisiert.
Tobías
Diese Geige hilft mir, mein Problem zu lösen. Können Sie es deutlicher machen, indem Sie es oben drauf machen oder so? Vielen Dank
Emily
60

Mit Chart.JS Version 2.1.3 sind Antworten, die älter als diese sind, nicht mehr gültig. Bei Verwendung der Methode getSegmentsAtEvent (event) wird folgende Meldung auf der Konsole ausgegeben:

getSegmentsAtEvent ist keine Funktion

Also ich denke es muss entfernt werden. Ich habe ehrlich gesagt kein Changelog gelesen. Um dies zu beheben, verwenden Sie einfach die getElementsAtEvent(event)Methode, wie sie in den Dokumenten zu finden ist .

Unten finden Sie das Skript, mit dem Sie die effektiv angeklickte Slice-Bezeichnung und den Wert erhalten. Beachten Sie, dass sich auch das Abrufen von Beschriftung und Wert geringfügig unterscheidet.

var ctx = document.getElementById("chart-area").getContext("2d");
var chart = new Chart(ctx, config);

document.getElementById("chart-area").onclick = function(evt)
{   
    var activePoints = chart.getElementsAtEvent(evt);

    if(activePoints.length > 0)
    {
      //get the internal index of slice in pie chart
      var clickedElementindex = activePoints[0]["_index"];

      //get specific label by index 
      var label = chart.data.labels[clickedElementindex];

      //get value by index      
      var value = chart.data.datasets[0].data[clickedElementindex];

      /* other stuff that requires slice's label and value */
   }
}

Ich hoffe es hilft.

alessandrob
quelle
Ich habe ein Donut-Diagramm erstellt, das einen Textwert im mittleren Loch anzeigt. Ist es möglich, den Klick dieses Textes zu verfolgen?
Techie_28
2
Ich sollte auch beachten, dass Sie, wenn Sie den Datensatzindex für Dinge wie gestapelte Balkendiagramme usw. erhalten möchten, diese chart.getDatasetAtEvent(evt)zusätzlich verwenden müssen chart.getElementsAtEvent(evt), um die Informationen zu erhalten.
HartleySan
38

Chart.js 2.0 hat dies noch einfacher gemacht.

Sie finden es unter der allgemeinen Diagrammkonfiguration in der Dokumentation. Sollte auf mehr als Kreisdiagrammen funktionieren.

options:{
    onClick: graphClickEvent
}

function graphClickEvent(event, array){
    if(array[0]){
        foo.bar; 
    }
}

Es wird im gesamten Diagramm ausgelöst. Wenn Sie jedoch auf einen Kreis klicken, wird das Modell dieses Kreises einschließlich des Index angezeigt, mit dem der Wert abgerufen werden kann.

Tom Glover
quelle
4
Dies ist eine praktische Antwort, da in der Dokumentation zu chart.js das Ereignis erwähnt wird, derzeit jedoch keine Beispielimplementierung angegeben wird: chartjs.org/docs/latest/general/interactions/events.html .
Tom John
22

Arbeiten Sie gut ChartJs Sektor onclick

ChartJS: Tortendiagramm - Optionen hinzufügen "onclick"

              options: {
                    legend: {
                        display: false
                    },
                    'onClick' : function (evt, item) {
                        console.log ('legend onClick', evt);
                        console.log('legd item', item);
                    }
                }
Lakshmi RM
quelle
15

Ich hatte seit einigen Tagen die gleichen Probleme. Heute habe ich die Lösung gefunden. Ich habe die vollständige Datei gezeigt, die zur Ausführung bereit ist.

<html>
<head><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js">
</script>
</head>
<body>
<canvas id="myChart" width="200" height="200"></canvas>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        backgroundColor: [
            'rgba(255, 99, 132, 0.2)',
            'rgba(54, 162, 235, 0.2)',
            'rgba(255, 206, 86, 0.2)',
            'rgba(75, 192, 192, 0.2)',
            'rgba(153, 102, 255, 0.2)',
            'rgba(255, 159, 64, 0.2)'
        ],
        borderColor: [
            'rgba(255,99,132,1)',
            'rgba(54, 162, 235, 1)',
            'rgba(255, 206, 86, 1)',
            'rgba(75, 192, 192, 1)',
            'rgba(153, 102, 255, 1)',
            'rgba(255, 159, 64, 1)'
        ],
        borderWidth: 1
    }]
},
options: {
    scales: {
        yAxes: [{
            ticks: {
                beginAtZero:true
            }
        }]
    },
onClick:function(e){
    var activePoints = myChart.getElementsAtEvent(e);
    var selectedIndex = activePoints[0]._index;
    alert(this.data.datasets[0].data[selectedIndex]);


}
}
});
</script>
</body>
</html>
Sachin Raghav
quelle
2
Danke, deine Antwort hat funktioniert. Kurz und präzise. Sollte die akzeptierte Antwort gewesen sein.
Ron Daulagupu
5

Wenn Sie ein Donught-Diagramm verwenden und verhindern möchten, dass der Benutzer Ihr Ereignis beim Klicken in den leeren Bereich um Ihre Diagrammkreise auslöst, können Sie die folgende Alternative verwenden:

var myDoughnutChart = new Chart(ctx).Doughnut(data);

document.getElementById("myChart").onclick = function(evt){
    var activePoints = myDoughnutChart.getSegmentsAtEvent(evt);

    /* this is where we check if event has keys which means is not empty space */       
    if(Object.keys(activePoints).length > 0)
    {
        var label = activePoints[0]["label"];
        var value = activePoints[0]["value"];
        var url = "http://example.com/?label=" + label + "&value=" + value
        /* process your url ... */
    }
};
Anwar
quelle
4

Wenn Sie TypeScript verwenden, ist der Code etwas funky, da es keine Typinferenz gibt. Dies funktioniert jedoch, um den Index der Daten abzurufen, die an das Diagramm übergeben wurden: // events public chartClicked (e: any): void { //console.log(e);

    try {
        console.log('DS ' + e.active['0']._datasetIndex);
        console.log('ID ' +  e.active['0']._index);
        console.log('Label: ' + this.doughnutChartLabels[e.active['0']._index]);
        console.log('Value: ' + this.doughnutChartData[e.active['0']._index]);


    } catch (error) {
        console.log("Error In LoadTopGraph", error);
    }

    try {
        console.log(e[0].active);
    } catch (error) {
        //console.log("Error In LoadTopGraph", error);
    }



}
Steve der Sultan
quelle
3

Um Klickereignisse erfolgreich zu verfolgen und auf welches Diagrammelement der Benutzer geklickt hat, habe ich in meiner .js-Datei die folgenden Variablen eingerichtet:

vm.chartOptions = {
    onClick: function(event, array) {
        let element = this.getElementAtEvent(event);
        if (element.length > 0) {
            var series= element[0]._model.datasetLabel;
            var label = element[0]._model.label;
            var value = this.data.datasets[element[0]._datasetIndex].data[element[0]._index];
        }
    }
};
vm.graphSeries = ["Series 1", "Serries 2"];
vm.chartLabels = ["07:00", "08:00", "09:00", "10:00"];
vm.chartData = [ [ 20, 30, 25, 15 ], [ 5, 10, 100, 20 ] ];

Dann richte ich in meiner HTML-Datei das Diagramm wie folgt ein:

<canvas id="releaseByHourBar" 
    class="chart chart-bar"
    chart-data="vm.graphData"
    chart-labels="vm.graphLabels" 
    chart-series="vm.graphSeries"
    chart-options="vm.chartOptions">
</canvas>
Carlo Bos
quelle
1
  var ctx = document.getElementById('pie-chart').getContext('2d');
 var myPieChart = new Chart(ctx, {
                // The type of chart we want to create
                type: 'pie',

            });

             //define click event
  $("#pie-chart").click(
            function (evt) {
                var activePoints = myPieChart.getElementsAtEvent(evt);
                var labeltag = activePoints[0]._view.label;

                      });
PradipPatel1411
quelle
-2

Innerhalb der Optionen platzieren Sie Ihren Onclick und nennen die Funktion, die Sie als Beispiel benötigen, den Ajax, den Sie benötigen. Ich lasse das Beispiel so, dass jeder Klick auf einen Punkt den Wert anzeigt und Sie ihn in Ihrer neuen Funktion verwenden können.

    options: {
        plugins: {
            // Change options for ALL labels of THIS CHART
            datalabels: {
                color: 'white',
                //backgroundColor:'#ffce00',
                align: 'start'
            }
        },
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true,
                    fontColor: "white"
                },gridLines: {
                        color: 'rgba(255,255,255,0.1)',
                        display: true
                    }
            }],
            xAxes: [{
                ticks: {
                    fontColor: "white"
                },gridLines: {                        
                        display: false
                    }
            }]
        },
        legend: {
        display: false

    },
    //onClick: abre     
        onClick:function(e){ 
    var activePoints = myChart.getElementsAtEvent(e); 
    var selectedIndex = activePoints[0]._index; 
    alert(this.data.datasets[0].data[selectedIndex]); 


} 
    }
jared maldonado
quelle