D3 & React

installation d3js

npm i d3 -S

npm i @types/d3 -D

Avec Typescript

import D3

import * as d3 from "d3";

initialisation dans react

import { useRef } from 'react';

export default function Module() {
  const svgRef = useRef() as React.RefObject<SVGSVGElement>;

  return (
    <div>
      <svg ref={svgRef}>
      <svg/>
    </div>
  );
}

Ici, nous créons un élément svg avec une référence en utilisant useRef

Appliquer une hauteur et largeur sur notre élément SGV

 import { useMeasure } from 'react-use';
 
 
 const [ref, { width, height }] = useMeasure();
 
 useEffect(() => {
   d3.select(svgRef.current).attr("width", width).attr("height", height);
 }, []);

Lorsque notre page se charge, nous sélectionnons la référence du conteneur pour lui affecter les attributs width et height

Créer un cercle SVG

<circle cy={height/2} cx={width/2} r="30" />

Nous créons un cercle de rayon 30 ayant pour coordonnée en x (la taille de notre client web divisé par deux) et pour coordonnée en y (la hauteur de notre client web divisé par deux).

 

Ainsi, notre cercle se retrouvera au milieu de notre page.

Appliquer un style à notre cercle

Nous souhaitons créer un cercle sans couleur de fond mais avec un bord en pointillés de couleur bleu et j'ajoute que je souhaite seulement 10 pointillés

 

Nous allons avoir besoin des propriétés suivantes:

  • fill
  • stroke
  • strokeDasharray
  • strokeWidth

La propriété fill

Cette propriété permet de remplir le cercle avec la couleur donnée.

Dans notre cas précis, nous souhaitons une couleur de fond transparente.

<circle fill="transparent" />

La propriété stroke

Cette propriété permet de définir la couleur du contour du cercle.

Dans notre cas précis, nous souhaitons une couleur bleue.

<circle fill="transparent" stroke="#3c81f6" />

La propriété stokeWidth

Cette propriété permet de définir la largeur du contour du cercle

Dans notre cas précis, nous souhaitons un contour de 5 pixels.

<circle fill="transparent" stroke="#3c81f6" strokeWidth="5" />

La propriété strokeDasharray

Cette propriété permet d'appliquer des pointillés sur notre contour de cercle.

Dans notre cas précis, nous souhaitons affecter une valeur de 10 sur notre propriété strokeDasharray.

<circle fill="transparent" stroke="#3c81f6" strokeWidth="5" strokeDasharray="10" />

Notons que notre résultat n'est pas parfait... Les pointillés ne sont pas répartis de manière uniforme autour du cercle.

Le cercle parfait !

Un calcul mathématique sera nécessaire afin de calculer la valeur que l'on affectera à la propriété strokeDasharray

  <!-- 
    The circumference of the circle is 2*PI*R ~ 314.16
    if we want N dashed we use d=314.16/N
    For N = 20 we have d=15.71
    For a gap of 5 we will have "10.71,5" (d - gap,gap)
  -->

Une petite recherche sur stackoverflow me fait tomber sur cette petite note qui sera bien utile pour ce que l'on souhaite faire.

Ce qu'il faut retenir

  <!-- 
    The circumference of the circle is 2*PI*R ~ 314.16
    if we want N dashed we use d=314.16/N
    For N = 20 we have d=15.71
    For a gap of 5 we will have "10.71,5" (d - gap,gap)
  -->

Dans notre cas, R ( le rayon du cercle ) vaut 30 donc

2 × π × 30 = 188.495559215

N est notre nombre de pointillés qui vaut 10

d = 188.495559215 / 10 = 18.8495559215

Notre gap entre chaque pointillé sera de 4 donc

x = 18.8495559215 - 4 = 14.8495559215

Le resultat

<circle 
    cy={position.y}
    cx={position.x}
    r="30"
    fill="transparent"
    stroke="#3c81f6"
    strokeDasharray="14.8495559215, 4"
    strokeWidth="5"
 />

Créer un cercle dynamique

export async function createCircle(ctx) {
  const { svgRef } = ctx;
  d3.select(svgRef.current)
    .append('circle')
    .attr('r', 20)
    .attr('cx', 200)
    .attr('cy', 200)
    .style('fill', 'transparent')
    .style('stroke', '#3c81f6')
    .style('stroke-width', 5)
    .style('cursor', 'pointer')
  return this;
}

Créer un rectangle SVG

<rect y={height/2} x={width/2} width="50" height="25" fill="crimson" />

Créer une ligne SVG

<line y1={height/2} x1={width/2} x2={width/4} y2={height/4} stroke="crimson" />

Créer un texte SVG

<text y={height/2} x={width/2} stroke="crimson">Hello</text>

D3js

By NicoHash

D3js

  • 50