优化一个超绝的绘图
This commit is contained in:
@@ -869,9 +869,13 @@
|
||||
|
||||
const geoData = servers
|
||||
.filter(s => s.lat && s.lng)
|
||||
.map(s => ({
|
||||
.map((s, idx) => ({
|
||||
name: s.job,
|
||||
value: [shiftLng(s.lng), s.lat],
|
||||
// Add a tiny, stable jitter to marker positions to prevent perfect overlap of nodes in the same city
|
||||
value: [
|
||||
shiftLng(s.lng) + (Math.sin(idx * 12.9898) * 0.008),
|
||||
s.lat + (Math.cos(idx * 78.2330) * 0.008)
|
||||
],
|
||||
job: s.job,
|
||||
city: s.city,
|
||||
country: s.country,
|
||||
@@ -957,7 +961,6 @@
|
||||
const end = getShiftedCoords(route.dest);
|
||||
if (start && end) {
|
||||
// Canonical points for grouping (independent of direction)
|
||||
// Sort by longitude then latitude
|
||||
const pts = [start, end].slice().sort((a, b) => a[0] - b[0] || a[1] - b[1]);
|
||||
const key = `${pts[0][0].toFixed(4)},${pts[0][1].toFixed(4)}_${pts[1][0].toFixed(4)},${pts[1][1].toFixed(4)}`;
|
||||
if (!routeGroups[key]) routeGroups[key] = [];
|
||||
@@ -969,24 +972,32 @@
|
||||
const routes = routeGroups[key];
|
||||
const count = routes.length;
|
||||
|
||||
// Spread overlapping lines visually
|
||||
routes.forEach((item, i) => {
|
||||
const { route, start, end } = item;
|
||||
|
||||
// Identify if the route is in the "canonical" direction
|
||||
const pts = [start, end].slice().sort((a, b) => a[0] - b[0] || a[1] - b[1]);
|
||||
const isForward = (start === pts[0]);
|
||||
const isForward = (start[0] === pts[0][0] && start[1] === pts[0][1]);
|
||||
|
||||
// Calculate curveness: ensure all lines are slightly curved
|
||||
// Use a deterministic hash of the path to jitter the curves to avoid coincidence with other nearby paths
|
||||
const pathSeed = pts[0][0] + pts[0][1] * 2 + pts[1][0] * 3 + pts[1][1] * 4;
|
||||
const curveJitter = (Math.abs(Math.sin(pathSeed)) * 0.12) - 0.06; // Variation of +/- 0.06
|
||||
|
||||
// Calculate curveness: ensure all lines are curved and distinct
|
||||
let finalCurve = 0;
|
||||
if (count === 1) {
|
||||
finalCurve = 0.15; // Default slight curve for single lines
|
||||
// Default curve for single lines with a bit of path-specific variation
|
||||
finalCurve = 0.2 + curveJitter;
|
||||
} else {
|
||||
// Spread overlapping lines: 0.15, -0.15, 0.3, -0.3...
|
||||
// This creates an "eye" or "fan" effect where no line is straight
|
||||
const magnitude = 0.15 + Math.floor(i / 2) * 0.15;
|
||||
// Spread overlapping lines: 0.2, -0.2, 0.35, -0.35...
|
||||
// Use a dynamic step to keep lines within a reasonable arc range
|
||||
const step = Math.min(0.2, 0.5 / Math.ceil(count / 2));
|
||||
const magnitude = 0.2 + Math.floor(i / 2) * step;
|
||||
const spread = (i % 2 === 0) ? magnitude : -magnitude;
|
||||
// Adjust sign based on direction so they occupy unique visual slots
|
||||
finalCurve = isForward ? spread : -spread;
|
||||
|
||||
// Adjust based on direction so A->B and B->A land in different visual arcs (forming an "eye")
|
||||
finalCurve = (isForward ? spread : -spread) + curveJitter;
|
||||
}
|
||||
|
||||
finalSeries.push({
|
||||
@@ -1038,6 +1049,7 @@
|
||||
const regions = new Set(geoData.map(d => d.country)).size;
|
||||
dom.globeTotalRegions.textContent = regions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ---- Update Dashboard ----
|
||||
|
||||
Reference in New Issue
Block a user