JSFiddle - React, Tailwind, and code Playground

by jacomyal

HTML

<div class="wrapper">
  <svg id="scatter"
     version="1.1"
     xmlns="http://www.w3.org/2000/svg">
    <g id="circles"></g>
    <g id="labels"></g>
  </svg>
</div>

CSS

.wrapper {
    position: absolute;
    top: 30px;
    bottom: 50px;
    left: 10px;
    right: 10px;
    border-left: 1px solid #000;
    border-bottom: 1px solid #000;
}
.wrapper::before,
.wrapper::after {
    content: " ";
    width: 0;
    height: 0;
    border-style: solid;
    position: absolute;
}
.wrapper::before {
    top: -5px;
    left: -4px;
    border-width: 0 4px 8px 4px;
    border-color: transparent transparent #000000 transparent;
}
.wrapper::after {
    border-width: 4px 0 4px 8px;
    border-color: transparent transparent transparent #000000;
    right: -5px;
    bottom: -5px;
}
#labels text {
    font-family: sans-serif;
}

JavaScript

var data = [
  { id: 'chrome',
    label: 'Chrome',
    value: {
      mySite: 11214,
      market: 0.403
    },
    color: '#f4b400' },
  { id: 'firefox',
    label: 'Firefox',
    value: {
      mySite: 3012,
      market: 0.136
    },
    color: '#ff9500' },
  { id: 'safari',
    label: 'Safari',
    value: {
      mySite: 1243,
      market: 0.183
    },
    color: '#53d769' },
  { id: 'explorer',
    label: 'Internet Explorer',
    value: {
      mySite: 430,
      market: 0.157
    },
    color: '#00a1f1' },
  { id: 'opera',
    label: 'Opera',
    value: {
      mySite: 134,
      market: 0.029
    },
    color: '#cc0f16' },
  { id: 'others',
    label: 'Autres',
    value: {
      mySite: 165,
      market: 0.107
    },
    color: '#cccccc' }
];

var scatter = document.getElementById('scatter'),
    circles = document.getElementById('circles'),
    labels = document.getElementById('labels'),
    margin = 50;

// Extraction des valeurs maximales de la donnée:
var max = {
  mySite: Math.max.apply(Math, data.map(function(obj) {
    return obj.value.mySite;
  })),
  market: Math.max.apply(Math, data.map(function(obj) {
    return obj.value.market;
  }))
};

// Pour pouvoir facilement retracer nos éléments au resize, leur dessin est dans
// une fonction réappelable:
function render() {
  // Le SVG doit prendre toute la taille de son conteneur
  // (ça ne peut pas être fait depuis la CSS):
  var wrapper = scatter.parentElement,
      width = wrapper.offsetWidth,
      height = wrapper.offsetHeight;

  scatter.style.width = width + 'px';
  scatter.style.height = height + 'px';
  scatter.setAttribute('width', width + 'px');
  scatter.setAttribute('height', height + 'px');

  // On garde une marge autour du SVG, pour que les ronds ne soient pas tracés
  // en dehors du SVG:
  var margin = 50;
  width = width - 2 * margin;
  height = height - 2 * margin;
  circles.setAttribute('transform', 'translate(' + margin + ',' + margin + ')');
 ...