Graphページで使用しているSigma.jsには(実装時のメモ)、camera というモジュールがある。グラフ全体のどこをどう表示するか、の状態を管理する。
export interface Coordinates {
x: number;
y: number;
}
export interface CameraState extends Coordinates {
angle: number;
ratio: number;
}
camera の使い方はあまりドキュメントには書かれていないが、直接ソースコード camera.ts をみた方が早い。上のインターフェースはtypes.tsより。
camera.animate()
この camera には animate() というメソッドが実装されており、これを使えば特定のノードにズームインすることができる。
カメラ状態の取得と復元
まず、検索前のカメラ状態を保存・復元するメソッドを定義
renderer = new Sigma();
camera = renderer.getCamera();
const captureCameraState = () => {
if (!camera) return null;
const { x, y, angle, ratio } = camera.getState();
return { x, y, angle, ratio };
};
const restoreCameraState = (state) => {
if (!camera || !state) return;
camera.animate(state, { duration: 350, easing: 'quadraticInOut' });
};
camera.getState() で現在の CameraState を取得し、camera.animate() でアニメーション付きで状態を復元する。
ノードへのフォーカス
特定ノードの座標を取得してカメラを移動するメソッドを定義
function focusOnNode(nodeId) {
if (!camera || !renderer) return;
try {
const displayData = renderer.getNodeDisplayData(nodeId);
const targetX = displayData.x;
const targetY = displayData.y;
if (typeof targetX !== 'number' || typeof targetY !== 'number') return;
const currentState = camera.getState();
const nextRatio = Math.max(0.08, currentState.ratio / 1.8);
camera.animate(
{ ...currentState, x: targetX, y: targetY, ratio: nextRatio },
{ duration: 450, easing: 'quadraticInOut' }
);
} catch (error) {
console.error('Failed to focus on search result node', error);
}
}
ポイント
renderer.getNodeDisplayData(nodeId)でレンダリング後の座標を取得camera.getState()で現在の状態を取得し、x,yを対象ノードの座標に、ratioを縮小(ズームイン)camera.animate()で滑らかに移動
1.の代わりあるいはフォールバックとして、nodeId を使って、グラフデータからgetNodeAttribute(nodeId, 'x')で xy座標を取得しても同じだと思う。
あとはこの focusOnNode() 関数を使えば、特定のノードにズームインでき、restoreCameraState() でズームアウトできる。
Graphページへ実装
早速Graphページに検索ボックスをつけて、検索して1つに絞られた場合、そのノードにズームインするようにしてみた。
