ChartJS - grafieken en diagrammen

Wat is ChartJS?

ChartJS is een JavaScript bibliotheek waarmee je op een gemakkelijke manier grafieken en diagrammen kunt maken. Meer informatie over ChartJS vind je op de website: ChartJS

Hoe maak je een grafiek met ChartJS

Een grafiek maken met ChartJS is eenvoudig. De code om een basis grafiek te maken vind je op de website van ChartJS Getting Started - ChartJS. De code hieronder is gebaseerd op het getting started voorbeeld van de website van ChartJS.

stap 1 - HTML pagina

Eerst heb je een HTML pagina nodig waar je de grafiek gaat afbeelden. Het voorbeeld hieronder laat alleen de onderdelen zien nodig voor ChartJS.

                
<script defer src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<div>
    <canvas class="chart-example"></canvas>
</div>
                
            

Eigenlijk heb je 2 onderdelen nodig voor ChartJS.

  1. Het script van ChartJS. (die zet je in je head met defer)
  2. Een leeg canvas waarin de grafiek gaat worden afgebeeld.

stap 2 - JavaScript

Om ChartJS aan de praat te krijgen heb je een eigen JavaScript bestand nodig (main.js) die je linkt aan je HTML pagina. Hieronder vind je voorbeeld code die je hierin kunt plaatsen die ervoor zorgt dat er een grafiek tevoorschijn komt.

            

//we halen de canvas op uit het HTML document met de class naam chart-example
const chart = document.querySelector('.chart-example');

//er wordt een nieuwe grafiek gemaakt van het type 'bar'
new Chart(chart, {
    type: 'bar',
    data: {
      //de labels komen op de x as
      labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
      datasets: [{
        label: '# of Votes',
        // de data komt op de y as
        data: [12, 19, 3, 5, 2, 3],
        borderWidth: 1
      }]
    },
    options: {
      scales: {
        y: {
          beginAtZero: true
        }
      }
    }
});

            
        

stap 3 - Testen

Als het goed is zie je nu een grafiek in de browser van het type 'bar'. Probeer nu het type eens te wijzigen naar 'pie' of 'line'.

Let op: voor een grafiek heb je dus twee arrays nodig. Een label array (x as) en een data array (y as). Deze twee arrays moeten evenveel elementen bevatten om te zorgen dat het goed werkt.

Een functie voor het weergeven van meerdere charts op een pagina

Vaak wil je meer dan 1 grafiek weergeven op een pagina. Hieronder een voorbeeld van een herbruikbare functie die 4x wordt gebruikt. Wil je een grafiek maken met meerdere datasets zul je deze functie moeten aanpassen.

            
//met querySelector worden 4 canvas elementen opgehaald
const chart1 = document.querySelector('.chart-1');
const chart2 = document.querySelector('.chart-2');
const chart3 = document.querySelector('.chart-3');
const chart4 = document.querySelector('.chart-4');

//de createChart functie wordt 4x aangeroepen met verschillende argumenten
createChart(chart1, 'bar', ['PC', 'Console', 'Mobile'], 'Games per platform', [25, 13, 45]);
createChart(chart2, 'line', ['Rick', 'Morty', 'Summer', 'Jerry'], 'Appearances in serie', [100, 100, 75, 89]);
createChart(chart3, 'pie', ['Psychic', 'Grass', 'Fire', 'Ghost'], 'Pokemon per type', [245, 133, 341, 67]);
createChart(chart4, 'doughnut', ['Electronics', 'Books', 'Clothes', 'Pets'], 'Products per category', [2135, 213, 4321, 134]);

/*de functie createChart heeft 5 parameters
1. canvas, het HTML element waarop de grafiek getekend gaat worden.
2. type, het type van de grafiek. Kan zijn 'bar', 'line', etc..
3. labels, een array met labels die op de x-as worden getoond.
4. label, dit is het label van de dataset en wordt getoond boven de grafiek of wanneer je eroverheen hovered.
5. data, een array met data die op de y-as worden getoond.
*/
function createChart(canvas, type, labels, label, data) {
    new Chart(canvas, {
        type: type,
        data: {
            labels: labels,
            datasets: [{
                label: label,
                data: data,
                borderWidth: 1
            }]
        },
        options: {
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        }
    });
}
            
        

Data weergeven vanuit fetch

De createChart functie uit het voorbeeld hierboven verwacht 2 arrays, een labels en data array. Deze kun je natuurlijk ook prima aanleveren vanuit een fetch. Hieronder vind je een code voorbeeld waarbij de data wordt aangeleverd vanuit een weather API.

            
//met querySelector worden 2 canvas elementen opgehaald
const chart1 = document.querySelector('.chart-1');
const chart2 = document.querySelector('.chart-2');

//fetch naar de API van open-meteo om weer data op te halen
fetch('https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t=temperature_2m,wind_speed_10m&hourly=temperature_2m,relative_humidity_2m,wind_speed_10m')
    .then(myData => myData.json())
    .then(myJsonData => createCharts(myJsonData));

