mirror of
https://github.com/projectstorm/react-diagrams.git
synced 2026-03-13 09:50:09 +08:00
custom link demo
This commit is contained in:
130
demos/demo12/index.tsx
Normal file
130
demos/demo12/index.tsx
Normal file
@@ -0,0 +1,130 @@
|
||||
import {
|
||||
DiagramEngine,
|
||||
DefaultNodeFactory,
|
||||
DefaultLinkFactory,
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
DefaultPortModel,
|
||||
DiagramWidget,
|
||||
LinkWidget,
|
||||
LinkProps,
|
||||
DefaultLinkWidget,
|
||||
CustomizableLinkProps
|
||||
} from "../../src/main";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import * as React from "react";
|
||||
import { LinkWidgetFactory } from "../../src/WidgetFactories";
|
||||
|
||||
export class AdvancedLinkModel extends LinkModel {
|
||||
constructor() {
|
||||
super();
|
||||
this.linkType = "advanced";
|
||||
}
|
||||
}
|
||||
|
||||
export class AdvancedPortModel extends DefaultPortModel
|
||||
{
|
||||
constructor(isInput: boolean, name: string, label: string = null, id?: string) {
|
||||
super(isInput, name, label, id);
|
||||
}
|
||||
|
||||
createLinkModel(): LinkModel | null {
|
||||
return new AdvancedLinkModel();
|
||||
}
|
||||
}
|
||||
|
||||
export class AdvancedLinkWidget extends DefaultLinkWidget {
|
||||
constructor(props: LinkProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
beforeLinkGenerated(props: CustomizableLinkProps): CustomizableLinkProps {
|
||||
return {
|
||||
color: 'green',
|
||||
width: 4,
|
||||
smooth: props.smooth
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class AdvancedLinkWidgetFactory extends LinkWidgetFactory {
|
||||
constructor() {
|
||||
super("advanced");
|
||||
}
|
||||
|
||||
generateReactWidget(diagramEngine: DiagramEngine, link: LinkModel): JSX.Element {
|
||||
return React.createElement(AdvancedLinkWidget, {
|
||||
link: link,
|
||||
diagramEngine: diagramEngine
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* Simple link styling demo
|
||||
*
|
||||
* @Author kfrajtak
|
||||
*/
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.registerNodeFactory(new DefaultNodeFactory());
|
||||
engine.registerLinkFactory(new AdvancedLinkWidgetFactory());
|
||||
engine.registerLinkFactory(new DefaultLinkFactory());
|
||||
|
||||
var node1 = new DefaultNodeModel("Source", "rgb(0,192,255)");
|
||||
var port1 = node1.addPort(new AdvancedPortModel(false, "out-1", "Out solid"));
|
||||
var port2 = node1.addPort(new AdvancedPortModel(false, "out-2", "Out dashed"));
|
||||
var port3 = node1.addPort(new DefaultPortModel(false, "out-3", "Out default"));
|
||||
node1.x = 100;
|
||||
node1.y = 100;
|
||||
|
||||
var node2 = new DefaultNodeModel("Target", "rgb(192,255,0)");
|
||||
var port4 = node2.addPort(new AdvancedPortModel(true, "in-1", "In solid"));
|
||||
var port5 = node2.addPort(new AdvancedPortModel(true, "in-2", "In dashed"));
|
||||
var port6 = node2.addPort(new DefaultPortModel(true, "in-3", "In default"));
|
||||
node2.x = 300;
|
||||
node2.y = 100;
|
||||
|
||||
[node1, node2].forEach((item) => {
|
||||
item.addListener({
|
||||
selectionChanged: action('selectionChanged')
|
||||
});
|
||||
});
|
||||
|
||||
/*function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) {
|
||||
//3-A) create a default node
|
||||
|
||||
|
||||
|
||||
//3-B) create another default node
|
||||
|
||||
|
||||
//3-C) link the 2 nodes together
|
||||
var link1 = new LinkModel();
|
||||
link1.setSourcePort(port1);
|
||||
link1.setTargetPort(port2);
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addNode(node1);
|
||||
model.addNode(node2);
|
||||
model.addLink(link1);
|
||||
}*/
|
||||
|
||||
//2) setup the diagram model
|
||||
var model = new DiagramModel();
|
||||
|
||||
model.addNode(node1);
|
||||
model.addNode(node2);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return (
|
||||
<div>
|
||||
<DiagramWidget diagramEngine={engine} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -14,6 +14,7 @@ import demo8 from "./demo8/index";
|
||||
import demo9 from "./demo9/index";
|
||||
import demo10 from "./demo10/index";
|
||||
import demo11 from "./demo11/index";
|
||||
import demo12 from "./demo12/index";
|
||||
import demoDagre from "./demo-dagre/index";
|
||||
import {Helper} from "./Helper";
|
||||
|
||||
@@ -59,6 +60,9 @@ storiesOf("React Diagrams", module)
|
||||
})
|
||||
.add("Zoom to fit", () => {
|
||||
return demo11();
|
||||
})
|
||||
.add("Link types", () => {
|
||||
return demo12();
|
||||
});
|
||||
|
||||
// enable this to log mouse location when writing new puppeteer tests
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { BaseEntity, BaseListener } from "./BaseEntity";
|
||||
import * as _ from "lodash";
|
||||
import { port } from "_debugger";
|
||||
import { DiagramEngine } from "./DiagramEngine";
|
||||
|
||||
export interface BaseModelListener extends BaseListener {
|
||||
selectionChanged?(item: BaseModel<BaseModelListener>, isSelected: boolean): void;
|
||||
@@ -74,8 +75,8 @@ export class PointModel extends BaseModel<BaseModelListener> {
|
||||
this.x = points.x;
|
||||
this.y = points.y;
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getSelectedEntities() {
|
||||
if (super.isSelected() && !this.isConnectedToPort()) {
|
||||
return [this];
|
||||
@@ -272,6 +273,10 @@ export class LinkModel extends BaseModel<LinkModelListener> {
|
||||
getType(): string {
|
||||
return this.linkType;
|
||||
}
|
||||
|
||||
generateLinkWidget(diagramEngine: DiagramEngine): JSX.Element | null {
|
||||
return diagramEngine.generateWidgetForLink(this);
|
||||
}
|
||||
}
|
||||
|
||||
export class PortModel extends BaseModel<BaseModelListener> {
|
||||
@@ -324,6 +329,10 @@ export class PortModel extends BaseModel<BaseModelListener> {
|
||||
getLinks(): { [id: string]: LinkModel } {
|
||||
return this.links;
|
||||
}
|
||||
|
||||
createLinkModel(): LinkModel | null {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export class NodeModel extends BaseModel<BaseModelListener> {
|
||||
|
||||
@@ -3,11 +3,14 @@ import { LinkModel, PointModel } from "../Common";
|
||||
import * as _ from "lodash";
|
||||
import { DiagramEngine } from "../DiagramEngine";
|
||||
|
||||
export interface DefaultLinkProps {
|
||||
export interface CustomizableLinkProps {
|
||||
color?: string;
|
||||
width?: number;
|
||||
smooth?: boolean;
|
||||
}
|
||||
|
||||
export interface DefaultLinkProps extends CustomizableLinkProps {
|
||||
link: LinkModel;
|
||||
smooth?: boolean;
|
||||
diagramEngine: DiagramEngine;
|
||||
pointAdded?: (point: PointModel, event) => any;
|
||||
}
|
||||
@@ -81,12 +84,22 @@ export class DefaultLinkWidget extends React.Component<DefaultLinkProps, Default
|
||||
);
|
||||
}
|
||||
|
||||
beforeLinkGenerated(props: CustomizableLinkProps): CustomizableLinkProps {
|
||||
return props;
|
||||
}
|
||||
|
||||
generateLink(extraProps: any, id: string | number): JSX.Element {
|
||||
var props = this.beforeLinkGenerated({
|
||||
color: this.props.color,
|
||||
smooth: this.props.smooth,
|
||||
width: this.props.width
|
||||
});
|
||||
|
||||
var Bottom = (
|
||||
<path
|
||||
className={this.state.selected || this.props.link.isSelected() ? "selected" : ""}
|
||||
strokeWidth={this.props.width}
|
||||
stroke={this.props.color}
|
||||
strokeWidth={props.width}
|
||||
stroke={props.color}
|
||||
{...extraProps}
|
||||
/>
|
||||
);
|
||||
@@ -101,7 +114,7 @@ export class DefaultLinkWidget extends React.Component<DefaultLinkProps, Default
|
||||
this.setState({ selected: true });
|
||||
}}
|
||||
data-linkid={this.props.link.getID()}
|
||||
stroke={this.props.color}
|
||||
stroke={props.color}
|
||||
strokeOpacity={this.state.selected ? 0.1 : 0}
|
||||
strokeWidth={20}
|
||||
onContextMenu={() => {
|
||||
|
||||
@@ -414,8 +414,9 @@ export class DiagramWidget extends React.Component<DiagramProps, DiagramState> {
|
||||
//its a port element, we want to drag a link
|
||||
if (!this.props.diagramEngine.isModelLocked(model.model)) {
|
||||
var relative = diagramEngine.getRelativeMousePoint(event);
|
||||
var link = new LinkModel();
|
||||
link.setSourcePort(model.model);
|
||||
var sourcePort = model.model;
|
||||
var link = sourcePort.createLinkModel() || new LinkModel();
|
||||
link.setSourcePort(sourcePort);
|
||||
|
||||
link.getFirstPoint().updateLocation(relative);
|
||||
link.getLastPoint().updateLocation(relative);
|
||||
|
||||
@@ -4,6 +4,7 @@ import { DiagramEngine } from "../DiagramEngine";
|
||||
import { PointModel } from "../Common";
|
||||
import { LinkWidget } from "./LinkWidget";
|
||||
import * as _ from "lodash";
|
||||
import { LinkModel } from "../main";
|
||||
|
||||
export interface LinkLayerProps {
|
||||
diagramEngine: DiagramEngine;
|
||||
@@ -57,7 +58,7 @@ export class LinkLayerWidget extends React.Component<LinkLayerProps, LinkLayerSt
|
||||
}
|
||||
|
||||
//generate links
|
||||
var generatedLink = this.props.diagramEngine.generateWidgetForLink(link);
|
||||
var generatedLink = link.generateLinkWidget(this.props.diagramEngine);
|
||||
if (!generatedLink) {
|
||||
console.log("no link generated for type: " + link.getType());
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user