Public
Edited
Dec 17
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
svg`<svg width="600" height="120">
<rect x="80" y="10" width="200" height="100" fill="yellow"></rect>
</svg>`
Insert cell
Insert cell
svg`<svg width="600" height="120">
<circle cx="425" cy="60" r="50" fill="blue"></circle>
</svg>`
Insert cell
Insert cell
svg`<svg width="600" height="120">
<path d="M 380 10 L 480 10 L 520 100 L480 120 Z"
style="fill: green; stroke: cadetblue; stroke-width: 10;"></path>
</svg>`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
svg`<svg width="600" height="250">
<!-- Bras -->
<g transform="translate(460, 50) rotate(20)">
<rect width="100" height="10" fill="red"></rect>
<!-- Avant-bras -->
<g transform="translate(100, 0) rotate(80)">
<rect width="100" height="10" fill="blue"></rect>
<!-- Poignet -->
<g transform="translate(100, 3) rotate(0)">
<!--Doigts -->
<rect transform="rotate(-60)" width="40"
height="4"></rect>
<rect transform="rotate(-15)" width="40"
height="4" y="0"></rect>
<rect transform="rotate(10)" width="40"
height="4" y="0"></rect>
</g>
</g>
</g>
</svg>`
Insert cell
Insert cell
Insert cell
svg`<svg width="600" height="124">
<rect style="fill: steelblue"
width="100" height="100" x="200" y="10"></rect>
</svg>`
Insert cell
Insert cell
svg`<svg width="600" height="124">
<rect style="stroke: steelblue; stroke-width: 6"
width="100" height="100" x="200" y="10"></rect>
</svg>`
Insert cell
Insert cell
Insert cell
svg`<svg width="600" height="550">
<g class="tige" transform="translate(250,137.5)">
<path d="M0,0 L-40,200 L20,600" style="stroke: #2ecc71; stroke-width: 20px; fill: none;"></path>
<g class="flower">
<circle r="60" transform="rotate(0) translate(40, 0) scale(1.5, 1)" style="fill: #f1c40f"></circle>
<circle r="60" transform="rotate(72) translate(40, 0) scale(1.5, 1)" style="fill: #f1c40f"></circle>
<circle r="60" transform="rotate(144) translate(40, 0) scale(1.5, 1)" style="fill: #f1c40f"></circle>
<circle r="60" transform="rotate(216) translate(40, 0) scale(1.5, 1)" style="fill: #f1c40f"></circle>
<circle r="60" transform="rotate(288) translate(40, 0) scale(1.5, 1)" style="fill: #f1c40f"></circle>
<circle r="60" style="fill: #f39c12"></circle>
</g>
</g>
</svg>`
Insert cell
Insert cell
Insert cell
{
// Création de l'objet principal SVG
const svg = d3.create('svg').attr('width', 600).attr('height', 240);

// Ajout d'un groupe racine décalé vers la droite
const g = svg.append('g')
.attr('transform', 'translate(250, 40)');

// Structure de données pour stocker la poisition Y et la couleur des cercles
const cData = [
{cy: 0, fill: '#e74c3c'},
{cy: 70, fill: '#f1c40f'},
{cy: 160, fill:'#2ecc71'}
];

// Boucle D3 de dessin des cercles
const circles = g.selectAll('circle').data(cData)
.enter()
.append('circle')
.attr('r', 35)
.attr('cx', function(d) {return d.cy; })
.attr('cy', function(d) {return d.cy; })
.attr('fill', function(d) { return d.fill; });
//Dessin par rendu
return svg.node();
}
Insert cell
Insert cell
Insert cell
{
// Création de l'objet principal SVG
const svg = d3.create('svg')
.attr('width', 400)
.attr('height', 240);

// Ajout d'un groupe racine décalé vers la droite
const g = svg.append('g')
.attr('transform', 'translate(250, 40)');

// Structure de données pour stocker la poisition Y et la couleur des cercles
const cData = [
{cy: 0, fill: '#e74c3c'},
{cy: 70, fill: '#f1c40f'},
{cy: 140, fill:'#2ecc71'}
];

// Boucle D3 de dessin des cercles, d'abord tous au même endroit, puis décalage vers le bas selon l'ordre
const circles = g.selectAll('circle').data(cData)
.enter()
.append('circle')
.attr('r', 35)
.attr('fill', function(d) { return d.fill; })
.transition()
.delay(function(d, i) { return i * 200; })
.attr('cy', function(d) {return d.cy; });
//Dessin par rendu
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
{
//Largeur et hauteur du graphe, marges et largeur de barre
const larg = 640;
const haut = 400;
const padding = 20;
const barre = 4;

// On crée l'arbre SVG
const svg = d3.create('svg')
.attr("width", larg)
.attr("height", haut);

// Deux échelles D3 pour calculer automatiquement les positions à partir du domaine des valeurs (leur étendue) et de l'espace disponible pour dessiner (le range), en fonction des dimensions et des marges.
const xScale = d3.scaleLinear()
.domain([d3.min(dataset, d=>d.a) - 1, d3.max(dataset, d=>d.a) + 1])
.range([padding, larg - padding * 2]);

const yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, d=>d.p)])
.range([haut - padding , padding]);
// On dessine les barres avec une boucle de <rect>
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d) {
return xScale(d.a);
})
.attr("y", function(d) {
return yScale(d.p)
})
.attr("width", function(d) {
return barre;
})
.attr("height", function(d) {
return (haut-padding)-yScale(d.p);
})
.attr("fill", "darkblue")
.attr("stroke-width", "1")
.attr("stroke", "lightgrey");