//de functie die vanuit fetch wordt aangeroepen om de createChart functie 2x aan te roepen, 1 voor temperatuur en 1 voor luchtvochtigheid
function createCharts(weatherData) {
    createChart(chart1, 'bar', weatherData.hourly.time, 'Temperature', weatherData.hourly.temperature_2m);
    createChart(chart2, 'line', weatherData.hourly.time, 'Relative humidity', weatherData.hourly.relative_humidity_2m);
}

/*de functie createChart heeft 5 parameters
1. canvas, het HTML element waarop de grafiek getekend gaat worden.
2. type, het type van de grafiek. Kan zijn 'bar', 'line', etc..
3. labels, een array met labels die op de x-as worden getoond.
4. label, dit is het label van de dataset en wordt getoond boven de grafiek of wanneer je eroverheen hovered.
5. data, een array met data die op de y-as worden getoond.
*/
function createChart(canvas, type, labels, label, data) {
    new Chart(canvas, {
        type: type,
        data: {
            labels: labels,
            datasets: [{
                label: label,
                data: data,
                borderWidth: 1
            }]
        },
        options: {
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        }
    });
}
            
        

Data groeperen

In veel gevallen kun je de data vanuit de JSON die je krijgt aangeleverd vanuit fetch direct gebruiken in ChartJS om op een grafiek te tonen. In het geval van bijvoorbeeld open-meteo krijg je de data kant en klaar aangeleverd in een labels array met datum/tijd en een data array met temperatuur en luchtvochtigheid. Helaas krijg je de data niet altijd zo netjes terug dat je het direct kunt gebruiken. Hiervoor moet je soms de data nog groeperen. Een methode om dit snel en efficiƫnt te doen is met behulp van Map

Hieronder zie je een voorbeeld van een JSON met Pokemon en het bijbehorende type. Wanneer je in een grafiek wilt tonen hoeveel Pokemon er zijn van elk type kun je dit niet zomaar doen zonder hiervoor eerst te tellen hoeveel Pokemon er zijn per type.

            
[
    {
       "id":1,
       "name":"bulbasaur",
       "type":"grass/poison",
       "img":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png",
       "imgShiny":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/1.png",
       "level":7
    },
    {
       "id":2,
       "name":"ivysaur",
       "type":"grass/poison",
       "img":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/2.png",
       "imgShiny":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/2.png",
       "level":9
    },
    {
       "id":3,
       "name":"venusaur",
       "type":"grass/poison",
       "img":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/3.png",
       "imgShiny":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/3.png",
       "level":6
    },
    {
       "id":4,
       "name":"charmander",
       "type":"fire",
       "img":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/4.png",
       "imgShiny":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/4.png",
       "level":8
    },
    {
       "id":5,
       "name":"charmeleon",
       "type":"fire",
       "img":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/5.png",
       "imgShiny":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/5.png",
       "level":7
    },
    {
       "id":7,
       "name":"squirtle",
       "type":"water",
       "img":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/7.png",
       "imgShiny":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/7.png",
       "level":6
    },
    {
       "id":10,
       "name":"caterpie",
       "type":"bug",
       "img":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/10.png",
       "imgShiny":"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/10.png",
       "level":8
    }
]
            
        

Bovenstaande JSON heeft 10 Pokemon die ieder weer een ander type hebben. Wanneer je in een grafiek het aantal Pokemon per type wil laten zien kun je hiervoor een Map gebruiken om te groeperen. Vanuit deze Map kun je gemakkelijk 2 arrays halen die je kunt gebruiken je grafiek te tekenen. Onderstaand een code voorbeeld:

            
fetch('/pokemon')
    .then(myData => myData.json())
    .then(myJsonData => createPokeCharts(myJsonData));

function createPokeCharts(pokemonData){
    //we maken een nieuwe map aan
    const pokemonTypeMap = new Map();
    //we loopen over alle pokemon objecten uit de JSON
    for (let i = 0; i < pokemonData.length; i++) {
        //we halen 1 pokemon uit de array
        const pokemon = pokemonData[i];
        //met has kijken we of het type nog niet bestaat in de Map
        if(!pokemonTypeMap.has(pokemon.type)){
            //zo niet voegen we het type toe en zetten de waarde op 0
            pokemonTypeMap.set(pokemon.type, 0);
        }
        //we zetten de nieuwe waarde van het type met set en halen de vorige waarde op met get en tellen er 1 bij op
        pokemonTypeMap.set(pokemon.type, pokemonTypeMap.get(pokemon.type) + 1);
    }
    //na de loop gaan we de chart maken. We geven de keys() mee als labels en de values() als data met behulp van Array.from
    createChart(chart3, 'bar', Array.from(pokemonTypeMap.keys()), 'Pokemon per Type', Array.from(pokemonTypeMap.values()));
}