function hover(svg, path) {
if ("ontouchstart" in document) svg
.style("-webkit-tap-highlight-color", "transparent")
.on("touchmove", moved)
.on("touchstart", entered)
.on("touchend", left)
else svg
.on("mousemove", moved)
.on("mouseenter", entered)
.on("mouseleave", left);
const dot = svg.append("g")
.attr("display", "none");
dot.append("polyline")
.attr("points","0,0 0,144 198,144 216,162 234, 144, 432, 144, 432,0 0,0")
.style("fill", "#fafafa")
.style("stroke"," #5dade2 ")
.style("opacity","0.8")
.style("stroke-width","1")
.attr("transform", "translate(-215, -170)");
dot.append("circle")
.attr("r", 6.5);
dot.append("text")
.attr("font-weight", "bold")
.attr("font-size", 18)
.attr("text-anchor", "middle")
.attr("id", "dot-name")
.attr("transform", "translate(0, -130)");
// création d'une puce (rond bleu dans le panneau)
dot.append("text")
.attr("font-size", 20)
.style("fill", "#FF0000")
.attr("dx", "-100")
.attr("dy", "-90")
.text("●");
// création du texte pour les dates
dot.append("text")
.attr("font-family", "sans-serif")
.attr("font-size", 16)
.attr("dx", "-80")
.attr("dy", "-90")
.attr("id", "dot-date"); // identifiant date
// création de la deuxième puce
dot.append("text")
.attr("font-size", 20)
.style("fill", "#FF0000")
.attr("dx", "-100")
.attr("dy", "-50")
.text("●");
// texte pour les taux de chômage
dot.append("text")
.attr("font-size", 16)
.attr("dx", "-80")
.attr("dy", "-50")
.attr("id", "dot-values") // identifiant
// associe l'affichage du panneau et la transparence des courbes non sélectionnées aux actions de la souris
function moved(event) {
event.preventDefault(); // change les valeurs par défaut affectées aux actions (clics, mouvement de la souris...)
const pointer = d3.pointer(event, this); // on construit un pointeur (tableau des coordonnées pour l'évènement this)
const xm = x.invert(pointer[0]); // retourne le range associé à la coordonnée en x
const ym = y.invert(pointer[1]); // retourne le range associé à la coordonné en y
const i = d3.bisectCenter(data.dates, xm); // index de la valeur de la date la plus proche de xm
const s = d3.least(data.series, d => Math.abs(d.values[i] - ym)); // retourne les taux de chômage tels que la distance entre ym et ces taux à la date xm soit minimale
const dateFormat = d3.timeFormat("%d/%m/%Y"); // on change le format des dates pour un plus joli affichage
path.attr("stroke", d => d === s ? null : "#ddd").filter(d => d === s).raise(); // trace une ligne avec les valeurs précédentes, raise() sert à faire passer cette ligne au premier plan
dot.attr("transform", `translate(${x(data.dates[i])},${y(s.values[i])})`); // translation
dot.select("#dot-name")
.text(s.name); // le texte avec l'identifiant dot-name renverra les noms de villes
d3.select('#dot-date')
.text("Date : " + dateFormat(data.dates[i])); // le texte avec l'identifiant dot-date renverra les dates
d3.select('#dot-values')
.text("Taux de chômage : " + s.values[i] + " %"); // le texte avec l'identifiant dot-values renverra lestaux de chômage
}
// définit ce qu'il se passe à l'entrée de la souris dans le graphe
function entered() {
path.style("mix-blend-mode", null).attr("stroke", "#ddd");
dot.attr("display", null); // aucun affichage
}
// définit ce qu'il se passe à la sortie de la souris dans le graphe
function left() {
path.style("mix-blend-mode", "multiply").attr("stroke", null);
dot.attr("display", "none"); // aucun affichage
}
}