Compare commits

..

86 Commits

Author SHA1 Message Date
Dylan Vorster
e497715520 Merge pull request #1028 from projectstorm/changeset-release/master
Version Packages
2024-02-15 00:24:48 -07:00
github-actions[bot]
42d43519d2 Version Packages 2024-02-15 07:23:36 +00:00
Dylan Vorster
78d10b8ff0 Merge pull request #1021 from LynchyC/master
Update lodash imports to use individual functions
2024-02-15 00:23:03 -07:00
Dylan Vorster
5045968abd Merge pull request #1014 from marian2js/master
fix: default link widget with react strict mode
2024-02-15 00:20:51 -07:00
Dylan Vorster
633d03a831 Merge pull request #1025 from TenTakano/remove_settimeout_from_demo_dagre
Remove setTimeout from demo-dagre to avoid layout breaks
2024-02-15 00:16:09 -07:00
Dylan Vorster
8031008e71 Merge pull request #1022 from jeevcat/master
Allow more derived State classes to be parameterized with a generic type
2024-02-15 00:14:11 -07:00
TenTakano
1be40737f5 Add changeset 2023-12-28 14:13:18 +09:00
TenTakano
7ab3572ea1 Remove setTimeout from demo-dagre to avoid layout breaks 2023-12-28 14:13:18 +09:00
Sam Jeeves
09ed60ff64 changeset 2023-12-16 15:00:41 +01:00
Sam Jeeves
8c2577703f Allow more derived State classes to provide a generic type 2023-12-16 14:55:13 +01:00
Charlie Lynch
80285feee5 release: add changeset 2023-11-08 21:14:26 +00:00
Charlie Lynch
cd8049dad1 refactor: update lodash imports to use individual functions 2023-11-08 21:07:46 +00:00
Dylan Vorster
a457385a8c storybook build fixes 2023-09-23 14:28:19 -06:00
Dylan Vorster
63b39cba79 Merge pull request #1019 from projectstorm/changeset-release/master
Version Packages
2023-09-23 14:24:05 -06:00
github-actions[bot]
a671b50e09 Version Packages 2023-09-23 20:22:45 +00:00
Dylan Vorster
7a664d5b64 Merge pull request #1018 from projectstorm/pnpm_upgrade
Maintenance
2023-09-23 14:22:03 -06:00
Dylan Vorster
66c687afc6 changeset 2023-09-23 14:18:27 -06:00
Dylan Vorster
23b5467806 upgrade everything 2023-09-23 14:16:35 -06:00
Dylan Vorster
1889c7cb40 lockfile 2023-09-23 14:00:39 -06:00
Dylan Vorster
c3146e1aa8 Update README.md 2023-09-23 13:57:22 -06:00
Dylan Vorster
8fb8d04885 Update README.md
missed a few
2023-09-23 13:56:44 -06:00
Dylan Vorster
74e814ab5a Update README.md
This project uses pnpm instead of yarn
2023-09-23 13:56:17 -06:00
marian2js
20766f539e fix: default link widget with react strict mode 2023-08-10 15:34:16 +01:00
Dylan Vorster
3d4e0b24d7 Merge pull request #1007 from projectstorm/dylanvorster-patch-1
Update CHANGELOG.md
2023-06-04 15:32:08 -06:00
Dylan Vorster
efd64ad278 Update CHANGELOG.md 2023-06-04 15:32:01 -06:00
Dylan Vorster
160b88fccf Merge pull request #990 from projectstorm/changeset-release/master
Version Packages
2023-03-05 10:56:47 -07:00
github-actions[bot]
80cd9c9306 Version Packages 2023-03-05 17:56:31 +00:00
Dylan Vorster
2de55fdf68 Merge pull request #989 from projectstorm/sources
inline sources in source map
2023-03-05 10:55:51 -07:00
Dylan Vorster
b8a4cbdf1a changeset 2023-03-05 10:54:52 -07:00
Dylan Vorster
76a2659948 inline sources 2023-03-05 10:53:27 -07:00
Dylan Vorster
63e33c07d8 Merge pull request #981 from projectstorm/changeset-release/master
Version Packages
2023-01-24 20:25:08 -07:00
github-actions[bot]
70b17a749c Version Packages 2023-01-25 00:17:49 +00:00
Dylan Vorster
4ccc5d58f3 Merge pull request #980 from projectstorm/features
Some Features and fixes
2023-01-24 17:17:09 -07:00
Dylan Vorster
fb7d646bde prettyier and changset 2023-01-24 17:14:38 -07:00
Dylan Vorster
e0d21f1435 pretty and changeset 2023-01-24 17:09:35 -07:00
Dylan Vorster
6ed1e0f89d Merge branch 'features' of github.com:projectstorm/react-diagrams into features 2023-01-24 17:08:12 -07:00
Dylan Vorster
7da7fa4cc9 merge 2023-01-24 17:07:59 -07:00
Dylan Vorster
ed7988f722 Merge branch 'h0111in-Reroute-(redistribute)-links-only,-based-on-current-nodes-positions-#731' into features 2023-01-24 17:06:30 -07:00
Dylan Vorster
e6b86321e2 Merge branch 'Reroute-(redistribute)-links-only,-based-on-current-nodes-positions-#731' of https://github.com/h0111in/react-diagrams into h0111in-Reroute-(redistribute)-links-only,-based-on-current-nodes-positions-#731 2023-01-24 17:00:47 -07:00
Dylan Vorster
17bb78b130 Merge pull request #939 from ToTheHit/update_default_link_widget
Remove hardcode for PointModel in DefaultLinkWidget.tsx
2023-01-24 16:56:27 -07:00
Dylan Vorster
ddeea124b0 Merge pull request #977 from projectstorm/changeset-release/master
Version Packages
2023-01-24 15:11:51 -07:00
github-actions[bot]
fcdbce54b5 Version Packages 2023-01-24 22:11:19 +00:00
Dylan Vorster
f1c38fb84a Merge pull request #979 from projectstorm/changelog
changelog
2023-01-24 15:10:42 -07:00
Dylan Vorster
74f9269869 changelog 2023-01-24 15:08:51 -07:00
Dylan Vorster
a28bcc037d Merge pull request #978 from projectstorm/readme
house keeping
2023-01-24 14:16:06 -07:00
Dylan Vorster
456e6b1b67 house keeping 2023-01-24 14:15:29 -07:00
Dylan Vorster
c9e819d78e Merge pull request #976 from projectstorm/changeset
V7
2023-01-24 13:40:54 -07:00
Dylan Vorster
8a2f5d198f changeset update 2023-01-24 13:32:30 -07:00
Dylan Vorster
251a1f9484 reworked geometry demo 2023-01-24 13:25:26 -07:00
Dylan Vorster
c1eac9873a lockfile 2023-01-23 21:38:49 -07:00
Dylan Vorster
95b35d6778 get rid of puppeteer 2023-01-23 20:47:36 -07:00
Dylan Vorster
d2a197245b pls3 2023-01-23 20:32:57 -07:00
Dylan Vorster
8f06e55127 pls 2023-01-23 20:25:14 -07:00
Dylan Vorster
b0e8e52077 pls2 2023-01-23 20:23:06 -07:00
Dylan Vorster
0d23e933e8 pls 2023-01-23 20:21:32 -07:00
Dylan Vorster
4dfeb403be CI test 4 2023-01-23 20:10:55 -07:00
Dylan Vorster
0e19827675 obviously we need pnpm 2023-01-23 20:07:01 -07:00
Dylan Vorster
2b1f54bbc9 CI test 2 2023-01-23 20:04:32 -07:00
Dylan Vorster
b3a6cc01fa CI test 1 2023-01-23 20:03:19 -07:00
Dylan Vorster
918d8d741b oh 2023-01-23 20:01:09 -07:00
Dylan Vorster
d15fb13adf why this so hard 2023-01-23 19:59:36 -07:00
Dylan Vorster
4f2b6132ba circleci begone 2023-01-23 19:56:17 -07:00
Dylan Vorster
7d9d137c66 test changeset trigger 2023-01-23 19:42:54 -07:00
Dylan Vorster
b051697791 github stuffs 2023-01-23 19:37:49 -07:00
Dylan Vorster
8fc9fe3aae more changes to the bundling and deps 2023-01-23 19:33:49 -07:00
Dylan Vorster
b4185dcb76 got storybook working again 2023-01-23 13:57:51 -07:00
Dylan Vorster
c1fa7ee865 docs fix 2023-01-23 13:47:50 -07:00
Dylan Vorster
05a5afb20e moved over more dependencies 2023-01-23 13:44:43 -07:00
Dylan Vorster
8bcc1436d3 changsets and v7 2023-01-23 12:56:25 -07:00
Dylan Vorster
9b39591d94 Merge pull request #954 from vadimshvetsov/patch-1
Update peer deps in react-canvas-core for working with React 18
2022-11-30 02:36:43 -07:00
Vadim Shvetsov
88296c28b4 Update package.json 2022-07-07 12:32:33 +03:00
Dylan Vorster
2a810ca2d3 changelog 2022-06-03 16:02:08 -06:00
Dylan Vorster
dfcf82e692 v6.7.4 2022-06-03 15:59:56 -06:00
Dylan Vorster
cd93bb96a3 v6.7.3 2022-06-03 15:59:24 -06:00
Dylan Vorster
5f49bbe5b1 v6.7.2 2022-06-03 15:58:45 -06:00
Dylan Vorster
d55790edcf Merge pull request #947 from projectstorm/upgrade
Upgrade all the things
2022-06-03 15:57:57 -06:00
Dylan Vorster
a1b2f6a59e v6.7.2-alpha.0 2022-06-03 15:48:20 -06:00
Dylan Vorster
e7b352644d v6.7.1-alpha.0 2022-06-03 15:47:17 -06:00
Dylan Vorster
2f620ce4af upgrade react storybook 2022-06-03 15:29:48 -06:00
Dylan Vorster
897bde204e upgrades 2022-06-03 15:21:23 -06:00
Dylan Vorster
2d9fca171c Merge pull request #927 from BenjaVR/fix/show-actions-addon
Register and enable the 'actions' addon panel
2022-05-04 09:21:20 -06:00
Dmitry Ushakov
77011af27a Remove hardcode for PointModel in DefaultLinkWidget.tsx 2022-05-04 18:07:31 +03:00
Benjamin Van Renterghem
32d47270cb Register and enable the 'actions' addon 2022-04-10 23:00:50 +02:00
Dylan Vorster
3060496db0 changelog 2022-02-06 22:51:19 -07:00
Hosein Nourani
580a26c73d miners 2020-10-28 17:52:26 -04:00
Hosein Nourani
4c03583d91 auto-redistribute-without-nodes 2020-10-13 04:41:41 -04:00
138 changed files with 14556 additions and 16276 deletions

8
.changeset/README.md Normal file
View File

@@ -0,0 +1,8 @@
# Changesets
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)

11
.changeset/config.json Normal file
View File

@@ -0,0 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@2.2.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
"baseBranch": "master",
"updateInternalDependencies": "patch",
"ignore": []
}

View File

@@ -1,23 +0,0 @@
version: 2
jobs:
build:
docker:
- image: buildkite/puppeteer
working_directory: ~/repo
steps:
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "yarn.lock" }}
- run: yarn install
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "yarn.lock" }}
# test building project
- run: yarn run build
# test e2e tests and jest snapshots
- run: cd diagrams-demo-gallery && yarn run test --ci
- run: cd packages/react-diagrams-routing && yarn run test --ci

View File

@@ -1,27 +0,0 @@
FROM node:8-slim
# Install latest chrome dev package.
# Note: this installs the necessary libs to make the bundled version of Chromium that Pupppeteer
# installs, work.
RUN apt-get update && apt-get install -y wget --no-install-recommends \
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
&& apt-get update \
&& apt-get install -y google-chrome-unstable \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get purge --auto-remove -y curl \
&& rm -rf /src/*.deb
RUN yarn add puppeteer
# Add pptr user.
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
&& mkdir -p /home/pptruser/Downloads \
&& chown -R pptruser:pptruser /home/pptruser \
&& chown -R pptruser:pptruser /node_modules
# Run user as non privileged.
USER pptruser
CMD ["google-chrome-unstable"]

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 231 KiB

View File

@@ -1,24 +1,16 @@
# Checklist
- [ ] The code has been run through pretty `yarn run pretty`
- [ ] The tests pass on CircleCI
- [ ] You have referenced the issue(s) or other PR(s) this fixes/relates-to
- [ ] The PR Template has been filled out (see below)
- [ ] Had a beer/coffee because you are awesome
- [ ] The tests pass
- [ ] I have referenced the issue(s) or other PR(s) this fixes/relates-to
- [ ] I have run ```pnpm changeset``` and followed the instructions
- [ ] I have explained in this PR, what I did and why
- [ ] I replaced the image below
- [ ] Had a beer/coffee/tea because I did something cool today
## What?
## What, why and how?
## Why?
## How?
## Feel good image:
(Add your own one below :])
![LOL](https://i.pinimg.com/originals/7f/1b/c3/7f1bc3fb2e123dd3255a85c04db22f19.jpg)
![LOL](https://i.pinimg.com/originals/7f/1b/c3/7f1bc3fb2e123dd3255a85c04db22f19.jpg)

23
.github/workflows/prettier.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: Prettier check
# This action works with pull requests and pushes
on:
pull_request:
jobs:
prettier:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
# Make sure the actual branch is checked out when running on pull requests
ref: ${{ github.head_ref }}
- uses: actions/checkout@v2 # Check out the repository first.
- uses: actionsx/prettier@v2
with:
# prettier CLI arguments.
args: --check --ignore-path .prettierignore --config .prettierrc '**/*.{ts,tsx,js,jsx}'

