- Foldable left panel (user profile) and right panel (task details) - Clicking a task in the list or graph node selects it and shows details - Both views (task list + graph) always mounted via absolute inset-0 for correct canvas dimensions; tabs toggle visibility with opacity - Graph node selection animation: other nodes repel outward (charge -600), then selected node smoothly slides to center (500ms cubic ease-out), then charge restores to -120 and graph stabilizes - Graph re-fits on tab switch and panel resize via ResizeObserver - Fix UUID string IDs throughout (backend returns UUIDs, not integers) - Add TaskDetailPanel, UserPanel components - Add CLAUDE.md project documentation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
27 lines
716 B
JavaScript
27 lines
716 B
JavaScript
const distance = (x1, y1, z1, x2, y2, z2) => Math.sqrt((x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2);
|
|
|
|
export function findAllWithinRadius(x, y, z, radius) {
|
|
const result = [];
|
|
|
|
const xMin = x - radius;
|
|
const yMin = y - radius;
|
|
const zMin = z - radius;
|
|
const xMax = x + radius;
|
|
const yMax = y + radius;
|
|
const zMax = z + radius;
|
|
|
|
this.visit((node, x1, y1, z1, x2, y2, z2) => {
|
|
if (!node.length) {
|
|
do {
|
|
const d = node.data;
|
|
if (distance(x, y, z, this._x(d), this._y(d), this._z(d)) <= radius) {
|
|
result.push(d);
|
|
}
|
|
} while (node = node.next);
|
|
}
|
|
return x1 > xMax || y1 > yMax || z1 > zMax || x2 < xMin || y2 < yMin || z2 < zMin;
|
|
});
|
|
|
|
return result;
|
|
}
|