JSFiddle - React, Tailwind, and code Playground
by jacomyal
HTML
<div class="wrapper">
<canvas id="serie"></canvas>
</div>
CSS
.wrapper {
position: absolute;
top: 30px;
bottom: 50px;
left: 0;
right: 0;
}
JavaScript
var data = [
344, 371, 527,
717, 638, 622,
619, 348, 298,
583, 691, 641,
561, 576, 301,
265
];
// "serie" sera notre référence sur le canvas:
var serie = document.getElementById('serie'),
// "ctx" est le contexte. C'est l'objet qui expose l'API de dessin du canvas:
ctx = serie.getContext('2d');
// Extraction de la valeur maximale de la donnée:
var max = Math.max.apply(Math, data);
// Pour pouvoir facilement retracer notre courbe au resize, le dessin de la
// courbe est dans une fonction réappelable:
function render() {
// Le canvas doit prendre toute la taille de son conteneur
// (ça ne peut pas être fait depuis la CSS):
var wrapper = serie.parentElement,
width = wrapper.offsetWidth,
height = wrapper.offsetHeight;
serie.style.width = width + 'px';
serie.style.height = height + 'px';
serie.setAttribute('width', width + 'px');
serie.setAttribute('height', height + 'px');
// On normalise les données pour pouvoir plus facilement les manipuler:
var normalized = data.map(function(val) {
return val / max;
}),
l = normalized.length - 1;
// On garde une marge autour du canvas, pour que les ronds ne soient pas
// tracés en dehors du canvas:
var margin = 20;
width = width - 2 * margin;
height = height - 2 * margin;
ctx.translate(margin, margin);
// Tracé de la courbe:
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = '#5062D2';
normalized.forEach(function(val, i) {
var prev = normalized[i - 1];
if (i === 0)
ctx.moveTo(0, (1 - val) * height);
else
ctx.bezierCurveTo(
// Point d'attache 1:
(i - 0.5) / l * width, (1 - prev) * height,
// Point d'attache 2:
(i - 0.5) / l * width, (1 - val) * height,
// Destination:
i / l * width, (1 - val) * height
);
});
ctx.stroke();
// Tracé des points:
normalized.forEach(function(val, i) {
ctx.beginPath();
ctx.lineWidth = 4;
ctx.fillStyle =...