Make second brain graph viewport circular
This commit is contained in:
@@ -435,9 +435,11 @@ function _graphCtx() { return _graphCanvas().getContext('2d'); }
|
||||
function _graphResizeCanvas() {
|
||||
const canvas = _graphCanvas();
|
||||
if (!canvas) return;
|
||||
const w = canvas.parentElement.clientWidth - 24;
|
||||
canvas.width = Math.max(320, w);
|
||||
canvas.height = Math.max(560, Math.min(980, (window.innerHeight || 900) - 250));
|
||||
const availableW = Math.max(320, canvas.parentElement.clientWidth - 24);
|
||||
const availableH = Math.max(360, (window.innerHeight || 900) - 250);
|
||||
const size = Math.max(320, Math.min(availableW, availableH, 920));
|
||||
canvas.width = size;
|
||||
canvas.height = size;
|
||||
}
|
||||
|
||||
function _graphResetData() {
|
||||
@@ -494,10 +496,10 @@ function _graphSourceCenter(source) {
|
||||
}
|
||||
const i = graphState.sourceIndex.get(key);
|
||||
const angle = i * 2.399963;
|
||||
const ring = i < 1 ? 0 : 260 + Math.sqrt(i) * 95;
|
||||
const ring = i < 1 ? 0 : 210 + Math.sqrt(i) * 80;
|
||||
return {
|
||||
x: Math.cos(angle) * ring,
|
||||
y: Math.sin(angle) * ring * 0.82,
|
||||
y: Math.sin(angle) * ring,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -507,12 +509,12 @@ function _graphPlaceNode(n) {
|
||||
}
|
||||
if (n.kind === 'tag') {
|
||||
const angle = _graphHashUnit(n.id) * Math.PI * 2;
|
||||
const ring = 520 + (_graphHashUnit(n.id + ':r') * 420);
|
||||
const ring = 470 + (_graphHashUnit(n.id + ':r') * 260);
|
||||
return {x: Math.cos(angle) * ring, y: Math.sin(angle) * ring};
|
||||
}
|
||||
if (n.kind === 'host') {
|
||||
const angle = _graphHashUnit(n.id) * Math.PI * 2;
|
||||
const ring = 760 + (_graphHashUnit(n.id + ':r') * 260);
|
||||
const ring = 640 + (_graphHashUnit(n.id + ':r') * 220);
|
||||
return {x: Math.cos(angle) * ring, y: Math.sin(angle) * ring};
|
||||
}
|
||||
|
||||
@@ -523,11 +525,11 @@ function _graphPlaceNode(n) {
|
||||
graphState.sourceCounts.set(source, local);
|
||||
const center = _graphSourceCenter(source);
|
||||
const angle = local * 2.399963 + _graphHashUnit(n.id) * 0.7;
|
||||
const radius = 18 + Math.sqrt(local) * 9 + _graphHashUnit(n.id + ':r') * 38;
|
||||
const squash = 0.72 + _graphHashUnit(source) * 0.46;
|
||||
const radius = 18 + Math.sqrt(local) * 7.5 + _graphHashUnit(n.id + ':r') * 28;
|
||||
const squash = 0.94 + (_graphHashUnit(source) - 0.5) * 0.16;
|
||||
return {
|
||||
x: center.x + Math.cos(angle) * radius * squash,
|
||||
y: center.y + Math.sin(angle) * radius * (1.55 - squash),
|
||||
y: center.y + Math.sin(angle) * radius / squash,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1141,7 +1143,14 @@ function _graphDraw() {
|
||||
const hint = document.getElementById('graphHint');
|
||||
|
||||
ctx.clearRect(0,0,canvas.width,canvas.height);
|
||||
const bg = ctx.createRadialGradient(canvas.width * 0.52, canvas.height * 0.48, 10, canvas.width * 0.5, canvas.height * 0.5, Math.max(canvas.width, canvas.height) * 0.72);
|
||||
const cx = canvas.width / 2;
|
||||
const cy = canvas.height / 2;
|
||||
const viewR = Math.min(canvas.width, canvas.height) / 2 - 3;
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
ctx.arc(cx, cy, viewR, 0, Math.PI * 2);
|
||||
ctx.clip();
|
||||
const bg = ctx.createRadialGradient(canvas.width * 0.52, canvas.height * 0.48, 10, cx, cy, viewR);
|
||||
bg.addColorStop(0, '#121a2b');
|
||||
bg.addColorStop(0.55, '#070b16');
|
||||
bg.addColorStop(1, '#02040a');
|
||||
@@ -1235,6 +1244,14 @@ function _graphDraw() {
|
||||
}
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
ctx.restore();
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
ctx.arc(cx, cy, viewR, 0, Math.PI * 2);
|
||||
ctx.strokeStyle = 'rgba(34, 211, 238, 0.18)';
|
||||
ctx.lineWidth = 1.2;
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
const loaded = graphState.totalEngrams ? ` | engrams=${graphState.loadedEngrams}/${graphState.totalEngrams}` : '';
|
||||
hint.textContent = `nodes=${graphState.nodes.length} edges=${graphState.edges.length}${loaded}` + (term ? ` | match=${matches}` : '');
|
||||
@@ -1272,19 +1289,23 @@ function resetGraphView() {
|
||||
function fitGraphView(opts = {}) {
|
||||
const canvas = _graphCanvas();
|
||||
if (!graphState.sim.length) return;
|
||||
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
||||
let sumX = 0, sumY = 0;
|
||||
for (const n of graphState.sim) {
|
||||
minX = Math.min(minX, n.x); minY = Math.min(minY, n.y);
|
||||
maxX = Math.max(maxX, n.x); maxY = Math.max(maxY, n.y);
|
||||
sumX += n.x;
|
||||
sumY += n.y;
|
||||
}
|
||||
const centerX = sumX / graphState.sim.length;
|
||||
const centerY = sumY / graphState.sim.length;
|
||||
let radius = 1;
|
||||
for (const n of graphState.sim) {
|
||||
const dx = n.x - centerX;
|
||||
const dy = n.y - centerY;
|
||||
radius = Math.max(radius, Math.sqrt(dx * dx + dy * dy));
|
||||
}
|
||||
const w = Math.max(1, maxX - minX);
|
||||
const h = Math.max(1, maxY - minY);
|
||||
const pad = graphState.sim.length > 20000 ? 96 : 54;
|
||||
const zx = (canvas.width - pad) / w;
|
||||
const zy = (canvas.height - pad) / h;
|
||||
graphState.zoom = Math.max(0.04, Math.min(2.5, Math.min(zx, zy)));
|
||||
graphState.panX = canvas.width / 2 - ((minX + maxX) / 2) * graphState.zoom;
|
||||
graphState.panY = canvas.height / 2 - ((minY + maxY) / 2) * graphState.zoom;
|
||||
graphState.zoom = Math.max(0.04, Math.min(2.5, (Math.min(canvas.width, canvas.height) - pad) / (radius * 2)));
|
||||
graphState.panX = canvas.width / 2 - centerX * graphState.zoom;
|
||||
graphState.panY = canvas.height / 2 - centerY * graphState.zoom;
|
||||
if (!opts.silent) _graphDraw();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user