This commit is contained in:
Dylan Vorster
2019-08-10 21:18:29 +02:00
parent 5c66c84a31
commit c9f7d2c516
8 changed files with 85 additions and 128 deletions

View File

@@ -6,32 +6,55 @@ import { TrayItemWidget } from './TrayItemWidget';
import { DefaultNodeModel } from '@projectstorm/react-diagrams';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../../helpers/DemoCanvasWidget';
import styled from '@emotion/styled';
export interface BodyWidgetProps {
app: Application;
}
export interface BodyWidgetState {}
namespace S {
export const Body = styled.div`
flex-grow: 1;
display: flex;
flex-direction: column;
min-height: 100%;
`;
export class BodyWidget extends React.Component<BodyWidgetProps, BodyWidgetState> {
constructor(props: BodyWidgetProps) {
super(props);
this.state = {};
}
export const Header = styled.div`
display: flex;
background: rgb(30, 30, 30);
flex-grow: 0;
flex-shrink: 0;
color: white;
font-family: Helvetica, Arial, sans-serif;
padding: 10px;
align-items: center;
`;
export const Content = styled.div`
display: flex;
flex-grow: 1;
`;
export const Layer = styled.div`
position: relative;
flex-grow: 1;
`;
}
export class BodyWidget extends React.Component<BodyWidgetProps> {
render() {
return (
<div className="body">
<div className="header">
<div className="title">Storm React Diagrams - Demo 5</div>
</div>
<div className="content">
<S.Body>
<S.Header>
<div className="title">Storm React Diagrams - DnD demo</div>
</S.Header>
<S.Content>
<TrayWidget>
<TrayItemWidget model={{ type: 'in' }} name="In Node" color="rgb(192,255,0)" />
<TrayItemWidget model={{ type: 'out' }} name="Out Node" color="rgb(0,192,255)" />
</TrayWidget>
<div
className="diagram-layer"
<S.Layer
onDrop={event => {
var data = JSON.parse(event.dataTransfer.getData('storm-diagram-node'));
var nodesCount = _.keys(
@@ -63,9 +86,9 @@ export class BodyWidget extends React.Component<BodyWidgetProps, BodyWidgetState
<DemoCanvasWidget>
<CanvasWidget engine={this.props.app.getDiagramEngine()} />
</DemoCanvasWidget>
</div>
</div>
</div>
</S.Layer>
</S.Content>
</S.Body>
);
}
}

View File

@@ -1,4 +1,5 @@
import * as React from 'react';
import styled from '@emotion/styled';
export interface TrayItemWidgetProps {
model: any;
@@ -6,25 +7,31 @@ export interface TrayItemWidgetProps {
name: string;
}
export interface TrayItemWidgetState {}
export class TrayItemWidget extends React.Component<TrayItemWidgetProps, TrayItemWidgetState> {
constructor(props: TrayItemWidgetProps) {
super(props);
this.state = {};
}
namespace S {
export const Tray = styled.div<{ color: string }>`
color: white;
font-family: Helvetica, Arial;
padding: 5px;
margin: 0px 10px;
border: solid 1px ${p => p.color};
border-radius: 5px;
margin-bottom: 2px;
cursor: pointer;
`;
}
export class TrayItemWidget extends React.Component<TrayItemWidgetProps> {
render() {
return (
<div
style={{ borderColor: this.props.color }}
<S.Tray
color={this.props.color}
draggable={true}
onDragStart={event => {
event.dataTransfer.setData('storm-diagram-node', JSON.stringify(this.props.model));
}}
className="tray-item">
{this.props.name}
</div>
</S.Tray>
);
}
}

View File

@@ -1,21 +1,17 @@
import * as React from 'react';
import styled from '@emotion/styled';
export interface TrayWidgetProps {}
export interface TrayWidgetState {}
/**
* @author Dylan Vorster
*/
export class TrayWidget extends React.Component<TrayWidgetProps, TrayWidgetState> {
public static defaultProps: TrayWidgetProps = {};
constructor(props: TrayWidgetProps) {
super(props);
this.state = {};
}
namespace S {
export const Tray = styled.div`
min-width: 200px;
background: rgb(20, 20, 20);
flex-grow: 0;
flex-shrink: 0;
`;
}
export class TrayWidget extends React.Component {
render() {
return <div className="tray">{this.props.children}</div>;
return <S.Tray>{this.props.children}</S.Tray>;
}
}

View File

@@ -3,10 +3,7 @@ import * as React from 'react';
import { BodyWidget } from './components/BodyWidget';
import { Application } from './Application';
import './sass/main.scss';
export default () => {
var app = new Application();
return <BodyWidget app={app} />;
};

View File

@@ -1,47 +0,0 @@
.body {
flex-grow: 1;
display: flex;
flex-direction: column;
min-height: 100%;
.header {
display: flex;
background: rgb(30, 30, 30);
flex-grow: 0;
flex-shrink: 0;
color: white;
font-family: Helvetica, Arial;
padding: 10px;
> * {
align-self: center;
}
}
.content {
display: flex;
flex-grow: 1;
.diagram-layer {
position: relative;
flex-grow: 1;
}
.tray {
min-width: 200px;
background: rgb(20, 20, 20);
flex-grow: 0;
flex-shrink: 0;
.tray-item {
color: white;
font-family: Helvetica, Arial;
padding: 5px;
margin: 0px 10px;
border: solid 1px;
border-radius: 5px;
margin-bottom: 2px;
cursor: pointer;
}
}
}
}

View File

@@ -6,7 +6,7 @@ import createEngine, {
DefaultLabelModel
} from '@projectstorm/react-diagrams';
import * as React from 'react';
import { DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
import { action } from '@storybook/addon-actions';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
@@ -57,12 +57,12 @@ export default () => {
return (
<DemoWorkspaceWidget
buttons={
<button
<DemoButton
onClick={() => {
action('Serialized Graph')(JSON.stringify(model.serializeDiagram(), null, 2));
action('Serialized Graph')(JSON.stringify(model.serialize(), null, 2));
}}>
Serialize Graph
</button>
</DemoButton>
}>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />

View File

@@ -2,7 +2,7 @@ import { NodeModel } from './entities/node/NodeModel';
import { PortModel } from './entities/port/PortModel';
import { LinkModel } from './entities/link/LinkModel';
import { LabelModel } from './entities/label/LabelModel';
import { Point } from '@projectstorm/geometry';
import { Point, Rectangle } from '@projectstorm/geometry';
import { MouseEvent } from 'react';
import {
AbstractModelFactory,
@@ -167,29 +167,13 @@ export class DiagramEngine extends CanvasEngine<CanvasEngineListener, DiagramMod
}
getPortCenter(port: PortModel): Point {
var sourceElement = this.getNodePortElement(port);
var sourceRect = sourceElement.getBoundingClientRect();
var rel = this.getRelativePoint(sourceRect.left, sourceRect.top);
return new Point(
sourceElement.offsetWidth / 2 + (rel.x - this.model.getOffsetX()) / (this.model.getZoomLevel() / 100.0),
sourceElement.offsetHeight / 2 + (rel.y - this.model.getOffsetY()) / (this.model.getZoomLevel() / 100.0)
);
return this.getPortCoords(port).getOrigin();
}
/**
* Calculate rectangular coordinates of the port passed in.
*/
getPortCoords(
port: PortModel,
element?: HTMLDivElement
): {
x: number;
y: number;
width: number;
height: number;
} {
getPortCoords(port: PortModel, element?: HTMLDivElement): Rectangle {
if (!this.canvas) {
throw new Error('Canvas needs to be set first');
}
@@ -197,14 +181,12 @@ export class DiagramEngine extends CanvasEngine<CanvasEngineListener, DiagramMod
element = this.getNodePortElement(port);
}
const sourceRect = element.getBoundingClientRect();
const canvasRect = this.canvas.getBoundingClientRect() as ClientRect;
return {
x: (sourceRect.left - this.model.getOffsetX()) / (this.model.getZoomLevel() / 100.0) - canvasRect.left,
y: (sourceRect.top - this.model.getOffsetY()) / (this.model.getZoomLevel() / 100.0) - canvasRect.top,
width: sourceRect.width,
height: sourceRect.height
};
const point = this.getRelativeMousePoint({
clientX: sourceRect.left,
clientY: sourceRect.top
});
const zoom = this.model.getZoomLevel() / 100.0;
return new Rectangle(point.x, point.y, sourceRect.width / zoom, sourceRect.height / zoom);
}
/**

View File

@@ -1,7 +1,7 @@
import { NodeModel } from '../node/NodeModel';
import { LinkModel } from '../link/LinkModel';
import * as _ from 'lodash';
import { Point } from '@projectstorm/geometry';
import { Point, Rectangle } from '@projectstorm/geometry';
import {
BaseEntityEvent,
BaseModelOptions,
@@ -142,11 +142,10 @@ export class PortModel<G extends PortModelGenerics = PortModelGenerics> extends
return new Point(this.getX() + this.width / 2, this.getY() + this.height / 2);
}
updateCoords(cords: { x: number; y: number; width: number; height: number }) {
const { x, y, width, height } = cords;
this.width = width;
this.height = height;
this.setPosition(x, y);
updateCoords(coords: Rectangle) {
this.width = coords.getWidth();
this.height = coords.getHeight();
this.setPosition(coords.getTopLeft());
this.reportedPosition = true;
this.reportPosition();
}