47
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,47 @@
name: Release
on:
push:
branches:
- master
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v2
- name: Read .nvmrc
run: echo "##[set-output name=NVMRC;]$(cat .nvmrc)"
id: nvm
- name: Use Node.js (.nvmrc)
uses: actions/setup-node@v2
with:
node-version: "${{ steps.nvm.outputs.NVMRC }}"
- name: Install PNPM
uses: pnpm/action-setup@v2
with:
version: latest
- name: Install Dependencies
run: pnpm install
- name: Create Release Pull Request
uses: changesets/action@v1
id: changesets
with:
# This expects you to have a script called release which does a build for your packages and calls changeset publish
publish: pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: publish storybook
if: steps.changesets.outputs.published == 'true'
run: pnpm release:storybook

30
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Build and Test
on:
pull_request:
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v2
- name: Read .nvmrc
run: echo "##[set-output name=NVMRC;]$(cat .nvmrc)"
id: nvm
- name: Use Node.js (.nvmrc)
uses: actions/setup-node@v2
with:
node-version: "${{ steps.nvm.outputs.NVMRC }}"
- name: Install PNPM
uses: pnpm/action-setup@v2
with:
version: latest
- name: Install Dependencies
run: pnpm install
- name: Build
run: pnpm build

1
.gitignore vendored
View File

@@ -5,6 +5,5 @@ dist
*.zip
.env
node_modules
yarn-error.log
tsconfig.tsbuildinfo
.vscode

View File

