DiagramMakerを動かしてみたので備忘録。
すぐ動くサンプル無さそうだったので…
サンプルはここに置いてます https://github.com/tzmfreedom/javascript-sample/tree/master/diagram-maker-sample
インストール
$ npm install diagram-maker
TypeScriptじゃなくても動くようですが公式のサンプルがTypeScriptだったり、ちゃんとstyleあてないといけないといけなかったりするので webpackや各種loaderも併せて一式インストール
$ npm install @types/node \
style-loader \
css-loader \
sass \
sass-loader \
typescript \
ts-loader \
dagre \
redux \
webpack \
webpack-cli
ざっと使い方
セレクタを指定して要素に対してDiagramMakerをアタッチするような使い方になるので、HTMLにそれ用の要素を用意します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>DiagramMaker Test Environment</title>
</head>
<body>
<div id="diagramMakerContainer"></div>
<div id="diagramMakerLogger"></div>
<script src="./bundle.js"></script>
</body>
</html>
JSはこんな感じで書く。第一引数はマウントするセレクタ。
import { DiagramMaker } from 'diagram-maker';
const config = {
// ...
};
const initData = {
// ...
};
const diagramMaker = new DiagramMaker(
'diagramMakerContainer',
config,
// optionParams
{
initialData: initData
}
);
configの例
const config = {
options: {
// コネクタの場所を定義
// ノードごとにコネクタの位置を定義したい場合はnodeTypeConfigのconnectorPlacementOverrideプロパティで上書き可能
connectorPlacement: ConnectorPlacement.LEFT_RIGHT
},
// DOM操作してノードの見た目を定義したり、クリック時の処理を変更するメイン設定
renderCallbacks: {
destroy: () => undefined,
node: (node: DiagramMakerNode<{}>, container: HTMLElement) => {
// workspaceに置かれるノードのDOMを作成する関数
// HTMLElementなcontainerに対してinnerHTMLやappendChildを使ってHTMLを定義
// nodeのデータにはnodeの種別やユーザ定義データが含まれるので、それを使って表示する内容を変更することが可能
return createRectangularNode(node, container);
},
potentialNode: (node: DiagramMakerPotentialNode, container: HTMLElement) => {
// 新規作成用のノードをドラッグしているときに表示されるノードのHTMLを定義
return createPotentialNode(node, container);
},
panels: {
// パネルを定義するところで、パネルに新規作成用のノードを置いたり、操作メニュー的な使い方が可能。
// library: (panel: any, state: any, container: HTMLElement) => createLibraryPanel(container),
// tools: (
// panel: any,
// state: any,
// container: HTMLElement
// ) => createToolsPanel(container, () => windowAsAny.diagramMaker)
},
contextMenu: {
// node, edge, panel, workspaceに対する右クリック時のコンテキストメニューの処理を定義
node: (id: string | undefined, container: HTMLElement) => createNodeContextMenu(id, container),
edge: (id: string | undefined, container: HTMLElement) => createEdgeContextMenu(id, container),
panel: (id: string | undefined, container: HTMLElement) => createPanelContextMenu(id, container),
workspace: (container: HTMLElement) => createWorkspaceContextMenu(container)
} as ContextMenuRenderCallbacks
},
actionInterceptor: (action: Action, next: Dispatch<Action>, getState: () => DiagramMakerData<{}, {}>) => {
// 各操作に対して処理を挟み込める
next(action);
},
// ノードの種別やサイズを定義
nodeTypeConfig: {
'testId-centered': {
size: { width: 100, height: 100 },
connectorPlacementOverride: ConnectorPlacement.CENTERED
},
// ...
}
};
データの例
export const graph: DiagramMakerData<{}, {}> = {
nodes: {
// ノードの定義
node1: {
id: 'node1',
diagramMakerData: {
position: { x: 200, y: 150 },
size: { width: 100, height: 50 }
},
// ユーザ定義データはconsumerDataに入れる
consumerData: {}
},
node2: {
id: 'node2',
diagramMakerData: {
position: { x: 400, y: 300 },
size: { width: 100, height: 50 }
},
consumerData: {}
}
},
edges: {
edge1: {
id: 'edge1',
src: 'node1',
dest: 'node2',
diagramMakerData: { }
}
},
panels: {
// パネルの座標や大きさの定義。パネルの中の要素やノードはconfigで設定する
[`library`]: {
id: `library`,
position: { x: 20, y: 20 },
size: { width: 250, height: 600 },
positionAnchor: PositionAnchor.TOP_RIGHT
},
[`tools`]: {
id: `tools`,
position: { x: 20, y: 20 },
size: { width: 150, height: 400 }
}
},
workspace: {
position: { x: 0, y: 0 },
scale: 1,
canvasSize: { width: 3200, height: 1600 },
viewContainerSize: { width: window.innerWidth, height: window.innerHeight }
},
editor: { mode: EditorMode.DRAG }
};
また、APIを使ってstateを抽出したりレイアウトを変えたりできる
const currentState = diagramMaker.store.getState();
diagramMaker.store.subscribe(() => {
console.log(diagramMaker.store.getState());
});
詳細は公式リファレンスを参照: https://awslabs.github.io/diagram-maker/usage/api.html
css/scssも当てないと何も表示されなかったりするので注意
import 'diagram-maker/dist/diagramMaker.css';
import '../scss/index.scss';
import '../scss/CircularNode.scss';
import '../scss/Logger.scss';
import '../scss/RectangularNode.scss';