2021-07-27 10:55:15 +00:00
|
|
|
/**
|
|
|
|
* @author Martin Karkowski
|
|
|
|
* @email m.karkowski@zema.de
|
|
|
|
* @create date 2021-07-23 10:44:48
|
2021-08-26 17:41:08 +00:00
|
|
|
* @modify date 2021-08-25 11:48:46
|
2021-07-27 10:55:15 +00:00
|
|
|
* @desc [description]
|
2020-12-01 12:05:35 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
import * as go from "gojs";
|
|
|
|
import { ReactDiagram } from "gojs-react";
|
|
|
|
import * as React from "react";
|
2021-08-26 17:41:08 +00:00
|
|
|
import { generateGraph, ImplementedGraphs } from "./graph-types/generateGraph";
|
2020-12-01 12:05:35 +00:00
|
|
|
|
|
|
|
interface DiagramProps {
|
|
|
|
nodeDataArray: Array<go.ObjectData>;
|
|
|
|
linkDataArray: Array<go.ObjectData>;
|
2021-07-27 10:55:15 +00:00
|
|
|
initDiagram?: () => go.Diagram;
|
2021-08-26 17:41:08 +00:00
|
|
|
diagramType?: ImplementedGraphs;
|
|
|
|
templates?: Array<{
|
2021-07-27 10:55:15 +00:00
|
|
|
name: string;
|
|
|
|
template: go.Part;
|
|
|
|
}>;
|
|
|
|
modelData?: go.ObjectData;
|
2020-12-01 12:05:35 +00:00
|
|
|
skipsDiagramUpdate: boolean;
|
2021-07-27 10:55:15 +00:00
|
|
|
onDiagramEvent?: (e: go.DiagramEvent) => void;
|
|
|
|
eventsToSubscribe?: go.DiagramEventName[];
|
2021-08-26 17:41:08 +00:00
|
|
|
onModelChange?: (e: go.Model) => void;
|
|
|
|
onDiagramReady?: (diagram: go.Diagram) => void;
|
|
|
|
size?: {
|
|
|
|
height: string;
|
|
|
|
width: string;
|
|
|
|
};
|
2020-12-01 12:05:35 +00:00
|
|
|
}
|
|
|
|
|
2021-07-27 10:55:15 +00:00
|
|
|
export class DiagramWrapper extends React.Component<DiagramProps, never> {
|
2020-12-01 12:05:35 +00:00
|
|
|
/**
|
|
|
|
* Ref to keep a reference to the Diagram component, which provides access to the GoJS diagram via getDiagram().
|
|
|
|
*/
|
|
|
|
private diagramRef: React.RefObject<ReactDiagram>;
|
|
|
|
|
|
|
|
/** @internal */
|
|
|
|
constructor(props: DiagramProps) {
|
|
|
|
super(props);
|
|
|
|
this.diagramRef = React.createRef();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the diagram reference and add any desired diagram listeners.
|
|
|
|
* Typically the same function will be used for each listener, with the function using a switch statement to handle the events.
|
|
|
|
*/
|
2021-07-27 10:55:15 +00:00
|
|
|
public componentDidMount(): void {
|
2020-12-01 12:05:35 +00:00
|
|
|
if (!this.diagramRef.current) return;
|
2021-07-27 10:55:15 +00:00
|
|
|
|
2020-12-01 12:05:35 +00:00
|
|
|
const diagram = this.diagramRef.current.getDiagram();
|
2021-07-27 10:55:15 +00:00
|
|
|
diagram.div.style.height = "100%";
|
|
|
|
diagram.div.style.width = "100%";
|
|
|
|
|
2020-12-01 12:05:35 +00:00
|
|
|
if (diagram instanceof go.Diagram) {
|
2021-07-27 10:55:15 +00:00
|
|
|
// If the Diagram is ready, we try to add the Templates.
|
|
|
|
const templates = Array.isArray(this.props.templates)
|
|
|
|
? this.props.templates
|
|
|
|
: [];
|
|
|
|
|
|
|
|
for (const template of templates) {
|
|
|
|
diagram.nodeTemplateMap.add(template.name, template.template);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof this.props.onDiagramEvent === "function") {
|
|
|
|
// Now we define the events we are listening on.
|
|
|
|
// We will forward these events to the callback
|
|
|
|
// "onDiagramEvent"
|
|
|
|
const subscribedEvents: go.DiagramEventName[] = Array.isArray(
|
|
|
|
this.props.eventsToSubscribe
|
|
|
|
)
|
|
|
|
? this.props.eventsToSubscribe
|
|
|
|
: [];
|
|
|
|
for (const eventName of subscribedEvents) {
|
|
|
|
diagram.addDiagramListener(eventName, this.props.onDiagramEvent);
|
|
|
|
}
|
|
|
|
}
|
2021-08-26 17:41:08 +00:00
|
|
|
|
|
|
|
if (typeof this.props.onDiagramReady === "function") {
|
|
|
|
this.props.onDiagramReady(diagram);
|
|
|
|
}
|
2020-12-01 12:05:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the diagram reference and remove listeners that were added during mounting.
|
|
|
|
*/
|
2021-07-27 10:55:15 +00:00
|
|
|
public componentWillUnmount(): void {
|
2020-12-01 12:05:35 +00:00
|
|
|
if (!this.diagramRef.current) return;
|
|
|
|
const diagram = this.diagramRef.current.getDiagram();
|
|
|
|
if (diagram instanceof go.Diagram) {
|
|
|
|
diagram.removeDiagramListener(
|
|
|
|
"ChangedSelection",
|
|
|
|
this.props.onDiagramEvent
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Diagram initialization method, which is passed to the ReactDiagram component.
|
|
|
|
* This method is responsible for making the diagram and initializing the model, any templates,
|
|
|
|
* and maybe doing other initialization tasks like customizing tools.
|
|
|
|
* The model's data should not be set here, as the ReactDiagram component handles that.
|
|
|
|
*/
|
2021-07-27 10:55:15 +00:00
|
|
|
protected initDiagram(): go.Diagram {
|
|
|
|
if (typeof this.props.initDiagram === "function") {
|
|
|
|
return this.props.initDiagram();
|
|
|
|
} else if (typeof this.props.diagramType === "string") {
|
|
|
|
return generateGraph(this.props.diagramType);
|
|
|
|
}
|
2020-12-01 12:05:35 +00:00
|
|
|
|
2021-07-27 10:55:15 +00:00
|
|
|
throw Error("");
|
2020-12-01 12:05:35 +00:00
|
|
|
}
|
|
|
|
|
2021-07-27 10:55:15 +00:00
|
|
|
public render(): JSX.Element {
|
2021-08-26 17:41:08 +00:00
|
|
|
const style = {
|
|
|
|
height: this.props.size?.height || "100%",
|
|
|
|
width: this.props.size?.width || "100%",
|
|
|
|
};
|
|
|
|
|
2021-07-27 10:55:15 +00:00
|
|
|
const _this = this;
|
2021-08-26 17:41:08 +00:00
|
|
|
console.log(_this.props.nodeDataArray, _this.props.linkDataArray);
|
2020-12-01 12:05:35 +00:00
|
|
|
return (
|
2021-08-26 17:41:08 +00:00
|
|
|
<div style={style}>
|
|
|
|
<ReactDiagram
|
|
|
|
ref={this.diagramRef}
|
|
|
|
divClassName="None"
|
|
|
|
initDiagram={() => {
|
|
|
|
// We will call init-diagram on the beginning
|
|
|
|
const diagram = _this.initDiagram();
|
|
|
|
return diagram;
|
|
|
|
}}
|
|
|
|
nodeDataArray={_this.props.nodeDataArray}
|
|
|
|
linkDataArray={_this.props.linkDataArray}
|
|
|
|
modelData={{}}
|
|
|
|
// modelData={_this.props.modelData}
|
|
|
|
onModelChange={(e) => {
|
|
|
|
if (typeof _this.props.onModelChange === "function") {
|
|
|
|
if (!_this.diagramRef.current) return;
|
|
|
|
const diagram = _this.diagramRef.current.getDiagram();
|
|
|
|
_this.props.onModelChange(diagram.model);
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
skipsDiagramUpdate={_this.props.skipsDiagramUpdate}
|
|
|
|
/>
|
|
|
|
</div>
|
2020-12-01 12:05:35 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|