|
@@ -2,12 +2,40 @@ import * as React from "react";
|
|
|
import * as Mantine from "@mantine/core";
|
|
|
import { Graphviz } from 'graphviz-react';
|
|
|
|
|
|
-import {D3Graph, defaultGraphForces, toGraphvizDot} from "../d3graph/d3graph";
|
|
|
+import {D3Graph, D3GraphData, defaultGraphForces} from "../d3graph/d3graph";
|
|
|
import {InfoHoverCardOverlay} from "../info_hover_card";
|
|
|
|
|
|
+function esc(str) {
|
|
|
+ return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
|
+}
|
|
|
+
|
|
|
+function esc2(str) {
|
|
|
+ return encodeURIComponent(str);
|
|
|
+}
|
|
|
+
|
|
|
+// I know global variables are bad, but a GraphViz URL can only call a global function:
|
|
|
+const graphvizMap = new Map();
|
|
|
+(window as any).graphvizClicked = function(nodeId, button) {
|
|
|
+ const callback = graphvizMap.get(nodeId);
|
|
|
+ if (callback) callback(button);
|
|
|
+}
|
|
|
+
|
|
|
export function GraphView({graphData, help, mouseUpHandler}) {
|
|
|
const [renderer, setRenderer] = React.useState<"d3"|"graphviz">("d3");
|
|
|
|
|
|
+ if (mouseUpHandler) {
|
|
|
+ for (const node of graphData.nodes) {
|
|
|
+ graphvizMap.set(esc2(node.id), (button) => mouseUpHandler({button}, {x:0, y:0}, node));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const dot = `digraph {
|
|
|
+ bgcolor="transparent";
|
|
|
+ ${graphData.nodes.map(node => `"${esc(node.id)}" [${node.label===""?`shape=circle, width=0.3, height=0.3`:`shape=box`}, label="${esc(node.label)}", fillcolor="${node.color}", style="filled,rounded${node.bold?`,bold`:``}", URL="javascript:${esc2(`graphvizClicked('${node.id}', 2)`)}"]`).join('\n')}
|
|
|
+ ${graphData.links.map(link => `"${esc(link.source.id || link.source)}" -> "${esc(link.target.id || link.target)}" [label="${esc(link.label)}", color="${link.color}"${link.bidirectional?`, dir=none`:``}, labelURL="javascript:${esc2(`graphvizClicked('${link.source.id||link.source}', 1)`)}"]`).join('\n')}
|
|
|
+ }`;
|
|
|
+
|
|
|
+ // console.log(dot);
|
|
|
+
|
|
|
return <Mantine.Stack>
|
|
|
<Mantine.Group position="center">
|
|
|
<Mantine.SegmentedControl
|
|
@@ -26,7 +54,7 @@ export function GraphView({graphData, help, mouseUpHandler}) {
|
|
|
:
|
|
|
// @ts-ignore:
|
|
|
<Mantine.ScrollArea style={{backgroundColor:"#eee"}}>
|
|
|
- <Graphviz dot={toGraphvizDot(graphData)} options={{fit:false, width:null, height:null, scale:0.8}}/>
|
|
|
+ <Graphviz dot={dot} options={{fit:false, width:null, height:null, scale:0.8}}/>
|
|
|
</Mantine.ScrollArea>
|
|
|
}
|
|
|
</Mantine.Stack>;
|