Public
Edited
Oct 21, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
y: { nice: true },
marks: [
// Tooltip par défaut : avec la propriété tip: true
Plot.barY(
alphabet,
{
x: "letter",
y: "frequency",
sort: {x: "y", reverse: true},
tip: true,
}
),
Plot.ruleY([0])
]
})
Insert cell
Insert cell
Plot.plot({
y: { nice: true },
marks: [
// Tooltip par défaut : avec la propriété tip: true
Plot.barY(
alphabet,
{
x: "letter",
y: "frequency",
sort: {x: "y", reverse: true},
tip: true,
// On peut afficher de nouveaux attributs (en plus de ceux qui le sont par défaut)
channels: {
'Ma propriété': (d) => `${d.letter}, une super lettre`,
// Typiquemenr on aurait affiché d'autres propriétés de nos individus mais ici le jeu de données n'a
// que deux colonnes...
}
}
),
Plot.ruleY([0])
]
})
Insert cell
Insert cell
Plot.plot({
y: { nice: true },
marks: [
Plot.barY(alphabet, {x: "letter", y: "frequency", sort: {x: "y", reverse: true} }),
// La marque Plot.tip + l'interaction Plot.pointer
Plot.tip(
alphabet,
Plot.pointerX(
{
x: "letter",
y: d => d.frequency / 2,
// Un contenu personnalisé (essayer de commenter la ligne qui suit pour revenir au tooltip par défaut)
title: d => `La lettre ${d.letter} a une fréquence d'apparition de ${d.frequency * 100}%`,
}
)
),
Plot.ruleY([0])
]
})
Insert cell
Insert cell
Insert cell
Plot.plot({
width: width * 2/3,
height: width * 2/4,
marks: [
// Une marque pour afficher les points
Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"}),
// La marque "crosshair"
Plot.crosshair(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"})
]
})
Insert cell
Insert cell
Insert cell
Plot.plot({
width: width * 2/3,
height: width * 2/4,
marks: [
// Une marque pour afficher les points, mais avec la transformation "pointer" -> seul le point survolé est affiché
// avec ces propriétés (fill: red, etc.)
Plot.dot(penguins, Plot.pointer({x: "culmen_length_mm", y: "culmen_depth_mm", fill: "red", r: 8})),
// La marque pour afficher tous les points
Plot.dot(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"}),
// La marque "crosshair"
Plot.crosshair(penguins, {x: "culmen_length_mm", y: "culmen_depth_mm"})
]
})
Insert cell
Plot.plot({
marks: [
Plot.barY(
alphabet,
{
x: "letter",
y: "frequency",
fill: "lightgray",
}
),
Plot.barY(
alphabet,
// On utilise ici "pointerX" car le graphique à une dimension "dominante"
// Essayez de remplacer 'pointerX' par 'pointer' et regardez la différence
Plot.pointerX({
x: "letter",
y: "frequency",
fill: "blue",
})
),
Plot.ruleY([0])
]
});
Insert cell
Insert cell
Insert cell
viewof selectedSport = Inputs.select([...new Set(olympians.map(d => d.sport))].sort(), {label: "Select one"})
Insert cell
Plot.plot({
marks: [
Plot.rectY(
olympians.filter(d => d.sport == selectedSport),
Plot.binX({y: "count"}, {x: "weight", fill: "sex"})
),
Plot.ruleY([0])
],
color: {
legend: true
},
x: {
domain: [0, 200]
}
})
Insert cell
Insert cell
viewof minFrequency = Inputs.range([0, .12], {label: "Min Frequency", step: .01, value: 0})
Insert cell
viewof pinAxis = Inputs.toggle({label: "Pin axis", value: false})
Insert cell
Plot.plot({
y: { nice: true },
marks: [
Plot.barY(
alphabet.filter(d => d.frequency >= minFrequency),
{
x: "letter",
y: "frequency"
}
),
Plot.ruleY([0])
],
x: {
domain: pinAxis ? d3.sort(alphabet.map(d => d.letter)) : undefined
}
})
Insert cell
Insert cell
Insert cell
Insert cell
viewof minFreqAlphaHighlight = Inputs.range([0, .13], {label: "Min Frequency", step: .01, value: 0.03})
Insert cell
Plot.plot({
y: { nice: true },
marks: [
Plot.ruleY([0, minFreqAlphaHighlight]),
Plot.barY(
alphabet,
{
x: "letter",
y: "frequency",
fill: d => d.frequency >= minFreqAlphaHighlight ? "steelblue" : "lightgray",
},
)
]
})
Insert cell
Insert cell
viewof cylinders = Inputs.radio([3, 4, 5, 6, 8], {label: "Cylinders", value: 4})
Insert cell
Plot.plot({
marks: [
Plot.dot(
cars,
{
x: "power (hp)",
y: "economy (mpg)",
title: "name",
fillOpacity: 0.8,
fill: d => d.cylinders === cylinders ? "crimson" : "lightgray",
r: d => d.cylinders === cylinders ? 6 : 4
}
)
],
height: 600,
width
})
Insert cell
Insert cell
Insert cell
viewof xDimension = Inputs.select(["economy (mpg)", "displacement (cc)", "power (hp)", "weight (lb)", "0-60 mph (s)"], {label: "Axe X"})
Insert cell
viewof yDimension = Inputs.select(["displacement (cc)", "power (hp)", "weight (lb)", "0-60 mph (s)", "economy (mpg)"], {label: "Axe Y"})
Insert cell
Plot.plot({
marks: [
Plot.dot(cars, { x: xDimension, y: yDimension, tip: true })
]
})
Insert cell
Insert cell
Insert cell
viewof genre = Inputs.select(["female", "male"], {label: "Selectionner"})
Insert cell
Plot.plot({
marginLeft: 60,
x: { nice: true, domain: [30, 200] },
marks: [
Plot.rectY(
olympians.filter((d) => d.sex === genre),
Plot.binX(
{ y2: "proportion" },
{
x: "weight",
fill: "sex",
stroke: "sex",
fillOpacity: 0.1,
strokeWidth: 1.5,
thresholds: 30,
// curve: "na",
}
)
),
Plot.ruleY([0]),
// On peut utiliser un opérateur ternaire pour afficher une marque différente
// en fonction de la valeur d'une variable
genre === 'male'
? Plot.ruleX([d3.mean(olympians.filter((d) => d.sex === genre).map((d) => d.weight))], { strokeWidth: 2, stroke: 'red'})
: Plot.ruleY([0.09]),
// On peut aussi utiliser un opérateur ternaire pour afficher une marque dans un cas
// mais ne rien afficher dans l'autre (notez le "null" après les ":")
genre === 'male'
? Plot.text(['Taille moyenne'], { x: 96, y: 0.135, fill: 'red'})
: null
]
})
Insert cell
Insert cell
{
// On stocke une référence à notre graphique dans une variable
const p = Plot.plot({
y: { nice: true },
marks: [
Plot.barY(
alphabet,
{
x: "letter",
y: "frequency",
fill: "grey",
sort: {x: "y", reverse: true},
inset: -0.5,
}
),
Plot.ruleY([0])
]
});

// On utilise la méthode querySelectorAll de cet objet pour
// sélectionner tous les éléments svg de type "rect"
const rects = p.querySelectorAll('rect');

// On définit deux fonctions qui seront utilisées pour
// définir le comportement, lorsque le curseur commence
// à survoler l'élément (mouseover)
// et lorsque le curseur quitte l'élément (mouseout)
const onMouseOver = (e) => {
// Tous les rectangles en gris clair
rects.forEach((_r) => {
_r.setAttribute('fill', 'lightgray')
});
// Sauf celui qui est la cible de l'événement,
// en rouge
e.target.setAttribute('fill', 'red');
};

const onMouseOut = () => {
// On remet la couleur initiale, le gris normal
rects.forEach((_r) => {
_r.setAttribute('fill', 'grey')
})
};

// Un tableau contenant les lettres dans l'ordre où elle apparaissent
const orderedLetters = alphabet.sort((a, b) => b.frequency - a.frequency).map(d => d.letter);
// Pour chaque rectangle, on ajoute son comportement
// au survol de la souris (mouseover),
// lorsque la souris arrête de survoler l'élément
// (mouseout) et lors d'un clic (click)
rects.forEach((r) => {
// On dit que le curseur, sur ces étiquettes est sous la forme 'pointer'
// (main avec l'index, montrant qu'il s'agit généralement d'un élément clicable)
r.style.cursor = 'pointer';

// Comportement mouseover / mouseout
r.addEventListener('mouseover', onMouseOver);
r.addEventListener('mouseout', onMouseOut);

// Comportement lors du clic
r.addEventListener("click", () => {
// On utilise la position du rectangle sur l'axe
// pour trouver la lettre correspondante
const letter = orderedLetters[r.__data__];
// On ouvre la page wikipedia qui correspond,
// dans un nouvel onglet
window.open(
`https://fr.wikipedia.org/wiki/${letter}_(lettre)`
);
});
});

// Ajoutons également un comportement pour le survol des étiquettes de l'axe Y
// On sélectionne d'abords toutes les étiquettes
const labels = p.querySelectorAll('g[aria-label="y-axis tick label"] > text');

// On passe par chaque étiquette
labels.forEach((textElement) => {
// Lors de l'entré du curseur, on grossi le label
textElement.addEventListener("mouseenter", () => {
textElement.style.fontWeight = "bold";
textElement.style.fontSize = 15;
});

// Lors de la sortie du curseur, on rétabli la taille du label
textElement.addEventListener("mouseleave", () => {
textElement.style.fontWeight = "normal";
textElement.style.fontSize = 10;
});
});

// Enfin, on retourne le graphique créé par 'Plot.plot'
return p;
}
Insert cell
Insert cell
Insert cell
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