import createEngine, {
DiagramModel,
DefaultNodeModel,
DefaultPortModel,
DefaultLinkFactory,
DefaultLinkModel,
DefaultLinkWidget
} from '@projectstorm/react-diagrams';
import { LinkWidget, PointModel } from '@projectstorm/react-diagrams-core';
import * as React from 'react';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
import { JSX, MouseEvent } from 'react';
import { DefaultLinkPointWidget, DefaultLinkSegmentWidget } from '@projectstorm/react-diagrams-defaults/dist';
import { DiagramEngine } from '@projectstorm/react-diagrams-core/dist';
export class AdvancedLinkModel extends DefaultLinkModel {
constructor() {
super({
type: 'advanced',
width: 4
});
}
}
export class AdvancedPortModel extends DefaultPortModel {
createLinkModel(): AdvancedLinkModel | null {
return new AdvancedLinkModel();
}
}
const CustomLinkArrowWidget = (props) => {
const { point, previousPoint } = props;
const angle =
90 +
(Math.atan2(
point.getPosition().y - previousPoint.getPosition().y,
point.getPosition().x - previousPoint.getPosition().x
) *
180) /
Math.PI;
//translate(50, -10),
return (
);
};
export interface AdvancedLinkWWidgetProps {
link: DefaultLinkModel;
diagramEngine: DiagramEngine;
pointAdded?: (point: PointModel, event: MouseEvent) => any;
renderPoints?: boolean;
selected?: (event: MouseEvent) => any;
}
export class AdvancedLinkWidget extends React.Component {
generatePoint = (point: PointModel): JSX.Element => {
return (
);
};
generateLink = (path: string, extraProps: any, id: string | number): JSX.Element => {
return (
);
};
addPointToLink = (event: MouseEvent, index: number) => {
if (
!event.shiftKey &&
!this.props.link.isLocked() &&
this.props.link.getPoints().length - 1 <= this.props.diagramEngine.getMaxNumberPointsPerLink()
) {
const position = this.props.diagramEngine.getRelativeMousePoint(event);
const point = this.props.link.point(position.x, position.y, index);
event.persist();
event.stopPropagation();
this.props.diagramEngine.getActionEventBus().fireAction({
event,
model: point
});
}
};
generateArrow(point: PointModel, previousPoint: PointModel): JSX.Element {
return (
);
}
render() {
//ensure id is present for all points on the path
var points = this.props.link.getPoints();
var paths = [];
//draw the multiple anchors and complex line instead
for (let j = 0; j < points.length - 1; j++) {
paths.push(
this.generateLink(
LinkWidget.generateLinePath(points[j], points[j + 1]),
{
'data-linkid': this.props.link.getID(),
'data-point': j,
onMouseDown: (event: MouseEvent) => {
this.addPointToLink(event, j + 1);
}
},
j
)
);
}
//render the circles
for (let i = 1; i < points.length - 1; i++) {
paths.push(this.generatePoint(points[i]));
}
if (this.props.link.getTargetPort() !== null) {
paths.push(this.generateArrow(points[points.length - 1], points[points.length - 2]));
} else {
paths.push(this.generatePoint(points[points.length - 1]));
}
return {paths};
}
}
export class AdvancedLinkFactory extends DefaultLinkFactory {
constructor() {
super('advanced');
}
generateModel(): AdvancedLinkModel {
return new AdvancedLinkModel();
}
generateReactWidget(event): JSX.Element {
return ;
}
}
/**
*
* Simple link styling demo
*
* @Author kfrajtak
*/
export default () => {
//1) setup the diagram engine
var engine = createEngine();
engine.getLinkFactories().registerFactory(new AdvancedLinkFactory());
// create some nodes
var node1 = new DefaultNodeModel('Source', 'rgb(0,192,255)');
let port1 = node1.addPort(new AdvancedPortModel(false, 'out'));
node1.setPosition(100, 100);
var node2 = new DefaultNodeModel('Target', 'rgb(192,255,0)');
var port2 = node2.addPort(new AdvancedPortModel(true, 'in'));
node2.setPosition(500, 350);
var node3 = new DefaultNodeModel('Source', 'rgb(0,192,255)');
let port3 = node3.addPort(new AdvancedPortModel(false, 'out'));
node3.setPosition(100, 500);
var node4 = new DefaultNodeModel('Target', 'rgb(192,255,0)');
var port4 = node4.addPort(new AdvancedPortModel(true, 'in'));
node4.setPosition(500, 450);
var model = new DiagramModel();
model.addAll(port1.link(port2), port3.link(port4));
// add everything else
model.addAll(node1, node2, node3, node4);
// load model into engine
engine.setModel(model);
// render the diagram!
return (
);
};