Adds support for external visualizer functions.
This commit is contained in:
@@ -46,7 +46,7 @@ export class VisJsGraphViewer extends React.Component<{
|
||||
shape: n.shape,
|
||||
});
|
||||
}
|
||||
this.nodes.forEach(item => {
|
||||
this.nodes.forEach((item) => {
|
||||
if (!newNodes.has(item.id)) {
|
||||
this.nodes.remove(item);
|
||||
}
|
||||
@@ -74,7 +74,7 @@ export class VisJsGraphViewer extends React.Component<{
|
||||
],
|
||||
});
|
||||
}
|
||||
this.edges.forEach(item => {
|
||||
this.edges.forEach((item) => {
|
||||
if (!newEdges.has(item.id)) {
|
||||
this.edges.remove(item);
|
||||
}
|
||||
@@ -99,6 +99,92 @@ export class VisJsGraphViewer extends React.Component<{
|
||||
},
|
||||
},
|
||||
};
|
||||
const network = new Network(this.divRef.current!, data, options);
|
||||
this.network = new Network(this.divRef.current!, data, options);
|
||||
this.divRef.current!.setAttribute("tabindex", "0");
|
||||
document.addEventListener("copy", this.onCopy);
|
||||
}
|
||||
|
||||
private network: Network | undefined;
|
||||
private readonly onCopy = (e: ClipboardEvent) => {
|
||||
if (!this.network) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!(
|
||||
document.activeElement &&
|
||||
document.activeElement.className === "vis-network"
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const n = this.network as any;
|
||||
|
||||
const nodesText: string[] = [];
|
||||
|
||||
let id = 10;
|
||||
const visJsIdToNodeId = new Map<string, number>();
|
||||
|
||||
// export to draw.io
|
||||
for (const node of Object.values(n.body.nodes) as any) {
|
||||
const label = node.shape.options.label;
|
||||
if (label === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let style = "";
|
||||
if (node.shape.constructor.name === "Ellipse") {
|
||||
style += "ellipse;";
|
||||
} else {
|
||||
style += "rounded=1;";
|
||||
}
|
||||
|
||||
const nodeId = id++;
|
||||
visJsIdToNodeId.set(node.id, nodeId);
|
||||
|
||||
nodesText.push(
|
||||
`
|
||||
<mxCell id="${nodeId}" value="${label}" style="${style}" vertex="1" parent="1">
|
||||
<mxGeometry x="${node.x}" y="${node.y}" width="${node.shape.width}" height="${node.shape.height}" as="geometry"/>
|
||||
</mxCell>`
|
||||
);
|
||||
}
|
||||
|
||||
for (const edge of Object.values(n.body.edges) as any) {
|
||||
const label = edge.options.label || "";
|
||||
const edgeId = id++;
|
||||
|
||||
nodesText.push(
|
||||
`
|
||||
<mxCell id="${edgeId}" value="${label}" edge="1" source="${visJsIdToNodeId.get(
|
||||
edge.from.id
|
||||
)}" target="${visJsIdToNodeId.get(edge.to.id)}" parent="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>`
|
||||
);
|
||||
}
|
||||
|
||||
const data = `
|
||||
<mxGraphModel>
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
|
||||
${nodesText.join("\n")}
|
||||
</root>
|
||||
</mxGraphModel>`;
|
||||
|
||||
/*
|
||||
<mxCell id="2" value="xxx" edge="1" source="3" target="4" parent="1">
|
||||
<mxGeometry relative="1" as="geometry"/>
|
||||
</mxCell>
|
||||
*/
|
||||
|
||||
e.clipboardData!.setData("text/plain", encodeURIComponent(data));
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener("copy", this.onCopy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
sOpenObject,
|
||||
sLiteral,
|
||||
sArrayOf,
|
||||
sLiteral,
|
||||
sNull,
|
||||
sNumber,
|
||||
sOpenObject,
|
||||
sOptionalProp,
|
||||
sAny,
|
||||
sProp,
|
||||
sString,
|
||||
sUnion,
|
||||
sNumber,
|
||||
sNull,
|
||||
} from "@hediet/semantic-json";
|
||||
import { makeLazyLoadable } from "../../utils/LazyLoadable";
|
||||
import { Deferred } from "@hediet/std/synchronization";
|
||||
import {
|
||||
createLazyReactVisualization,
|
||||
createVisualizer,
|
||||
globalVisualizationFactory,
|
||||
createReactVisualization,
|
||||
createLazyReactVisualization,
|
||||
} from "@hediet/visualization-core";
|
||||
import * as React from "react";
|
||||
import { visualizationNs } from "../../consts";
|
||||
import { makeLazyLoadable } from "../../utils/LazyLoadable";
|
||||
|
||||
const PlotlyViewerLazyLoadable = makeLazyLoadable(
|
||||
async () => (await import("./PlotlyViewer")).PlotlyViewer
|
||||
@@ -45,16 +44,22 @@ export const plotlyVisualizer = createVisualizer({
|
||||
x: sOptionalProp(sDatumArr),
|
||||
y: sOptionalProp(sDatumArr),
|
||||
z: sOptionalProp(sDatumArr),
|
||||
cells: sOptionalProp(sOpenObject({
|
||||
values: sArrayOf(sDatumArr),
|
||||
})),
|
||||
header: sOptionalProp(sOpenObject({
|
||||
values: sDatumArr,
|
||||
})),
|
||||
domain: sOptionalProp(sOpenObject({
|
||||
x: sArrayOf(sNumber()),
|
||||
y: sArrayOf(sNumber()),
|
||||
})),
|
||||
cells: sOptionalProp(
|
||||
sOpenObject({
|
||||
values: sArrayOf(sDatumArr),
|
||||
})
|
||||
),
|
||||
header: sOptionalProp(
|
||||
sOpenObject({
|
||||
values: sDatumArr,
|
||||
})
|
||||
),
|
||||
domain: sOptionalProp(
|
||||
sOpenObject({
|
||||
x: sArrayOf(sNumber()),
|
||||
y: sArrayOf(sNumber()),
|
||||
})
|
||||
),
|
||||
type: sOptionalProp(
|
||||
sUnion([
|
||||
sLiteral("bar"),
|
||||
@@ -129,14 +134,20 @@ export const plotlyVisualizer = createVisualizer({
|
||||
priority: 1000,
|
||||
preload: PlotlyViewerLazyLoadable.preload,
|
||||
},
|
||||
({ theme, readyCallback }) => (
|
||||
<PlotlyViewerLazyLoadable
|
||||
data={data.data}
|
||||
layout={data.layout}
|
||||
theme={theme}
|
||||
onReady={readyCallback}
|
||||
/>
|
||||
)
|
||||
({ theme }) => {
|
||||
const b = new Deferred();
|
||||
return {
|
||||
node: (
|
||||
<PlotlyViewerLazyLoadable
|
||||
data={data.data}
|
||||
layout={data.layout}
|
||||
theme={theme}
|
||||
onReady={() => b.resolve}
|
||||
/>
|
||||
),
|
||||
ready: b.promise,
|
||||
};
|
||||
}
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user