317 lines
9.8 KiB
TypeScript
317 lines
9.8 KiB
TypeScript
/**
|
|
* @author Martin Karkowski
|
|
* @email m.karkowski@zema.de
|
|
* @create date 2021-06-24 09:22:49
|
|
* @modify date 2021-06-24 09:22:49
|
|
* @desc [description]
|
|
*/
|
|
import * as go from "gojs";
|
|
import { ReactDiagram, ReactPalette } from "gojs-react";
|
|
import * as React from "react";
|
|
import { PETRINET as FLOWCHART } from "../../resources/ui/gojs/graph-types/petri-net";
|
|
import { addNodeNextTo } from "../../resources/ui/gojs/helpers/add-node-next-to";
|
|
import { transitionTemplate } from "../../resources/ui/gojs/nodes/transition";
|
|
|
|
// props passed in from a parent component holding state, some of which will be passed to ReactDiagram
|
|
interface WrapperProps {
|
|
nodeDataArray: Array<go.ObjectData>;
|
|
linkDataArray: Array<go.ObjectData>;
|
|
modelData: go.ObjectData;
|
|
skipsDiagramUpdate: boolean;
|
|
onDiagramEvent: (e: go.DiagramEvent) => void;
|
|
onModelChange: (e: go.IncrementalData) => void;
|
|
}
|
|
|
|
export class DiagramWrapper extends React.Component<WrapperProps, {}> {
|
|
/**
|
|
* Ref to keep a reference to the component, which provides access to the GoJS diagram via getDiagram().
|
|
*/
|
|
private diagramRef: React.RefObject<ReactDiagram>;
|
|
private paletteRef: React.RefObject<ReactPalette>;
|
|
|
|
constructor(props: WrapperProps) {
|
|
super(props);
|
|
this.diagramRef = React.createRef();
|
|
this.paletteRef = 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.
|
|
* This is only necessary when you want to define additional app-specific diagram listeners.
|
|
*/
|
|
public componentDidMount(): void {
|
|
if (!this.diagramRef.current) return;
|
|
const diagram = this.diagramRef.current.getDiagram();
|
|
if (diagram instanceof go.Diagram) {
|
|
// diagram.link
|
|
const make = go.GraphObject.make;
|
|
diagram.div.style.height = "800px";
|
|
diagram.div.style.width = "1000px";
|
|
diagram.nodeTemplateMap.add(
|
|
"transition",
|
|
transitionTemplate([
|
|
make(
|
|
"Button",
|
|
{
|
|
alignment: go.Spot.TopCenter,
|
|
alignmentFocus: go.Spot.Right,
|
|
click: (e, b) => {
|
|
// take a button panel in an Adornment, get its Adornment, and then get its adorned Node
|
|
const node: go.Node = b.part.adornedPart;
|
|
addNodeNextTo(
|
|
node,
|
|
{ category: "place" },
|
|
{ category: "logicFlow", toPort: "LogicFlowIn" },
|
|
"to",
|
|
"n"
|
|
);
|
|
},
|
|
},
|
|
make(go.Shape, "PlusLine", { width: 6, height: 6 })
|
|
),
|
|
make(
|
|
"Button",
|
|
{
|
|
alignment: go.Spot.BottomCenter,
|
|
click: (e, b) => {
|
|
// take a button panel in an Adornment, get its Adornment, and then get its adorned Node
|
|
const node: go.Node = b.part.adornedPart;
|
|
addNodeNextTo(
|
|
node,
|
|
{ category: "place" },
|
|
{ category: "logicFlow", fromPort: "LogicFlowOut" },
|
|
"from",
|
|
"s"
|
|
);
|
|
},
|
|
toolTip: make("ToolTip", ""),
|
|
},
|
|
make(go.Shape, "PlusLine", { width: 6, height: 6 })
|
|
),
|
|
])
|
|
);
|
|
|
|
// diagram.linkT;
|
|
|
|
diagram.nodeTemplateMap.add(
|
|
"place",
|
|
make(
|
|
go.Node,
|
|
"Spot",
|
|
{
|
|
desiredSize: new go.Size(75, 75),
|
|
},
|
|
make(go.Shape, "Circle", {
|
|
fill: "#52ce60" /* green */,
|
|
stroke: null,
|
|
portId: "test",
|
|
fromLinkable: true,
|
|
fromLinkableSelfNode: false,
|
|
fromLinkableDuplicates: false,
|
|
toLinkable: true,
|
|
toLinkableSelfNode: false,
|
|
toLinkableDuplicates: false,
|
|
cursor: "pointer",
|
|
}),
|
|
make(go.TextBlock, "Start", {
|
|
font: "bold 16pt helvetica, bold arial, sans-serif",
|
|
stroke: "whitesmoke",
|
|
})
|
|
)
|
|
);
|
|
diagram.linkTemplateMap.add(
|
|
"logicFlow",
|
|
make(
|
|
go.Link, // the whole link panel
|
|
{
|
|
routing: go.Link.Normal,
|
|
corner: 15,
|
|
curve: go.Link.Bezier,
|
|
// adjusting: go.Link.Scale,
|
|
reshapable: true,
|
|
resegmentable: true,
|
|
curviness: 20,
|
|
// relinkableFrom: true,
|
|
// relinkableTo: true,
|
|
// toShortLength: 1,
|
|
category: "logicFlow",
|
|
},
|
|
// new go.Binding("points").makeTwoWay(),
|
|
// new go.Binding("curviness"),
|
|
make(
|
|
go.Shape, // the link shape
|
|
{ strokeWidth: 1.5 },
|
|
new go.Binding("stroke", "progress", function (progress) {
|
|
return progress ? "#52ce60" /* green */ : "black";
|
|
}),
|
|
new go.Binding("strokeWidth", "progress", function (progress) {
|
|
return progress ? 2.5 : 1.5;
|
|
})
|
|
),
|
|
make(
|
|
go.Shape, // the arrowhead
|
|
{ toArrow: "standard", stroke: null },
|
|
new go.Binding("fill", "progress", function (progress) {
|
|
return progress ? "#52ce60" /* green */ : "black";
|
|
})
|
|
),
|
|
make(
|
|
go.Panel,
|
|
"Auto",
|
|
make(
|
|
go.Shape, // the label background, which becomes transparent around the edges,
|
|
"Rectangle",
|
|
{
|
|
fill: "white",
|
|
stroke: null,
|
|
}
|
|
),
|
|
make(
|
|
go.TextBlock,
|
|
"transition", // the label text
|
|
{
|
|
textAlign: "center",
|
|
font: "9pt helvetica, arial, sans-serif",
|
|
margin: 4,
|
|
editable: true, // enable in-place editing
|
|
},
|
|
// editing the text automatically updates the model data
|
|
new go.Binding("text").makeTwoWay()
|
|
)
|
|
)
|
|
)
|
|
);
|
|
|
|
diagram.addDiagramListener("LinkDrawn", (e) => {
|
|
console.log(e.subject);
|
|
});
|
|
}
|
|
|
|
if (!this.paletteRef.current) return;
|
|
const palette = this.paletteRef.current.getPalette();
|
|
|
|
palette.div.style.height = "800px";
|
|
palette.div.style.width = "1000px";
|
|
}
|
|
|
|
/**
|
|
* Get the diagram reference and remove listeners that were added during mounting.
|
|
* This is only necessary when you have defined additional app-specific diagram listeners.
|
|
*/
|
|
public componentWillUnmount() {
|
|
if (!this.diagramRef.current) return;
|
|
const diagram = this.diagramRef.current.getDiagram();
|
|
if (diagram instanceof go.Diagram) {
|
|
diagram.removeDiagramListener(
|
|
"ChangedSelection",
|
|
this.props.onDiagramEvent
|
|
);
|
|
}
|
|
}
|
|
|
|
onModelChange(...args) {
|
|
console.log(...args);
|
|
}
|
|
|
|
/**
|
|
* 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 via the other props.
|
|
*/
|
|
private initDiagram(): go.Diagram {
|
|
const diagram = FLOWCHART();
|
|
|
|
// diagram.grid.visible = true;
|
|
diagram.toolManager.draggingTool.isGridSnapEnabled = true;
|
|
diagram.toolManager.resizingTool.isGridSnapEnabled = true;
|
|
|
|
return diagram;
|
|
}
|
|
|
|
public render(): JSX.Element {
|
|
return (
|
|
<div style={{ background: "white" }}>
|
|
<div draggable="true">Water</div>
|
|
<ReactDiagram
|
|
ref={this.diagramRef}
|
|
divClassName="none"
|
|
initDiagram={this.initDiagram}
|
|
nodeDataArray={this.props.nodeDataArray}
|
|
linkDataArray={this.props.linkDataArray}
|
|
modelData={this.props.modelData}
|
|
skipsDiagramUpdate={this.props.skipsDiagramUpdate}
|
|
/>
|
|
<ReactPalette
|
|
ref={this.paletteRef}
|
|
initPalette={(...args) => {
|
|
const myPalette = new go.Palette();
|
|
// the list of data to show in the Palette
|
|
|
|
myPalette.nodeTemplateMap.add("transition", transitionTemplate());
|
|
// myPalette.nodeTemplateMap.add("test", );
|
|
|
|
return myPalette;
|
|
}}
|
|
divClassName="none"
|
|
nodeDataArray={[
|
|
{
|
|
label: "Transtion",
|
|
guard: "x+1",
|
|
category: "transition",
|
|
icon: "https://cdn-images-1.medium.com/max/1600/0*F9ptwf7KyiVfrX0x.jpg",
|
|
description: "General Legal Division Director",
|
|
serviceName: "testservice",
|
|
serviceInputs: [
|
|
{
|
|
portId: 21,
|
|
label: "i1",
|
|
},
|
|
{
|
|
portId: 22,
|
|
label: "i2",
|
|
},
|
|
{
|
|
portId: 23,
|
|
label: "i3",
|
|
},
|
|
],
|
|
serviceOutputs: [
|
|
{
|
|
portId: 10,
|
|
label: "outp",
|
|
},
|
|
],
|
|
guardInputs: [
|
|
{
|
|
portId: 31,
|
|
label: "g1",
|
|
},
|
|
{
|
|
portId: 32,
|
|
label: "g2",
|
|
},
|
|
{
|
|
portId: 33,
|
|
label: "g3",
|
|
},
|
|
],
|
|
guardOutputs: [
|
|
{
|
|
portId: 11,
|
|
label: "g1",
|
|
},
|
|
],
|
|
},
|
|
{},
|
|
]}
|
|
></ReactPalette>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default DiagramWrapper;
|