The lens follows your cursor. Nodes, edges, labels, and picking all share one warp, so hover and drag stay exact inside the magnified region.
// Enable the lens with a radius and distortion strength; pointer position is the only live
// input. OGJS applies one warp to nodes, edges, labels, and hit testing, keeping hover and
// drag exact without application-side magnification math.
import { Ogjs } from '../../src/index';
const og = new Ogjs({ container: '#viz', theme: 'light' });
const nodes = [], edges = [];
const PAL = ['#4f8cff', '#47d78a', '#f2a33c', '#e5484d', '#9d6bff'];
for (let c = 0; c < 5; c++) for (let k = 0; k < 24; k++) {
const i = c * 24 + k;
nodes.push({ id: i, size: k === 0 ? 10 : 4, color: PAL[c],
label: k === 0 ? 'hub-' + c : 'n' + i, data: { cluster: c } });
if (k > 0) edges.push({ source: i, target: c * 24 + (k > 4 ? (i % k) : 0) });
}
for (let c = 0; c < 5; c++) edges.push({ source: c * 24, target: ((c + 1) % 5) * 24 });
og.setGraph({ nodes, edges });
// Layout runs once in graph space. The fisheye is a camera-space lens, so enabling it never
// rewrites node coordinates or disturbs the force arrangement underneath.
og.layouts.force({ sync: true, iterations: 260, springLength: 46, repulsion: 1400 });
og.camera.fit();
og.enableHoverHighlight();
og.fisheye.enable(1.5, 240);
let on = true;
document.querySelector('#toggle').addEventListener('click', () => {
on = !on;
// Radius and strength describe the lens; pointer tracking and the shared node/edge/label
// distortion are owned by OGJS. Disable restores the exact unwarped view.
if (on) og.fisheye.enable(1.5, 240); else og.fisheye.disable();
});