// D3 sait dessiner les axes du graphe automatiquement, en fonction des échelles fournies.
const xAxis = d3.axisBottom()
.scale(xScale)
.ticks(16, 1000); //Nombre approx. de barbules et format d'année sur 4 chiffres

const yAxis = d3.axisLeft()
.scale(yScale)
.ticks(12)
.tickSizeInner(-larg + padding + padding);// Les ticks deviennent des barres horizontales de repérage.

// On ajoute les axes en les affectant à un borde du graphe, ici l'axe des abcisses est placé en bas.
svg.append("g")
.attr("transform", "translate(0," + (haut - padding) + ")")
.call(xAxis);

// L'axe des ordonnées est à gauche avec des lignes en tiretés à la place des barbules (ticks).
svg.append("g")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis)
.call(g => g.selectAll(".tick:not(:first-of-type) line")
.attr("stroke-opacity", 0.5)
.attr("stroke-dasharray", "2,2"));

//Dessin par rendu
return svg.node();
}
Insert cell
Insert cell
Insert cell
{
//Largeur et hauteur du graphe
const larg = 500;
const haut = 400;
const padding = 20; // Décalage du bord à gauche et en haut
const svg = d3.create('svg')
.attr("width", larg)
.attr("height", haut);
// On définit un petit jeu de données à 3 dimensions
const datatest = [
[14, 20, 1], [880, 80, 4], [250, 50, 2], [100, 33, 1], [330, 85, 5],
[410, 12, 3], [475, 44, 2], [25, 67, 4], [85, 21, 5], [220, 88, 2]];
// Des échelles pour les posisions X, Y, les tailles R (rayon des cercles) et les couleurs.
const xScale = d3.scaleLinear()
.domain([0, d3.max(datatest, function(d) { return d[0]; })])
.range([padding, larg - padding * 2]);

const yScale = d3.scaleLinear()
.domain([0, d3.max(datatest, function(d) { return d[1]; })])
.range([haut - padding , padding]);

const rScale = d3.scaleLinear()
.domain([0, d3.max(datatest, function(d) { return Math.sqrt(d[2]); })])
.range([1, 10]);
// Pour les couleurs des cercles, on choisit d'affecter aux valeurs le début du gradient YlGnBu.
const cScale = d3.scaleLinear()
.domain([0, d3.max(datatest, function(d) { return d[2]; })])
.range([0,0.6]);

// On dessine les cercles
svg.selectAll("circle")
.data(datatest)
.enter()
.append("circle")
.attr("cx", function(d) {
return xScale(d[0]);
})
.attr("cy", function(d) {
return yScale(d[1]);
})
.attr("r", function(d) {
return rScale(Math.sqrt(d[2]));
})
.attr("fill", function(d) {
return d3.interpolateYlGnBu(cScale(d[2]))
})
.attr("stroke-width", "1")
.attr("stroke", "grey");

svg.selectAll("text")
.data(datatest)
.enter()
.append("text")
.text(function(d) {
return d[2];
})
.attr("x", function(d){
return xScale(d[0]) + rScale(d[2])/2+4; // Décalage horizontal de l'étiquette à droite
})
.attr("y", function(d) {
return yScale(d[1]) - rScale(d[2])/2+4; // Décalage verticel de l'étiquette en haut
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "grey");

// On dessine les axes à partir des échelles
const xAxis = d3.axisBottom()
.scale(xScale)
.ticks(8); //Nombre approx. de barbules

const yAxis = d3.axisLeft()
.scale(yScale)
.ticks(6);

svg.append("g")
.attr("class", "axis") //Assigne la classe CSS "axis"
.attr("transform", "translate(0," + (haut - padding) + ")")
.call(xAxis);

svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);

//Dessin par rendu
return svg.node();
}
Insert cell
Insert cell
Insert cell
//Le fond de carte est un fichier JSON téléchargé en temps réel.
world = (await fetch("https://unpkg.com/world-atlas@1/world/50m.json")).json()
Insert cell
{
const larg = 600;
const haut = 500;

// D3 reconnait plusieurs types de projection, ici une azimuthale orthographique
const projection = d3.geoOrthographic()
.scale(280) //Échelle
.translate([larg / 2, haut / 2]) //Dimensions
.rotate([-4, -48]) //France au centre
.clipAngle(90)
.precision(.1);

// La projection est affectée à un objet "geopath" qui va recevoir les polygones de la couche mondiale.
const path = d3.geoPath()
.projection(projection);

// Création de l'élément SVG
const svg = d3.create('svg')
.attr("width", larg)
.attr("height", haut);

// On dessine les terres émergées en beige avec un contour bleu clair
svg.append("g")
.attr("class", "countries")
.selectAll("path")
.data(topojson.feature( world, world.objects.countries ).features )
.enter().append("path")
.attr("d", path)
.attr("stroke", "lightblue")
.attr("fill", "beige");

// Puis les frontières en orange
svg.append("path")
.attr( "class", "country-borders" )
.attr("d", path(topojson.mesh( world, world.objects.countries, function( a, b)
{
return a !== b;
})))
.attr("stroke", "orange")
.attr("fill", "none");
//Dessin par rendu
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
{
const larg = 600;
const haut = 500;

// Ici une projection conique conforme, qui ressemble à la Lambert-93
const projection = d3.geoConicConformal()
.center([2.454071, 46.279229]) // Center on France
.scale(2600)
.translate([larg / 2 - 50, haut / 2]);

const path = d3.geoPath()
.projection(projection);

//Création de l'élément SVG
const svg = d3.create('svg')
.attr("width", larg)
.attr("height", haut);
// On dessine les polygones des départements, avec un style qui change selon le survol de la souris.
svg.append("path")
.datum(topojson.feature(france, france.objects.depts))
.attr("class", "depts")
.attr("d", path)
.attr("stroke", "lightgrey")
.attr("fill", "beige")
.on("mouseover", function(d) {
d3.select(this).attr("fill", "grey")
})
.on("mouseout", function(d) {
d3.select(this).attr("fill", "beige")
});
//Dessin par rendu
return svg.node();
}
Insert cell
Insert cell
Insert cell
{
const larg = 600;
const haut = 500;

const projection = d3.geoConicConformal() // Lambert-93
.center([2.454071, 46.279229]) // Center on France
.scale(2600)
.translate([larg / 2 - 50, haut / 2]);

const path = d3.geoPath()
.projection(projection);

//Création de l'élément SVG
const svg = d3.create('svg')
.attr("width", larg)
.attr("height", haut);
// Dans le fichier de données TopoJSON on trouve les polygones des départements et les données attributaires des centroïdes, du code et du nom du département et du nombre d'hôtels en 2017.
const depts = topojson.feature(france, france.objects.depts).features;
var maxVal = 0;
var cerclesDepts = depts.map(function (feature){
var nh = feature.properties["NbHotels2017"];
// Recherche de la valeur max. à dessiner
if (maxVal<nh) maxVal = nh;
return {"nbh": nh, "ctr": path.centroid(feature)};
});
// Tri des cercles dans l'ordre décroissant de taille, pour les dessiner sans masquage.
cerclesDepts.sort(function(x,y){
return d3.descending(x.nbh, y.nbh);
});
// Calcul du coefficient pour que maxVal soit dessinée avec un rayon max. de 20 pixels.
var coefSymboles = 20 / Math.sqrt(maxVal);
// Dessin du fond de carte
svg.append("path")
.datum(topojson.feature(france, france.objects.depts))
.attr("class", "depts")
.attr("d", path)
.attr("stroke", "lightgrey")
.attr("fill", "white");
// Dessin des cercles, dont la taille est proportionnelle à la racine des valeurs.
var carte = svg.selectAll(".cercles").data(cerclesDepts)
.enter().append("circle")
.attr("class", "cercles")
.attr("cx", function (d){return d.ctr[0]})
.attr("cy", function (d){return d.ctr[1]})
.attr("r", function (d){return Math.sqrt(d.nbh) * coefSymboles})
.attr("fill", "red")
.attr("stroke", "white");
//Dessin par rendu
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
d3 = require('d3@6');
Insert cell
topojson = require('topojson');
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more