本記事は図形をグリグリ動かせるアプリケーションを作るために図形ライブラリ使ってみたSigma.js編です。
図形をグリグリ動かせる!無料JS図形ライブラリ5選比較してみた
本記事👉図形をグリグリ動かすためのSigma.js+ Electron入門
図形をグリグリ動かすためのJSPlumb+ Electron入門
図形をグリグリ動かすためのCytoscape+ Electron入門
図形をグリグリ動かすためのmxGraph+ Electron入門
図形をグリグリ動かすためのD3.js+ Electron入門
今回お試しで作ったやつはこんな感じ
図形をグリグリしたかったんですが、おそらくSigma.jsはできないですね。
デモサイト を見ても図形は動かせなさそうなんですが、作っちゃったので供養として記事にします😭
Sigma.jsの使い方
Node.jsのインストール
本記事では、electron上で目的のライブラリを動作するため、まずはelectronを動かすうえで必要となるnode.jsをインストールしましょう。
ソースコード
package.json
{
"name": "sample",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"license": "ISC",
"devDependencies": {
"electron": "^35.1.4"
},
"dependencies": {
"graphology": "^0.26.0",
"sigma": "^3.0.1"
}
}
main.js
const { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'">
<title>Sigma.js Graph Example</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="graph-container"></div>
<script>
window.graphology = require('graphology');
window.sigma = require('sigma');
</script>
<script src="./renderer.js"></script>
</body>
</html>
renderer.js
// DOMの読み込み完了を待つ
document.addEventListener('DOMContentLoaded', () => {
// グラフのインスタンスを作成
const graph = new graphology.Graph();
// サンプルノードとエッジを追加
graph.addNode('1', {
x: 0,
y: 0,
size: 10,
label: 'Node 1',
color: '#FF6B6B'
});
graph.addNode('2', {
x: 2,
y: 2,
size: 10,
label: 'Node 2',
color: '#4ECDC4'
});
graph.addNode('3', {
x: -2,
y: 2,
size: 10,
label: 'Node 3',
color: '#45B7D1'
});
graph.addNode('4', {
x: 0,
y: 4,
size: 10,
label: 'Node 4',
color: '#96CEB4'
});
// エッジを追加
graph.addEdge('1', '2', { color: '#666' });
graph.addEdge('1', '3', { color: '#666' });
graph.addEdge('2', '4', { color: '#666' });
graph.addEdge('3', '4', { color: '#666' });
// Sigma.jsのインスタンスを作成
const container = document.getElementById('graph-container');
const renderer = new sigma.Sigma(graph, container, {
minCameraRatio: 0.1,
maxCameraRatio: 10,
labelRenderedSizeThreshold: 6,
labelSize: 12,
defaultNodeColor: '#999',
defaultEdgeColor: '#666',
defaultEdgeSize: 2,
renderEdgeLabels: true
});
// カメラの位置を調整
const camera = renderer.getCamera();
camera.setState({
ratio: 2,
x: 0,
y: 0
});
// ランダムな色を生成する関数
function getRandomColor() {
return '#' + Math.floor(Math.random()*16777215).toString(16).padStart(6, '0');
}
// ノードのクリックイベントを設定
renderer.on('clickNode', (event) => {
const node = event.node;
// 左クリックで色を変更
graph.setNodeAttribute(node, 'color', getRandomColor());
renderer.refresh();
});
// ノードの右クリックイベントを設定
renderer.on('rightClickNode', (event) => {
const node = event.node;
// 右クリックでサイズを変更
const currentSize = graph.getNodeAttribute(node, 'size');
const newSize = currentSize === 10 ? 20 : 10;
graph.setNodeAttribute(node, 'size', newSize);
renderer.refresh();
});
// マウスホイールでズーム
renderer.getMouseCaptor().on('wheel', (event) => {
const factor = event.delta > 0 ? 1.1 : 0.9;
camera.animatedZoom({ duration: 200, factor });
});
// ドラッグでパン
renderer.getMouseCaptor().on('mousedown', (event) => {
if (event.originalEvent.button === 0) { // 左クリック
renderer.getMouseCaptor().on('mousemove', (event) => {
camera.animate({
x: camera.x - event.deltaX / camera.ratio,
y: camera.y - event.deltaY / camera.ratio
}, { duration: 0 });
});
}
});
// マウスアップでドラッグ終了
renderer.getMouseCaptor().on('mouseup', () => {
renderer.getMouseCaptor().off('mousemove');
});
});
ソースコード解説
グラフの初期化とノードの追加
// グラフのインスタンスを作成
const graph = new graphology.Graph();
// サンプルノードを追加
graph.addNode('1', {
x: 0,
y: 0,
size: 10,
label: 'Node 1',
color: '#FF6B6B'
});
graphology.Graph()で新しいグラフインスタンスを作成
addNode()メソッドでノードを追加
エッジの追加
// エッジを追加
graph.addEdge('1', '2', { color: '#666' });
addEdge()メソッドでノード間の接続を追加
Sigma.jsのレンダリング設定
以下の箇所でsigma.Sigmaインスタンスを作成してグラフを可視化しています。
const renderer = new sigma.Sigma(graph, container, {
minCameraRatio: 0.1,
maxCameraRatio: 10,
labelRenderedSizeThreshold: 6,
labelSize: 12,
defaultNodeColor: '#999',
defaultEdgeColor: '#666',
defaultEdgeSize: 2,
renderEdgeLabels: true
});
重要な設定パラメータ:
minCameraRatio/maxCameraRatio: ズームの制限
labelRenderedSizeThreshold: ラベルを表示する最小サイズ
labelSize: ラベルのフォントサイズ
defaultNodeColor/defaultEdgeColor: デフォルトの色設定
インタラクティブ機能の実装
// ノードのクリックイベント
renderer.on('clickNode', (event) => {
const node = event.node;
graph.setNodeAttribute(node, 'color', getRandomColor());
renderer.refresh();
});
// マウスホイールでのズーム
renderer.getMouseCaptor().on('wheel', (event) => {
const factor = event.delta > 0 ? 1.1 : 0.9;
camera.animatedZoom({ duration: 200, factor });
});
イベントリスナーの設定:
clickNode: ノードクリック時の色変更
wheel: マウスホイールでのズーム操作
getRandomColor(): ランダムな色を生成する関数
camera.animatedZoom(): アニメーション付きのズーム操作
実行
ライブラリのインストール
npm install
アプリケーション起動!
npm start
終わりに
リサーチ不足でSigma.jsで図形をグリグリできない事を知らずに試してしまったので、記事の趣旨と少し違うものになってしまいましたが、グラフネットワークとか作りたくなったらまたチャレンジしてみようと思います。
参考URL
https://github.com/fujarenpaw/codeForBlog/tree/main/code/electron/sigmajs