@@ -1,7 +1,6 @@
{
"semi": true,
"singleQuote": true,
"jsxBracketSameLine": true,
"useTabs": true,
"printWidth": 120,
"trailingComma": "none"

View File

@@ -1 +0,0 @@
--ignore-engines true

View File

@@ -1,3 +1,33 @@
__V7!__
we are now using changesets! you can see the changes for individual packages in their corresponding folders.
Here is the main changeset for the core package which depends on everything:
[Changelog for @projectstorm/react-diagrams](./packages/react-diagrams/CHANGELOG.md)
---
__6.7.4__
.0 -> .4 because I messed up the version / publishing
* (upgrade all dependencies, including a move to React 18)
* https://github.com/projectstorm/react-diagrams/pull/947
__6.7.0__
bug fixes:
* https://github.com/projectstorm/react-diagrams/pull/882
* https://github.com/projectstorm/react-diagrams/pull/914
* https://github.com/projectstorm/react-diagrams/pull/875
types
* https://github.com/projectstorm/react-diagrams/pull/906
features:
* https://github.com/projectstorm/react-diagrams/pull/915
* https://github.com/projectstorm/react-diagrams/pull/877
__6.6.1__
bug fixes:
@@ -127,7 +157,7 @@ __5.1.0__
* (refactor) consistently use lodash where possible
* (maintenance) upgrade node modules
__5.0.0__ http://dylanv.blog/2018/03/03/storm-react-diagrams-5-0-0/
__5.0.0__ [http://dylanv.blog/2018/03/03/storm-react-diagrams-5-0-0/](https://dylanvorster.com/storm-react-diagrams-v5-0/)
PR: https://github.com/projectstorm/react-diagrams/pull/145
@@ -144,7 +174,7 @@ PR: https://github.com/projectstorm/react-diagrams/pull/145
* (tests) automatically load JEST Snapshots
* (feature) Link labels!
__4.0.0__ http://dylanv.blog/2018/01/18/storm-react-diagrams-v4-0-0/
__4.0.0__ [http://dylanv.blog/2018/01/18/storm-react-diagrams-v4-0-0/](https://dylanvorster.com/storm-react-diagrams-v4-0/)
* (refactor) Events system was completely overhauled
* (demo) Custom Link Sizes
@@ -158,7 +188,7 @@ __4.0.0__ http://dylanv.blog/2018/01/18/storm-react-diagrams-v4-0-0/
* (demo) Cloning
* (feature) models control isLocked
__3.2.0__ http://dylanv.blog/2017/11/22/storm-react-diagrams-3-2-0/
__3.2.0__ [http://dylanv.blog/2017/11/22/storm-react-diagrams-3-2-0/](https://dylanvorster.com/storm-react-diagrams-3-2-0/)
* (feature) zoom to fit
* added Circle CI tests
* (demo) dagre automatic layouts
@@ -181,14 +211,14 @@ __3.1.2__
* Hotfix: fix zooming when canvas not in the top left corner
(https://github.com/projectstorm/react-diagrams/pull/88)
__3.1.0__ http://dylanv.blog/2017/09/15/storm-react-diagrams-3-1-0/
__3.1.0__ [http://dylanv.blog/2017/09/15/storm-react-diagrams-3-1-0/](https://dylanvorster.com/storm-react-diagrams-3-1-0/)
* Zoom relative to mouse location
* Fixed links not connecting when grid is larger than port size
* Prevented points from dragging when connected to a port and the node itself is not selected
* API fixes
* Code cleanup
__3.0.0__ http://dylanv.blog/2017/09/13/storm-react-diagrams-v3/
__3.0.0__ [http://dylanv.blog/2017/09/13/storm-react-diagrams-v3/](https://dylanvorster.com/storm-react-diagrams-3-0/)
* Massive performance updates
* Complete rewrite
* Started a changelog and design documents for each revision

View File

@@ -1,6 +1,6 @@
# Introduction
[![Join the chat at https://gitter.im/projectstorm/react-diagrams](https://badges.gitter.im/projectstorm/react-diagrams.svg)](https://gitter.im/projectstorm/react-diagrams?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![NPM](https://img.shields.io/npm/v/@projectstorm/react-diagrams.svg)](https://npmjs.org/package/@projectstorm/react-diagrams) [![Package Quality](https://npm.packagequality.com/shield/storm-react-diagrams.svg)](https://packagequality.com/#?package=storm-react-diagrams) [![CircleCI](https://circleci.com/gh/projectstorm/react-diagrams/tree/master.svg?style=svg)](https://circleci.com/gh/projectstorm/react-diagrams/tree/master) [![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)
[![Join the chat at https://gitter.im/projectstorm/react-diagrams](https://badges.gitter.im/projectstorm/react-diagrams.svg)](https://gitter.im/projectstorm/react-diagrams?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![NPM](https://img.shields.io/npm/v/@projectstorm/react-diagrams.svg)](https://npmjs.org/package/@projectstorm/react-diagrams) [![Package Quality](https://npm.packagequality.com/shield/storm-react-diagrams.svg)](https://packagequality.com/#?package=storm-react-diagrams)
![](.gitbook/assets/logo.jpg)
@@ -70,7 +70,7 @@ yarn add @projectstorm/react-diagrams-routing
## How to use
Before running any of the examples, please run `yarn build` in the root. This project is a monorepo, and the packages (including the demos) require the packages to first be built.
Before running any of the examples, please run `pnpm build` in the root. This project is a monorepo, and the packages (including the demos) require the packages to first be built.
Take a look at the [diagram demos](https://github.com/projectstorm/react-diagrams/tree/master/diagrams-demo-gallery/demos)
@@ -85,11 +85,11 @@ Take a look at the [demo project](https://github.com/projectstorm/react-diagrams
## Run the demos
After running `yarn install` and `yarn build`, you must then run: `cd diagrams-demo-gallery && yarn run start`
After running `pnpm install` and `pnpm build`, you must then run: `cd diagrams-demo-gallery && pnpm run start`
## Building from source
Simply run `yarn` then `yarn build` or `yarn build:prod` in the root directory and it will spit out the transpiled code and typescript definitions into the dist directory as a single file.
Simply run `pnpm` then `pnpm build` or `pnpm build:prod` in the root directory and it will spit out the transpiled code and typescript definitions into the dist directory as a single file.
## Built with react-diagrams

View File

@@ -0,0 +1,18 @@
{
"sourceType": "unambiguous",
"presets": [
[
"@babel/preset-env",
{
"targets": {
"chrome": 100,
"safari": 15,
"firefox": 91
}
}
],
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": []
}

View File

@@ -1,6 +1,8 @@
module.exports = {
stories: ['../demos/*.stories.tsx'],
core: {
builder: 'webpack5'
addons: ['@storybook/addon-actions'],
framework: {
name: '@storybook/react-webpack5',
options: {}
}
};

View File

@@ -1,4 +1,5 @@
import { addons } from '@storybook/addons';
import diagramsTheme from './theme';
addons.setConfig({

View File

@@ -0,0 +1,5 @@
<style>
html, body, #storybook-root {
height: 100%;
}
</style>

View File

@@ -0,0 +1,87 @@
# @projectstorm/react-diagrams-gallery
## 7.2.0
### Minor Changes
- 1be4073: Remove setTimeout from demo-dagre to avoid layout breaks
### Patch Changes
- 80285fe: refactor: update lodash imports to use individual functions
- Updated dependencies [09ed60f]
- Updated dependencies [20766f5]
- Updated dependencies [80285fe]
- @projectstorm/react-canvas-core@7.0.3
- @projectstorm/react-diagrams-core@7.0.3
- @projectstorm/react-diagrams-defaults@7.1.3
- @projectstorm/react-diagrams@7.0.4
## 7.1.2
### Patch Changes
- 66c687a: Upgrade all dependencies and fix Storybook after upgrade
- Updated dependencies [66c687a]
- @projectstorm/react-diagrams-defaults@7.1.2
- @projectstorm/react-diagrams-core@7.0.2
- @projectstorm/react-canvas-core@7.0.2
- @projectstorm/react-diagrams@7.0.3
## 7.1.1
### Patch Changes
- b8a4cbd: Inline sources in sourcemap
- Updated dependencies [b8a4cbd]
- @projectstorm/react-canvas-core@7.0.1
- @projectstorm/react-diagrams@7.0.2
- @projectstorm/react-diagrams-core@7.0.1
- @projectstorm/react-diagrams-defaults@7.1.1
## 7.1.0
### Minor Changes
- e0d21f1: - [feature] new ability to refresh links in auto distribute system [PR 756](https://github.com/projectstorm/react-diagrams/pull/756)
- [fix] Default link now uses the correct method for creating a point allowing this to be overridden [PR 939](https://github.com/projectstorm/react-diagrams/pull/939)
Big thanks to @ToTheHit and @h0111in for your help on these, even though its very delayed on my part :)
### Patch Changes
- Updated dependencies [e0d21f1]
- @projectstorm/react-diagrams-defaults@7.1.0
- @projectstorm/react-diagrams@7.0.1
## 7.0.0
### Major Changes
- b051697: - [internal] moves to `Pnpm` (instead of yarn -\_-)
- [internal]moves to `Changesets` for releases
- [internal]removes `Lerna`
- [internal] upgrades all dependencies
- [internal] switches to workspace protocol syntax (Changesets will bake in the correct version when a publish occurs)
- [internal] Changesets will open a release PR which can wrap up several changes in 1 go
- [internal] Changesets will run the storybook deploy automatically upon merging the release PR
- [internal] removes a lot of the stuff from the root package.json
- [internal] cleans up the build and clean commands
- [internal] remove E2E tests, they are a nightmare to maintain and the ROI is far too low
- [fix] Wrong type name for react-canvas model listener
- [fix] export more stuff form the main react-diagrams package
- [fix] circular deps with Rectangle and Polygon (turns out this was a problem but only with UMD builds, sorry @everyone who I doubted, but this is also why I could never reproduce the issue)
- [breaking change] compile both ES6 and UMD
- [breaking change] moves dependencies back to each package. (After years of working on libraries, I've come to actually hate peer dependencies, and this is easily solved with build systems / package managers).
- [breaking change] static methods on `Polygon` and `Rectangle` moved to standalone methods
- [breaking change] static construction methods to rather deal with different Rectangle constructor overloads (I now consider this bad design)
- [breaking change] introduce `Bounds` as a simpler point-array type to deal with boundary computation instead
### Patch Changes
- Updated dependencies [b051697]
- @projectstorm/react-diagrams-defaults@7.0.0
- @projectstorm/react-diagrams-core@7.0.0
- @projectstorm/react-canvas-core@7.0.0
- @projectstorm/react-diagrams@7.0.0

View File

@@ -31,7 +31,8 @@ class CanvasDragToggle extends React.Component<any, any> {
<DemoButton key={2} onClick={this.disableDrag}>
Disable canvas drag
</DemoButton>
]}>
]}
>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>

View File

@@ -1,5 +1,5 @@
import createEngine, { DiagramModel, DefaultNodeModel, LinkModel, NodeModel } from '@projectstorm/react-diagrams';
import * as _ from 'lodash';
import _forEach from 'lodash/forEach';
import * as React from 'react';
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
import { BaseModel, CanvasWidget } from '@projectstorm/react-canvas-core';
@@ -20,7 +20,7 @@ class CloneSelected extends React.Component<any, any> {
let model = engine.getModel();
let itemMap = {};
_.forEach(model.getSelectedEntities(), (item: BaseModel<any>) => {
_forEach(model.getSelectedEntities(), (item: BaseModel<any>) => {
let newItem = item.clone(itemMap);
// offset the nodes slightly

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import * as _ from 'lodash';
import _forEach from 'lodash/forEach';
import createEngine, { DiagramModel, DefaultNodeModel, DefaultLinkModel } from '@projectstorm/react-diagrams';
import { CanvasWidget, Action, ActionEvent, InputType } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
@@ -26,7 +26,7 @@ class CustomDeleteItemsAction extends Action {
const confirm = window.confirm('Are you sure you want to delete?');
if (confirm) {
_.forEach(selectedEntities, (model) => {
_forEach(selectedEntities, (model) => {
// only delete items which are not locked
if (!model.isLocked()) {
model.remove();

View File

@@ -36,7 +36,8 @@ export class DiamondNodeWidget extends React.Component<DiamondNodeWidgetProps> {
position: 'relative',
width: this.props.size,
height: this.props.size
}}>
}}
>
<svg
width={this.props.size}
height={this.props.size}
@@ -72,7 +73,8 @@ export class DiamondNodeWidget extends React.Component<DiamondNodeWidgetProps> {
position: 'absolute'
}}
port={this.props.node.getPort(PortModelAlignment.LEFT)}
engine={this.props.engine}>
engine={this.props.engine}
>
<S.Port />
</PortWidget>
<PortWidget
@@ -82,7 +84,8 @@ export class DiamondNodeWidget extends React.Component<DiamondNodeWidgetProps> {
position: 'absolute'
}}
port={this.props.node.getPort(PortModelAlignment.TOP)}
engine={this.props.engine}>
engine={this.props.engine}
>
<S.Port />
</PortWidget>
<PortWidget
@@ -92,7 +95,8 @@ export class DiamondNodeWidget extends React.Component<DiamondNodeWidgetProps> {
position: 'absolute'
}}
port={this.props.node.getPort(PortModelAlignment.RIGHT)}
engine={this.props.engine}>
engine={this.props.engine}
>
<S.Port />
</PortWidget>
<PortWidget
@@ -102,7 +106,8 @@ export class DiamondNodeWidget extends React.Component<DiamondNodeWidgetProps> {
position: 'absolute'
}}
port={this.props.node.getPort(PortModelAlignment.BOTTOM)}
engine={this.props.engine}>
engine={this.props.engine}
>
<S.Port />
</PortWidget>
</div>

View File

@@ -7,7 +7,7 @@ import createEngine, {
DiagramEngine,
PathFindingLinkFactory
} from '@projectstorm/react-diagrams';
import * as React from 'react';
import { useLayoutEffect, useRef } from 'react';
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
@@ -33,57 +33,82 @@ function connectNodes(nodeFrom, nodeTo, engine: DiagramEngine) {
/**
* Tests auto distribution
*/
class DemoWidget extends React.Component<{ model: DiagramModel; engine: DiagramEngine }, any> {
engine: DagreEngine;
function genDagreEngine() {
return new DagreEngine({
graph: {
rankdir: 'RL',
ranker: 'longest-path',
marginx: 25,
marginy: 25
},
includeLinks: true,
nodeMargin: 25
});
}
constructor(props) {
super(props);
this.engine = new DagreEngine({
graph: {
rankdir: 'RL',
ranker: 'longest-path',
marginx: 25,
marginy: 25
},
includeLinks: true
});
}
function autoDistribute(engine: DiagramEngine) {
const model = engine.getModel();
autoDistribute = () => {
this.engine.redistribute(this.props.model);
const dagreEngine = genDagreEngine();
dagreEngine.redistribute(model);
// only happens if pathfing is enabled (check line 25)
this.reroute();
this.props.engine.repaintCanvas();
};
reroute(engine);
engine.repaintCanvas();
}
componentDidMount(): void {
setTimeout(() => {
this.autoDistribute();
}, 500);
}
function autoRefreshLinks(engine: DiagramEngine) {
const model = engine.getModel();
reroute() {
this.props.engine
const dagreEngine = genDagreEngine();
dagreEngine.refreshLinks(model);
// only happens if pathfing is enabled (check line 29)
reroute(engine);
engine.repaintCanvas();
}
function reroute(engine: DiagramEngine) {
engine
.getLinkFactories()
.getFactory<PathFindingLinkFactory>(PathFindingLinkFactory.NAME)
.calculateRoutingMatrix();
}
function DemoWidget(props) {
const engine = props.engine;
useLayoutEffect(() => {
autoDistribute(engine);
}, []);
const redistribute = () => {
autoDistribute(engine);
}
render() {
return (
<DemoWorkspaceWidget buttons={<DemoButton onClick={this.autoDistribute}>Re-distribute</DemoButton>}>
<DemoCanvasWidget>
<CanvasWidget engine={this.props.engine} />
</DemoCanvasWidget>
</DemoWorkspaceWidget>
);
const refreshLinks = () => {
autoRefreshLinks(engine);
}
return (
<DemoWorkspaceWidget
buttons={
<div>
<DemoButton onClick={redistribute}>Re-distribute</DemoButton>
<DemoButton onClick={refreshLinks}>Refresh Links</DemoButton>
</div>
}
>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>
</DemoWorkspaceWidget>
);
}
export default () => {
//1) setup the diagram engine
let engine = createEngine();
const engineRef = useRef(createEngine());
let engine = engineRef.current;
//2) setup the diagram model
let model = new DiagramModel();
@@ -106,9 +131,11 @@ export default () => {
});
// more links for more complicated diagram
links.push(connectNodes(nodesFrom[0], nodesTo[1], engine));
links.push(connectNodes(nodesTo[0], nodesFrom[1], engine));
links.push(connectNodes(nodesFrom[1], nodesTo[2], engine));
links.push(connectNodes(nodesTo[0], nodesTo[1], engine));
links.push(connectNodes(nodesTo[1], nodesTo[2], engine));
links.push(connectNodes(nodesTo[0], nodesTo[2], engine));
links.push(connectNodes(nodesFrom[0], nodesFrom[2], engine));
links.push(connectNodes(nodesFrom[0], nodesTo[2], engine));
// initial random position
nodesFrom.forEach((node, index) => {

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import * as _ from 'lodash';
import _keys from 'lodash/keys';
import { TrayWidget } from './TrayWidget';
import { Application } from '../Application';
import { TrayItemWidget } from './TrayItemWidget';
@@ -57,7 +57,7 @@ export class BodyWidget extends React.Component<BodyWidgetProps> {
<S.Layer
onDrop={(event) => {
var data = JSON.parse(event.dataTransfer.getData('storm-diagram-node'));
var nodesCount = _.keys(this.props.app.getDiagramEngine().getModel().getNodes()).length;
var nodesCount = _keys(this.props.app.getDiagramEngine().getModel().getNodes()).length;
var node: DefaultNodeModel = null;
if (data.type === 'in') {
@@ -74,7 +74,8 @@ export class BodyWidget extends React.Component<BodyWidgetProps> {
}}
onDragOver={(event) => {
event.preventDefault();
}}>
}}
>
<DemoCanvasWidget>
<CanvasWidget engine={this.props.app.getDiagramEngine()} />
</DemoCanvasWidget>

View File

@@ -29,7 +29,8 @@ export class TrayItemWidget extends React.Component<TrayItemWidgetProps> {
onDragStart={(event) => {
event.dataTransfer.setData('storm-diagram-node', JSON.stringify(this.props.model));
}}
className="tray-item">
className="tray-item"
>
{this.props.name}
</S.Tray>
);

View File

@@ -1,5 +1,5 @@
import createEngine, { DiagramModel, DefaultNodeModel, DiagramEngine } from '@projectstorm/react-diagrams';
import * as _ from 'lodash';
import _values from 'lodash/values';
import * as React from 'react';
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
@@ -7,7 +7,7 @@ import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
class CloneSelected extends React.Component<{ model: DiagramModel; engine: DiagramEngine }, any> {
addPorts = () => {
const nodes: DefaultNodeModel[] = _.values(this.props.model.getNodes()) as DefaultNodeModel[];
const nodes: DefaultNodeModel[] = _values(this.props.model.getNodes()) as DefaultNodeModel[];
for (let node of nodes) {
if (node.getOptions().name === 'Node 2') {
node.addInPort(`in-${node.getInPorts().length + 1}`, false);

View File

@@ -53,10 +53,12 @@ export default () => {
<DemoButton
onClick={() => {
action('Serialized Graph')(JSON.stringify(model.serializeDiagram(), null, 2));
}}>
}}
>
Serialize Graph
</DemoButton>
}>
}
>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>

View File

@@ -1,6 +1,6 @@
import createEngine, { DiagramModel, DefaultNodeModel, NodeModel } from '@projectstorm/react-diagrams';
import * as React from 'react';
import * as _ from 'lodash';
import _values from 'lodash/values';
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
@@ -30,7 +30,7 @@ class NodeDelayedPosition extends React.Component<any, any> {
let str = JSON.stringify(model.serialize());
let model2 = new DiagramModel();
let obj: ReturnType<DiagramModel['serialize']> = JSON.parse(str);
let node: ReturnType<NodeModel['serialize']> = _.values(obj.layers[1].models)[0] as any;
let node: ReturnType<NodeModel['serialize']> = _values(obj.layers[1].models)[0] as any;
node.x += 30;
node.y += 30;
@@ -49,7 +49,8 @@ class NodeDelayedPosition extends React.Component<any, any> {
<DemoButton key={2} onClick={this.updatePositionViaSerialize}>
Update position via serialize
</DemoButton>
]}>
]}
>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>

View File

@@ -58,10 +58,12 @@ export default () => {
<DemoButton
onClick={() => {
action('Serialized Graph')(JSON.stringify(model.serialize(), null, 2));
}}>
}}
>
Serialize Graph
</DemoButton>
}>
}
>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>

View File

@@ -49,10 +49,12 @@ export default () => {
<DemoButton
onClick={() => {
action('Serialized Graph')(beautify(model2.serialize(), null, 2, 80));
}}>
}}
>
Serialize Graph
</DemoButton>
}>
}
>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>

View File

@@ -60,10 +60,12 @@ export default () => {
<DemoButton
onClick={() => {
action('Serialized Graph')(JSON.stringify(model.serialize(), null, 2));
}}>
}}
>
Serialize Graph
</DemoButton>
}>
}
>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>

View File

@@ -29,7 +29,8 @@ export default () => {
//6) render the diagram!
return (
<DemoWorkspaceWidget
buttons={<DemoButton onClick={() => engine.zoomToFitSelectedNodes(50)}>Zoom to fit</DemoButton>}>
buttons={<DemoButton onClick={() => engine.zoomToFitSelectedNodes(50)}>Zoom to fit</DemoButton>}
>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>

View File

@@ -55,14 +55,15 @@ namespace S {
`;
}
export class DemoCanvasWidget extends React.Component<DemoCanvasWidgetProps> {
export class DemoCanvasWidget extends React.Component<React.PropsWithChildren<DemoCanvasWidgetProps>> {
render() {
return (
<>
<Global styles={S.Expand} />
<S.Container
background={this.props.background || 'rgb(60, 60, 60)'}
color={this.props.color || 'rgba(255,255,255, 0.05)'}>
color={this.props.color || 'rgba(255,255,255, 0.05)'}
>
{this.props.children}
</S.Container>
</>

View File

@@ -43,7 +43,7 @@ export const DemoButton = styled.button`
}
`;
export class DemoWorkspaceWidget extends React.Component<DemoWorkspaceWidgetProps> {
export class DemoWorkspaceWidget extends React.Component<React.PropsWithChildren<DemoWorkspaceWidgetProps>> {
render() {
return (
<S.Container>

View File

@@ -1,6 +1,6 @@
html,
body,
#root {
#storybook-root {
height: 100%;
padding: 0;
margin: 0;

View File

@@ -1,7 +0,0 @@
module.exports = {
launch: {
dumpio: true,
headless: process.env.CI === 'true'
},
browserContext: 'default'
};

View File

@@ -1,9 +0,0 @@
const path = require('path');
module.exports = {
preset: 'jest-puppeteer',
transform: {
'^.+\\.tsx?$': 'ts-jest'
},
roots: [path.join(__dirname, 'tests-e2e')],
testMatch: ['**/*.test.{ts,tsx}']
};

View File

@@ -1,13 +0,0 @@
{
"name": "@projectstorm/react-diagrams-gallery",
"version": "6.7.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"gsap": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/gsap/-/gsap-3.0.1.tgz",
"integrity": "sha512-9nzEBF7Ss9Ogyw6oEOXZxxVYH8WNRA/nHmIp3DrPOTKmlLxX9MN2ovSoH9TApA+rucBgp9veCedujp5oSQRvZw=="
}
}
}

View File

@@ -1,40 +1,53 @@
{
"name": "@projectstorm/react-diagrams-gallery",
"version": "6.7.0",
"author": "dylanvorster",
"license": "MIT",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/projectstorm/react-diagrams.git"
},
"scripts": {
"start": "./node_modules/.bin/start-storybook",
"storybook:build": "./node_modules/.bin/build-storybook -c .storybook -o .out",
"github": "./node_modules/.bin/storybook-to-ghpages",
"test:run": "../node_modules/.bin/jest --no-cache",
"test": "yarn storybook:build && yarn test:run"
},
"keywords": [
"web",
"diagram",
"diagrams",
"react",
"typescript",
"flowchart",
"simple",
"links",
"nodes"
],
"dependencies": {
"@storybook/addon-actions": "^6.2.8",
"@storybook/addon-options": "^5.3.21",
"@storybook/addons": "^6.2.8",
"@storybook/builder-webpack5": "^6.2.8",
"@storybook/manager-webpack5": "^6.3.2",
"@storybook/react": "^6.3.2",
"@storybook/storybook-deployer": "^2.8.7",
"@storybook/theming": "^6.2.8",
"gsap": "^3.7.1"
}
"name": "@projectstorm/react-diagrams-gallery",
"version": "7.2.0",
"author": "dylanvorster",
"license": "MIT",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/projectstorm/react-diagrams.git"
},
"scripts": {
"start": "pnpm storybook dev",
"storybook:build": "pnpm storybook build -c .storybook -o .out"
},
"keywords": [
"web",
"diagram",
"diagrams",
"react",
"typescript",
"flowchart",
"simple",
"links",
"nodes"
],
"dependencies": {
"@projectstorm/react-canvas-core": "workspace:*",
"@projectstorm/react-diagrams": "workspace:*",
"@projectstorm/react-diagrams-core": "workspace:*",
"@projectstorm/react-diagrams-defaults": "workspace:*",
"gsap": "^3.12.2",
"json-beautify": "^1.1.1",
"lodash": "^4.17.21",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@babel/preset-env": "^7.22.20",
"@babel/preset-react": "^7.22.15",
"@babel/preset-typescript": "^7.22.15",
"@storybook/addon-actions": "^7.4.4",
"@storybook/addon-options": "^5.3.21",
"@storybook/addons": "^7.4.4",
"@storybook/react": "^7.4.4",
"@storybook/react-webpack5": "^7.4.4",
"@storybook/storybook-deployer": "^2.8.16",
"@storybook/theming": "^7.4.4",
"@types/lodash": "^4.14.200",
"@types/react": "^18.2.22",
"@types/react-dom": "^18.2.7",
"storybook": "^7.4.4"
}
}

View File

@@ -1,28 +0,0 @@
import { ElementHandle } from 'puppeteer';
export abstract class E2EBase {
name: string;
constructor(name: string) {
this.name = name;
}
async getSelector(): Promise<any> {
return page;
}
async getElement(): Promise<ElementHandle> {
if (!(await this.getSelector())) {
return null;
}
return (await this.getSelector()).$(this.selector());
}
async waitForElement(): Promise<ElementHandle | null> {
return (await this.getSelector()).waitForSelector(this.selector(), {
timeout: 1000
});
}
protected abstract selector(): string;
}

View File

@@ -1,27 +0,0 @@
import { E2EBase } from './E2EBase';
export class E2ELink extends E2EBase {
isID: boolean;
async select(): Promise<any> {
const point = await page.evaluate((id) => {
const path = document.querySelector(id) as SVGPathElement;
const rect = path.getClientRects().item(0);
return {
x: rect.x + rect.width / 2,
y: rect.y
};
}, this.selector());
await page.keyboard.down('Shift');
await page.mouse.move(point.x, point.y);
await page.mouse.down();
await page.keyboard.up('Shift');
}
protected selector(): string {
if (this.isID) {
return `[data-linkid="${this.name}"] path`;
}
return `[data-default-link-test="${this.name}"] path`;
}
}

View File

@@ -1,12 +0,0 @@
import { E2EBase } from './E2EBase';
import { E2EPort } from './E2EPort';
export class E2ENode extends E2EBase {
async port(id: string): Promise<E2EPort> {
return new E2EPort(id, this);
}
selector(): string {
return `[data-default-node-name="${this.name}"]`;
}
}

View File

@@ -1,82 +0,0 @@
import * as _ from 'lodash';
import { E2EBase } from './E2EBase';
import { E2ENode } from './E2ENode';
import { E2ELink } from './E2ELink';
export class E2EPort extends E2EBase {
parent: E2ENode;
constructor(name: string, parent: E2ENode) {
super(name);
this.parent = parent;
}
async getLinks(): Promise<E2ELink[]> {
const attribute = await page.evaluate((id) => {
return document.querySelector(id).getAttribute('data-links');
}, this.selector());
if (attribute.trim() === '') {
return [];
}
return _.map(attribute.split(','), (id) => {
const e = new E2ELink(id);
e.isID = true;
return e;
});
}
async link(port: E2EPort): Promise<E2ELink> {
let currentLinks = _.map(await this.getLinks(), 'name');
let bounds = await (await this.getElement()).boundingBox();
// click on this port
page.mouse.move(bounds.x, bounds.y);
page.mouse.down();
//
let bounds2 = await (await port.getElement()).boundingBox();
// drag to other port
page.mouse.move(bounds2.x, bounds2.y);
page.mouse.up();
let newLinks = _.map(await this.getLinks(), 'name');
const s = new E2ELink(_.difference(newLinks, currentLinks)[0]);
s.isID = true;
return s;
}
async linkToPoint(x: number, y: number): Promise<E2ELink> {
let currentLinks = _.map(await this.getLinks(), 'id');
let bounds = await (await this.getElement()).boundingBox();
// click on this port
page.mouse.move(bounds.x, bounds.y);
page.mouse.down();
// drag to point
page.mouse.move(x, y);
page.mouse.up();
let newLinks = _.map(await this.getLinks(), 'id');
const link = _.difference(newLinks, currentLinks)[0];
if (!link) {
return null;
}
// get the parent to get the link
return new E2ELink(link);
}
async getSelector(): Promise<any> {
return (await this.parent.getElement()) as any;
}
protected selector(): string {
return `${this.parent.selector()} .port[data-name="${this.name}"]`;
}
}

View File

@@ -1,33 +0,0 @@
import 'jest';
import { E2ENode } from './helpers/E2ENode';
describe('simple flow test', () => {
beforeEach(async () => {
await page.goto(`file://${__dirname}/../.out/iframe.html?path=/story/simple-usage--simple-flow-example`);
});
it('drag link to port adds a link', async () => {
// create a new link
let node1 = new E2ENode('Node 3');
let node2 = new E2ENode('Node 2');
let port1 = await node1.port('Out');
let port2 = await node2.port('In');
let newlink = await port1.link(port2);
await expect(await newlink.waitForElement()).toBeTruthy();
});
it('drag link to node does not add a link', async () => {
// create a new link
let node1 = new E2ENode('Node 3');
let node2 = new E2ENode('Node 2');
let port1 = await node1.port('Out');
let node2Bounds = await (await node2.waitForElement()).boundingBox();
let newlink = await port1.linkToPoint(node2Bounds.x, node2Bounds.y);
await expect(newlink).toBeFalsy();
});
});

View File

@@ -1,31 +0,0 @@
import 'jest';
import { E2ELink } from './helpers/E2ELink';
import { E2ENode } from './helpers/E2ENode';
describe('simple test', () => {
beforeAll(async () => {
await page.goto(`file://${__dirname}/../.out/iframe.html?path=/story/simple-usage--demo-simple`);
});
it('should delete a link and create a new one', async () => {
// get the existing link
let link = new E2ELink('Test');
await expect(await link.waitForElement()).toBeTruthy();
// remove it
await link.select();
await page.keyboard.press('Delete');
await expect(await link.getElement()).toBeFalsy();
// create a new link
let node1 = new E2ENode('Node 1');
let node2 = new E2ENode('Node 2');
let port1 = await node1.port('Out');
let port2 = await node2.port('In');
let newlink = await port1.link(port2);
await expect(await newlink.waitForElement()).toBeTruthy();
});
});

View File

@@ -2,6 +2,7 @@
"compileOnSave": false,
"compilerOptions": {
"suppressExcessPropertyErrors": true,
"esModuleInterop": true,
"declaration": true,
"composite": true,
"incremental": true,

View File

@@ -0,0 +1,56 @@
# @projectstorm/react-diagrams-demo
## 7.0.4
### Patch Changes
- @projectstorm/react-diagrams@7.0.4
## 7.0.3
### Patch Changes
- 66c687a: Upgrade all dependencies and fix Storybook after upgrade
- @projectstorm/react-diagrams@7.0.3
## 7.0.2
### Patch Changes
- b8a4cbd: Inline sources in sourcemap
- Updated dependencies [b8a4cbd]
- @projectstorm/react-diagrams@7.0.2
## 7.0.1
### Patch Changes
- @projectstorm/react-diagrams@7.0.1
## 7.0.0
### Major Changes
- b051697: - [internal] moves to `Pnpm` (instead of yarn -\_-)
- [internal]moves to `Changesets` for releases
- [internal]removes `Lerna`
- [internal] upgrades all dependencies
- [internal] switches to workspace protocol syntax (Changesets will bake in the correct version when a publish occurs)
- [internal] Changesets will open a release PR which can wrap up several changes in 1 go
- [internal] Changesets will run the storybook deploy automatically upon merging the release PR
- [internal] removes a lot of the stuff from the root package.json
- [internal] cleans up the build and clean commands
- [internal] remove E2E tests, they are a nightmare to maintain and the ROI is far too low
- [fix] Wrong type name for react-canvas model listener
- [fix] export more stuff form the main react-diagrams package
- [fix] circular deps with Rectangle and Polygon (turns out this was a problem but only with UMD builds, sorry @everyone who I doubted, but this is also why I could never reproduce the issue)
- [breaking change] compile both ES6 and UMD
- [breaking change] moves dependencies back to each package. (After years of working on libraries, I've come to actually hate peer dependencies, and this is easily solved with build systems / package managers).
- [breaking change] static methods on `Polygon` and `Rectangle` moved to standalone methods
- [breaking change] static construction methods to rather deal with different Rectangle constructor overloads (I now consider this bad design)
- [breaking change] introduce `Bounds` as a simpler point-array type to deal with boundary computation instead
### Patch Changes
- Updated dependencies [b051697]
- @projectstorm/react-diagrams@7.0.0

View File

@@ -1,6 +1,6 @@
{
"name": "@projectstorm/react-diagrams-demo",
"version": "6.7.0",
"version": "7.0.4",
"author": "dylanvorster",
"license": "MIT",
"private": true,
@@ -25,10 +25,22 @@
"main": "./dist/index.js",
"typings": "./dist/@types/index",
"dependencies": {
"@projectstorm/react-diagrams": "^6.7.0",
"webpack": "^5.46.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2"
"@projectstorm/react-diagrams": "workspace:*",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"gitHead": "bb878657ba0c2f81764f32901fd96158a0f8352e"
"devDependencies": {
"source-map-loader": "^4.0.1",
"html-webpack-plugin": "^5.5.3",
"@babel/core": "^7.22.20",
"@babel/preset-react": "^7.22.15",
"@types/react": "^18.2.22",
"@types/react-dom": "^18.2.7",
"babel-loader": "^9.1.3",
"css-loader": "^6.8.1",
"style-loader": "^3.3.3",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
}
}

View File

@@ -1,6 +1,5 @@
import * as React from 'react';
import { DiagramEngine } from '@projectstorm/react-diagrams';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DiagramEngine, CanvasWidget } from '@projectstorm/react-diagrams';
export interface BodyWidgetProps {
engine: DiagramEngine;

View File

@@ -1,7 +1,7 @@
import * as React from 'react';
import { JSCustomNodeModel } from './JSCustomNodeModel';
import { JSCustomNodeWidget } from './JSCustomNodeWidget';
import { AbstractReactFactory } from '@projectstorm/react-canvas-core';
import { AbstractReactFactory } from '@projectstorm/react-diagrams';
export class JSCustomNodeFactory extends AbstractReactFactory {
constructor() {

View File

@@ -1,8 +1,8 @@
import * as React from 'react';
import { TSCustomNodeModel } from './TSCustomNodeModel';
import { TSCustomNodeWidget } from './TSCustomNodeWidget';
import { AbstractReactFactory } from '@projectstorm/react-canvas-core';
import { DiagramEngine } from '@projectstorm/react-diagrams-core';
import { AbstractReactFactory } from '@projectstorm/react-diagrams';
import { DiagramEngine } from '@projectstorm/react-diagrams';
export class TSCustomNodeFactory extends AbstractReactFactory<TSCustomNodeModel, DiagramEngine> {
constructor() {

View File

@@ -1,5 +1,4 @@
import { NodeModel, DefaultPortModel } from '@projectstorm/react-diagrams';
import { BaseModelOptions } from '@projectstorm/react-canvas-core';
import { BaseModelOptions, DefaultPortModel, NodeModel } from '@projectstorm/react-diagrams';
export interface TSCustomNodeModelOptions extends BaseModelOptions {
color?: string;

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import { DiagramEngine, PortWidget } from '@projectstorm/react-diagrams-core';
import { DiagramEngine, PortWidget } from '@projectstorm/react-diagrams';
import { TSCustomNodeModel } from './TSCustomNodeModel';
export interface TSCustomNodeWidgetProps {

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';
import './main.css';
import createEngine, { DefaultLinkModel, DiagramModel } from '@projectstorm/react-diagrams';
import { JSCustomNodeFactory } from './custom-node-js/JSCustomNodeFactory';
@@ -39,5 +39,6 @@ model.addAll(node1, node2, link1);
engine.setModel(model);
document.addEventListener('DOMContentLoaded', () => {
ReactDOM.render(<BodyWidget engine={engine} />, document.querySelector('#application'));
const root = createRoot(document.querySelector('#application'));
root.render(<BodyWidget engine={engine} />);
});

View File

@@ -5,7 +5,7 @@
"jsx": "react",
"allowJs": true,
"target": "es6",
"moduleResolution": "node"
"module": "CommonJS"
},
"include": [
"./src"

View File

@@ -1,6 +1,7 @@
const path = require('path');
const production = process.env.NODE_ENV === 'production';
const TerserPlugin = require('terser-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: production ? 'production' : 'development',
@@ -23,8 +24,18 @@ module.exports = {
})
]
},
plugins: [
new HtmlWebpackPlugin({
template: 'index.html'
})
],
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
@@ -36,18 +47,15 @@ module.exports = {
},
{
test: /\.tsx?$/,
loader: 'ts-loader',
options: {
transpileOnly: true
}
loader: 'ts-loader'
}
]
},
devServer: {
host: '0.0.0.0',
compress: true,
disableHostCheck: true,
overlay: true
client: {
overlay: true
},
hot: false,
compress: true
}
};

View File

@@ -8,7 +8,7 @@ Joint JS \(a fantastic library\) + my need for rich HTML nodes + LabView + Blend
## Why render the nodes as HTML Elements and not SVG's?
My original requirement for this library stemmed from the requirement of wanting HTML nodes that would allow me to embed rich controls such as input fields, drop downs and have the system treat such nodes as first class citizens. I originally tried to make this work in JointJS, but ran into a number of problems of which this was a relatively big one.
My original requirement for this library stemmed from the requirement of wanting HTML nodes that would allow me to embed rich controls such as input fields, dropdowns and have the system treat such nodes as first class citizens. I originally tried to make this work in JointJS, but ran into a number of problems of which this was a relatively big one.
JointJS does allow you to do this, but at the time of writing this library originally, I was having a lot of trouble to make it work exactly like I needed it, and therefore decided from the very beginning that I would attempt this with an HTML first mindset.
@@ -16,7 +16,7 @@ JointJS does allow you to do this, but at the time of writing this library origi
Firstly, because it can transpile into any level of ECMAScript. This means that I don't need to break our the refactor tractor every time ECMAScript decides it wants to add features which it should have done years ago.
I also ported it to Typescript to accommodate the heavy architectural changes I was starting to make. Since porting the library to typescript, and seeing the project explode in size and complexity, I consider this the best decision made with regards to this library so far.
I also ported it to Typescript to accommodate the heavy architectural changes I was starting to make. Since porting the library to typescript, and seeing the project explode in size and complexity, I consider this the best decision made with regard to this library so far.
Porting to typescript also afforded us a set of powerful features such as generics and static analysis that all the project contributors have made exclusive use of.
@@ -24,11 +24,11 @@ Typescript is &lt;3 typescript is life.
## Why not Flow instead of Typescript?
At the time when I first started evaluating languages that could transpile to ECMAScript, I was not so sold on the supporting environment surrounding flow, and and found that there was better tooling to support typescript, they are ultimately trying to do the same thing though, and I guess in the end, typescript just made more sense.
At the time when I first started evaluating languages that could transpile to ECMAScript, I was not so sold on the supporting environment surrounding flow, and found that there was better tooling to support typescript, they are ultimately trying to do the same thing though, and I guess in the end, typescript just made more sense.
## Why React ?
React is really efficient at rendering and managing HTML in a declarative manner. React has also become one of the bigger industry standards and has a rich eco system that plays really well with typescript. Apart from these notable points, I am really fond of React and wanted a diagramming library that takes full advantage of it, and makes it easy for engineers to use its power as well, when extending this library.
React is really efficient at rendering and managing HTML in a declarative manner. React has also become one of the bigger industry standards and has a rich ecosystem that plays really well with typescript. Apart from these notable points, I am really fond of React and wanted a diagramming library that takes full advantage of it, and makes it easy for engineers to use its power as well, when extending this library.
## Why cant the Default models and widgets do this or that ?

View File

@@ -2,7 +2,7 @@
## End to end testing
To test the functionality of the library, we make use of e2e tests \(end to end tests\). In this library, we spin up a headless chrome using pupeteer and interactively and programmatically tell the mouse pointer to click and drag on various elements while making assertions along the way.
To test the functionality of the library, we make use of e2e tests \(end to end tests\). In this library, we spin up a headless chrome using puppeteer and interactively and programmatically tell the mouse pointer to click and drag on various elements while making assertions along the way.
We use Jest for the assertions and the interactivity is handled by puppeteer. Due to the laborious nature of writing e2e tests, there is a helper method that is provided in each test that makes interacting with the diagrams a lot easier. Using this helper, you can easily tell the mouse to drag links between nodes, select them and also easily assert information about them. The important thing here, is that this helper does not touch the model in any way, but is purely a helper for writing the tests themselves. Please make use of this helper when writing tests, as it ensure that the tests are defensive in nature, and also reduces the overhead of physically writing them.

View File

@@ -2,7 +2,7 @@
## Get the package
The first thing you need to do, is grab the distribution files on NPM. You can do this either using **yarn** or **npm.**
The first thing you need to do, is grab the distribution files on NPM.
**Via yarn:**
@@ -16,25 +16,10 @@ yarn add @projectstorm/react-diagrams
npm install @projectstorm/react-diagrams
```
When you run this in your project directory, this will install the library into `./node_modules/@projectstorm/react-diagrams`. You will then find a **dist** folder that contains all the minified and production ready code.
## Install the peer dependencies
The library includes it's dependencies as peer-dependencies, so yarn will output warnings letting you know which ones are missing. Simple install them, specifically these ones:
**Via yarn:**
**Via pnpm:**
```text
yarn add closest lodash react dagre pathfinding paths-js @emotion/react @emotion/styled resize-observer-polyfill
pnpm add @projectstorm/react-diagrams
```
**Via npm:**
```text
npm install closest lodash react dagre pathfinding paths-js @emotion/react @emotion/styled resize-observer-polyfill
```
We do this, so that you can better control the versions of these libraries yourself since you might make use of `Lodash` in other parts of your software.
When you run this in your project directory, this will install the library into `./node_modules/@projectstorm/react-diagrams`. You will then find a **dist** folder that contains all the minified and production ready code.

View File

@@ -1,5 +0,0 @@
{
"npmClient": "yarn",
"useWorkspaces": true,
"version": "6.7.0"
}

View File

@@ -6,11 +6,6 @@
"type": "git",
"url": "https://github.com/projectstorm/react-diagrams.git"
},
"workspaces": [
"diagrams-demo-gallery",
"diagrams-demo-project",
"packages/*"
],
"keywords": [
"web",
"diagram",
@@ -23,70 +18,31 @@
"nodes"
],
"scripts": {
"clean": "tsc --build --clean && lerna run clean --stream",
"build": "tsc --build && lerna run build --stream",
"build:prod": "NODE_ENV=production yarn build",
"publish:dev": "yarn build:prod && lerna publish --force-publish --dist-tag=next",
"publish:prod": "yarn build:prod && lerna publish --force-publish",
"publish:storybook": "cd diagrams-demo-gallery && yarn storybook:build && ../node_modules/.bin/storybook-to-ghpages --existing-output-dir .out",
"test:ci": "lerna run test --stream -- --runInBand --ci ",
"test": "lerna run test --stream",
"pretty": "prettier --write \"**/*.{ts,tsx,scss,js,jsx}\""
},
"peerDependencies": {
"emotion": "11.*",
"lodash": "4.*",
"pathfinding": "^0.4.18",
"paths-js": "^0.4.11",
"react": "16.* || 17.*"
"ncu": "ncu -u && pnpm recursive exec -- ncu -u",
"format": "prettier --write \"**/*.{ts,tsx,js,jsx}\"",
"clean": "rm -rf packages/*/dist",
"test": "pnpm run -r test",
"build": "tsc --build && pnpm run -r build",
"build:prod": "NODE_ENV=production pnpm build",
"release": "pnpm build:prod && pnpm changeset publish",
"release:storybook": "tsc --build && cd diagrams-demo-gallery && pnpm storybook:build && ./node_modules/.bin/storybook-to-ghpages --existing-output-dir .out"
},
"devDependencies": {
"@babel/core": "^7.14.8",
"@babel/preset-react": "^7.14.5",
"@emotion/react": "^11.4.0",
"@emotion/styled": "^11.3.0",
"@types/dagre": "^0.7.45",
"@types/jest": "^26.0.24",
"@types/jest-environment-puppeteer": "^4.4.1",
"@types/lodash": "^4.14.171",
"@types/node": "^16.4.1",
"@types/puppeteer": "^5.4.4",
"@types/react": "^17.0.14",
"babel-loader": "^8.2.2",
"cross-env": "^7.0.3",
"css-loader": "^6.2.0",
"dagre": "^0.8.5",
"emotion": "^11.0.0",
"enzyme": "^3.11.0",
"file-loader": "^6.2.0",
"glob": "^7.1.7",
"jest": "^27.0.6",
"jest-cli": "^27.0.6",
"jest-puppeteer": "^5.0",
"json-beautify": "^1.1.1",
"lerna": "^4.0.0",
"lodash": "^4.17.21",
"pathfinding": "^0.4.18",
"paths-js": "^0.4.11",
"prettier": "^2.3.2",
"puppeteer": "10.1.0",
"raf": "^3.4.1",
"raw-loader": "^4.0.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-test-renderer": "^17.0.2",
"resize-observer-polyfill": "^1.5.1",
"rimraf": "^3.0.2",
"source-map-loader": "^3.0.0",
"style-loader": "^3.2.1",
"terser-webpack-plugin": "^5.1.4",
"ts-jest": "^27.0.4",
"ts-loader": "^9.2.3",
"typescript": "^4.3.5",
"val-loader": "^4.0.0",
"webpack": "^5.46.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2",
"@changesets/cli": "^2.26.2",
"@types/jest": "^29.5.5",
"@types/node": "^20.6.3",
"jest": "^29.7.0",
"jest-cli": "^29.7.0",
"prettier": "^3.0.3",
"rimraf": "^5.0.1",
"source-map-loader": "^4.0.1",
"terser-webpack-plugin": "^5.3.9",
"ts-jest": "^29.1.1",
"ts-loader": "^9.4.4",
"typescript": "^5.2.2",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1",
"webpack-node-externals": "^3.0.0"
}
}

View File

@@ -1,5 +1,4 @@
*
!src/**/*
!dist/**/*
!package.json
!README.md
dist/tsconfig.tsbuildinfo

View File

@@ -0,0 +1,42 @@
# @projectstorm/geometry
## 7.0.3
### Patch Changes
- 80285fe: refactor: update lodash imports to use individual functions
## 7.0.2
### Patch Changes
- 66c687a: Upgrade all dependencies and fix Storybook after upgrade
## 7.0.1
### Patch Changes
- b8a4cbd: Inline sources in sourcemap
## 7.0.0
### Major Changes
- b051697: - [internal] moves to `Pnpm` (instead of yarn -\_-)
- [internal]moves to `Changesets` for releases
- [internal]removes `Lerna`
- [internal] upgrades all dependencies
- [internal] switches to workspace protocol syntax (Changesets will bake in the correct version when a publish occurs)
- [internal] Changesets will open a release PR which can wrap up several changes in 1 go
- [internal] Changesets will run the storybook deploy automatically upon merging the release PR
- [internal] removes a lot of the stuff from the root package.json
- [internal] cleans up the build and clean commands
- [internal] remove E2E tests, they are a nightmare to maintain and the ROI is far too low
- [fix] Wrong type name for react-canvas model listener
- [fix] export more stuff form the main react-diagrams package
- [fix] circular deps with Rectangle and Polygon (turns out this was a problem but only with UMD builds, sorry @everyone who I doubted, but this is also why I could never reproduce the issue)
- [breaking change] compile both ES6 and UMD
- [breaking change] moves dependencies back to each package. (After years of working on libraries, I've come to actually hate peer dependencies, and this is easily solved with build systems / package managers).
- [breaking change] static methods on `Polygon` and `Rectangle` moved to standalone methods
- [breaking change] static construction methods to rather deal with different Rectangle constructor overloads (I now consider this bad design)
- [breaking change] introduce `Bounds` as a simpler point-array type to deal with boundary computation instead

View File

@@ -1,6 +1,6 @@
{
"name": "@projectstorm/geometry",
"version": "6.7.0",
"version": "7.0.3",
"author": "dylanvorster",
"license": "MIT",
"repository": {
@@ -28,5 +28,10 @@
"main": "./dist/index.umd.js",
"module": "./dist/index.js",
"typings": "./dist/@types/index",
"gitHead": "bb878657ba0c2f81764f32901fd96158a0f8352e"
"dependencies": {
"lodash": "^4.17.21"
},
"devDependencies": {
"@types/lodash": "^4.14.200"
}
}

View File

@@ -0,0 +1,28 @@
import { Point } from './Point';
export enum BoundsCorner {
TOP_LEFT = 'TL',
TOP_RIGHT = 'TR',
BOTTOM_RIGHT = 'BR',
BOTTOM_LEFT = 'BL'
}
export type Bounds = { [k in BoundsCorner]: Point };
export const boundsFromPositionAndSize = (x: number, y: number, width: number, height: number): Bounds => {
return {
[BoundsCorner.TOP_LEFT]: new Point(x, y),
[BoundsCorner.TOP_RIGHT]: new Point(x + width, y),
[BoundsCorner.BOTTOM_RIGHT]: new Point(x + width, y + height),
[BoundsCorner.BOTTOM_LEFT]: new Point(x, y + height)
};
};
export const createEmptyBounds = () => {
return {
[BoundsCorner.TOP_LEFT]: new Point(),
[BoundsCorner.TOP_RIGHT]: new Point(),
[BoundsCorner.BOTTOM_RIGHT]: new Point(),
[BoundsCorner.BOTTOM_LEFT]: new Point()
};
};

View File

@@ -1,3 +1,5 @@
import { Point } from './Point';
export class Matrix {
matrix: number[][];
@@ -19,4 +21,52 @@ export class Matrix {
get(rowIndex: number, columnIndex: number): number {
return this.asArray()[rowIndex][columnIndex];
}
public static multiply(...matrices: Matrix[]): Matrix {
let m: Matrix = matrices[0];
for (let i = 1; i < matrices.length; i++) {
m = m.mmul(matrices[i]);
}
return m;
}
public static scaleMatrix(x: number, y: number): Matrix {
return new Matrix([
[x, 0, 0],
[0, y, 0],
[0, 0, 1]
]);
}
public static translateMatrix(x: number, y: number): Matrix {
return new Matrix([
[1, 0, x],
[0, 1, y],
[0, 0, 1]
]);
}
public static rotateMatrix(deg: number): Matrix {
return new Matrix([
[Math.cos(deg), -1 * Math.sin(deg), 0],
[Math.sin(deg), Math.cos(deg), 0],
[0, 0, 1]
]);
}
static createScaleMatrix(x, y, origin: Point): Matrix {
return this.multiply(
Matrix.translateMatrix(origin.x, origin.y),
Matrix.scaleMatrix(x, y),
Matrix.translateMatrix(-origin.x, -origin.y)
);
}
static createRotateMatrix(deg: number, origin: Point): Matrix {
return this.multiply(
Matrix.translateMatrix(origin.x, origin.y),
Matrix.rotateMatrix(deg),
Matrix.translateMatrix(-origin.x, -origin.y)
);
}
}

View File

@@ -4,7 +4,7 @@ export class Point {
x: number;
y: number;
constructor(x: number, y: number) {
constructor(x: number = 0, y: number = 0) {
this.x = x;
this.y = y;
}
@@ -35,52 +35,4 @@ export class Point {
public static middlePoint(pointA: Point, pointB: Point): Point {
return new Point((pointB.x + pointA.x) / 2, (pointB.y + pointA.y) / 2);
}
public static multiply(...matrices: Matrix[]): Matrix {
let m: Matrix = matrices[0];
for (let i = 1; i < matrices.length; i++) {
m = m.mmul(matrices[i]);
}
return m;
}
public static scaleMatrix(x: number, y: number): Matrix {
return new Matrix([
[x, 0, 0],
[0, y, 0],
[0, 0, 1]
]);
}
public static translateMatrix(x: number, y: number): Matrix {
return new Matrix([
[1, 0, x],
[0, 1, y],
[0, 0, 1]
]);
}
public static rotateMatrix(deg: number): Matrix {
return new Matrix([
[Math.cos(deg), -1 * Math.sin(deg), 0],
[Math.sin(deg), Math.cos(deg), 0],
[0, 0, 1]
]);
}
static createScaleMatrix(x, y, origin: Point): Matrix {
return this.multiply(
Point.translateMatrix(origin.x, origin.y),
Point.scaleMatrix(x, y),
Point.translateMatrix(-origin.x, -origin.y)
);
}
static createRotateMatrix(deg: number, origin: Point): Matrix {
return this.multiply(
Point.translateMatrix(origin.x, origin.y),
Point.rotateMatrix(deg),
Point.translateMatrix(-origin.x, -origin.y)
);
}
}

View File

@@ -1,6 +1,9 @@
import { Point } from './Point';
import * as _ from 'lodash';
import _forEach from 'lodash/forEach';
import _map from 'lodash/map';
import { Matrix } from './Matrix';
import { boundingBoxFromPoints } from './toolkit';
import { Bounds, BoundsCorner } from './Bounds';
export class Polygon {
protected points: Point[];
@@ -10,26 +13,26 @@ export class Polygon {
}
serialize() {
return _.map(this.points, (point) => {
return _map(this.points, (point) => {
return [point.x, point.y];
});
}
deserialize(data: any) {
this.points = _.map(data, (point) => {
this.points = _map(data, (point) => {
return new Point(point[0], point[1]);
});
}
scale(x, y, origin: Point) {
let matrix = Point.createScaleMatrix(x, y, origin);
_.forEach(this.points, (point) => {
let matrix = Matrix.createScaleMatrix(x, y, origin);
_forEach(this.points, (point) => {
point.transform(matrix);
});
}
transform(matrix: Matrix) {
_.forEach(this.points, (point) => {
_forEach(this.points, (point) => {
point.transform(matrix);
});
}
@@ -43,17 +46,17 @@ export class Polygon {
}
rotate(degrees: number) {
this.transform(Point.createRotateMatrix(degrees / (180 / Math.PI), this.getOrigin()));
this.transform(Matrix.createRotateMatrix(degrees / (180 / Math.PI), this.getOrigin()));
}
translate(offsetX: number, offsetY: number) {
_.forEach(this.points, (point) => {
_forEach(this.points, (point) => {
point.translate(offsetX, offsetY);
});
}
doClone(ob: this) {
this.points = _.map(ob.points, (point) => {
this.points = _map(ob.points, (point) => {
return point.clone();
});
}
@@ -68,69 +71,11 @@ export class Polygon {
if (this.points.length === 0) {
return null;
}
let dimensions = this.getBoundingBox();
return Point.middlePoint(dimensions.getTopLeft(), dimensions.getBottomRight());
let dimensions = boundingBoxFromPoints(this.points);
return Point.middlePoint(dimensions[BoundsCorner.TOP_LEFT], dimensions[BoundsCorner.BOTTOM_RIGHT]);
}
static boundingBoxFromPolygons(polygons: Polygon[]): Rectangle {
return Polygon.boundingBoxFromPoints(
_.flatMap(polygons, (polygon) => {
return polygon.getPoints();
})
);
}
static boundingBoxFromPoints(points: Point[]): Rectangle {
if (points.length === 0) {
return new Rectangle(0, 0, 0, 0);
}
let minX = points[0].x;
let maxX = points[0].x;
let minY = points[0].y;
let maxY = points[0].y;
for (let i = 1; i < points.length; i++) {
if (points[i].x < minX) {
minX = points[i].x;
}
if (points[i].x > maxX) {
maxX = points[i].x;
}
if (points[i].y < minY) {
minY = points[i].y;
}
if (points[i].y > maxY) {
maxY = points[i].y;
}
}
return new Rectangle(new Point(minX, minY), new Point(maxX, minY), new Point(maxX, maxY), new Point(minX, maxY));
}
getBoundingBox(): Rectangle {
let minX = this.points[0].x;
let maxX = this.points[0].x;
let minY = this.points[0].y;
let maxY = this.points[0].y;
for (let i = 1; i < this.points.length; i++) {
if (this.points[i].x < minX) {
minX = this.points[i].x;
}
if (this.points[i].x > maxX) {
maxX = this.points[i].x;
}
if (this.points[i].y < minY) {
minY = this.points[i].y;
}
if (this.points[i].y > maxY) {
maxY = this.points[i].y;
}
}
return new Rectangle(new Point(minX, minY), new Point(maxX, minY), new Point(maxX, maxY), new Point(minX, maxY));
getBoundingBox(): Bounds {
return boundingBoxFromPoints(this.points);
}
}
import { Rectangle } from './Rectangle';

View File

@@ -1,27 +1,37 @@
import { Point } from './Point';
import { Polygon } from './Polygon';
import { Bounds, BoundsCorner, boundsFromPositionAndSize, createEmptyBounds } from './Bounds';
export class Rectangle extends Polygon {
constructor(tl: Point, tr: Point, br: Point, bl: Point);
constructor(position: Point, width: number, height: number);
constructor(x?: number, y?: number, width?: number, height?: number);
constructor(a: any = 0, b: any = 0, c: any = 0, d: any = 0) {
if (a instanceof Point && b instanceof Point && c instanceof Point && d instanceof Point) {
super([a, b, c, d]);
} else if (a instanceof Point) {
super([a, new Point(a.x + b, a.y), new Point(a.x + b, a.y + c), new Point(a.x, a.y + c)]);
} else {
super(Rectangle.pointsFromBounds(a, b, c, d));
}
static fromPositionAndSize(x: number, y: number, width: number, height: number) {
return new Rectangle(boundsFromPositionAndSize(x, y, width, height));
}
static pointsFromBounds(x: number, y: number, width: number, height: number): Point[] {
return [new Point(x, y), new Point(x + width, y), new Point(x + width, y + height), new Point(x, y + height)];
static fromPointAndSize(position: Point, width: number, height: number) {
return new Rectangle(boundsFromPositionAndSize(position.x, position.y, width, height));
}
constructor(points?: Bounds) {
if (!points) {
points = createEmptyBounds();
}
super([
points[BoundsCorner.TOP_LEFT],
points[BoundsCorner.TOP_RIGHT],
points[BoundsCorner.BOTTOM_RIGHT],
points[BoundsCorner.BOTTOM_LEFT]
]);
}
updateDimensions(x: number, y: number, width: number, height: number) {
this.points = Rectangle.pointsFromBounds(x, y, width, height);
const points = boundsFromPositionAndSize(x, y, width, height);
this.setPoints([
points[BoundsCorner.TOP_LEFT],
points[BoundsCorner.TOP_RIGHT],
points[BoundsCorner.BOTTOM_RIGHT],
points[BoundsCorner.BOTTOM_LEFT]
]);
}
setPoints(points: Point[]) {

View File

@@ -3,3 +3,5 @@ export * from './Matrix';
export * from './Polygon';
export * from './Rectangle';
export * from './BezierCurve';
export * from './toolkit';
export * from './Bounds';

View File

@@ -0,0 +1,45 @@
import { Point } from './Point';
import _flatMap from 'lodash/flatMap';
import { Polygon } from './Polygon';
import { Bounds, BoundsCorner, createEmptyBounds } from './Bounds';
export const boundingBoxFromPoints = (points: Point[]): Bounds => {
if (points.length === 0) {
return createEmptyBounds();
}
let minX = points[0].x;
let maxX = points[0].x;
let minY = points[0].y;
let maxY = points[0].y;
for (let i = 1; i < points.length; i++) {
if (points[i].x < minX) {
minX = points[i].x;
}
if (points[i].x > maxX) {
maxX = points[i].x;
}
if (points[i].y < minY) {
minY = points[i].y;
}
if (points[i].y > maxY) {
maxY = points[i].y;
}
}
return {
[BoundsCorner.TOP_LEFT]: new Point(minX, minY),
[BoundsCorner.TOP_RIGHT]: new Point(maxX, minY),
[BoundsCorner.BOTTOM_RIGHT]: new Point(maxX, maxY),
[BoundsCorner.BOTTOM_LEFT]: new Point(minX, maxY)
};
};
export const boundingBoxFromPolygons = (polygons: Polygon[]): Bounds => {
return boundingBoxFromPoints(
_flatMap(polygons, (polygon) => {
return polygon.getPoints();
})
);
};

View File

@@ -1,11 +1,12 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"outDir": "dist",
"rootDir": "src",
"declarationDir": "dist/@types"
"sourceMap": true,
"declarationDir": "dist/@types",
"tsBuildInfoFile": "dist/tsconfig.tsbuildinfo"
},
"include": [
"./src"
]
"include": ["./src"]
}

View File

@@ -1,5 +1,4 @@
*
!src/**/*
!dist/**/*
!package.json
!README.md
dist/tsconfig.tsbuildinfo

View File

@@ -0,0 +1,54 @@
# @projectstorm/react-canvas-core
## 7.0.3
### Patch Changes
- 09ed60f: Allow more derived State classes to provide a generic type
- 80285fe: refactor: update lodash imports to use individual functions
- Updated dependencies [80285fe]
- @projectstorm/geometry@7.0.3
## 7.0.2
### Patch Changes
- 66c687a: Upgrade all dependencies and fix Storybook after upgrade
- Updated dependencies [66c687a]
- @projectstorm/geometry@7.0.2
## 7.0.1
### Patch Changes
- b8a4cbd: Inline sources in sourcemap
- Updated dependencies [b8a4cbd]
- @projectstorm/geometry@7.0.1
## 7.0.0
### Major Changes
- b051697: - [internal] moves to `Pnpm` (instead of yarn -\_-)
- [internal]moves to `Changesets` for releases
- [internal]removes `Lerna`
- [internal] upgrades all dependencies
- [internal] switches to workspace protocol syntax (Changesets will bake in the correct version when a publish occurs)
- [internal] Changesets will open a release PR which can wrap up several changes in 1 go
- [internal] Changesets will run the storybook deploy automatically upon merging the release PR
- [internal] removes a lot of the stuff from the root package.json
- [internal] cleans up the build and clean commands
- [internal] remove E2E tests, they are a nightmare to maintain and the ROI is far too low
- [fix] Wrong type name for react-canvas model listener
- [fix] export more stuff form the main react-diagrams package
- [fix] circular deps with Rectangle and Polygon (turns out this was a problem but only with UMD builds, sorry @everyone who I doubted, but this is also why I could never reproduce the issue)
- [breaking change] compile both ES6 and UMD
- [breaking change] moves dependencies back to each package. (After years of working on libraries, I've come to actually hate peer dependencies, and this is easily solved with build systems / package managers).
- [breaking change] static methods on `Polygon` and `Rectangle` moved to standalone methods
- [breaking change] static construction methods to rather deal with different Rectangle constructor overloads (I now consider this bad design)
- [breaking change] introduce `Bounds` as a simpler point-array type to deal with boundary computation instead
### Patch Changes
- Updated dependencies [b051697]
- @projectstorm/geometry@7.0.0

View File

@@ -1,6 +1,6 @@
{
"name": "@projectstorm/react-canvas-core",
"version": "6.7.0",
"version": "7.0.3",
"author": "dylanvorster",
"license": "MIT",
"repository": {
@@ -29,11 +29,14 @@
"module": "./dist/index.js",
"typings": "./dist/@types/index",
"dependencies": {
"@projectstorm/geometry": "^6.7.0"
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@projectstorm/geometry": "workspace:*",
"react": "^18.2.0",
"lodash": "^4.17.21"
},
"peerDependencies": {
"lodash": "4.*",
"react": "16.* || 17.*"
},
"gitHead": "bb878657ba0c2f81764f32901fd96158a0f8352e"
"devDependencies": {
"@types/react": "^18.2.22",
"@types/lodash": "^4.14.200"
}
}

View File

@@ -1,4 +1,4 @@
import { debounce } from 'lodash';
import _debounce from 'lodash/debounce';
import { CanvasModel } from './entities/canvas/CanvasModel';
import { FactoryBank } from './core/FactoryBank';
import { AbstractReactFactory } from './core/AbstractReactFactory';
@@ -148,7 +148,7 @@ export class CanvasEngine<
let repaintFn = repaint;
if (repaintDebounceMs > 0) {
repaintFn = debounce(repaint, repaintDebounceMs);
repaintFn = _debounce(repaint, repaintDebounceMs);
}
if (promise) {

View File

@@ -20,7 +20,7 @@ export class Toolkit {
public static closest(element: Element, selector: string) {
if (!Element.prototype.closest) {
Element.prototype.closest = function(s) {
Element.prototype.closest = function (s) {
var el = this;
do {

View File

@@ -1,6 +1,7 @@
import { Action, ActionEvent, InputType } from '../core-actions/Action';
import { KeyboardEvent } from 'react';
import * as _ from 'lodash';
import _forEach from 'lodash/forEach';
import _isEqual from 'lodash/isEqual';
export interface DeleteItemsActionOptions {
keyCodes?: number[];
@@ -31,8 +32,8 @@ export class DeleteItemsAction extends Action {
fire: (event: ActionEvent<KeyboardEvent>) => {
const { keyCode, ctrlKey, shiftKey, altKey, metaKey } = event.event;
if (keyCodes.indexOf(keyCode) !== -1 && _.isEqual({ ctrlKey, shiftKey, altKey, metaKey }, modifiers)) {
_.forEach(this.engine.getModel().getSelectedEntities(), (model) => {
if (keyCodes.indexOf(keyCode) !== -1 && _isEqual({ ctrlKey, shiftKey, altKey, metaKey }, modifiers)) {
_forEach(this.engine.getModel().getSelectedEntities(), (model) => {
// only delete items which are not locked
if (!model.isLocked()) {
model.remove();

View File

@@ -1,6 +1,7 @@
import { Action, ActionEvent, InputType } from './Action';
import { KeyboardEvent, MouseEvent } from 'react';
import * as _ from 'lodash';
import _filter from 'lodash/filter';
import _keys from 'lodash/keys';
import { CanvasEngine } from '../CanvasEngine';
import { BaseModel } from '../core-models/BaseModel';
@@ -16,7 +17,7 @@ export class ActionEventBus {
}
getKeys(): string[] {
return _.keys(this.keys);
return _keys(this.keys);
}
registerAction(action: Action): () => void {
@@ -33,7 +34,7 @@ export class ActionEventBus {
}
getActionsForType(type: InputType): Action[] {
return _.filter(this.actions, (action) => {
return _filter(this.actions, (action) => {
return action.options.type === type;
});
}

View File

@@ -1,8 +1,7 @@
import { Toolkit } from '../Toolkit';
import * as _ from 'lodash';
import _cloneDeep from 'lodash/cloneDeep';
import { CanvasEngine } from '../CanvasEngine';
import { BaseEvent, BaseListener, BaseObserver } from '../core/BaseObserver';
import { AbstractModelFactory } from '../core/AbstractModelFactory';
import { BaseModel } from './BaseModel';
export interface BaseEntityEvent<T extends BaseEntity = BaseEntity> extends BaseEvent {
@@ -13,6 +12,9 @@ export interface BaseEntityListener<T extends BaseEntity = BaseEntity> extends B
lockChanged?(event: BaseEntityEvent<T> & { locked: boolean }): void;
}
/**
* @TODO move to enums
*/
export type BaseEntityType = 'node' | 'link' | 'port' | 'point';
export interface BaseEntityOptions {
@@ -60,7 +62,7 @@ export class BaseEntity<T extends BaseEntityGenerics = BaseEntityGenerics> exten
if (lookupTable[this.options.id]) {
return lookupTable[this.options.id];
}
let clone = _.cloneDeep(this);
let clone = _cloneDeep(this);
clone.options = {
...this.options,
id: Toolkit.UID()

View File

@@ -18,7 +18,8 @@ export interface BasePositionModelGenerics extends BaseModelGenerics {
export class BasePositionModel<G extends BasePositionModelGenerics = BasePositionModelGenerics>
extends BaseModel<G>
implements ModelGeometryInterface {
implements ModelGeometryInterface
{
protected position: Point;
constructor(options: G['OPTIONS']) {
@@ -38,7 +39,7 @@ export class BasePositionModel<G extends BasePositionModelGenerics = BasePositio
}
getBoundingBox(): Rectangle {
return new Rectangle(this.position, 0, 0);
return Rectangle.fromPointAndSize(this.position, 0, 0);
}
deserialize(event: DeserializeEvent<this>) {

View File

@@ -1,7 +1,7 @@
import { CanvasEngine } from '../CanvasEngine';
import { Action, ActionEvent, InputType } from '../core-actions/Action';
import { SyntheticEvent } from 'react';
import * as _ from 'lodash';
import _intersection from 'lodash/intersection';
export interface StateOptions {
name: string;
@@ -73,7 +73,7 @@ export abstract class State<E extends CanvasEngine = CanvasEngine> {
}
isKeysFullfilled(keys: string[]) {
return _.intersection(this.keys, keys).length === this.keys.length;
return _intersection(this.keys, keys).length === this.keys.length;
}
activated(previous: State) {

View File

@@ -1,5 +1,5 @@
import { State } from './State';
import * as _ from 'lodash';
import _last from 'lodash/last';
import { CanvasEngine } from '../CanvasEngine';
import { BaseEvent, BaseListener, BaseObserver } from '../core/BaseObserver';
@@ -29,7 +29,7 @@ export class StateMachine extends BaseObserver<StateMachineListener> {
popState() {
this.stateStack.pop();
this.setState(_.last(this.stateStack));
this.setState(_last(this.stateStack));
}
setState(state: State) {

View File

@@ -1,6 +1,6 @@
import { BaseEvent, BaseListener, BaseObserver } from './BaseObserver';
import { AbstractFactory } from './AbstractFactory';
import * as _ from 'lodash';
import _values from 'lodash/values';
export interface FactoryBankListener<F extends AbstractFactory = AbstractFactory> extends BaseListener {
/**
@@ -29,7 +29,7 @@ export class FactoryBank<
}
getFactories(): F[] {
return _.values(this.factories);
return _values(this.factories);
}
clearFactories() {

View File

@@ -1,4 +1,8 @@
import * as _ from 'lodash';
import _filter from 'lodash/filter';
import _flatMap from 'lodash/flatMap';
import _forEach from 'lodash/forEach';
import _map from 'lodash/map';
import _values from 'lodash/values';
import {
BaseEntity,
BaseEntityEvent,
@@ -11,7 +15,7 @@ import { LayerModel } from '../layer/LayerModel';
import { BaseModel } from '../../core-models/BaseModel';
import { CanvasEngine } from '../../CanvasEngine';
export interface DiagramListener extends BaseEntityListener {
export interface CanvasModelListener extends BaseEntityListener {
offsetUpdated?(event: BaseEntityEvent<CanvasModel> & { offsetX: number; offsetY: number }): void;
zoomUpdated?(event: BaseEntityEvent<CanvasModel> & { zoom: number }): void;
@@ -19,7 +23,7 @@ export interface DiagramListener extends BaseEntityListener {
gridUpdated?(event: BaseEntityEvent<CanvasModel> & { size: number }): void;
}
export interface DiagramModelOptions extends BaseEntityOptions {
export interface CanvasModelOptions extends BaseEntityOptions {
offsetX?: number;
offsetY?: number;
zoom?: number;
@@ -27,8 +31,8 @@ export interface DiagramModelOptions extends BaseEntityOptions {
}
export interface CanvasModelGenerics extends BaseEntityGenerics {
LISTENER: DiagramListener;
OPTIONS: DiagramModelOptions;
LISTENER: CanvasModelListener;
OPTIONS: CanvasModelOptions;
LAYER: LayerModel;
}
@@ -47,26 +51,26 @@ export class CanvasModel<G extends CanvasModelGenerics = CanvasModelGenerics> ex
}
getSelectionEntities(): BaseModel[] {
return _.flatMap(this.layers, (layer) => {
return _flatMap(this.layers, (layer) => {
return layer.getSelectionEntities();
});
}
getSelectedEntities(): BaseModel[] {
return _.filter(this.getSelectionEntities(), (ob) => {
return _filter(this.getSelectionEntities(), (ob) => {
return ob.isSelected();
});
}
clearSelection() {
_.forEach(this.getSelectedEntities(), (element) => {
_forEach(this.getSelectedEntities(), (element) => {
element.setSelected(false);
});
}
getModels(): BaseModel[] {
return _.flatMap(this.layers, (layer) => {
return _.values(layer.getModels());
return _flatMap(this.layers, (layer) => {
return _values(layer.getModels());
});
}
@@ -144,7 +148,7 @@ export class CanvasModel<G extends CanvasModelGenerics = CanvasModelGenerics> ex
this.options.offsetY = event.data.offsetY;
this.options.zoom = event.data.zoom;
this.options.gridSize = event.data.gridSize;
_.forEach(event.data.layers, (layer) => {
_forEach(event.data.layers, (layer) => {
const layerOb = event.engine.getFactoryForLayer(layer.type).generateModel({
initialConfig: layer
});
@@ -163,7 +167,7 @@ export class CanvasModel<G extends CanvasModelGenerics = CanvasModelGenerics> ex
offsetY: this.options.offsetY,
zoom: this.options.zoom,
gridSize: this.options.gridSize,
layers: _.map(this.layers, (layer) => {
layers: _map(this.layers, (layer) => {
return layer.serialize();
})
};

View File

@@ -99,7 +99,8 @@ export class CanvasWidget extends React.Component<DiagramProps> {
}}
onTouchMove={(event) => {
this.props.engine.getActionEventBus().fireAction({ event });
}}>
}}
>
{model.getLayers().map((layer) => {
return (
<TransformLayerWidget layer={layer} key={layer.getID()}>

View File

@@ -1,6 +1,8 @@
import { BaseModel, BaseModelGenerics, BaseModelOptions } from '../../core-models/BaseModel';
import { CanvasModel } from '../canvas/CanvasModel';
import * as _ from 'lodash';
import _flatMap from 'lodash/flatMap';
import _forEach from 'lodash/forEach';
import _mapValues from 'lodash/mapValues';
import { CanvasEngine } from '../../CanvasEngine';
import { FactoryBank } from '../../core/FactoryBank';
import { AbstractModelFactory } from '../../core/AbstractModelFactory';
@@ -37,7 +39,7 @@ export abstract class LayerModel<G extends LayerModelGenerics = LayerModelGeneri
super.deserialize(event);
this.options.isSvg = !!event.data.isSvg;
this.options.transformed = !!event.data.transformed;
_.forEach(event.data.models, (model) => {
_forEach(event.data.models, (model) => {
const modelOb = this.getChildModelFactoryBank(event.engine).getFactory(model.type).generateModel({
initialConfig: model
});
@@ -54,7 +56,7 @@ export abstract class LayerModel<G extends LayerModelGenerics = LayerModelGeneri
...super.serialize(),
isSvg: this.options.isSvg,
transformed: this.options.transformed,
models: _.mapValues(this.models, (model) => {
models: _mapValues(this.models, (model) => {
return model.serialize();
})
};
@@ -81,7 +83,7 @@ export abstract class LayerModel<G extends LayerModelGenerics = LayerModelGeneri
}
getSelectionEntities(): Array<BaseModel> {
return _.flatMap(this.models, (model) => {
return _flatMap(this.models, (model) => {
return model.getSelectionEntities();
});
}

View File

@@ -31,7 +31,7 @@ namespace S {
`;
}
export class TransformLayerWidget extends React.Component<TransformLayerWidgetProps> {
export class TransformLayerWidget extends React.Component<React.PropsWithChildren<TransformLayerWidgetProps>> {
constructor(props: TransformLayerWidgetProps) {
super(props);
this.state = {};

View File

@@ -1,8 +1,9 @@
import * as React from 'react';
import styled from '@emotion/styled';
import { SimpleClientRect } from '../../states/SelectionBoxState';
export interface SelectionBoxWidgetProps {
rect: ClientRect;
rect: SimpleClientRect;
}
namespace S {

View File

@@ -2,9 +2,10 @@ import { LayerModel } from '../layer/LayerModel';
import { FactoryBank } from '../../core/FactoryBank';
import { AbstractModelFactory } from '../../core/AbstractModelFactory';
import { BaseModel } from '../../core-models/BaseModel';
import { SimpleClientRect } from '../../states/SelectionBoxState';
export class SelectionLayerModel extends LayerModel {
box: ClientRect;
box: SimpleClientRect;
constructor() {
super({
@@ -14,7 +15,7 @@ export class SelectionLayerModel extends LayerModel {
});
}
setBox(rect: ClientRect) {
setBox(rect: SimpleClientRect) {
this.box = rect;
}

View File

@@ -1,3 +1,4 @@
import { CanvasEngine } from '../CanvasEngine';
import { AbstractDisplacementState, AbstractDisplacementStateEvent } from '../core-state/AbstractDisplacementState';
import { State } from '../core-state/State';
@@ -8,7 +9,7 @@ export interface DragCanvasStateOptions {
allowDrag?: boolean;
}
export class DragCanvasState extends AbstractDisplacementState {
export class DragCanvasState<E extends CanvasEngine = CanvasEngine> extends AbstractDisplacementState<E> {
// store this as we drag the canvas
initialCanvasX: number;
initialCanvasY: number;

View File

@@ -2,8 +2,9 @@ import { State } from '../core-state/State';
import { Action, ActionEvent, InputType } from '../core-actions/Action';
import { SelectionBoxState } from './SelectionBoxState';
import { MouseEvent } from 'react';
import { CanvasEngine } from '../CanvasEngine';
export class SelectingState extends State {
export class SelectingState<E extends CanvasEngine = CanvasEngine> extends State<E> {
constructor() {
super({
name: 'selecting'

View File

@@ -2,9 +2,20 @@ import { AbstractDisplacementState, AbstractDisplacementStateEvent } from '../co
import { State } from '../core-state/State';
import { SelectionLayerModel } from '../entities/selection/SelectionLayerModel';
import { Point, Rectangle } from '@projectstorm/geometry';
import { BasePositionModel } from '../core-models/BasePositionModel';
import { ModelGeometryInterface } from '../core/ModelGeometryInterface';
import { CanvasEngine } from '../CanvasEngine';
export class SelectionBoxState extends AbstractDisplacementState {
export interface SimpleClientRect {
left: number;
right: number;
width: number;
height: number;
top: number;
bottom: number;
}
export class SelectionBoxState<E extends CanvasEngine = CanvasEngine> extends AbstractDisplacementState<E> {
layer: SelectionLayerModel;
constructor() {
@@ -25,7 +36,7 @@ export class SelectionBoxState extends AbstractDisplacementState {
this.engine.repaintCanvas();
}
getBoxDimensions(event: AbstractDisplacementStateEvent): ClientRect {
getBoxDimensions(event: AbstractDisplacementStateEvent): SimpleClientRect {
let rel: Point;
if ('touches' in event.event) {
@@ -58,7 +69,11 @@ export class SelectionBoxState extends AbstractDisplacementState {
if (event.virtualDisplacementY < 0) {
relative.y -= Math.abs(event.virtualDisplacementY);
}
const rect = new Rectangle(relative, Math.abs(event.virtualDisplacementX), Math.abs(event.virtualDisplacementY));
const rect = Rectangle.fromPointAndSize(
relative,
Math.abs(event.virtualDisplacementX),
Math.abs(event.virtualDisplacementY)
);
for (let model of this.engine.getModel().getSelectionEntities()) {
if ((model as unknown as ModelGeometryInterface).getBoundingBox) {

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import * as _ from 'lodash';
import _isEqual from 'lodash/isEqual';
import { BaseModel } from '../core-models/BaseModel';
export interface PeformanceWidgetProps {
@@ -25,7 +25,7 @@ export class PeformanceWidget extends React.Component<PeformanceWidgetProps, Pef
}
// change event
return !_.isEqual(this.props.serialized, nextProps.serialized);
return !_isEqual(this.props.serialized, nextProps.serialized);
}
render() {

View File

@@ -1,13 +1,12 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"outDir": "dist",
"rootDir": "src",
"declarationDir": "dist/@types"
"declarationDir": "dist/@types",
"tsBuildInfoFile": "dist/tsconfig.tsbuildinfo"
},
"include": [
"./src"
],
"references": [
{
"path": "../geometry"

View File

@@ -1,5 +1,4 @@
*
!src/**/*
!dist/**/*
!package.json
!README.md
dist/tsconfig.tsbuildinfo

View File

@@ -1,15 +1,73 @@
# Changelog
## 7.0.3
### Patch Changes
- 09ed60f: Allow more derived State classes to provide a generic type
- 80285fe: refactor: update lodash imports to use individual functions
- Updated dependencies [09ed60f]
- Updated dependencies [80285fe]
- @projectstorm/react-canvas-core@7.0.3
- @projectstorm/geometry@7.0.3
## 7.0.2
### Patch Changes
- 66c687a: Upgrade all dependencies and fix Storybook after upgrade
- Updated dependencies [66c687a]
- @projectstorm/react-canvas-core@7.0.2
- @projectstorm/geometry@7.0.2
## 7.0.1
### Patch Changes
- b8a4cbd: Inline sources in sourcemap
- Updated dependencies [b8a4cbd]
- @projectstorm/geometry@7.0.1
- @projectstorm/react-canvas-core@7.0.1
## 7.0.0
### Major Changes
- b051697: - [internal] moves to `Pnpm` (instead of yarn -\_-)
- [internal]moves to `Changesets` for releases
- [internal]removes `Lerna`
- [internal] upgrades all dependencies
- [internal] switches to workspace protocol syntax (Changesets will bake in the correct version when a publish occurs)
- [internal] Changesets will open a release PR which can wrap up several changes in 1 go
- [internal] Changesets will run the storybook deploy automatically upon merging the release PR
- [internal] removes a lot of the stuff from the root package.json
- [internal] cleans up the build and clean commands
- [internal] remove E2E tests, they are a nightmare to maintain and the ROI is far too low
- [fix] Wrong type name for react-canvas model listener
- [fix] export more stuff form the main react-diagrams package
- [fix] circular deps with Rectangle and Polygon (turns out this was a problem but only with UMD builds, sorry @everyone who I doubted, but this is also why I could never reproduce the issue)
- [breaking change] compile both ES6 and UMD
- [breaking change] moves dependencies back to each package. (After years of working on libraries, I've come to actually hate peer dependencies, and this is easily solved with build systems / package managers).
- [breaking change] static methods on `Polygon` and `Rectangle` moved to standalone methods
- [breaking change] static construction methods to rather deal with different Rectangle constructor overloads (I now consider this bad design)
- [breaking change] introduce `Bounds` as a simpler point-array type to deal with boundary computation instead
### Patch Changes
- Updated dependencies [b051697]
- @projectstorm/react-canvas-core@7.0.0
- @projectstorm/geometry@7.0.0
## 6.0.0
### Breaking changes
* `AbstractFactory:getNewInstance` renamed to `AbstractFactory:generateModel` and now gets given an event object
so that we can add to the event object without relying on more parameters
- `AbstractFactory:getNewInstance` renamed to `AbstractFactory:generateModel` and now gets given an event object
so that we can add to the event object without relying on more parameters
* `AbstractFactory::generateReactWidget` now receives an event object
- `AbstractFactory::generateReactWidget` now receives an event object
* Moved factories in the diagramEngine into `FactoryBank`'s, which means we can remove the listeners in the DiagramEngine.
methods such as factoryAdded and factoryRemoved are now available on the FactoryBank (better design that allows more control)
- Moved factories in the diagramEngine into `FactoryBank`'s, which means we can remove the listeners in the DiagramEngine.
methods such as factoryAdded and factoryRemoved are now available on the FactoryBank (better design that allows more control)
* `addListener` renamed to `registerListener`
- `addListener` renamed to `registerListener`

View File

@@ -1,6 +1,6 @@
{
"name": "@projectstorm/react-diagrams-core",
"version": "6.7.0",
"version": "7.0.3",
"author": "dylanvorster",
"license": "MIT",
"repository": {
@@ -31,13 +31,15 @@
"module": "./dist/index.js",
"typings": "./dist/@types/index",
"dependencies": {
"@projectstorm/geometry": "^6.7.0",
"@projectstorm/react-canvas-core": "^6.7.0"
},
"peerDependencies": {
"lodash": "4.*",
"react": "16.* || 17.*",
"@emotion/styled": "^11.11.0",
"@projectstorm/geometry": "workspace:*",
"@projectstorm/react-canvas-core": "workspace:*",
"lodash": "^4.17.21",
"react": "^18.2.0",
"resize-observer-polyfill": "^1.5.1"
},
"gitHead": "bb878657ba0c2f81764f32901fd96158a0f8352e"
"devDependencies": {
"@types/react": "^18.2.22",
"@types/lodash": "^4.14.200"
}
}

View File

@@ -2,17 +2,17 @@ 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, Rectangle, Polygon } from '@projectstorm/geometry';
import { boundingBoxFromPolygons, Point, Rectangle } from '@projectstorm/geometry';
import { MouseEvent } from 'react';
import {
AbstractModelFactory,
AbstractReactFactory,
BaseModel,
CanvasEngine,
FactoryBank,
Toolkit,
CanvasEngineListener,
CanvasEngineOptions
CanvasEngineOptions,
FactoryBank,
Toolkit
} from '@projectstorm/react-canvas-core';
import { DiagramModel } from './models/DiagramModel';
@@ -187,7 +187,7 @@ export class DiagramEngine extends CanvasEngine<CanvasEngineListener, DiagramMod
clientY: sourceRect.top
});
const zoom = this.model.getZoomLevel() / 100.0;
return new Rectangle(point.x, point.y, sourceRect.width / zoom, sourceRect.height / zoom);
return Rectangle.fromPointAndSize(point, sourceRect.width / zoom, sourceRect.height / zoom);
}
/**
@@ -214,10 +214,9 @@ export class DiagramEngine extends CanvasEngine<CanvasEngineListener, DiagramMod
getBoundingNodesRect(nodes: NodeModel[]): Rectangle {
if (nodes) {
if (nodes.length === 0) {
return new Rectangle(0, 0, 0, 0);
return new Rectangle();
}
return Polygon.boundingBoxFromPolygons(nodes.map((node) => node.getBoundingBox()));
return new Rectangle(boundingBoxFromPolygons(nodes.map((node) => node.getBoundingBox())));
}
}

Some files were not shown because too many files have changed in this diff Show More