thibaud frere
commited on
Commit
·
eb44cbb
1
Parent(s):
4bcb726
update scatter
Browse files
app/src/content/embeds/d3-scatter.html
CHANGED
|
@@ -77,7 +77,31 @@
|
|
| 77 |
const color = d3.scaleOrdinal();
|
| 78 |
const radius = () => 4;
|
| 79 |
let isDarkMode = false;
|
| 80 |
-
function getDotStrokeColor(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 81 |
|
| 82 |
// Data loading (real): banner visualization positions by category
|
| 83 |
async function fetchFirstAvailable(paths){
|
|
@@ -146,7 +170,7 @@
|
|
| 146 |
dots.enter().append('circle').attr('class','dot')
|
| 147 |
.attr('cx', d=>x(d.x)).attr('cy', d=>y(d.y)).attr('r', radius())
|
| 148 |
.attr('fill', fillFor).attr('fill-opacity', 0.85)
|
| 149 |
-
.attr('stroke', getDotStrokeColor()).attr('stroke-width', '0.75px')
|
| 150 |
.on('mouseenter', function(ev, d){
|
| 151 |
d3.select(this).style('stroke','var(--text-color)').style('stroke-width','1.5px').attr('fill-opacity', 1);
|
| 152 |
const swatch = `<svg width="10" height="10" viewBox="0 0 10 10" aria-hidden="true"><circle cx="5" cy="5" r="5" fill="${fillFor(d)}" /></svg>`;
|
|
@@ -158,12 +182,12 @@
|
|
| 158 |
tip.style.opacity = '1';
|
| 159 |
})
|
| 160 |
.on('mousemove', function(ev){ const [mx, my] = d3.pointer(ev, container); const ox=12, oy=12; tip.style.transform = `translate(${Math.round(mx+ox)}px, ${Math.round(my+oy)}px)`; })
|
| 161 |
-
.on('mouseleave', function(){ tip.style.opacity='0'; tip.style.transform='translate(-9999px, -9999px)'; d3.select(this).style('stroke', getDotStrokeColor()).style('stroke-width','0.75px').attr('fill-opacity', 0.85); })
|
| 162 |
.merge(dots)
|
| 163 |
.transition().duration(180)
|
| 164 |
.attr('cx', d=>x(d.x)).attr('cy', d=>y(d.y)).attr('r', radius())
|
| 165 |
.attr('fill', fillFor).attr('fill-opacity', 0.85)
|
| 166 |
-
.attr('stroke', getDotStrokeColor()).attr('stroke-width','0.75px');
|
| 167 |
dots.exit().remove();
|
| 168 |
|
| 169 |
// Compute centroids per category
|
|
|
|
| 77 |
const color = d3.scaleOrdinal();
|
| 78 |
const radius = () => 4;
|
| 79 |
let isDarkMode = false;
|
| 80 |
+
function getDotStrokeColor(fillColor = null){
|
| 81 |
+
if (!fillColor) return 'var(--muted-color)';
|
| 82 |
+
|
| 83 |
+
// Résoudre les variables CSS en couleurs réelles
|
| 84 |
+
let resolvedColor = fillColor;
|
| 85 |
+
if (fillColor.startsWith('var(')) {
|
| 86 |
+
const tempEl = document.createElement('div');
|
| 87 |
+
tempEl.style.color = fillColor;
|
| 88 |
+
document.body.appendChild(tempEl);
|
| 89 |
+
resolvedColor = getComputedStyle(tempEl).color;
|
| 90 |
+
document.body.removeChild(tempEl);
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
try {
|
| 94 |
+
const colorObj = d3.color(resolvedColor);
|
| 95 |
+
if (!colorObj) return 'var(--muted-color)';
|
| 96 |
+
|
| 97 |
+
// En mode light: bordure plus claire, en mode dark: bordure plus sombre
|
| 98 |
+
return isDarkMode ?
|
| 99 |
+
colorObj.darker(0.3).toString() :
|
| 100 |
+
colorObj.brighter(0.8).toString();
|
| 101 |
+
} catch {
|
| 102 |
+
return 'var(--muted-color)';
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
|
| 106 |
// Data loading (real): banner visualization positions by category
|
| 107 |
async function fetchFirstAvailable(paths){
|
|
|
|
| 170 |
dots.enter().append('circle').attr('class','dot')
|
| 171 |
.attr('cx', d=>x(d.x)).attr('cy', d=>y(d.y)).attr('r', radius())
|
| 172 |
.attr('fill', fillFor).attr('fill-opacity', 0.85)
|
| 173 |
+
.attr('stroke', d => getDotStrokeColor(fillFor(d))).attr('stroke-width', '0.75px')
|
| 174 |
.on('mouseenter', function(ev, d){
|
| 175 |
d3.select(this).style('stroke','var(--text-color)').style('stroke-width','1.5px').attr('fill-opacity', 1);
|
| 176 |
const swatch = `<svg width="10" height="10" viewBox="0 0 10 10" aria-hidden="true"><circle cx="5" cy="5" r="5" fill="${fillFor(d)}" /></svg>`;
|
|
|
|
| 182 |
tip.style.opacity = '1';
|
| 183 |
})
|
| 184 |
.on('mousemove', function(ev){ const [mx, my] = d3.pointer(ev, container); const ox=12, oy=12; tip.style.transform = `translate(${Math.round(mx+ox)}px, ${Math.round(my+oy)}px)`; })
|
| 185 |
+
.on('mouseleave', function(ev, d){ tip.style.opacity='0'; tip.style.transform='translate(-9999px, -9999px)'; d3.select(this).style('stroke', getDotStrokeColor(fillFor(d))).style('stroke-width','0.75px').attr('fill-opacity', 0.85); })
|
| 186 |
.merge(dots)
|
| 187 |
.transition().duration(180)
|
| 188 |
.attr('cx', d=>x(d.x)).attr('cy', d=>y(d.y)).attr('r', radius())
|
| 189 |
.attr('fill', fillFor).attr('fill-opacity', 0.85)
|
| 190 |
+
.attr('stroke', d => getDotStrokeColor(fillFor(d))).attr('stroke-width','0.75px');
|
| 191 |
dots.exit().remove();
|
| 192 |
|
| 193 |
// Compute centroids per category
|