/** * @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; linkDataArray: Array; modelData: go.ObjectData; skipsDiagramUpdate: boolean; onDiagramEvent: (e: go.DiagramEvent) => void; onModelChange: (e: go.IncrementalData) => void; } export class DiagramWrapper extends React.Component { /** * Ref to keep a reference to the component, which provides access to the GoJS diagram via getDiagram(). */ private diagramRef: React.RefObject; private paletteRef: React.RefObject; 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 (
Water
{ 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", }, ], }, {}, ]} >
); } } export default DiagramWrapper;