Make second brain graph viewport circular
This commit is contained in:
@@ -168,7 +168,7 @@ body {
|
|||||||
margin: 8px auto 0;
|
margin: 8px auto 0;
|
||||||
background:#02040a;
|
background:#02040a;
|
||||||
border:1px solid #172033;
|
border:1px solid #172033;
|
||||||
border-radius: 8px;
|
border-radius: 50%;
|
||||||
box-shadow: 0 0 28px rgba(34,211,238,0.08), inset 0 0 42px rgba(124,58,237,0.08);
|
box-shadow: 0 0 28px rgba(34,211,238,0.08), inset 0 0 42px rgba(124,58,237,0.08);
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -435,9 +435,11 @@ function _graphCtx() { return _graphCanvas().getContext('2d'); }
|
|||||||
function _graphResizeCanvas() {
|
function _graphResizeCanvas() {
|
||||||
const canvas = _graphCanvas();
|
const canvas = _graphCanvas();
|
||||||
if (!canvas) return;
|
if (!canvas) return;
|
||||||
const w = canvas.parentElement.clientWidth - 24;
|
const availableW = Math.max(320, canvas.parentElement.clientWidth - 24);
|
||||||
canvas.width = Math.max(320, w);
|
const availableH = Math.max(360, (window.innerHeight || 900) - 250);
|
||||||
canvas.height = Math.max(560, Math.min(980, (window.innerHeight || 900) - 250));
|
const size = Math.max(320, Math.min(availableW, availableH, 920));
|
||||||
|
canvas.width = size;
|
||||||
|
canvas.height = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _graphResetData() {
|
function _graphResetData() {
|
||||||
@@ -494,10 +496,10 @@ function _graphSourceCenter(source) {
|
|||||||
}
|
}
|
||||||
const i = graphState.sourceIndex.get(key);
|
const i = graphState.sourceIndex.get(key);
|
||||||
const angle = i * 2.399963;
|
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 {
|
return {
|
||||||
x: Math.cos(angle) * ring,
|
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') {
|
if (n.kind === 'tag') {
|
||||||
const angle = _graphHashUnit(n.id) * Math.PI * 2;
|
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};
|
return {x: Math.cos(angle) * ring, y: Math.sin(angle) * ring};
|
||||||
}
|
}
|
||||||
if (n.kind === 'host') {
|
if (n.kind === 'host') {
|
||||||
const angle = _graphHashUnit(n.id) * Math.PI * 2;
|
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};
|
return {x: Math.cos(angle) * ring, y: Math.sin(angle) * ring};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,11 +525,11 @@ function _graphPlaceNode(n) {
|
|||||||
graphState.sourceCounts.set(source, local);
|
graphState.sourceCounts.set(source, local);
|
||||||
const center = _graphSourceCenter(source);
|
const center = _graphSourceCenter(source);
|
||||||
const angle = local * 2.399963 + _graphHashUnit(n.id) * 0.7;
|
const angle = local * 2.399963 + _graphHashUnit(n.id) * 0.7;
|
||||||
const radius = 18 + Math.sqrt(local) * 9 + _graphHashUnit(n.id + ':r') * 38;
|
const radius = 18 + Math.sqrt(local) * 7.5 + _graphHashUnit(n.id + ':r') * 28;
|
||||||
const squash = 0.72 + _graphHashUnit(source) * 0.46;
|
const squash = 0.94 + (_graphHashUnit(source) - 0.5) * 0.16;
|
||||||
return {
|
return {
|
||||||
x: center.x + Math.cos(angle) * radius * squash,
|
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');
|
const hint = document.getElementById('graphHint');
|
||||||
|
|
||||||
ctx.clearRect(0,0,canvas.width,canvas.height);
|
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, '#121a2b');
|
||||||
bg.addColorStop(0.55, '#070b16');
|
bg.addColorStop(0.55, '#070b16');
|
||||||
bg.addColorStop(1, '#02040a');
|
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();
|
ctx.restore();
|
||||||
const loaded = graphState.totalEngrams ? ` | engrams=${graphState.loadedEngrams}/${graphState.totalEngrams}` : '';
|
const loaded = graphState.totalEngrams ? ` | engrams=${graphState.loadedEngrams}/${graphState.totalEngrams}` : '';
|
||||||
hint.textContent = `nodes=${graphState.nodes.length} edges=${graphState.edges.length}${loaded}` + (term ? ` | match=${matches}` : '');
|
hint.textContent = `nodes=${graphState.nodes.length} edges=${graphState.edges.length}${loaded}` + (term ? ` | match=${matches}` : '');
|
||||||
@@ -1272,19 +1289,23 @@ function resetGraphView() {
|
|||||||
function fitGraphView(opts = {}) {
|
function fitGraphView(opts = {}) {
|
||||||
const canvas = _graphCanvas();
|
const canvas = _graphCanvas();
|
||||||
if (!graphState.sim.length) return;
|
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) {
|
for (const n of graphState.sim) {
|
||||||
minX = Math.min(minX, n.x); minY = Math.min(minY, n.y);
|
sumX += n.x;
|
||||||
maxX = Math.max(maxX, n.x); maxY = Math.max(maxY, n.y);
|
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 pad = graphState.sim.length > 20000 ? 96 : 54;
|
||||||
const zx = (canvas.width - pad) / w;
|
graphState.zoom = Math.max(0.04, Math.min(2.5, (Math.min(canvas.width, canvas.height) - pad) / (radius * 2)));
|
||||||
const zy = (canvas.height - pad) / h;
|
graphState.panX = canvas.width / 2 - centerX * graphState.zoom;
|
||||||
graphState.zoom = Math.max(0.04, Math.min(2.5, Math.min(zx, zy)));
|
graphState.panY = canvas.height / 2 - centerY * graphState.zoom;
|
||||||
graphState.panX = canvas.width / 2 - ((minX + maxX) / 2) * graphState.zoom;
|
|
||||||
graphState.panY = canvas.height / 2 - ((minY + maxY) / 2) * graphState.zoom;
|
|
||||||
if (!opts.silent) _graphDraw();
|
if (!opts.silent) _graphDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user