mirror of
https://github.com/projectstorm/react-diagrams.git
synced 2026-03-13 09:50:09 +08:00
Compare commits
191 Commits
v6.1.0
...
@projectst
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
160b88fccf | ||
|
|
80cd9c9306 | ||
|
|
2de55fdf68 | ||
|
|
b8a4cbdf1a | ||
|
|
76a2659948 | ||
|
|
63e33c07d8 | ||
|
|
70b17a749c | ||
|
|
4ccc5d58f3 | ||
|
|
fb7d646bde | ||
|
|
e0d21f1435 | ||
|
|
6ed1e0f89d | ||
|
|
7da7fa4cc9 | ||
|
|
ed7988f722 | ||
|
|
e6b86321e2 | ||
|
|
17bb78b130 | ||
|
|
ddeea124b0 | ||
|
|
fcdbce54b5 | ||
|
|
f1c38fb84a | ||
|
|
74f9269869 | ||
|
|
a28bcc037d | ||
|
|
456e6b1b67 | ||
|
|
c9e819d78e | ||
|
|
8a2f5d198f | ||
|
|
251a1f9484 | ||
|
|
c1eac9873a | ||
|
|
95b35d6778 | ||
|
|
d2a197245b | ||
|
|
8f06e55127 | ||
|
|
b0e8e52077 | ||
|
|
0d23e933e8 | ||
|
|
4dfeb403be | ||
|
|
0e19827675 | ||
|
|
2b1f54bbc9 | ||
|
|
b3a6cc01fa | ||
|
|
918d8d741b | ||
|
|
d15fb13adf | ||
|
|
4f2b6132ba | ||
|
|
7d9d137c66 | ||
|
|
b051697791 | ||
|
|
8fc9fe3aae | ||
|
|
b4185dcb76 | ||
|
|
c1fa7ee865 | ||
|
|
05a5afb20e | ||
|
|
8bcc1436d3 | ||
|
|
9b39591d94 | ||
|
|
88296c28b4 | ||
|
|
2a810ca2d3 | ||
|
|
dfcf82e692 | ||
|
|
cd93bb96a3 | ||
|
|
5f49bbe5b1 | ||
|
|
d55790edcf | ||
|
|
a1b2f6a59e | ||
|
|
e7b352644d | ||
|
|
2f620ce4af | ||
|
|
897bde204e | ||
|
|
2d9fca171c | ||
|
|
77011af27a | ||
|
|
32d47270cb | ||
|
|
3060496db0 | ||
|
|
02a37fcf1f | ||
|
|
e4848b4784 | ||
|
|
c4d0136402 | ||
|
|
413838b841 | ||
|
|
9b5b14d144 | ||
|
|
f8fa5564c1 | ||
|
|
24ff005d9e | ||
|
|
04d5bc97f7 | ||
|
|
d7aa385cf5 | ||
|
|
b2fa681494 | ||
|
|
a2ac399632 | ||
|
|
3d0521cc93 | ||
|
|
1825076cd4 | ||
|
|
00d92392cc | ||
|
|
d07f3a3047 | ||
|
|
d21e8e8860 | ||
|
|
25bf056b0a | ||
|
|
5ebe6f84cd | ||
|
|
adc173f689 | ||
|
|
889108d7fd | ||
|
|
09c2014efc | ||
|
|
cd22725103 | ||
|
|
dd68d1fe67 | ||
|
|
8b2f5c8961 | ||
|
|
e23b68b2d1 | ||
|
|
77e1abba97 | ||
|
|
db25ec3cca | ||
|
|
61882f0637 | ||
|
|
c9098377dc | ||
|
|
a0bbde14cf | ||
|
|
ee30b45ff0 | ||
|
|
36a3eddca7 | ||
|
|
1ad8d79b4c | ||
|
|
87a75437c3 | ||
|
|
ad4efe70e7 | ||
|
|
9460ce8eeb | ||
|
|
8e7b7cd05e | ||
|
|
f661824282 | ||
|
|
5b2ceabfd4 | ||
|
|
bb6e1d52af | ||
|
|
be422431d2 | ||
|
|
66184bd0fa | ||
|
|
ef4439d895 | ||
|
|
ee66f8ad61 | ||
|
|
6a4e17aca6 | ||
|
|
10d6a286b4 | ||
|
|
1bdc6c7624 | ||
|
|
f5bc087e7a | ||
|
|
369ca9cf91 | ||
|
|
ba4fbe101d | ||
|
|
5b642a1d1b | ||
|
|
df9b076140 | ||
|
|
0f403bb71c | ||
|
|
abadce19ac | ||
|
|
eb59992bc3 | ||
|
|
b0f0379329 | ||
|
|
63a41c634f | ||
|
|
e34c73ca00 | ||
|
|
44fae73a52 | ||
|
|
81f26a19ca | ||
|
|
2d5ae2fb44 | ||
|
|
d2f05438b8 | ||
|
|
d9bd430f82 | ||
|
|
df308897b7 | ||
|
|
590ba09c3c | ||
|
|
3c8912bc86 | ||
|
|
291241cacb | ||
|
|
1ac3a8de78 | ||
|
|
e974627fd0 | ||
|
|
ade86f215c | ||
|
|
e7a606d987 | ||
|
|
67be47b4ae | ||
|
|
43b75505fe | ||
|
|
3c79850c85 | ||
|
|
8173b70834 | ||
|
|
53eee3f518 | ||
|
|
4649597a97 | ||
|
|
89adc1ee38 | ||
|
|
ff0f7188fa | ||
|
|
c6556d7475 | ||
|
|
8497c1bf6c | ||
|
|
a15191bcef | ||
|
|
d7c7dcf0b1 | ||
|
|
57a65aec20 | ||
|
|
b0343daf6f | ||
|
|
5d7bfd81d4 | ||
|
|
d42087a3ac | ||
|
|
6adff81ae7 | ||
|
|
4f3df60758 | ||
|
|
2f366d21f7 | ||
|
|
b7dfa6da21 | ||
|
|
293123b5c6 | ||
|
|
00c2a41c0c | ||
|
|
63dbe41df0 | ||
|
|
c1485224ba | ||
|
|
580a26c73d | ||
|
|
4c03583d91 | ||
|
|
9b58fa3963 | ||
|
|
3e69dafef9 | ||
|
|
442462af2d | ||
|
|
0d9ba41c9a | ||
|
|
73ef7df153 | ||
|
|
5fe7b37fc2 | ||
|
|
093e1f6a08 | ||
|
|
1e95edbc6f | ||
|
|
c92313f9b1 | ||
|
|
b8b66642d5 | ||
|
|
39dbbe3db9 | ||
|
|
1ba35fd518 | ||
|
|
04443ad85e | ||
|
|
17952c8829 | ||
|
|
a8234a1a8d | ||
|
|
3f86c36c44 | ||
|
|
a2cf7483f1 | ||
|
|
72739dc3d3 | ||
|
|
07df1fd6f5 | ||
|
|
ef9e72ed3a | ||
|
|
8df5ff94b6 | ||
|
|
17c5a3cfb9 | ||
|
|
a69ec38a5a | ||
|
|
2c66c18f6d | ||
|
|
012418741d | ||
|
|
3d71f5a80b | ||
|
|
c5b24f6e7b | ||
|
|
655462087f | ||
|
|
6bdc21826d | ||
|
|
27194cfd36 | ||
|
|
61c8d7e610 | ||
|
|
08f9ea6aa6 | ||
|
|
cef51577a3 | ||
|
|
e8fb8804a8 | ||
|
|
ef822f5540 |
8
.changeset/README.md
Normal file
8
.changeset/README.md
Normal 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
11
.changeset/config.json
Normal 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": []
|
||||
}
|
||||
@@ -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 packages/diagrams-demo-gallery && yarn run test --ci
|
||||
- run: cd packages/react-diagrams-routing && yarn run test --ci
|
||||
@@ -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"]
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 231 KiB |
24
.github/PULL_REQUEST_TEMPLATE.md
vendored
24
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -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 :])
|
||||
|
||||

|
||||
|
||||
|
||||

