mirror of
https://github.com/projectstorm/react-diagrams.git
synced 2026-03-13 09:50:09 +08:00
more generics
This commit is contained in:
@@ -1,14 +1,32 @@
|
||||
import { Toolkit } from '../Toolkit';
|
||||
import { Toolkit } from "../Toolkit";
|
||||
|
||||
export interface BaseEvent {
|
||||
firing: boolean;
|
||||
stopPropagation: () => any;
|
||||
}
|
||||
|
||||
export interface BaseEventProxy extends BaseEvent {
|
||||
function: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listeners are always in the form of an object that contains methods that take events
|
||||
*/
|
||||
export type BaseListener = { [key: string]: (event: BaseEvent) => any };
|
||||
export type BaseListener = {
|
||||
/**
|
||||
* Generic event that fires before a specific event was fired
|
||||
*/
|
||||
eventWillFire?: (event: BaseEvent & { function: string }) => void;
|
||||
|
||||
/**
|
||||
* Generic event that fires after a specific event was fired (even if it was consumed)
|
||||
*/
|
||||
eventDidFire?: (event: BaseEvent & { function: string }) => void;
|
||||
/**
|
||||
* Type for other events that will fire
|
||||
*/
|
||||
[key: string]: (event: BaseEvent) => any
|
||||
};
|
||||
|
||||
/**
|
||||
* Base observer pattern class for working with listeners
|
||||
@@ -20,6 +38,19 @@ export class BaseObserver<L extends BaseListener = BaseListener> {
|
||||
this.listeners = {};
|
||||
}
|
||||
|
||||
private fireEventInternal(fire: boolean, k: keyof L, event: BaseEvent, ) {
|
||||
this.iterateListeners(listener => {
|
||||
// returning false here will instruct itteration to stop
|
||||
if (!fire && !event.firing) {
|
||||
return false;
|
||||
}
|
||||
// fire selected listener
|
||||
if (listener[k]) {
|
||||
listener[k](event as BaseEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fireEvent(event: Partial<BaseEvent> & object, k: keyof L) {
|
||||
event = {
|
||||
firing: true,
|
||||
@@ -29,15 +60,20 @@ export class BaseObserver<L extends BaseListener = BaseListener> {
|
||||
...event
|
||||
};
|
||||
|
||||
this.iterateListeners(listener => {
|
||||
// returning false here will instruct itteration to stop
|
||||
if (!event.firing) {
|
||||
return false;
|
||||
}
|
||||
if (listener[k]) {
|
||||
listener[k](event as BaseEvent);
|
||||
}
|
||||
});
|
||||
// fire pre
|
||||
this.fireEventInternal( true, "eventWillFire", {
|
||||
...event,
|
||||
function: k
|
||||
} as BaseEventProxy);
|
||||
|
||||
// fire main event
|
||||
this.fireEventInternal( false, k, event as BaseEvent);
|
||||
|
||||
// fire post
|
||||
this.fireEventInternal( true, "eventDidFire", {
|
||||
...event,
|
||||
function: k
|
||||
} as BaseEventProxy);
|
||||
}
|
||||
|
||||
iterateListeners(cb: (listener: L) => any) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { BaseModel, BaseModelGenerics, BaseModelListener } from "../core-models/BaseModel";
|
||||
import { PortModel } from './PortModel';
|
||||
import { BaseModelListener } from "../core-models/BaseModel";
|
||||
import * as _ from 'lodash';
|
||||
import { DiagramEngine } from '../DiagramEngine';
|
||||
import { BaseEntityEvent } from '../core-models/BaseEntity';
|
||||
import { BasePositionModel, BasePositionModelGenerics } from "../core-models/BasePositionModel";
|
||||
import { DiagramModel } from "./DiagramModel";
|
||||
import { PortModel } from "./PortModel";
|
||||
|
||||
export interface NodeModelListener extends BaseModelListener {
|
||||
positionChanged?(event: BaseEntityEvent<NodeModel>): void;
|
||||
@@ -13,11 +13,12 @@ export interface NodeModelListener extends BaseModelListener {
|
||||
export interface NodeModelGenerics extends BasePositionModelGenerics{
|
||||
LISTENER: NodeModelListener;
|
||||
PARENT: DiagramModel;
|
||||
PORT: PortModel;
|
||||
}
|
||||
|
||||
export class NodeModel<G extends NodeModelGenerics = NodeModelGenerics> extends BasePositionModel<G> {
|
||||
|
||||
ports: { [s: string]: PortModel };
|
||||
ports: { [s: string]: G['PORT'] };
|
||||
|
||||
// calculated post rendering so routing can be done correctly
|
||||
width: number;
|
||||
@@ -100,7 +101,7 @@ export class NodeModel<G extends NodeModelGenerics = NodeModelGenerics> extends
|
||||
});
|
||||
}
|
||||
|
||||
getPortFromID(id): PortModel | null {
|
||||
getPortFromID(id): G['PORT'] | null {
|
||||
for (var i in this.ports) {
|
||||
if (this.ports[i].getID() === id) {
|
||||
return this.ports[i];
|
||||
@@ -109,15 +110,15 @@ export class NodeModel<G extends NodeModelGenerics = NodeModelGenerics> extends
|
||||
return null;
|
||||
}
|
||||
|
||||
getPort(name: string): PortModel | null {
|
||||
getPort(name: string): G['PORT'] | null {
|
||||
return this.ports[name];
|
||||
}
|
||||
|
||||
getPorts(): { [s: string]: PortModel } {
|
||||
getPorts(): { [s: string]: G['PORT'] } {
|
||||
return this.ports;
|
||||
}
|
||||
|
||||
removePort(port: PortModel) {
|
||||
removePort(port: G['PORT']) {
|
||||
//clear the parent node reference
|
||||
if (this.ports[port.getName()]) {
|
||||
this.ports[port.getName()].setParent(null);
|
||||
@@ -125,7 +126,7 @@ export class NodeModel<G extends NodeModelGenerics = NodeModelGenerics> extends
|
||||
}
|
||||
}
|
||||
|
||||
addPort<T extends PortModel>(port: T): T {
|
||||
addPort<T extends G['PORT']>(port: T): T {
|
||||
port.setParent(this);
|
||||
this.ports[port.getName()] = port;
|
||||
return port;
|
||||
|
||||
@@ -1,26 +1,41 @@
|
||||
import { DiagramEngine, LabelModel } from '@projectstorm/react-diagrams-core';
|
||||
import {
|
||||
BaseModelGenerics,
|
||||
BaseModelOptions,
|
||||
DiagramEngine,
|
||||
LabelModel,
|
||||
} from "@projectstorm/react-diagrams-core";
|
||||
|
||||
export class DefaultLabelModel extends LabelModel {
|
||||
label: string;
|
||||
export interface DefaultLabelModelOptions extends Omit<BaseModelOptions, 'type'>{
|
||||
label?: string;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super('default');
|
||||
export interface DefaultLabelModelGenerics{
|
||||
OPTIONS: DefaultLabelModelOptions;
|
||||
}
|
||||
|
||||
export class DefaultLabelModel extends LabelModel<BaseModelGenerics & DefaultLabelModelGenerics> {
|
||||
|
||||
constructor(options: DefaultLabelModelOptions = {}) {
|
||||
super({
|
||||
...options,
|
||||
type: 'default'
|
||||
});
|
||||
this.offsetY = -23;
|
||||
}
|
||||
|
||||
setLabel(label: string) {
|
||||
this.label = label;
|
||||
this.options.label = label;
|
||||
}
|
||||
|
||||
deSerialize(ob, engine: DiagramEngine) {
|
||||
super.deSerialize(ob, engine);
|
||||
this.label = ob.label;
|
||||
this.options.label = ob.label;
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return {
|
||||
...super.serialize(),
|
||||
label: this.label
|
||||
label: this.options.label
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@ export class DefaultLabelWidget extends BaseWidget<DefaultLabelWidgetProps> {
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div {...this.getProps()}>{this.props.model.label}</div>;
|
||||
return <div {...this.getProps()}>{this.props.model.getOptions().label}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ import * as React from 'react';
|
||||
import { AbstractReactFactory } from '@projectstorm/react-diagrams-core';
|
||||
import { DefaultNodeModel } from './DefaultNodeModel';
|
||||
import { DefaultNodeWidget } from './DefaultNodeWidget';
|
||||
/**
|
||||
* @author Dylan Vorster
|
||||
*/
|
||||
|
||||
export class DefaultNodeFactory extends AbstractReactFactory<DefaultNodeModel> {
|
||||
constructor() {
|
||||
super('default');
|
||||
|
||||
@@ -1,48 +1,71 @@
|
||||
import * as _ from 'lodash';
|
||||
import { DiagramEngine, NodeModel, NodeModelListener, Toolkit } from '@projectstorm/react-diagrams-core';
|
||||
import {
|
||||
BaseModelOptions,
|
||||
DiagramEngine,
|
||||
NodeModel,
|
||||
NodeModelGenerics,
|
||||
} from "@projectstorm/react-diagrams-core";
|
||||
import { DefaultPortModel } from '../port/DefaultPortModel';
|
||||
|
||||
export class DefaultNodeModel extends NodeModel<NodeModelListener> {
|
||||
name: string;
|
||||
color: string;
|
||||
ports: { [s: string]: DefaultPortModel };
|
||||
export interface DefaultNodeModelOptions extends Omit<BaseModelOptions, 'type'>{
|
||||
name?: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
constructor(name: string = 'Untitled', color: string = 'rgb(0,192,255)') {
|
||||
super('default');
|
||||
this.name = name;
|
||||
this.color = color;
|
||||
export interface DefaultNodeModelGenerics{
|
||||
PORT: DefaultPortModel;
|
||||
OPTIONS: DefaultNodeModelOptions;
|
||||
}
|
||||
|
||||
export class DefaultNodeModel extends NodeModel<DefaultNodeModelGenerics & NodeModelGenerics> {
|
||||
|
||||
constructor(options: DefaultNodeModelOptions = {}) {
|
||||
super({
|
||||
type: 'default',
|
||||
name: 'Untitled',
|
||||
color: 'rgb(0,192,255)',
|
||||
...options
|
||||
});
|
||||
}
|
||||
|
||||
addInPort(label: string): DefaultPortModel {
|
||||
return this.addPort(new DefaultPortModel(true, Toolkit.UID(), label));
|
||||
return this.addPort(new DefaultPortModel({
|
||||
in: true,
|
||||
name: label,
|
||||
label: label
|
||||
}));
|
||||
}
|
||||
|
||||
addOutPort(label: string): DefaultPortModel {
|
||||
return this.addPort(new DefaultPortModel(false, Toolkit.UID(), label));
|
||||
return this.addPort(new DefaultPortModel({
|
||||
in: false,
|
||||
name: label,
|
||||
label: label
|
||||
}));
|
||||
}
|
||||
|
||||
deSerialize(object, engine: DiagramEngine) {
|
||||
super.deSerialize(object, engine);
|
||||
this.name = object.name;
|
||||
this.color = object.color;
|
||||
this.options.name = object.name;
|
||||
this.options.color = object.color;
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return _.merge(super.serialize(), {
|
||||
name: this.name,
|
||||
color: this.color
|
||||
name: this.options.name,
|
||||
color: this.options.color
|
||||
});
|
||||
}
|
||||
|
||||
getInPorts(): DefaultPortModel[] {
|
||||
return _.filter(this.ports, portModel => {
|
||||
return portModel.in;
|
||||
return portModel.getOptions().in;
|
||||
});
|
||||
}
|
||||
|
||||
getOutPorts(): DefaultPortModel[] {
|
||||
return _.filter(this.ports, portModel => {
|
||||
return !portModel.in;
|
||||
return !portModel.getOptions().in;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,15 +49,34 @@ export interface DefaultNodeProps extends BaseWidgetProps {
|
||||
* for both all the input ports on the left, and the output ports on the right.
|
||||
*/
|
||||
export class DefaultNodeWidget extends BaseWidget<DefaultNodeProps> {
|
||||
|
||||
listener: any;
|
||||
|
||||
generatePort = port => {
|
||||
return <DefaultPortLabel model={port} key={port.id} />;
|
||||
};
|
||||
|
||||
componentWillUnmount(): void {
|
||||
|
||||
// release repaint listener
|
||||
if(this.listener){
|
||||
this.listener();
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this.listener = this.props.node.registerListener({
|
||||
eventDidFire: () => {
|
||||
this.forceUpdate()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<S.Node background={this.props.node.color}>
|
||||
<S.Node background={this.props.node.getOptions().color}>
|
||||
<S.Title>
|
||||
<S.TitleName>{this.props.node.name}</S.TitleName>
|
||||
<S.TitleName>{this.props.node.getOptions().name}</S.TitleName>
|
||||
</S.Title>
|
||||
<S.Ports>
|
||||
<S.PortsContainer>{_.map(this.props.node.getInPorts(), this.generatePort)}</S.PortsContainer>
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
PortModelOptions
|
||||
} from "@projectstorm/react-diagrams-core";
|
||||
import { DefaultLinkModel } from '../link/DefaultLinkModel';
|
||||
import { DefaultNodeModel } from "../node/DefaultNodeModel";
|
||||
|
||||
export interface DefaultPortModelOptions extends Omit<PortModelOptions, 'type'>{
|
||||
label?: string;
|
||||
@@ -15,7 +16,7 @@ export interface DefaultPortModelOptions extends Omit<PortModelOptions, 'type'>{
|
||||
|
||||
export interface DefaultPortModelGenerics{
|
||||
OPTIONS: DefaultPortModelOptions;
|
||||
PARENT: DefaultLinkModel;
|
||||
PARENT: DefaultNodeModel;
|
||||
}
|
||||
|
||||
export class DefaultPortModel extends PortModel<PortModelGenerics & DefaultPortModelGenerics> {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as PF from 'pathfinding';
|
||||
import { PathFindingLinkFactory } from '../link/PathFindingLinkFactory';
|
||||
import { PointModel } from "@projectstorm/react-diagrams-core";
|
||||
|
||||
/*
|
||||
it can be very expensive to calculate routes when every single pixel on the canvas
|
||||
@@ -26,23 +27,17 @@ export default class PathFinding {
|
||||
* finds a direct path from point A to B.
|
||||
*/
|
||||
calculateDirectPath(
|
||||
from: {
|
||||
x: number;
|
||||
y: number;
|
||||
},
|
||||
to: {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
from: PointModel,
|
||||
to: PointModel
|
||||
): number[][] {
|
||||
const matrix = this.factory.getCanvasMatrix();
|
||||
const grid = new PF.Grid(matrix);
|
||||
|
||||
return pathFinderInstance.findPath(
|
||||
this.factory.translateRoutingX(Math.floor(from.x / this.factory.ROUTING_SCALING_FACTOR)),
|
||||
this.factory.translateRoutingY(Math.floor(from.y / this.factory.ROUTING_SCALING_FACTOR)),
|
||||
this.factory.translateRoutingX(Math.floor(to.x / this.factory.ROUTING_SCALING_FACTOR)),
|
||||
this.factory.translateRoutingY(Math.floor(to.y / this.factory.ROUTING_SCALING_FACTOR)),
|
||||
this.factory.translateRoutingX(Math.floor(from.getX() / this.factory.ROUTING_SCALING_FACTOR)),
|
||||
this.factory.translateRoutingY(Math.floor(from.getY() / this.factory.ROUTING_SCALING_FACTOR)),
|
||||
this.factory.translateRoutingX(Math.floor(to.getX() / this.factory.ROUTING_SCALING_FACTOR)),
|
||||
this.factory.translateRoutingY(Math.floor(to.getY() / this.factory.ROUTING_SCALING_FACTOR)),
|
||||
grid
|
||||
);
|
||||
}
|
||||
|
||||
@@ -125,26 +125,26 @@ export class PathFindingLinkFactory extends AbstractReactFactory<PathFindingLink
|
||||
vAdjustmentFactor: number;
|
||||
} => {
|
||||
const allNodesCoords = _.values(this.engine.diagramModel.getNodes()).map(item => ({
|
||||
x: item.x,
|
||||
x: item.getX(),
|
||||
width: item.width,
|
||||
y: item.y,
|
||||
y: item.getY(),
|
||||
height: item.height
|
||||
}));
|
||||
|
||||
const allLinks = _.values(this.engine.diagramModel.getLinks());
|
||||
const allPortsCoords = _.flatMap(allLinks.map(link => [link.sourcePort, link.targetPort]))
|
||||
const allPortsCoords = _.flatMap(allLinks.map(link => [link.getSourcePort(), link.getTargetPort()]))
|
||||
.filter(port => port !== null)
|
||||
.map(item => ({
|
||||
x: item.x,
|
||||
x: item.getX(),
|
||||
width: item.width,
|
||||
y: item.y,
|
||||
y: item.getY(),
|
||||
height: item.height
|
||||
}));
|
||||
const allPointsCoords = _.flatMap(allLinks.map(link => link.points)).map(item => ({
|
||||
const allPointsCoords = _.flatMap(allLinks.map(link => link.getPoints())).map(item => ({
|
||||
// points don't have width/height, so let's just use 0
|
||||
x: item.x,
|
||||
x: item.getX(),
|
||||
width: 0,
|
||||
y: item.y,
|
||||
y: item.getY(),
|
||||
height: 0
|
||||
}));
|
||||
|
||||
@@ -181,10 +181,10 @@ export class PathFindingLinkFactory extends AbstractReactFactory<PathFindingLink
|
||||
*/
|
||||
markNodes = (matrix: number[][]): void => {
|
||||
_.values(this.engine.diagramModel.getNodes()).forEach(node => {
|
||||
const startX = Math.floor(node.x / this.ROUTING_SCALING_FACTOR);
|
||||
const endX = Math.ceil((node.x + node.width) / this.ROUTING_SCALING_FACTOR);
|
||||
const startY = Math.floor(node.y / this.ROUTING_SCALING_FACTOR);
|
||||
const endY = Math.ceil((node.y + node.height) / this.ROUTING_SCALING_FACTOR);
|
||||
const startX = Math.floor(node.getX() / this.ROUTING_SCALING_FACTOR);
|
||||
const endX = Math.ceil((node.getX() + node.width) / this.ROUTING_SCALING_FACTOR);
|
||||
const startY = Math.floor(node.getY() / this.ROUTING_SCALING_FACTOR);
|
||||
const endY = Math.ceil((node.getY() + node.height) / this.ROUTING_SCALING_FACTOR);
|
||||
|
||||
for (let x = startX - 1; x <= endX + 1; x++) {
|
||||
for (let y = startY - 1; y < endY + 1; y++) {
|
||||
@@ -199,7 +199,7 @@ export class PathFindingLinkFactory extends AbstractReactFactory<PathFindingLink
|
||||
*/
|
||||
markPorts = (matrix: number[][]): void => {
|
||||
const allElements = _.flatMap(
|
||||
_.values(this.engine.diagramModel.getLinks()).map(link => [].concat(link.sourcePort, link.targetPort))
|
||||
_.values(this.engine.diagramModel.getLinks()).map(link => [].concat(link.getSourcePort(), link.getTargetPort()))
|
||||
);
|
||||
allElements
|
||||
.filter(port => port !== null)
|
||||
|
||||
@@ -3,6 +3,8 @@ import { LinkModel } from '@projectstorm/react-diagrams-core';
|
||||
|
||||
export class PathFindingLinkModel extends LinkModel {
|
||||
constructor() {
|
||||
super(PathFindingLinkFactory.NAME);
|
||||
super({
|
||||
type: PathFindingLinkFactory.NAME
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import * as _ from 'lodash';
|
||||
import { BaseWidget, BaseWidgetProps, DiagramEngine, LabelModel, PointModel } from '@projectstorm/react-diagrams-core';
|
||||
import PathFinding from '../engine/PathFinding';
|
||||
import { PathFindingLinkFactory } from './PathFindingLinkFactory';
|
||||
import { PathFindingLinkModel } from './PathFindingLinkModel';
|
||||
import * as React from "react";
|
||||
import * as _ from "lodash";
|
||||
import { BaseWidget, BaseWidgetProps, DiagramEngine, LabelModel, PointModel } from "@projectstorm/react-diagrams-core";
|
||||
import PathFinding from "../engine/PathFinding";
|
||||
import { PathFindingLinkFactory } from "./PathFindingLinkFactory";
|
||||
import { PathFindingLinkModel } from "./PathFindingLinkModel";
|
||||
|
||||
export interface PathFindingLinkWidgetProps extends BaseWidgetProps {
|
||||
color?: string;
|
||||
@@ -21,7 +21,7 @@ export interface PathFindingLinkWidgetState {
|
||||
|
||||
export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps, PathFindingLinkWidgetState> {
|
||||
public static defaultProps: PathFindingLinkWidgetProps = {
|
||||
color: 'black',
|
||||
color: "black",
|
||||
width: 3,
|
||||
link: null,
|
||||
engine: null,
|
||||
@@ -37,7 +37,7 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
pathFinding: PathFinding; // only set when smart routing is active
|
||||
|
||||
constructor(props: PathFindingLinkWidgetProps) {
|
||||
super('srd-default-link', props);
|
||||
super("srd-default-link", props);
|
||||
|
||||
this.refLabels = {};
|
||||
this.refPaths = [];
|
||||
@@ -48,37 +48,37 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
}
|
||||
|
||||
calculateAllLabelPosition() {
|
||||
_.forEach(this.props.link.labels, (label, index) => {
|
||||
_.forEach(this.props.link.getLabels(), (label, index) => {
|
||||
this.calculateLabelPosition(label, index + 1);
|
||||
});
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.props.link.labels.length > 0) {
|
||||
if (this.props.link.getLabels().length > 0) {
|
||||
window.requestAnimationFrame(this.calculateAllLabelPosition.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.link.labels.length > 0) {
|
||||
if (this.props.link.getLabels().length > 0) {
|
||||
window.requestAnimationFrame(this.calculateAllLabelPosition.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
generatePoint(pointIndex: number): JSX.Element {
|
||||
let x = this.props.link.points[pointIndex].x;
|
||||
let y = this.props.link.points[pointIndex].y;
|
||||
let x = this.props.link.getPoints()[pointIndex].getX();
|
||||
let y = this.props.link.getPoints()[pointIndex].getY();
|
||||
|
||||
return (
|
||||
<g key={'point-' + this.props.link.points[pointIndex].getID()}>
|
||||
<g key={"point-" + this.props.link.getPoints()[pointIndex].getID()}>
|
||||
<circle
|
||||
cx={x}
|
||||
cy={y}
|
||||
r={5}
|
||||
className={
|
||||
'point ' +
|
||||
this.bem('__point') +
|
||||
(this.props.link.points[pointIndex].isSelected() ? this.bem('--point-selected') : '')
|
||||
"point " +
|
||||
this.bem("__point") +
|
||||
(this.props.link.getPoints()[pointIndex].isSelected() ? this.bem("--point-selected") : "")
|
||||
}
|
||||
/>
|
||||
<circle
|
||||
@@ -88,13 +88,13 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
onMouseEnter={() => {
|
||||
this.setState({ selected: true });
|
||||
}}
|
||||
data-id={this.props.link.points[pointIndex].getID()}
|
||||
data-id={this.props.link.getPoints()[pointIndex].getID()}
|
||||
data-linkid={this.props.link.getID()}
|
||||
cx={x}
|
||||
cy={y}
|
||||
r={15}
|
||||
opacity={0}
|
||||
className={'point ' + this.bem('__point')}
|
||||
className={"point " + this.bem("__point")}
|
||||
/>
|
||||
</g>
|
||||
);
|
||||
@@ -104,9 +104,12 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
if (
|
||||
!event.shiftKey &&
|
||||
!this.props.diagramEngine.isModelLocked(this.props.link) &&
|
||||
this.props.link.points.length - 1 <= this.props.diagramEngine.getMaxNumberPointsPerLink()
|
||||
this.props.link.getPoints().length - 1 <= this.props.diagramEngine.getMaxNumberPointsPerLink()
|
||||
) {
|
||||
const point = new PointModel(this.props.link, this.props.diagramEngine.getRelativeMousePoint(event));
|
||||
const point = new PointModel({
|
||||
link: this.props.link,
|
||||
points: this.props.diagramEngine.getRelativeMousePoint(event)
|
||||
});
|
||||
point.setSelected(true);
|
||||
this.forceUpdate();
|
||||
this.props.link.addPoint(point, index);
|
||||
@@ -119,7 +122,7 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
return (
|
||||
<foreignObject
|
||||
key={label.getID()}
|
||||
className={this.bem('__label')}
|
||||
className={this.bem("__label")}
|
||||
width={canvas.offsetWidth}
|
||||
height={canvas.offsetHeight}>
|
||||
<div ref={ref => (this.refLabels[label.getID()] = ref)}>
|
||||
@@ -132,7 +135,7 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
generateLink(path: string, extraProps: any, id: string | number): JSX.Element {
|
||||
let Bottom = (
|
||||
<path
|
||||
className={this.state.selected ? this.bem('--path-selected') : ''}
|
||||
className={this.state.selected ? this.bem("--path-selected") : ""}
|
||||
strokeWidth={this.props.width}
|
||||
stroke={this.props.color}
|
||||
ref={ref => ref && this.refPaths.push(ref)}
|
||||
@@ -142,7 +145,7 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
|
||||
var Top = React.cloneElement(Bottom, {
|
||||
...extraProps,
|
||||
strokeLinecap: 'round',
|
||||
strokeLinecap: "round",
|
||||
onMouseLeave: () => {
|
||||
this.setState({ selected: false });
|
||||
},
|
||||
@@ -150,7 +153,7 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
this.setState({ selected: true });
|
||||
},
|
||||
ref: null,
|
||||
'data-linkid': this.props.link.getID(),
|
||||
"data-linkid": this.props.link.getID(),
|
||||
strokeOpacity: this.state.selected ? 0.1 : 0,
|
||||
strokeWidth: 20,
|
||||
onContextMenu: () => {
|
||||
@@ -162,7 +165,7 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
});
|
||||
|
||||
return (
|
||||
<g key={'link-' + id}>
|
||||
<g key={"link-" + id}>
|
||||
{Bottom}
|
||||
{Top}
|
||||
</g>
|
||||
@@ -176,7 +179,7 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
// calculate the point where we want to display the label
|
||||
let labelPosition =
|
||||
lengths.reduce((previousValue, currentValue) => previousValue + currentValue, 0) *
|
||||
(index / (this.props.link.labels.length + 1));
|
||||
(index / (this.props.link.getLabels().length + 1));
|
||||
|
||||
// find the path where the label will be rendered and calculate the relative position
|
||||
let pathIndex = 0;
|
||||
@@ -214,7 +217,7 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
y: pathCentre.y - labelDimensions.height / 2 + label.offsetY
|
||||
};
|
||||
this.refLabels[label.id].setAttribute(
|
||||
'style',
|
||||
"style",
|
||||
`transform: translate(${labelCoordinates.x}px, ${labelCoordinates.y}px);`
|
||||
);
|
||||
};
|
||||
@@ -226,7 +229,7 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
}
|
||||
|
||||
//ensure id is present for all points on the path
|
||||
var points = this.props.link.points;
|
||||
var points = this.props.link.getPoints();
|
||||
var paths = [];
|
||||
|
||||
// first step: calculate a direct path between the points being linked
|
||||
@@ -252,7 +255,7 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
this.addPointToLink(event, 1);
|
||||
}
|
||||
},
|
||||
'0'
|
||||
"0"
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -261,7 +264,7 @@ export class PathFindingLinkWidget extends BaseWidget<PathFindingLinkWidgetProps
|
||||
return (
|
||||
<g {...this.getProps()}>
|
||||
{paths}
|
||||
{_.map(this.props.link.labels, labelModel => {
|
||||
{_.map(this.props.link.getLabels(), labelModel => {
|
||||
return this.generateLabel(labelModel);
|
||||
})}
|
||||
</g>
|
||||
|
||||
Reference in New Issue
Block a user