はじめに
ReactFlowでnodeの移動範囲を可視化する方法を調べたのですが、あまり出てこなかったので、まとめました。
以下は、ChatGPTに出してもらった、ReactFlowの基本コードです。
import React, { useCallback, useState } from "react";
import ReactFlow, {
Background,
Controls,
MiniMap,
useNodesState,
useEdgesState,
} from "reactflow";
import "reactflow/dist/style.css";
import "./App.css";
const initialNodes = [
{
id: "1",
type: "default",
position: { x: 250, y: 150 },
data: { label: "Hello, React Flow!" },
},
];
const initialEdges = [];
const App = () => {
// ノードとエッジの状態を管理
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
return (
<div style={{ width: "100vw", height: "100vh" }}>
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
>
<Background />
<Controls />
<MiniMap />
</ReactFlow>
</div>
);
};
export default App;
方法
視界とノードの移動範囲を設定する
このままでは、視界もノードも、自由にどこへでも移動できるので、動かせる範囲を設定します。
以下の公式ドキュメントに書かれている、translateExtentとnodeExtentを使用します。
公式Doc: https://reactflow.dev/api-reference/react-flow
以下、サンプルコード。
import React from "react";
import ReactFlow, {
Background,
Controls,
MiniMap,
useNodesState,
useEdgesState,
} from "reactflow";
import "reactflow/dist/style.css";
import "./App.css";
const initialNodes = [
{
id: "1",
type: "default",
position: { x: 250, y: 150 },
data: { label: "Hello, React Flow!" },
},
];
const initialEdges = [];
const nodeExtent = [
[0, 0], // 最小範囲 (左上の座標)
[500, 300], // 最大範囲 (右下の座標)
];
const translateExtent = [
[0, 0], // 最小視界 (左上の座標)
[600, 400], // 最大視界 (右下の座標)
];
const App = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
return (
<div style={{ width: "100vw", height: "100vh" }}>
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
nodeExtent={nodeExtent} // ノードの移動範囲を制限
translateExtent={translateExtent} // カメラの移動範囲を制限
>
<Background />
<Controls />
<MiniMap />
</ReactFlow>
</div>
);
};
export default App;
これで動かせる範囲を調整できるようになります。
ノード移動範囲を可視化する
ここまでは調べて出るのですが、このノードが動かせる範囲を可視化しようとすると、なぜか方法があまり出ませんでした。
少し強引ですが、以下のような方法が使えます。
① css で react-flow__container クラスに対して、border、またはoutlineを設定する
以下の画像の通り、ReactFlowには react-flow__container などのクラスがあるので、
そのクラスに対し、css でボーダーを付けてしまう。
.react-flow__container{
border: 1px dashed #222;
}
追記:今回のサンプルコードではborderを使用しているが、borderは要素の大きさに影響が出るので、outlineの方が望ましい。
② css で react-flow__container クラスにwidthとheightを設定し、nodeExtextと合わせる
同様の形で react-flow__container にwidthとheightを設定する。
今回の場合は、nodeExtentの横が500、縦が300となっているので、widthは500px、heightは300pxとなる。
(同じ値にしてもずれることがあるので、そこは要調整。)
const nodeExtent = [
[0, 0], // 最小範囲 (左上の座標)
[500, 300], // 最大範囲 (右下の座標)
];
.react-flow__container{
width: 500px;
height: 300px;
border: 1px dashed #222;
}
まとめ
最終的なコードは以下。
import React from "react";
import ReactFlow, {
Background,
Controls,
MiniMap,
useNodesState,
useEdgesState,
} from "reactflow";
import "reactflow/dist/style.css";
import "./App.css";
const initialNodes = [
{
id: "1",
type: "default",
position: { x: 250, y: 150 },
data: { label: "Hello, React Flow!" },
},
];
const initialEdges = [];
const nodeExtent = [
[0, 0], // 最小範囲 (左上の座標)
[500, 300], // 最大範囲 (右下の座標)
];
const translateExtent = [
[0, 0], // 最小視界 (左上の座標)
[600, 400], // 最大視界 (右下の座標)
];
const App = () => {
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
return (
<div style={{ width: "100vw", height: "100vh" }}>
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
nodeExtent={nodeExtent} // ノードの移動範囲を制限
translateExtent={translateExtent} // カメラの移動範囲を制限
>
<Background />
<Controls />
<MiniMap />
</ReactFlow>
</div>
);
};
export default App;
/* 以下の内容を追記 */
.react-flow__container{
width: 500px;
height: 300px;
border: 1px dashed #222;
}
こういった方法で視界(カメラ)と、ノードの範囲を設定・可視化することができます。
以上です。