tweaked map markers

This commit is contained in:
Lorenzo Venerandi
2026-02-28 16:45:07 +01:00
parent 4194c4585b
commit ce713d8072

View File

@@ -36,14 +36,45 @@ function createClusterIcon(cluster) {
gradientStops.push(`${color} ${start.toFixed(1)}deg ${end.toFixed(1)}deg`); gradientStops.push(`${color} ${start.toFixed(1)}deg ${end.toFixed(1)}deg`);
}); });
const size = Math.max(32, Math.min(50, 32 + Math.log2(total) * 5)); const size = Math.max(20, Math.min(44, 20 + Math.log2(total) * 4));
const inner = size - 10; const centerSize = size - 8;
const offset = 5; // (size - inner) / 2 const centerOffset = 4;
const ringWidth = 4;
const radius = (size / 2) - (ringWidth / 2);
const cx = size / 2;
const cy = size / 2;
const gapDeg = 8;
// Build SVG arc segments with gaps - glow layer first, then sharp layer
let glowSegments = '';
let segments = '';
let currentAngle = -90;
sorted.forEach(([cat, count], idx) => {
const sliceDeg = (count / total) * 360;
if (sliceDeg < gapDeg) return;
const startAngle = currentAngle + (gapDeg / 2);
const endAngle = currentAngle + sliceDeg - (gapDeg / 2);
const startRad = (startAngle * Math.PI) / 180;
const endRad = (endAngle * Math.PI) / 180;
const x1 = cx + radius * Math.cos(startRad);
const y1 = cy + radius * Math.sin(startRad);
const x2 = cx + radius * Math.cos(endRad);
const y2 = cy + radius * Math.sin(endRad);
const largeArc = (endAngle - startAngle) > 180 ? 1 : 0;
const color = categoryColors[cat] || '#8b949e';
// Glow layer - subtle
glowSegments += `<path d="M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2}" fill="none" stroke="${color}" stroke-width="${ringWidth + 4}" stroke-linecap="round" opacity="0.35" filter="url(#glow)"/>`;
// Sharp layer
segments += `<path d="M ${x1} ${y1} A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2}" fill="none" stroke="${color}" stroke-width="${ringWidth}" stroke-linecap="round"/>`;
currentAngle += sliceDeg;
});
return L.divIcon({ return L.divIcon({
html: `<div style="position:relative;width:${size}px;height:${size}px;">` + html: `<div style="position:relative;width:${size}px;height:${size}px;">` +
`<div style="position:absolute;top:0;left:0;width:${size}px;height:${size}px;border-radius:50%;background:conic-gradient(${gradientStops.join(', ')});box-shadow:0 0 6px rgba(0,0,0,0.5);"></div>` + `<svg width="${size}" height="${size}" style="position:absolute;top:0;left:0;overflow:visible;">` +
`<div style="position:absolute;top:${offset}px;left:${offset}px;width:${inner}px;height:${inner}px;border-radius:50%;background:rgba(13,17,23,0.85);color:#e6edf3;font-size:11px;font-weight:700;line-height:${inner}px;text-align:center;">${total}</div>` + `<defs><filter id="glow" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="2" result="blur"/></filter></defs>` +
`${glowSegments}${segments}</svg>` +
`<div style="position:absolute;top:${centerOffset}px;left:${centerOffset}px;width:${centerSize}px;height:${centerSize}px;border-radius:50%;background:#0d1117;display:flex;align-items:center;justify-content:center;color:#e6edf3;font-family:'SF Mono',Monaco,Consolas,monospace;font-size:${Math.max(9, centerSize * 0.38)}px;font-weight:600;">${total}</div>` +
`</div>`, `</div>`,
className: 'ip-cluster-icon', className: 'ip-cluster-icon',
iconSize: L.point(size, size) iconSize: L.point(size, size)
@@ -180,11 +211,11 @@ function buildMapMarkers(ips) {
// Single cluster group with custom pie-chart icons // Single cluster group with custom pie-chart icons
clusterGroup = L.markerClusterGroup({ clusterGroup = L.markerClusterGroup({
maxClusterRadius: 20, maxClusterRadius: 35,
spiderfyOnMaxZoom: true, spiderfyOnMaxZoom: true,
showCoverageOnHover: false, showCoverageOnHover: false,
zoomToBoundsOnClick: true, zoomToBoundsOnClick: true,
disableClusteringAtZoom: 10, disableClusteringAtZoom: 8,
iconCreateFunction: createClusterIcon iconCreateFunction: createClusterIcon
}); });