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 =...