|
||||
23
.github/workflows/prettier.yml
vendored
Normal file
23
.github/workflows/prettier.yml
vendored
Normal 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
47
.github/workflows/release.yml
vendored
Normal 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
30
.github/workflows/test.yml
vendored
Normal 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
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,4 +5,5 @@ dist
|
||||
*.zip
|
||||
.env
|
||||
node_modules
|
||||
yarn-error.log
|
||||
tsconfig.tsbuildinfo
|
||||
.vscode
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"jsxBracketSameLine": true,
|
||||
"useTabs": true,
|
||||
"printWidth": 120
|
||||
"printWidth": 120,
|
||||
"trailingComma": "none"
|
||||
}
|
||||
|
||||
108
CHANGELOG.md
108
CHANGELOG.md
@@ -1,13 +1,101 @@
|
||||
__6.1.0__
|
||||
__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:
|
||||
* https://github.com/projectstorm/react-diagrams/pull/861
|
||||
* https://github.com/projectstorm/react-diagrams/pull/871
|
||||
* https://github.com/projectstorm/react-diagrams/pull/870
|
||||
|
||||
Some maintenance:
|
||||
* https://github.com/projectstorm/react-diagrams/pull/861
|
||||
|
||||
__6.6.0__
|
||||
|
||||
* (docs-broken) https://github.com/projectstorm/react-diagrams/pull/834
|
||||
* (bug) https://github.com/projectstorm/react-diagrams/pull/838
|
||||
* (docs-broken) https://github.com/projectstorm/react-diagrams/pull/847
|
||||
* (bug) https://github.com/projectstorm/react-diagrams/pull/852
|
||||
* (docs-broken) https://github.com/projectstorm/react-diagrams/pull/856
|
||||
* (improvement) https://github.com/projectstorm/react-diagrams/pull/857
|
||||
* (bug) https://github.com/projectstorm/react-diagrams/pull/860
|
||||
|
||||
Also includes a bump on all packages using `ncu` recursively.
|
||||
|
||||
__6.5.2__
|
||||
|
||||
https://github.com/projectstorm/react-diagrams/pull/830
|
||||
|
||||
* (fix) issue with zoom to fit selected
|
||||
* (improvement) properly export PathFinding
|
||||
* (maintenance) bump all dependencies
|
||||
|
||||
__6.5.1__
|
||||
|
||||
https://github.com/projectstorm/react-diagrams/pull/829
|
||||
|
||||
* (improved) zoom to fit now centers correctly
|
||||
* (fix) remove wrong peer dependency (@emotion/core)
|
||||
|
||||
__6.5.0__
|
||||
|
||||
https://github.com/projectstorm/react-diagrams/pull/814
|
||||
|
||||
* Some rendering fixes
|
||||
* small api change around `zoomToFit`
|
||||
* more api options with the `DefaultLink`
|
||||
|
||||
__6.4.0__
|
||||
|
||||
https://github.com/projectstorm/react-diagrams/pull/813
|
||||
|
||||
* Bump all packages and move to Emotion 11 and React 17
|
||||
* Move to the latest Storybook
|
||||
|
||||
__6.2.0__
|
||||
|
||||
* (improvement) Move away fromn math-js (https://github.com/projectstorm/react-diagrams/pull/651)
|
||||
* (fix) https://github.com/projectstorm/react-diagrams/pull/639
|
||||
* (fix) Fixing link spawning at (0,0) when clicking port once (inspired by https://github.com/projectstorm/react-diagrams/pull/637)
|
||||
|
||||
__6.1.1__
|
||||
|
||||
* (feature) https://github.com/projectstorm/react-diagrams/pull/576 [Add zoom to fit nodes feature, fixes #568]
|
||||
* (improvement) https://github.com/projectstorm/react-diagrams/pull/621 [Support deriving from DefaultLabelModel]
|
||||
* (fix) https://github.com/projectstorm/react-diagrams/pull/603
|
||||
* (fix) https://github.com/projectstorm/react-diagrams/pull/603
|
||||
[Fixes selectionChanged listener not being deregistered on NodeWidget, Fixes unchecked access to this.props.link.getSourcePort() on LinkWidget]
|
||||
* (maintenance) bump everything
|
||||
* fix serialize/deserialize issue with example project raw JS node
|
||||
|
||||
__6.0.0__
|
||||
__6.0.0__
|
||||
|
||||
Note: This is a complete rewrite of the library, a good place to start to see how the new system works
|
||||
is with the new demo project which illustrates the new capability.
|
||||
@@ -21,7 +109,7 @@ I would also recommend taking a look at the new updated DiamondPort widget which
|
||||
* Introduce multiple layers (can now have multiple node and link layers)
|
||||
* Rewrote the deserialization system to be promise based
|
||||
* Completely overhauled the observer framework on the models
|
||||
* Moved all the logic in the DiagramWidget into a a new hierarchical state machine
|
||||
* Moved all the logic in the DiagramWidget into a a new hierarchical state machine
|
||||
* Introduces new states for editing
|
||||
* Introduced faster layout rendering when transforming the canvas directly
|
||||
* Moved all canvas smart routing into its own link-type under routing package
|
||||
@@ -37,7 +125,7 @@ I would also recommend taking a look at the new updated DiamondPort widget which
|
||||
* Completely removed the double render state system that required nodes to render before links, this is done when ports report their new positions
|
||||
* Ports can now dynamically be added and removed without having to tell the system it happeend
|
||||
* Port widgets are now containers dumb containers for you own ports
|
||||
* Port widgets report new sizing information to their target links when they change position, you no longer need to invalidate them
|
||||
* Port widgets report new sizing information to their target links when they change position, you no longer need to invalidate them
|
||||
|
||||
__5.3.2__
|
||||
|
||||
@@ -58,7 +146,7 @@ __5.2.1__
|
||||
* (bug) https://github.com/projectstorm/react-diagrams/commit/75ef02dd4d131a0e7c08b2680c69efc390e50b84
|
||||
-> and other improvements, also checkout the foundation work happening over at https://github.com/projectstorm/react-canvas
|
||||
|
||||
__5.1.0__
|
||||
__5.1.0__
|
||||
|
||||
* (api) Rename XXXFactory into AbstractXXXFactory
|
||||
* (refactor) tslint and prettier are now the same
|
||||
@@ -98,7 +186,7 @@ __4.0.0__ http://dylanv.blog/2018/01/18/storm-react-diagrams-v4-0-0/
|
||||
* (refactor) Merged the concept of instance factories and widget factories into one
|
||||
* (feature) Models can now be cloned at various parts of the model graph
|
||||
* (demo) Cloning
|
||||
* (feature) models control isLocked
|
||||
* (feature) models control isLocked
|
||||
|
||||
__3.2.0__ http://dylanv.blog/2017/11/22/storm-react-diagrams-3-2-0/
|
||||
* (feature) zoom to fit
|
||||
@@ -113,13 +201,13 @@ __3.2.0__ http://dylanv.blog/2017/11/22/storm-react-diagrams-3-2-0/
|
||||
* (bugs) issues with the rendering pipeline #107
|
||||
* added ci badge to Readme
|
||||
|
||||
__3.1.3__
|
||||
__3.1.3__
|
||||
* Refactor links slightly
|
||||
* use min extension for css
|
||||
* bump package versions
|
||||
* export more classes
|
||||
|
||||
__3.1.2__
|
||||
__3.1.2__
|
||||
* Hotfix: fix zooming when canvas not in the top left corner
|
||||
(https://github.com/projectstorm/react-diagrams/pull/88)
|
||||
|
||||
@@ -128,7 +216,7 @@ __3.1.0__ http://dylanv.blog/2017/09/15/storm-react-diagrams-3-1-0/
|
||||
* 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
|
||||
* Code cleanup
|
||||
|
||||
__3.0.0__ http://dylanv.blog/2017/09/13/storm-react-diagrams-v3/
|
||||
* Massive performance updates
|
||||
|
||||
28
README.md
28
README.md
@@ -1,11 +1,9 @@
|
||||
# Introduction
|
||||
|
||||
[](https://gitter.im/projectstorm/react-diagrams?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://npmjs.org/package/@projectstorm/react-diagrams) [](https://packagequality.com/#?package=storm-react-diagrams) [](https://circleci.com/gh/projectstorm/react-diagrams/tree/master) [](https://lerna.js.org/)
|
||||
[](https://gitter.im/projectstorm/react-diagrams?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://npmjs.org/package/@projectstorm/react-diagrams) [](https://packagequality.com/#?package=storm-react-diagrams)
|
||||
|
||||

|
||||
|
||||
[pssst! Looking for the old version 5?](https://github.com/projectstorm/react-diagrams/tree/v5.3.2)
|
||||
|
||||
**DEMO**: [http://projectstorm.cloud/react-diagrams](http://projectstorm.cloud/react-diagrams)
|
||||
|
||||
**DOCS \(wip\)** [https://projectstorm.gitbook.io/react-diagrams](https://projectstorm.gitbook.io/react-diagrams)
|
||||
@@ -26,7 +24,7 @@ A flow & process orientated diagramming library inspired by **Blender**, **Labvi
|
||||
|
||||
Example implementation using custom models: \(Dylan's personal code\)
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
Get started with the default models right out of the box:
|
||||
@@ -38,7 +36,7 @@ Get started with the default models right out of the box:
|
||||
For all the bells and whistles:
|
||||
|
||||
```text
|
||||
yarn add @projectstorm/react-diagrams@next
|
||||
yarn add @projectstorm/react-diagrams
|
||||
```
|
||||
|
||||
This includes all the packages listed below \(and works \(mostly and conceptually\) like it used to in version 5.0\)
|
||||
@@ -48,35 +46,38 @@ This includes all the packages listed below \(and works \(mostly and conceptuall
|
||||
This library now has a more modular design and you can import just the core \(contains no default factories or routing\)
|
||||
|
||||
```text
|
||||
yarn add @projectstorm/react-diagrams-core@next
|
||||
yarn add @projectstorm/react-diagrams-core
|
||||
```
|
||||
|
||||
this is built ontop of the evolving **react-canvas-core** library
|
||||
|
||||
```text
|
||||
yarn add @projectstorm/react-canvas-core@next
|
||||
yarn add @projectstorm/react-canvas-core
|
||||
```
|
||||
|
||||
which makes use of
|
||||
|
||||
```text
|
||||
yarn add @projectstorm/react-geometry@next
|
||||
yarn add @projectstorm/geometry
|
||||
```
|
||||
|
||||
and of course, you can add some extras:
|
||||
|
||||
```text
|
||||
yarn add @projectstorm/react-diagrams-defaults@next
|
||||
yarn add @projectstorm/react-diagrams-routing@next
|
||||
yarn add @projectstorm/react-diagrams-defaults
|
||||
yarn add @projectstorm/react-diagrams-routing
|
||||
```
|
||||
|
||||
## How to use
|
||||
|
||||
Take a look at the [diagram demos](https://github.com/projectstorm/react-diagrams/tree/master/packages/diagrams-demo-gallery/demos)
|
||||
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.
|
||||
|
||||
|
||||
Take a look at the [diagram demos](https://github.com/projectstorm/react-diagrams/tree/master/diagrams-demo-gallery/demos)
|
||||
|
||||
**or**
|
||||
|
||||
Take a look at the [demo project](https://github.com/projectstorm/react-diagrams/tree/master/packages/diagrams-demo-project) which contains an example for ES6 as well as Typescript
|
||||
Take a look at the [demo project](https://github.com/projectstorm/react-diagrams/tree/master/diagrams-demo-project) which contains an example for ES6 as well as Typescript
|
||||
|
||||
**or**
|
||||
|
||||
@@ -84,11 +85,12 @@ Take a look at the [demo project](https://github.com/projectstorm/react-diagrams
|
||||
|
||||
## Run the demos
|
||||
|
||||
After running `yarn install` you must then run: `cd packages/diagrams-demo-gallery && yarn run start`
|
||||
After running `yarn install` and `yarn build`, you must then run: `cd diagrams-demo-gallery && yarn 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.
|
||||
|
||||
## Built with react-diagrams
|
||||
|
||||
> Do you have an interesting project built with *react-diagrams*? PR it into this section for others to see.
|
||||
|
||||
7
diagrams-demo-gallery/.storybook/main.js
Normal file
7
diagrams-demo-gallery/.storybook/main.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
stories: ['../demos/*.stories.tsx'],
|
||||
core: {
|
||||
builder: 'webpack5'
|
||||
},
|
||||
addons: ['@storybook/addon-actions']
|
||||
};
|
||||
7
diagrams-demo-gallery/.storybook/manager.js
Normal file
7
diagrams-demo-gallery/.storybook/manager.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import { addons } from '@storybook/addons';
|
||||
|
||||
import diagramsTheme from './theme';
|
||||
|
||||
addons.setConfig({
|
||||
theme: diagramsTheme
|
||||
});
|
||||
3
diagrams-demo-gallery/.storybook/preview.js
Normal file
3
diagrams-demo-gallery/.storybook/preview.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export const parameters = {
|
||||
layout: 'fullscreen'
|
||||
};
|
||||
7
diagrams-demo-gallery/.storybook/theme.js
Normal file
7
diagrams-demo-gallery/.storybook/theme.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import { create } from '@storybook/theming';
|
||||
|
||||
export default create({
|
||||
base: 'dark',
|
||||
brandTitle: 'STORM React Diagrams',
|
||||
brandUrl: 'https://github.com/projectstorm/react-diagrams'
|
||||
});
|
||||
59
diagrams-demo-gallery/CHANGELOG.md
Normal file
59
diagrams-demo-gallery/CHANGELOG.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# @projectstorm/react-diagrams-gallery
|
||||
|
||||
## 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
|
||||
32
diagrams-demo-gallery/demos/1_SimpleUsage.stories.tsx
Normal file
32
diagrams-demo-gallery/demos/1_SimpleUsage.stories.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import { Toolkit } from '@projectstorm/react-canvas-core';
|
||||
Toolkit.TESTING = true;
|
||||
|
||||
export default {
|
||||
title: 'Simple Usage'
|
||||
};
|
||||
|
||||
import demo_simple from './demo-simple';
|
||||
import demo_flow from './demo-simple-flow';
|
||||
import demo_performance from './demo-performance';
|
||||
import demo_locks from './demo-locks';
|
||||
import demo_grid from './demo-grid';
|
||||
import demo_listeners from './demo-listeners';
|
||||
import demo_zoom from './demo-zoom-to-fit';
|
||||
import demo_zoom_nodes from './demo-zoom-to-fit-nodes';
|
||||
import demo_canvas_drag from './demo-canvas-drag';
|
||||
import demo_pan_and_zoom from './demo-pan-and-zoom';
|
||||
import demo_dynamic_ports from './demo-dynamic-ports';
|
||||
import demo_labels from './demo-labelled-links';
|
||||
|
||||
export const DemoSimple = demo_simple;
|
||||
export const SimpleFlowExample = demo_flow;
|
||||
export const PerformanceDemo = demo_performance;
|
||||
export const LockedWidget = demo_locks;
|
||||
export const CanvasGridSize = demo_grid;
|
||||
export const EventsAndListeners = demo_listeners;
|
||||
export const ZoomToFit = demo_zoom;
|
||||
export const ZoomToFitSelectNodes = demo_zoom_nodes;
|
||||
export const CanvasDrag = demo_canvas_drag;
|
||||
export const CanvasPanAndZoom = demo_pan_and_zoom;
|
||||
export const DynamicPorts = demo_dynamic_ports;
|
||||
export const LinksWithLabels = demo_labels;
|
||||
24
diagrams-demo-gallery/demos/2_AdvancedUsage.stories.tsx
Normal file
24
diagrams-demo-gallery/demos/2_AdvancedUsage.stories.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Toolkit } from '@projectstorm/react-canvas-core';
|
||||
Toolkit.TESTING = true;
|
||||
|
||||
export default {
|
||||
title: 'Advanced Usage'
|
||||
};
|
||||
|
||||
import demo_adv_clone_selected from './demo-cloning';
|
||||
import demo_adv_ser_des from './demo-serializing';
|
||||
import demo_adv_prog from './demo-mutate-graph';
|
||||
import demo_adv_dnd from './demo-drag-and-drop';
|
||||
import demo_smart_routing from './demo-smart-routing';
|
||||
import demo_right_angles_routing from './demo-right-angles-routing';
|
||||
import demo_alternative_linking from './demo-alternative-linking';
|
||||
import demo_custom_delete_keys from './demo-custom_delete_keys';
|
||||
|
||||
export const CloneSelected = demo_adv_clone_selected;
|
||||
export const SerializingAndDeSerializing = demo_adv_ser_des;
|
||||
export const ProgramaticallyModifyingGraph = demo_adv_prog;
|
||||
export const DragAndDrop = demo_adv_dnd;
|
||||
export const SmartRouting = demo_smart_routing;
|
||||
export const RightAnglesRouting = demo_right_angles_routing;
|
||||
export const LinkingByClickingInsteadOfDragging = demo_alternative_linking;
|
||||
export const SettingCustomDeleteKeys = demo_custom_delete_keys;
|
||||
18
diagrams-demo-gallery/demos/3_Customization.stories.tsx
Normal file
18
diagrams-demo-gallery/demos/3_Customization.stories.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Toolkit } from '@projectstorm/react-canvas-core';
|
||||
Toolkit.TESTING = true;
|
||||
|
||||
export default {
|
||||
title: 'Customization'
|
||||
};
|
||||
|
||||
import demo_custom_link_label from './demo-custom-link-label';
|
||||
import demo_custom_action from './demo-custom-action';
|
||||
import demo_cust_nodes from './demo-custom-node1';
|
||||
import demo_cust_links from './demo-custom-link1';
|
||||
import demo_cust_links2 from './demo-custom-link2';
|
||||
|
||||
export const CustomDiamondNode = demo_cust_nodes;
|
||||
export const CustomAnimatedLinks = demo_cust_links;
|
||||
export const CustomLinkEndsWithArrows = demo_cust_links2;
|
||||
export const CustomLinkLabel = demo_custom_link_label;
|
||||
export const CustomEvent = demo_custom_action;
|
||||
12
diagrams-demo-gallery/demos/4_Libraries.stories.tsx
Normal file
12
diagrams-demo-gallery/demos/4_Libraries.stories.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Toolkit } from '@projectstorm/react-canvas-core';
|
||||
Toolkit.TESTING = true;
|
||||
|
||||
export default {
|
||||
title: 'External Libs'
|
||||
};
|
||||
|
||||
import demo_3rd_dagre from './demo-dagre';
|
||||
import demo_gsap from './demo-animation';
|
||||
|
||||
export const DagreDistribute = demo_3rd_dagre;
|
||||
export const GsapAnimation = demo_gsap;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { MouseEvent } from 'react';
|
||||
import { MouseEvent, TouchEvent } from 'react';
|
||||
import {
|
||||
SelectingState,
|
||||
State,
|
||||
@@ -45,6 +45,16 @@ export class DefaultState extends State<DiagramEngine> {
|
||||
})
|
||||
);
|
||||
|
||||
// touch drags the canvas
|
||||
this.registerAction(
|
||||
new Action({
|
||||
type: InputType.TOUCH_START,
|
||||
fire: (event: ActionEvent<TouchEvent>) => {
|
||||
this.transitionWithEvent(new DragCanvasState(), event);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this.registerAction(
|
||||
new Action({
|
||||
type: InputType.MOUSE_UP,
|
||||
@@ -60,7 +60,7 @@ export default () => {
|
||||
engine.setModel(model);
|
||||
|
||||
var interval = setInterval(() => {
|
||||
[node1, node2, node3, node4].map(node => {
|
||||
[node1, node2, node3, node4].map((node) => {
|
||||
var obj = { x: 0, y: 0 };
|
||||
gsap.fromTo(
|
||||
obj,
|
||||
72
diagrams-demo-gallery/demos/demo-canvas-drag/index.tsx
Normal file
72
diagrams-demo-gallery/demos/demo-canvas-drag/index.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import * as React from 'react';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
* Tests the drag on/off
|
||||
*/
|
||||
class CanvasDragToggle extends React.Component<any, any> {
|
||||
enableDrag = () => {
|
||||
const { engine } = this.props;
|
||||
const state = engine.getStateMachine().getCurrentState();
|
||||
state.dragCanvas.config.allowDrag = true;
|
||||
};
|
||||
|
||||
disableDrag = () => {
|
||||
const { engine } = this.props;
|
||||
const state = engine.getStateMachine().getCurrentState();
|
||||
state.dragCanvas.config.allowDrag = false;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { engine } = this.props;
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={[
|
||||
<DemoButton key={1} onClick={this.enableDrag}>
|
||||
Enable canvas drag
|
||||
</DemoButton>,
|
||||
<DemoButton key={2} onClick={this.disableDrag}>
|
||||
Disable canvas drag
|
||||
</DemoButton>
|
||||
]}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = createEngine();
|
||||
|
||||
//2) setup the diagram model
|
||||
var model = new DiagramModel();
|
||||
|
||||
//3-A) create a default node
|
||||
var node1 = new DefaultNodeModel('Node 1', 'rgb(0,192,255)');
|
||||
var port1 = node1.addOutPort('Out');
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
var port2 = node2.addInPort('In');
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
//3-C) link the 2 nodes together
|
||||
var link1 = port1.link(port2);
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <CanvasDragToggle engine={engine} model={model} />;
|
||||
};
|
||||
@@ -29,7 +29,7 @@ class CloneSelected extends React.Component<any, any> {
|
||||
model.addNode(newItem);
|
||||
} else if (newItem instanceof LinkModel) {
|
||||
// offset the link points
|
||||
newItem.getPoints().forEach(p => {
|
||||
newItem.getPoints().forEach((p) => {
|
||||
p.setPosition(p.getX() + offset.x, p.getY() + offset.y);
|
||||
});
|
||||
model.addLink(newItem);
|
||||
@@ -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();
|
||||
@@ -0,0 +1,20 @@
|
||||
import * as React from 'react';
|
||||
import { AbstractReactFactory, GenerateWidgetEvent } from '@projectstorm/react-canvas-core';
|
||||
import { DiagramEngine } from '@projectstorm/react-diagrams';
|
||||
|
||||
import { EditableLabelModel } from './EditableLabelModel';
|
||||
import { EditableLabelWidget } from './EditableLabelWidget';
|
||||
|
||||
export class EditableLabelFactory extends AbstractReactFactory<EditableLabelModel, DiagramEngine> {
|
||||
constructor() {
|
||||
super('editable-label');
|
||||
}
|
||||
|
||||
generateModel(): EditableLabelModel {
|
||||
return new EditableLabelModel();
|
||||
}
|
||||
|
||||
generateReactWidget(event: GenerateWidgetEvent<EditableLabelModel>): JSX.Element {
|
||||
return <EditableLabelWidget model={event.model} />;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { LabelModel } from '@projectstorm/react-diagrams';
|
||||
import { BaseModelOptions, DeserializeEvent } from '@projectstorm/react-canvas-core';
|
||||
|
||||
export interface EditableLabelOptions extends BaseModelOptions {
|
||||
value?: string;
|
||||
}
|
||||
|
||||
export class EditableLabelModel extends LabelModel {
|
||||
value: string;
|
||||
|
||||
constructor(options: EditableLabelOptions = {}) {
|
||||
super({
|
||||
...options,
|
||||
type: 'editable-label'
|
||||
});
|
||||
this.value = options.value || '';
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return {
|
||||
...super.serialize(),
|
||||
value: this.value
|
||||
};
|
||||
}
|
||||
|
||||
deserialize(event: DeserializeEvent<this>): void {
|
||||
super.deserialize(event);
|
||||
this.value = event.data.value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { EditableLabelModel } from './EditableLabelModel';
|
||||
import styled from '@emotion/styled';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
export interface FlowAliasLabelWidgetProps {
|
||||
model: EditableLabelModel;
|
||||
}
|
||||
|
||||
namespace S {
|
||||
// NOTE: this CSS rules allows to interact with elements in label
|
||||
export const Label = styled.div`
|
||||
user-select: none;
|
||||
pointer-events: auto;
|
||||
`;
|
||||
}
|
||||
|
||||
// now we can render all what we want in the label
|
||||
export const EditableLabelWidget: React.FunctionComponent<FlowAliasLabelWidgetProps> = (props) => {
|
||||
const [str, setStr] = React.useState(props.model.value);
|
||||
|
||||
return (
|
||||
<S.Label>
|
||||
<input
|
||||
value={str}
|
||||
onChange={(event) => {
|
||||
const newVal = event.target.value;
|
||||
|
||||
// update value both in internal component state
|
||||
setStr(newVal);
|
||||
// and in model object
|
||||
props.model.value = newVal;
|
||||
}}
|
||||
/>
|
||||
|
||||
<button onClick={() => action('model eventDidFire')('You clicked the button')}>Click me!</button>
|
||||
</S.Label>
|
||||
);
|
||||
};
|
||||
55
diagrams-demo-gallery/demos/demo-custom-link-label/index.tsx
Normal file
55
diagrams-demo-gallery/demos/demo-custom-link-label/index.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import * as React from 'react';
|
||||
import createEngine, { DefaultNodeModel, DiagramModel } from '@projectstorm/react-diagrams';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
import { EditableLabelFactory } from './EditableLabelFactory';
|
||||
import { EditableLabelModel } from './EditableLabelModel';
|
||||
|
||||
/**
|
||||
* @Author Shumaf Lovpache (aka Soarex16)
|
||||
*/
|
||||
|
||||
export default () => {
|
||||
// engine setup
|
||||
const engine = createEngine();
|
||||
|
||||
// register our label factory
|
||||
engine.getLabelFactories().registerFactory(new EditableLabelFactory());
|
||||
|
||||
// setup diagram model
|
||||
const model = new DiagramModel();
|
||||
|
||||
// create some nodes
|
||||
const node1 = new DefaultNodeModel('Node1', 'red');
|
||||
const port1 = node1.addOutPort('out');
|
||||
node1.setPosition(250, 100);
|
||||
|
||||
const node2 = new DefaultNodeModel('Node2', 'green');
|
||||
const port2 = node2.addInPort('in');
|
||||
node2.setPosition(800, 300);
|
||||
|
||||
// link nodes together
|
||||
const link1 = port1.link(port2);
|
||||
|
||||
// !!!
|
||||
// add our custom label to link
|
||||
link1.addLabel(
|
||||
new EditableLabelModel({
|
||||
value: 'Hello, I am label!'
|
||||
})
|
||||
);
|
||||
|
||||
// add models to the root graph
|
||||
model.addAll(node1, port1, node2, port2, link1);
|
||||
|
||||
// load model into engine
|
||||
engine.setModel(model);
|
||||
|
||||
// render diagram
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
@@ -70,7 +70,7 @@ export class AdvancedLinkSegment extends React.Component<{ model: AdvancedLinkMo
|
||||
<>
|
||||
<path
|
||||
fill="none"
|
||||
ref={ref => {
|
||||
ref={(ref) => {
|
||||
this.path = ref;
|
||||
}}
|
||||
strokeWidth={this.props.model.getOptions().width}
|
||||
@@ -78,7 +78,7 @@ export class AdvancedLinkSegment extends React.Component<{ model: AdvancedLinkMo
|
||||
d={this.props.path}
|
||||
/>
|
||||
<circle
|
||||
ref={ref => {
|
||||
ref={(ref) => {
|
||||
this.circle = ref;
|
||||
}}
|
||||
r={10}
|
||||
@@ -3,14 +3,14 @@ import createEngine, {
|
||||
DefaultNodeModel,
|
||||
DefaultPortModel,
|
||||
DefaultLinkFactory,
|
||||
DefaultLinkPointWidget,
|
||||
DefaultLinkModel,
|
||||
DefaultLinkWidget
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import { DiagramEngine, LinkWidget, PointModel } from '@projectstorm/react-diagrams-core';
|
||||
import { LinkWidget, PointModel } from '@projectstorm/react-diagrams-core';
|
||||
import * as React from 'react';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
import { MouseEvent } from 'react';
|
||||
|
||||
export class AdvancedLinkModel extends DefaultLinkModel {
|
||||
constructor() {
|
||||
@@ -27,7 +27,7 @@ export class AdvancedPortModel extends DefaultPortModel {
|
||||
}
|
||||
}
|
||||
|
||||
const CustomLinkArrowWidget = props => {
|
||||
const CustomLinkArrowWidget = (props) => {
|
||||
const { point, previousPoint } = props;
|
||||
|
||||
const angle =
|
||||
@@ -47,14 +47,9 @@ const CustomLinkArrowWidget = props => {
|
||||
<polygon
|
||||
points="0,10 8,30 -8,30"
|
||||
fill={props.color}
|
||||
onMouseLeave={() => {
|
||||
this.setState({ selected: false });
|
||||
}}
|
||||
onMouseEnter={() => {
|
||||
this.setState({ selected: true });
|
||||
}}
|
||||
data-id={point.getID()}
|
||||
data-linkid={point.getLink().getID()}></polygon>
|
||||
data-linkid={point.getLink().getID()}
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
@@ -125,6 +120,7 @@ export class AdvancedLinkFactory extends DefaultLinkFactory {
|
||||
return <AdvancedLinkWidget link={event.model} diagramEngine={this.engine} />;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Simple link styling demo
|
||||
@@ -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>
|
||||
@@ -18,7 +18,7 @@ export default () => {
|
||||
// register some other factories as well
|
||||
engine
|
||||
.getPortFactories()
|
||||
.registerFactory(new SimplePortFactory('diamond', config => new DiamondPortModel(PortModelAlignment.LEFT)));
|
||||
.registerFactory(new SimplePortFactory('diamond', (config) => new DiamondPortModel(PortModelAlignment.LEFT)));
|
||||
engine.getNodeFactories().registerFactory(new DiamondNodeFactory());
|
||||
|
||||
//2) setup the diagram model
|
||||
@@ -45,7 +45,8 @@ class DemoWidget extends React.Component<{ model: DiagramModel; engine: DiagramE
|
||||
marginx: 25,
|
||||
marginy: 25
|
||||
},
|
||||
includeLinks: true
|
||||
includeLinks: true,
|
||||
nodeMargin: 25
|
||||
});
|
||||
}
|
||||
|
||||
@@ -57,6 +58,13 @@ class DemoWidget extends React.Component<{ model: DiagramModel; engine: DiagramE
|
||||
this.props.engine.repaintCanvas();
|
||||
};
|
||||
|
||||
autoRefreshLinks = () => {
|
||||
this.engine.refreshLinks(this.props.model);
|
||||
|
||||
// only happens if pathfing is enabled (check line 25)
|
||||
this.reroute();
|
||||
this.props.engine.repaintCanvas();
|
||||
};
|
||||
componentDidMount(): void {
|
||||
setTimeout(() => {
|
||||
this.autoDistribute();
|
||||
@@ -72,7 +80,14 @@ class DemoWidget extends React.Component<{ model: DiagramModel; engine: DiagramE
|
||||
|
||||
render() {
|
||||
return (
|
||||
<DemoWorkspaceWidget buttons={<DemoButton onClick={this.autoDistribute}>Re-distribute</DemoButton>}>
|
||||
<DemoWorkspaceWidget
|
||||
buttons={
|
||||
<div>
|
||||
<DemoButton onClick={this.autoDistribute}>Re-distribute</DemoButton>
|
||||
<DemoButton onClick={this.autoRefreshLinks}>Refresh Links</DemoButton>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={this.props.engine} />
|
||||
</DemoCanvasWidget>
|
||||
@@ -106,9 +121,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) => {
|
||||
@@ -121,7 +138,7 @@ export default () => {
|
||||
model.addNode(node);
|
||||
});
|
||||
|
||||
links.forEach(link => {
|
||||
links.forEach((link) => {
|
||||
model.addLink(link);
|
||||
});
|
||||
|
||||
@@ -55,14 +55,9 @@ export class BodyWidget extends React.Component<BodyWidgetProps> {
|
||||
<TrayItemWidget model={{ type: 'out' }} name="Out Node" color="rgb(0,192,255)" />
|
||||
</TrayWidget>
|
||||
<S.Layer
|
||||
onDrop={event => {
|
||||
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,15 +69,13 @@ export class BodyWidget extends React.Component<BodyWidgetProps> {
|
||||
}
|
||||
var point = this.props.app.getDiagramEngine().getRelativeMousePoint(event);
|
||||
node.setPosition(point);
|
||||
this.props.app
|
||||
.getDiagramEngine()
|
||||
.getModel()
|
||||
.addNode(node);
|
||||
this.props.app.getDiagramEngine().getModel().addNode(node);
|
||||
this.forceUpdate();
|
||||
}}
|
||||
onDragOver={event => {
|
||||
onDragOver={(event) => {
|
||||
event.preventDefault();
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={this.props.app.getDiagramEngine()} />
|
||||
</DemoCanvasWidget>
|
||||
@@ -13,7 +13,7 @@ namespace S {
|
||||
font-family: Helvetica, Arial;
|
||||
padding: 5px;
|
||||
margin: 0px 10px;
|
||||
border: solid 1px ${p => p.color};
|
||||
border: solid 1px ${(p) => p.color};
|
||||
border-radius: 5px;
|
||||
margin-bottom: 2px;
|
||||
cursor: pointer;
|
||||
@@ -26,10 +26,11 @@ export class TrayItemWidget extends React.Component<TrayItemWidgetProps> {
|
||||
<S.Tray
|
||||
color={this.props.color}
|
||||
draggable={true}
|
||||
onDragStart={event => {
|
||||
onDragStart={(event) => {
|
||||
event.dataTransfer.setData('storm-diagram-node', JSON.stringify(this.props.model));
|
||||
}}
|
||||
className="tray-item">
|
||||
className="tray-item"
|
||||
>
|
||||
{this.props.name}
|
||||
</S.Tray>
|
||||
);
|
||||
@@ -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>
|
||||
@@ -34,7 +34,7 @@ export default () => {
|
||||
let models = model.addAll(node1, node2, node3, link1, link2);
|
||||
|
||||
// add a selection listener to each
|
||||
models.forEach(item => {
|
||||
models.forEach((item) => {
|
||||
item.registerListener({
|
||||
eventDidFire: action('element eventDidFire')
|
||||
});
|
||||
@@ -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>
|
||||
57
diagrams-demo-gallery/demos/demo-pan-and-zoom/index.tsx
Normal file
57
diagrams-demo-gallery/demos/demo-pan-and-zoom/index.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import * as React from 'react';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
* Tests the pan and zoom action, which is intended as a trackpad/mobile
|
||||
* alternative to the standard ZoomCanvasAction
|
||||
*/
|
||||
class CanvasPanAndZoomToggle extends React.Component<any, any> {
|
||||
render() {
|
||||
const { engine } = this.props;
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => {
|
||||
/**
|
||||
* 1) setup the diagram engine
|
||||
* PandAndZoomCanvasAction and ZoomCanvasAction are mutually exclusive
|
||||
* If both are enabled, ZoomCanvasAction will override.
|
||||
*/
|
||||
var engine = createEngine({
|
||||
registerDefaultPanAndZoomCanvasAction: true,
|
||||
registerDefaultZoomCanvasAction: false
|
||||
});
|
||||
|
||||
//2) setup the diagram model
|
||||
var model = new DiagramModel();
|
||||
|
||||
//3-A) create a default node
|
||||
var node1 = new DefaultNodeModel('Node 1', 'rgb(0,192,255)');
|
||||
var port1 = node1.addOutPort('Out');
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
var port2 = node2.addInPort('In');
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
//3-C) link the 2 nodes together
|
||||
var link1 = port1.link(port2);
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <CanvasPanAndZoomToggle engine={engine} model={model} />;
|
||||
};
|
||||
@@ -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>
|
||||
@@ -1,4 +1,4 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DefaultLabelModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
@@ -25,6 +25,7 @@ export default () => {
|
||||
|
||||
//3-C) link the 2 nodes together
|
||||
var link1 = port1.link(port2);
|
||||
link1.addLabel(new DefaultLabelModel({ label: 'Label' }));
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addAll(node1, node2, link1);
|
||||
@@ -48,10 +49,12 @@ export default () => {
|
||||
<DemoButton
|
||||
onClick={() => {
|
||||
action('Serialized Graph')(beautify(model2.serialize(), null, 2, 80));
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Serialize Graph
|
||||
</DemoButton>
|
||||
}>
|
||||
}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
@@ -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>
|
||||
@@ -28,7 +28,9 @@ export default () => {
|
||||
|
||||
//6) render the diagram!
|
||||
return (
|
||||
<DemoWorkspaceWidget buttons={<DemoButton onClick={() => engine.zoomToFitNodes(50)}>Zoom to fit</DemoButton>}>
|
||||
<DemoWorkspaceWidget
|
||||
buttons={<DemoButton onClick={() => engine.zoomToFitSelectedNodes(50)}>Zoom to fit</DemoButton>}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
72
diagrams-demo-gallery/demos/helpers/DemoCanvasWidget.tsx
Normal file
72
diagrams-demo-gallery/demos/helpers/DemoCanvasWidget.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import * as React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { css, Global } from '@emotion/react';
|
||||
|
||||
export interface DemoCanvasWidgetProps {
|
||||
color?: string;
|
||||
background?: string;
|
||||
}
|
||||
|
||||
namespace S {
|
||||
export const Container = styled.div<{ color: string; background: string }>`
|
||||
height: 100%;
|
||||
background-color: ${(p) => p.background};
|
||||
background-size: 50px 50px;
|
||||
display: flex;
|
||||
|
||||
> * {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
background-image: linear-gradient(
|
||||
0deg,
|
||||
transparent 24%,
|
||||
${(p) => p.color} 25%,
|
||||
${(p) => p.color} 26%,
|
||||
transparent 27%,
|
||||
transparent 74%,
|
||||
${(p) => p.color} 75%,
|
||||
${(p) => p.color} 76%,
|
||||
transparent 77%,
|
||||
transparent
|
||||
),
|
||||
linear-gradient(
|
||||
90deg,
|
||||
transparent 24%,
|
||||
${(p) => p.color} 25%,
|
||||
${(p) => p.color} 26%,
|
||||
transparent 27%,
|
||||
transparent 74%,
|
||||
${(p) => p.color} 75%,
|
||||
${(p) => p.color} 76%,
|
||||
transparent 77%,
|
||||
transparent
|
||||
);
|
||||
`;
|
||||
|
||||
export const Expand = css`
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
height: 100%;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
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)'}
|
||||
>
|
||||
{this.props.children}
|
||||
</S.Container>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -15,7 +15,7 @@ export class Helper {
|
||||
element.style.zIndex = '10';
|
||||
window.parent.document.body.appendChild(element);
|
||||
|
||||
window.parent.window.addEventListener('mousemove', event => {
|
||||
window.parent.window.addEventListener('mousemove', (event) => {
|
||||
console.clear();
|
||||
console.log(event.clientX, event.clientY);
|
||||
});
|
||||
48
diagrams-demo-gallery/package.json
Normal file
48
diagrams-demo-gallery/package.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "@projectstorm/react-diagrams-gallery",
|
||||
"version": "7.1.1",
|
||||
"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"
|
||||
},
|
||||
"keywords": [
|
||||
"web",
|
||||
"diagram",
|
||||
"diagrams",
|
||||
"react",
|
||||
"typescript",
|
||||
"flowchart",
|
||||
"simple",
|
||||
"links",
|
||||
"nodes"
|
||||
],
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21",
|
||||
"@projectstorm/react-canvas-core": "workspace:*",
|
||||
"@projectstorm/react-diagrams": "workspace:*",
|
||||
"@projectstorm/react-diagrams-core": "workspace:*",
|
||||
"@projectstorm/react-diagrams-defaults": "workspace:*",
|
||||
"gsap": "^3.11.4",
|
||||
"json-beautify": "^1.1.1",
|
||||
"react": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.191",
|
||||
"@types/react": "^18.0.27",
|
||||
"@storybook/addons": "^6.5.15",
|
||||
"@storybook/addon-actions": "^6.5.15",
|
||||
"@storybook/addon-options": "^5.3.21",
|
||||
"@storybook/builder-webpack5": "^6.5.15",
|
||||
"@storybook/manager-webpack5": "^6.5.15",
|
||||
"@storybook/react": "^6.5.15",
|
||||
"@storybook/storybook-deployer": "^2.8.16",
|
||||
"@storybook/theming": "^6.5.15"
|
||||
}
|
||||
}
|
||||
23
diagrams-demo-gallery/tsconfig.json
Normal file
23
diagrams-demo-gallery/tsconfig.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"suppressExcessPropertyErrors": true,
|
||||
"declaration": true,
|
||||
"composite": true,
|
||||
"incremental": true,
|
||||
"strictNullChecks": false,
|
||||
"sourceMap": true,
|
||||
"skipLibCheck": true,
|
||||
"jsx": "react",
|
||||
"target": "ES6",
|
||||
"module": "commonjs",
|
||||
"strict": false,
|
||||
"lib": [
|
||||
"DOM",
|
||||
"ES6"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"demos"
|
||||
]
|
||||
}
|
||||
43
diagrams-demo-project/CHANGELOG.md
Normal file
43
diagrams-demo-project/CHANGELOG.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# @projectstorm/react-diagrams-demo
|
||||
|
||||
## 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
|
||||
@@ -5,8 +5,8 @@
|
||||
In this repo you will find a simple webpack-dev-server project
|
||||
that shows how to get started with the library.
|
||||
|
||||
It contains an example of how to implement a custom node in both Vanilla ES6 as well
|
||||
It contains an example of how to implement a custom node in both Vanilla ES6 as-well
|
||||
as typescript (the recommended way).
|
||||
|
||||
Simply run `yarn start` and the server will start on port `9000`.
|
||||
Simply run `yarn start` which will also open your browser.
|
||||
|
||||
46
diagrams-demo-project/package.json
Normal file
46
diagrams-demo-project/package.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "@projectstorm/react-diagrams-demo",
|
||||
"version": "7.0.2",
|
||||
"author": "dylanvorster",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/projectstorm/react-diagrams.git"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "./node_modules/.bin/webpack serve --open"
|
||||
},
|
||||
"keywords": [
|
||||
"web",
|
||||
"diagram",
|
||||
"diagrams",
|
||||
"react",
|
||||
"typescript",
|
||||
"flowchart",
|
||||
"simple",
|
||||
"links",
|
||||
"nodes"
|
||||
],
|
||||
"main": "./dist/index.js",
|
||||
"typings": "./dist/@types/index",
|
||||
"dependencies": {
|
||||
"@projectstorm/react-diagrams": "workspace:*",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"source-map-loader": "^4.0.1",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"@babel/core": "^7.20.12",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@types/react": "^18.0.27",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"babel-loader": "^9.1.2",
|
||||
"css-loader": "^6.7.3",
|
||||
"style-loader": "^3.3.1",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-cli": "^5.0.1",
|
||||
"webpack-dev-server": "^4.11.1"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 263 KiB After Width: | Height: | Size: 263 KiB |
@@ -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;
|
||||
@@ -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() {
|
||||
@@ -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() {
|
||||
@@ -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;
|
||||
@@ -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 {
|
||||
@@ -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} />);
|
||||
});
|
||||
@@ -5,7 +5,7 @@
|
||||
"jsx": "react",
|
||||
"allowJs": true,
|
||||
"target": "es6",
|
||||
"moduleResolution": "node"
|
||||
"module": "CommonJS"
|
||||
},
|
||||
"include": [
|
||||
"./src"
|
||||
@@ -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,19 +47,15 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true
|
||||
}
|
||||
loader: 'ts-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
devServer: {
|
||||
host: '0.0.0.0',
|
||||
compress: true,
|
||||
port: 9000,
|
||||
disableHostCheck: true,
|
||||
overlay: true
|
||||
client: {
|
||||
overlay: true
|
||||
},
|
||||
hot: false,
|
||||
compress: true
|
||||
}
|
||||
};
|
||||
@@ -5,6 +5,7 @@
|
||||
* [Using the library](getting-started/using-the-library.md)
|
||||
* [Customizing](customizing/README.md)
|
||||
* [Extending DefaultLinkModel](customizing/extending-default-links.md)
|
||||
* [Custom Nodes](customizing/nodes.md)
|
||||
* [Custom Ports](customizing/ports.md)
|
||||
* [About the project](about-the-project/README.md)
|
||||
* [Testing](about-the-project/testing.md)
|
||||
|
||||
@@ -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 <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 ?
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# Customizing
|
||||
|
||||
Almost all components in react-diagrams are customizable. While some customization is better documented than others, the best way to learn about customization is through the examples in the codebase and by looking at the type annotations that come with the library.
|
||||
|
||||
Most UI customization can be done through extending existing base classes. While node, port, and link have different data models, they share the same customization pattern:
|
||||
|
||||
- they need a **model factory** extended off `AbstractModelFactory`, and that factory needs to be registered with the engine under a different model type
|
||||
- optionally, if you data model is different from the default, you can extend existing base classes such as `NodeModel`, `PortModel`, `DefaultLinkModel`, etc.
|
||||
- they need to have a **custom component** which renders using its default or customized data model. Some component such as the port can also be extended with composition such as port if you want to simply change the appearance.
|
||||
|
||||
## Working with custom links
|
||||
|
||||
This is the easiest way to get started:
|
||||
@@ -8,4 +16,6 @@ This is the easiest way to get started:
|
||||
|
||||
## Working with custom nodes
|
||||
|
||||
[Working with Ports](./ports.md)
|
||||
[Working with Nodes](./nodes.md)
|
||||
|
||||
[Working with Ports](./ports.md)
|
||||
|
||||
@@ -47,6 +47,6 @@ export class AdvancedLinkFactory extends DefaultLinkFactory {
|
||||
}
|
||||
```
|
||||
|
||||
The actual code for the `AdvancedLinkSegment` [can be found here](https://github.com/projectstorm/react-diagrams/blob/master/packages/diagrams-demo-gallery/demos/demo-custom-link1/index.tsx) (it is in the `demo-custom-link1` folder in the demo gallery).
|
||||
The actual code for the `AdvancedLinkSegment` [can be found here](https://github.com/projectstorm/react-diagrams/tree/master/diagrams-demo-gallery/demos/demo-custom-link1) (it is in the `demo-custom-link1` folder in the demo gallery).
|
||||
|
||||
This is the easiest and most simple way to get started with custom links.
|
||||
This is the easiest and most simple way to get started with custom links.
|
||||
|
||||
180
docs/customizing/nodes.md
Normal file
180
docs/customizing/nodes.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# Nodes
|
||||
|
||||
A node contains the node content itself and its ports. Check [NodeModel source code](https://github.com/projectstorm/react-diagrams/blob/master/packages/react-diagrams-core/src/entities/node/NodeModel.ts#L24), if you want to see what class methods can be extended.
|
||||
|
||||
## Extending the NodeModel
|
||||
|
||||
If you want to create a custom node that looks entirely different, then you need to create a component that renders using its default or customized data mode. In the example below, it uses a customized data model `DiamondNodeModel` to render `DiamondNodeWidget`, and both of them are being created in the model factory `DiamondNodeFactory`.
|
||||
|
||||

|
||||
|
||||
Because our Diamond node always has four ports, we add four default port models into the `DiamondNodeModel`. Depending on the type of node you are creating, this is basically where you store your vertex data in the graph theory sense.
|
||||
|
||||
```typescript
|
||||
// DiamondNodeModel.ts
|
||||
import { NodeModel, NodeModelGenerics, PortModelAlignment } from '@projectstorm/react-diagrams';
|
||||
import { DiamondPortModel } from './DiamondPortModel';
|
||||
|
||||
export interface DiamondNodeModelGenerics {
|
||||
PORT: DiamondPortModel;
|
||||
}
|
||||
|
||||
// this can be further extended for more complicated node types
|
||||
export class DiamondNodeModel extends NodeModel<NodeModelGenerics & DiamondNodeModelGenerics> {
|
||||
constructor() {
|
||||
super({
|
||||
type: 'diamond'
|
||||
});
|
||||
this.addPort(new DiamondPortModel(PortModelAlignment.TOP));
|
||||
this.addPort(new DiamondPortModel(PortModelAlignment.LEFT));
|
||||
this.addPort(new DiamondPortModel(PortModelAlignment.BOTTOM));
|
||||
this.addPort(new DiamondPortModel(PortModelAlignment.RIGHT));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This is where we create our customized component. This component can be any customized react component as long as they respect the node and engine props. Ports also need to be rendered inside the node component.
|
||||
|
||||
```typescript
|
||||
// DiamondNodeWidget.tsx
|
||||
import * as React from 'react';
|
||||
import { DiamondNodeModel } from './DiamondNodeModel';
|
||||
import { DiagramEngine, PortModelAlignment, PortWidget } from '@projectstorm/react-diagrams';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
export interface DiamondNodeWidgetProps {
|
||||
// node and engine props are required
|
||||
node: DiamondNodeModel;
|
||||
engine: DiagramEngine;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
namespace S {
|
||||
export const Port = styled.div`
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
z-index: 10;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 1);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
// this can be any customized react component as long as they respect
|
||||
// the node and engine props
|
||||
export class DiamondNodeWidget extends React.Component<DiamondNodeWidgetProps> {
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
className={'diamond-node'}
|
||||
style={{
|
||||
position: 'relative',
|
||||
width: this.props.size,
|
||||
height: this.props.size
|
||||
}}>
|
||||
<svg
|
||||
width={this.props.size}
|
||||
height={this.props.size}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html:
|
||||
`
|
||||
<g id="Layer_1">
|
||||
</g>
|
||||
<g id="Layer_2">
|
||||
<polygon fill="mediumpurple" stroke="${
|
||||
this.props.node.isSelected() ? 'white' : '#000000'
|
||||
}" stroke-width="3" stroke-miterlimit="10" points="10,` +
|
||||
this.props.size / 2 +
|
||||
` ` +
|
||||
this.props.size / 2 +
|
||||
`,10 ` +
|
||||
(this.props.size - 10) +
|
||||
`,` +
|
||||
this.props.size / 2 +
|
||||
` ` +
|
||||
this.props.size / 2 +
|
||||
`,` +
|
||||
(this.props.size - 10) +
|
||||
` "/>
|
||||
</g>
|
||||
`
|
||||
}}
|
||||
/>
|
||||
<PortWidget
|
||||
style={{
|
||||
top: this.props.size / 2 - 8,
|
||||
left: -8,
|
||||
position: 'absolute'
|
||||
}}
|
||||
port={this.props.node.getPort(PortModelAlignment.LEFT)}
|
||||
engine={this.props.engine}>
|
||||
<S.Port />
|
||||
</PortWidget>
|
||||
<PortWidget
|
||||
style={{
|
||||
left: this.props.size / 2 - 8,
|
||||
top: -8,
|
||||
position: 'absolute'
|
||||
}}
|
||||
port={this.props.node.getPort(PortModelAlignment.TOP)}
|
||||
engine={this.props.engine}>
|
||||
<S.Port />
|
||||
</PortWidget>
|
||||
<PortWidget
|
||||
style={{
|
||||
left: this.props.size - 8,
|
||||
top: this.props.size / 2 - 8,
|
||||
position: 'absolute'
|
||||
}}
|
||||
port={this.props.node.getPort(PortModelAlignment.RIGHT)}
|
||||
engine={this.props.engine}>
|
||||
<S.Port />
|
||||
</PortWidget>
|
||||
<PortWidget
|
||||
style={{
|
||||
left: this.props.size / 2 - 8,
|
||||
top: this.props.size - 8,
|
||||
position: 'absolute'
|
||||
}}
|
||||
port={this.props.node.getPort(PortModelAlignment.BOTTOM)}
|
||||
engine={this.props.engine}>
|
||||
<S.Port />
|
||||
</PortWidget>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now we need to create a new node factory to tell the system how our new node model fits into the core system. We specifically are going to extend the `DefaultLinkFactory` because we want to render a `DiamondNodeWidget` with data model being `DiamondNodeModel`. To accomplish that, we simply extend `generateReactWidget(event)` to return a `DiamondNodeWidget` and extend `generateModel` to return a `DiamondNodeModel` instance.
|
||||
|
||||
```typescript
|
||||
// DiamondNodeFactory.tsx
|
||||
import { DiamondNodeWidget } from './DiamondNodeWidget';
|
||||
import { DiamondNodeModel } from './DiamondNodeModel';
|
||||
import * as React from 'react';
|
||||
import { AbstractReactFactory } from '@projectstorm/react-canvas-core';
|
||||
import { DiagramEngine } from '@projectstorm/react-diagrams-core';
|
||||
|
||||
export class DiamondNodeFactory extends AbstractReactFactory<DiamondNodeModel, DiagramEngine> {
|
||||
constructor() {
|
||||
super('diamond');
|
||||
}
|
||||
|
||||
generateReactWidget(event): JSX.Element {
|
||||
// event.model is basically what's returned from generateModel()
|
||||
return <DiamondNodeWidget engine={this.engine} size={50} node={event.model} />;
|
||||
}
|
||||
|
||||
generateModel(event) {
|
||||
return new DiamondNodeModel();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The actual code for the `DiamondNode` [can be found here](https://github.com/projectstorm/react-diagrams/tree/master/diagrams-demo-gallery/demos/demo-custom-node1) (it is in the `demo-custom-node1` folder in the demo gallery).
|
||||
|
||||
This is the easiest and most simple way to get started with custom nodes.
|
||||
@@ -2,31 +2,24 @@
|
||||
|
||||
## 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:**
|
||||
|
||||
```text
|
||||
yarn add @projectstorm/react-diagrams@next
|
||||
yarn add @projectstorm/react-diagrams
|
||||
```
|
||||
|
||||
**Via npm:**
|
||||
|
||||
```text
|
||||
npm install @projectstorm/react-diagrams@next
|
||||
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 pnpm:**
|
||||
|
||||
```text
|
||||
yarn add closest lodash react mathjs dagre pathfinding paths-js @emotion/core
|
||||
pnpm add @projectstorm/react-diagrams
|
||||
```
|
||||
|
||||
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.
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"version": "6.1.0"
|
||||
}
|
||||
101
package.json
101
package.json
@@ -6,7 +6,6 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/projectstorm/react-diagrams.git"
|
||||
},
|
||||
"workspaces": ["packages/*"],
|
||||
"keywords": [
|
||||
"web",
|
||||
"diagram",
|
||||
@@ -19,83 +18,31 @@
|
||||
"nodes"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "yarn build:clean && lerna run build --stream",
|
||||
"build:es": "lerna run build:es --stream",
|
||||
"build:prod": "yarn build:clean && lerna run build:prod --stream",
|
||||
"watch": "yarn build:clean && lerna run watch --stream",
|
||||
"publish:dev": "yarn build:prod && lerna publish --force-publish --dist-tag=next",
|
||||
"publish:prod": "yarn build:prod && lerna publish --force-publish",
|
||||
"publish:storybook": "cd packages/diagrams-demo-gallery && yarn storybook:build && ../../node_modules/.bin/storybook-to-ghpages --existing-output-dir .out",
|
||||
"build:clean": "lerna run clean --stream",
|
||||
"test:ci": "lerna run test --stream -- --runInBand --ci ",
|
||||
"pretty": "prettier --write \"packages/**/*.{ts,tsx,scss,js,jsx}\""
|
||||
},
|
||||
"peerDependencies": {
|
||||
"closest": "^0.0.1",
|
||||
"lodash": "4.*",
|
||||
"pathfinding": "^0.4.18",
|
||||
"paths-js": "^0.4.10",
|
||||
"react": "16.*",
|
||||
"emotion": "10.*"
|
||||
"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.9.0",
|
||||
"@babel/preset-react": "^7.9.4",
|
||||
"@emotion/core": "^10.0.28",
|
||||
"@emotion/styled": "^10.0.27",
|
||||
"@storybook/addon-actions": "^5.3.18",
|
||||
"@storybook/addon-options": "^5.3.18",
|
||||
"@storybook/addons": "^5.3.18",
|
||||
"@storybook/react": "^5.3.18",
|
||||
"@storybook/storybook-deployer": "^2.8.5",
|
||||
"@storybook/theming": "^5.3.18",
|
||||
"@types/dagre": "^0.7.43",
|
||||
"@types/jest": "^25.2.1",
|
||||
"@types/jest-environment-puppeteer": "^4.3.1",
|
||||
"@types/lodash": "^4.14.150",
|
||||
"@types/mathjs": "^6.0.5",
|
||||
"@types/node": "^13.13.2",
|
||||
"@types/promise": "^7.1.30",
|
||||
"@types/puppeteer": "^2.0.1",
|
||||
"@types/react": "^16.9.34",
|
||||
"babel-loader": "^8.1.0",
|
||||
"closest": "^0.0.1",
|
||||
"cross-env": "^7.0.2",
|
||||
"css-loader": "^3.5.3",
|
||||
"dagre": "^0.8.5",
|
||||
"enzyme": "^3.11.0",
|
||||
"file-loader": "^6.0.0",
|
||||
"glob": "^7.1.6",
|
||||
"jest": "^25.4.0",
|
||||
"jest-cli": "^25.4.0",
|
||||
"jest-puppeteer": "^4.4.0",
|
||||
"json-beautify": "^1.1.1",
|
||||
"lerna": "^3.20.2",
|
||||
"lodash": "4.*",
|
||||
"mathjs": "^6.6.4",
|
||||
"pathfinding": "^0.4.18",
|
||||
"paths-js": "^0.4.10",
|
||||
"prettier": "^2.0.5",
|
||||
"puppeteer": "^3.0.1",
|
||||
"raf": "^3.4.1",
|
||||
"raw-loader": "^4.0.1",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-test-renderer": "^16.13.1",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"source-map-loader": "^0.2.4",
|
||||
"storybook-host": "^5.1.0",
|
||||
"storybook-readme": "^5.0.8",
|
||||
"style-loader": "^1.2.0",
|
||||
"terser-webpack-plugin": "^2.3.6",
|
||||
"ts-jest": "^25.4.0",
|
||||
"ts-loader": "^7.0.1",
|
||||
"typescript": "^3.8.3",
|
||||
"val-loader": "^2.1.1",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.11",
|
||||
"webpack-dev-server": "^3.10.3",
|
||||
"webpack-node-externals": "^1.7.2"
|
||||
"@changesets/cli": "^2.26.0",
|
||||
"@types/jest": "^29.2.6",
|
||||
"@types/node": "^18.11.18",
|
||||
"jest": "^29.4.0",
|
||||
"jest-cli": "^29.4.0",
|
||||
"prettier": "^2.8.3",
|
||||
"rimraf": "^4.1.2",
|
||||
"source-map-loader": "^4.0.1",
|
||||
"terser-webpack-plugin": "^5.3.6",
|
||||
"ts-jest": "^29.0.5",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^4.9.4",
|
||||
"webpack": "^5.75.0",
|
||||
"webpack-cli": "^5.0.1",
|
||||
"webpack-dev-server": "^4.11.1",
|
||||
"webpack-node-externals": "^3.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
import '@storybook/addon-actions/register';
|
||||
import '@storybook/addon-options/register';
|
||||
@@ -1,8 +0,0 @@
|
||||
import { configure } from '@storybook/react';
|
||||
|
||||
function loadStories() {
|
||||
require('../index.tsx');
|
||||
// You can require as many demos as you need.
|
||||
}
|
||||
|
||||
configure(loadStories, module);
|
||||
@@ -1,43 +0,0 @@
|
||||
const path = require('path');
|
||||
module.exports = async ({ config, mode }) => {
|
||||
return {
|
||||
...config,
|
||||
resolve: {
|
||||
...config.resolve,
|
||||
extensions: ['.tsx', '.ts', '.js']
|
||||
},
|
||||
module: {
|
||||
...config.module,
|
||||
rules: [
|
||||
...config.module.rules,
|
||||
...[
|
||||
{
|
||||
test: /\.scss$/,
|
||||
loaders: [
|
||||
'style-loader',
|
||||
'css-loader',
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: { config: { path: path.join(__dirname, '..') } }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
enforce: 'pre',
|
||||
test: /\.js$/,
|
||||
loader: 'source-map-loader',
|
||||
exclude: [/node_modules/]
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
export interface DemoCanvasWidgetProps {
|
||||
color?: string;
|
||||
background?: string;
|
||||
}
|
||||
|
||||
namespace S {
|
||||
export const Container = styled.div<{ color: string; background: string }>`
|
||||
height: 100%;
|
||||
background-color: ${p => p.background};
|
||||
background-size: 50px 50px;
|
||||
display: flex;
|
||||
|
||||
> * {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
background-image: linear-gradient(
|
||||
0deg,
|
||||
transparent 24%,
|
||||
${p => p.color} 25%,
|
||||
${p => p.color} 26%,
|
||||
transparent 27%,
|
||||
transparent 74%,
|
||||
${p => p.color} 75%,
|
||||
${p => p.color} 76%,
|
||||
transparent 77%,
|
||||
transparent
|
||||
),
|
||||
linear-gradient(
|
||||
90deg,
|
||||
transparent 24%,
|
||||
${p => p.color} 25%,
|
||||
${p => p.color} 26%,
|
||||
transparent 27%,
|
||||
transparent 74%,
|
||||
${p => p.color} 75%,
|
||||
${p => p.color} 76%,
|
||||
transparent 77%,
|
||||
transparent
|
||||
);
|
||||
`;
|
||||
}
|
||||
|
||||
export class DemoCanvasWidget extends React.Component<DemoCanvasWidgetProps> {
|
||||
render() {
|
||||
return (
|
||||
<S.Container
|
||||
background={this.props.background || 'rgb(60, 60, 60)'}
|
||||
color={this.props.color || 'rgba(255,255,255, 0.05)'}>
|
||||
{this.props.children}
|
||||
</S.Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user