Compare commits
385 Commits
v6.0.0-alp
...
@projectst
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63b39cba79 | ||
|
|
a671b50e09 | ||
|
|
7a664d5b64 | ||
|
|
66c687afc6 | ||
|
|
23b5467806 | ||
|
|
1889c7cb40 | ||
|
|
c3146e1aa8 | ||
|
|
8fb8d04885 | ||
|
|
74e814ab5a | ||
|
|
3d4e0b24d7 | ||
|
|
efd64ad278 | ||
|
|
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 | ||
|
|
2a28368d5e | ||
|
|
987d3c84ab | ||
|
|
1ea06fb3d5 | ||
|
|
3fdbe4c975 | ||
|
|
1aa1058eb5 | ||
|
|
ff2a668842 | ||
|
|
86b4c97e89 | ||
|
|
696994f0ad | ||
|
|
7d133abf58 | ||
|
|
53068cbe1f | ||
|
|
379e808d70 | ||
|
|
15d70e988e | ||
|
|
355add35a8 | ||
|
|
280a1fc0e4 | ||
|
|
eeece55c31 | ||
|
|
fb5f6e95e7 | ||
|
|
8d73d238fe | ||
|
|
49242281e7 | ||
|
|
f148b8e391 | ||
|
|
f78c5de4ae | ||
|
|
6e77f3503a | ||
|
|
4787163492 | ||
|
|
d8009f02a5 | ||
|
|
aa186f7040 | ||
|
|
09358d9b93 | ||
|
|
b84265d802 | ||
|
|
410d6cfccf | ||
|
|
1dd26253b2 | ||
|
|
7e15c55a73 | ||
|
|
61bc333658 | ||
|
|
8cf6b0269c | ||
|
|
51258b68b6 | ||
|
|
469dbc00af | ||
|
|
dbe0e595b8 | ||
|
|
20a6bfe012 | ||
|
|
fd38a20c23 | ||
|
|
5124c1a628 | ||
|
|
46d7aa14b5 | ||
|
|
971bae29f3 | ||
|
|
5ec4327912 | ||
|
|
1511bec663 | ||
|
|
3e91dad2e1 | ||
|
|
1d5ab683c3 | ||
|
|
96d6d0dcf2 | ||
|
|
ddc17a8dc3 | ||
|
|
a9e5575646 | ||
|
|
d0331cb205 | ||
|
|
8556937ff1 | ||
|
|
341e540af6 | ||
|
|
9bd86480e9 | ||
|
|
5e0a75d4ed | ||
|
|
91789729c4 | ||
|
|
361fbe4ffe | ||
|
|
80e9bdcfc0 | ||
|
|
97c66b99ab | ||
|
|
220852697f | ||
|
|
8e05f28931 | ||
|
|
a450c9b5b5 | ||
|
|
508fbf2777 | ||
|
|
11dc57a834 | ||
|
|
ed63bf151c | ||
|
|
6dd0677b28 | ||
|
|
ea6130d1a9 | ||
|
|
3c8839a1ec | ||
|
|
a7ab686463 | ||
|
|
11c2c70ec6 | ||
|
|
a3ca75d039 | ||
|
|
dedc627294 | ||
|
|
c000ffc3cd | ||
|
|
37babb3bb2 | ||
|
|
33651b22a1 | ||
|
|
dfc7102b1c | ||
|
|
a399f135ba | ||
|
|
36e097cb70 | ||
|
|
23e1742e99 | ||
|
|
5d913f28ba | ||
|
|
1c955b4d12 | ||
|
|
741851b855 | ||
|
|
4729bbedc9 | ||
|
|
994ff7c714 | ||
|
|
05f1345e62 | ||
|
|
5079188b99 | ||
|
|
13dd53f185 | ||
|
|
502faeef5a | ||
|
|
39c4f37d12 | ||
|
|
1dccace7e2 | ||
|
|
85857afd31 | ||
|
|
c875ce6e22 | ||
|
|
422b967be7 | ||
|
|
1a8b3caca4 | ||
|
|
116a296bf5 | ||
|
|
57f4e2d832 | ||
|
|
b0089662aa | ||
|
|
8ded9cd30e | ||
|
|
14a76ffbf5 | ||
|
|
1a7acafdc8 | ||
|
|
ad25420166 | ||
|
|
1fb622366b | ||
|
|
761ac41901 | ||
|
|
c8aa7a67ac | ||
|
|
e923245f6d | ||
|
|
0cb6c66b1f | ||
|
|
f20bb0bd2e | ||
|
|
0deaec246d | ||
|
|
cb79d4e390 | ||
|
|
35a53c8134 | ||
|
|
326567c290 | ||
|
|
7fa51d5ea0 | ||
|
|
e72e7e999c | ||
|
|
25fe2a8e64 | ||
|
|
e59edefbeb | ||
|
|
27022d2965 | ||
|
|
897237c9ca | ||
|
|
f0242c7924 | ||
|
|
cf9f9cb01d | ||
|
|
4c90895bcd | ||
|
|
3f6d04521d | ||
|
|
3a46047ee8 | ||
|
|
77418ee8e7 | ||
|
|
07c74d850f | ||
|
|
75d1b6bb5d | ||
|
|
4cae28c808 | ||
|
|
cff54426c9 | ||
|
|
3dd329b209 | ||
|
|
6396abc17c | ||
|
|
16f6b484b5 | ||
|
|
68c2c76d72 | ||
|
|
16033a658c | ||
|
|
96655baff2 | ||
|
|
630467cf97 | ||
|
|
23b174736c | ||
|
|
9de0708535 | ||
|
|
4786208fe6 | ||
|
|
98888f6d96 | ||
|
|
f017873cdc | ||
|
|
d14f1a3bb3 | ||
|
|
cdda07b026 | ||
|
|
fa6bebce6f | ||
|
|
04362b8da8 | ||
|
|
0dbdee9f18 | ||
|
|
a5c4d917eb | ||
|
|
93cc419767 | ||
|
|
7a7fef85d0 | ||
|
|
4eccdbdc8a | ||
|
|
962883ce4a | ||
|
|
6571dbe159 | ||
|
|
8fbd87df8c | ||
|
|
ce38f77027 | ||
|
|
bec82cd92c | ||
|
|
d2c5bac65c | ||
|
|
5fc17b6217 | ||
|
|
d2e1cf2dd1 | ||
|
|
9e2f6ffb0f | ||
|
|
cc900b2a90 | ||
|
|
51c6bd2391 | ||
|
|
a8c6031166 | ||
|
|
a6655dbf2d | ||
|
|
37532edd01 | ||
|
|
4538884a96 | ||
|
|
c9f7d2c516 | ||
|
|
5c66c84a31 | ||
|
|
4a57ecdc97 | ||
|
|
9fc65b7d7f | ||
|
|
2573c5d8cc | ||
|
|
a46e17306b | ||
|
|
7045d75ae7 | ||
|
|
47e4a14520 | ||
|
|
58eee117e9 | ||
|
|
09d5b65e59 | ||
|
|
6512ca0eb0 | ||
|
|
bfde4226ec | ||
|
|
ea6adbe61b | ||
|
|
5f74600157 | ||
|
|
3590245f6c | ||
|
|
46aa99b2ea | ||
|
|
80f86867fd | ||
|
|
52f9105b1b | ||
|
|
e9558919fb | ||
|
|
dd5a0b7d8d | ||
|
|
0f7930e132 | ||
|
|
3823adc8e8 | ||
|
|
fce011a11b | ||
|
|
4962343b54 |
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
@@ -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,22 +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: 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"]
|
||||
@@ -4,6 +4,6 @@ indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# Some exceptions
|
||||
[{package.json}]
|
||||
[{package.json,*.yml}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
4
.gitbook.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
root: ./docs/
|
||||
|
||||
structure:
|
||||
summary: README.md
|
||||
|
Before Width: | Height: | Size: 438 KiB After Width: | Height: | Size: 438 KiB |
|
Before Width: | Height: | Size: 313 KiB After Width: | Height: | Size: 313 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
BIN
.gitbook/assets/logo.jpg
Normal file
|
After Width: | Height: | Size: 231 KiB |
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
@@ -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
@@ -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
@@ -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
@@ -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"
|
||||
}
|
||||
|
||||
150
CHANGELOG.md
@@ -1,7 +1,131 @@
|
||||
__6.0.0__
|
||||
__V7!__
|
||||
|
||||
* (maintenance) move to Lerna and break up the library
|
||||
* (api)(breaking) smart routing is now a Link Factory
|
||||
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
|
||||
[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__
|
||||
|
||||
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.
|
||||
|
||||
I would also recommend taking a look at the new updated DiamondPort widget which shows more capability.
|
||||
|
||||
* Break up library into monorepo
|
||||
* Introduce react-canvas-core as a new framework
|
||||
* Use geometry classes instead of raw X and Y primitives so we can do matrix stuff in the future
|
||||
* move testing framework to a name based system instead of ID's
|
||||
* 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
|
||||
* 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
|
||||
* Broke up link rendering into a much more modular system that is much easier to extend
|
||||
* Introduced port alignment allowing the developer to specify how enter it
|
||||
* Improved generics throughout the entire model system with Mapped Types
|
||||
* Rewrote all the styles using emotion instead of sass
|
||||
* Fixed up all the demos to use the new API
|
||||
* Introduced a demo project that illustrates how to use the library with ES6 as well as with Typescript
|
||||
* Improved the grid rendering system to allow graphical elements to specify how they get transformed
|
||||
* Introduced a performance widget for improving performance in a more deterministic way by comparing the serialization of the model (with a way of opting out)
|
||||
* Renamed a bunch of methods to be more consistent and more understandable
|
||||
* 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
|
||||
|
||||
__5.3.2__
|
||||
|
||||
@@ -22,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
|
||||
@@ -33,7 +157,7 @@ __5.1.0__
|
||||
* (refactor) consistently use lodash where possible
|
||||
* (maintenance) upgrade node modules
|
||||
|
||||
__5.0.0__ http://dylanv.blog/2018/03/03/storm-react-diagrams-5-0-0/
|
||||
__5.0.0__ [http://dylanv.blog/2018/03/03/storm-react-diagrams-5-0-0/](https://dylanvorster.com/storm-react-diagrams-v5-0/)
|
||||
|
||||
PR: https://github.com/projectstorm/react-diagrams/pull/145
|
||||
|
||||
@@ -50,7 +174,7 @@ PR: https://github.com/projectstorm/react-diagrams/pull/145
|
||||
* (tests) automatically load JEST Snapshots
|
||||
* (feature) Link labels!
|
||||
|
||||
__4.0.0__ http://dylanv.blog/2018/01/18/storm-react-diagrams-v4-0-0/
|
||||
__4.0.0__ [http://dylanv.blog/2018/01/18/storm-react-diagrams-v4-0-0/](https://dylanvorster.com/storm-react-diagrams-v4-0/)
|
||||
|
||||
* (refactor) Events system was completely overhauled
|
||||
* (demo) Custom Link Sizes
|
||||
@@ -62,9 +186,9 @@ __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/
|
||||
__3.2.0__ [http://dylanv.blog/2017/11/22/storm-react-diagrams-3-2-0/](https://dylanvorster.com/storm-react-diagrams-3-2-0/)
|
||||
* (feature) zoom to fit
|
||||
* added Circle CI tests
|
||||
* (demo) dagre automatic layouts
|
||||
@@ -77,24 +201,24 @@ __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)
|
||||
|
||||
__3.1.0__ http://dylanv.blog/2017/09/15/storm-react-diagrams-3-1-0/
|
||||
__3.1.0__ [http://dylanv.blog/2017/09/15/storm-react-diagrams-3-1-0/](https://dylanvorster.com/storm-react-diagrams-3-1-0/)
|
||||
* Zoom relative to mouse location
|
||||
* Fixed links not connecting when grid is larger than port size
|
||||
* Prevented points from dragging when connected to a port and the node itself is not selected
|
||||
* API fixes
|
||||
* Code cleanup
|
||||
* Code cleanup
|
||||
|
||||
__3.0.0__ http://dylanv.blog/2017/09/13/storm-react-diagrams-v3/
|
||||
__3.0.0__ [http://dylanv.blog/2017/09/13/storm-react-diagrams-v3/](https://dylanvorster.com/storm-react-diagrams-3-0/)
|
||||
* Massive performance updates
|
||||
* Complete rewrite
|
||||
* Started a changelog and design documents for each revision
|
||||
|
||||
100
README.md
@@ -1,78 +1,96 @@
|
||||
# STORM React Diagrams
|
||||
# Introduction
|
||||
|
||||
__PSA 2018__: React Diagrams ~is currently~ was getting a bit of a rewrite to enable much more advanced features. To see the new foundation WIP visit [https://github.com/projectstorm/react-canvas](https://github.com/projectstorm/react-canvas).
|
||||
[](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)
|
||||
|
||||
__PSA 2019__: I still want to jump onto the rewrite, but it is a much larger project than anticipated, so going to try maintain this one in the mean time.
|
||||
|
||||
---
|
||||

|
||||
|
||||
**DEMO**: [http://projectstorm.cloud/react-diagrams](http://projectstorm.cloud/react-diagrams)
|
||||
|
||||
**(SOME) DOCS:** [https://projectstorm.gitbooks.io/react-diagrams](https://projectstorm.gitbooks.io/react-diagrams)
|
||||
**DOCS \(wip\)** [https://projectstorm.gitbook.io/react-diagrams](https://projectstorm.gitbook.io/react-diagrams)
|
||||
|
||||
**RELEASE NOTES** : [http://dylanv.blog/2018/03/03/storm-react-diagrams-5-0-0/](http://dylanv.blog/2018/03/03/storm-react-diagrams-5-0-0/)
|
||||
Docs are currently being worked on, along with a migration path.
|
||||
|
||||
A super simple, no-nonsense diagramming library written in React that just works.
|
||||
## What
|
||||
|
||||
[](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://npmjs.org/package/storm-react-diagrams) [](http://packagequality.com/#?package=storm-react-diagrams) [](https://circleci.com/gh/projectstorm/react-diagrams/tree/master) [](https://lerna.js.org/)
|
||||
A flow & process orientated diagramming library inspired by **Blender**, **Labview** and **Unreal engine**.
|
||||
|
||||
* **Modern Codebase** written entirely in Typescript and React, the library makes use of powerful generics, advanced software engineering principles and is broken up into multiple modules.
|
||||
* **Hackable and extensible** the entire library including its core can be extended, rewired and re-assembled into fundamentally different software to suit your own software needs.
|
||||
* **HTML nodes as a first class citizen** the library was originally written to represent advanced dynamic nodes, that are difficult to represent as SVG's due to complex input requirements ux requirements.
|
||||
* **Designed for process** the library is aimed for software engineers that want to rewire their programs at runtime, and that want to make their software more dynamic.
|
||||
* **Fast diagram editing** the defaults provided give the highest priority to editing diagrams as fast as possible.
|
||||
|
||||
Example implementation using custom models: (Dylan's personal code)
|
||||
## Gallery
|
||||
|
||||
Example implementation using custom models: \(Dylan's personal code\)
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
Get started with the default models right out of the box:
|
||||

|
||||
|
||||
## Introduction
|
||||
|
||||
A no-nonsense diagramming library written entirely in React with the help of a few small libraries. It aims to be:
|
||||
|
||||
* Simple, and void of any fuss/complications when implementing it into your own application
|
||||
* Customizable without having to hack the core \(adapters/factories etc..\)
|
||||
* Simple to operate and understand without sugar and magic
|
||||
* Fast and optimized to handle large diagrams with hundreds of nodes/links
|
||||
* Use HTML to create nodes, instead of SVG's
|
||||
* Super easy to use, and should work as you expect it to
|
||||
* Perfect for creating declarative systems such as programmatic pipelines and visual programming languages (Labview, Symlink etc..)
|
||||

|
||||
|
||||
## Installing
|
||||
|
||||
For all the bells and whistles:
|
||||
|
||||
yarn add @projectstorm/react-diagrams
|
||||
```text
|
||||
yarn add @projectstorm/react-diagrams
|
||||
```
|
||||
|
||||
This includes all the packages listed below (and works like it used to before version 6.0)
|
||||
This includes all the packages listed below \(and works \(mostly and conceptually\) like it used to in version 5.0\)
|
||||
|
||||
### A more modular approach
|
||||
|
||||
This library now has a more modular design and you can import just the core (contains no default factories or routing)
|
||||
This library now has a more modular design and you can import just the core \(contains no default factories or routing\)
|
||||
|
||||
yarn add @projectstorm/react-diagrams-core
|
||||
```text
|
||||
yarn add @projectstorm/react-diagrams-core
|
||||
```
|
||||
|
||||
and add some extras:
|
||||
this is built ontop of the evolving **react-canvas-core** library
|
||||
|
||||
```text
|
||||
yarn add @projectstorm/react-canvas-core
|
||||
```
|
||||
|
||||
which makes use of
|
||||
|
||||
```text
|
||||
yarn add @projectstorm/geometry
|
||||
```
|
||||
|
||||
and of course, you can add some extras:
|
||||
|
||||
```text
|
||||
yarn add @projectstorm/react-diagrams-defaults
|
||||
yarn add @projectstorm/react-diagrams-routing
|
||||
```
|
||||
|
||||
yarn add @projectstorm/react-diagrams-defaults
|
||||
yarn add @projectstorm/react-diagrams-routing
|
||||
|
||||
## How to use
|
||||
|
||||
Take a look at the demos [lib-demo-gallery/demos](https://github.com/projectstorm/react-diagrams/tree/lerna/lib-demo-gallery/demos)
|
||||
Before running any of the examples, please run `pnpm build` in the root. This project is a monorepo, and the packages (including the demos) require the packages to first be built.
|
||||
|
||||
__or__
|
||||
|
||||
Take a look at the demo project: [lib-demo-project](https://github.com/projectstorm/react-diagrams/tree/lerna/lib-demo-project)
|
||||
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/diagrams-demo-project) which contains an example for ES6 as well as Typescript
|
||||
|
||||
**or**
|
||||
|
||||
[Checkout the docs](https://projectstorm.gitbook.io/react-diagrams/)
|
||||
|
||||
## Run the demos
|
||||
|
||||
After running `yarn install` you must then run: `yarn run storybook`
|
||||
After running `pnpm install` and `pnpm build`, you must then run: `cd diagrams-demo-gallery && pnpm run start`
|
||||
|
||||
## Building from source
|
||||
|
||||
Simply run `yarn build` in the root directory \(or `NODE_ENV=production yarn build` if you want a production build\) and it will spit out the transpiled code and typescript definitions into the dist directory as a single file.
|
||||
We use webpack for this because TSC cannot compile a single UMD file \(TSC can currently only output multiple UMD files\).
|
||||
|
||||
## [Checkout the docs](https://projectstorm.gitbooks.io/react-diagrams)
|
||||
|
||||
Simply run `pnpm` then `pnpm build` or `pnpm build:prod` in the root directory and it will spit out the transpiled code and typescript definitions into the dist directory as a single file.
|
||||
|
||||
## Built with react-diagrams
|
||||
|
||||
> Do you have an interesting project built with *react-diagrams*? PR it into this section for others to see.
|
||||
|
||||
11
SUMMARY.md
@@ -1,11 +0,0 @@
|
||||
# Summary
|
||||
|
||||
* [Introduction](README.md)
|
||||
* [Interacting with diagrams](/docs/Interactive Usage.md)
|
||||
* [Getting Started](/docs/Getting Started.md)
|
||||
* [About the project](about-the-project.md)
|
||||
* [Testing](/docs/Testing.md)
|
||||
* [Architecture Questions](/docs/Architecture Questions.md)
|
||||
|
||||
|
||||
|
||||
18
diagrams-demo-gallery/.babelrc.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"sourceType": "unambiguous",
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"chrome": 100,
|
||||
"safari": 15,
|
||||
"firefox": 91
|
||||
}
|
||||
}
|
||||
],
|
||||
"@babel/preset-react",
|
||||
"@babel/preset-typescript"
|
||||
],
|
||||
"plugins": []
|
||||
}
|
||||
8
diagrams-demo-gallery/.storybook/main.js
Normal file
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
stories: ['../demos/*.stories.tsx'],
|
||||
addons: ['@storybook/addon-actions'],
|
||||
framework: {
|
||||
name: '@storybook/react-webpack5',
|
||||
options: {}
|
||||
}
|
||||
};
|
||||
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
|
||||
});
|
||||
5
diagrams-demo-gallery/.storybook/preview-head.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<style>
|
||||
html, body, #storybook-root {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
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
@@ -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'
|
||||
});
|
||||
70
diagrams-demo-gallery/CHANGELOG.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# @projectstorm/react-diagrams-gallery
|
||||
|
||||
## 7.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 66c687a: Upgrade all dependencies and fix Storybook after upgrade
|
||||
- Updated dependencies [66c687a]
|
||||
- @projectstorm/react-diagrams-defaults@7.1.2
|
||||
- @projectstorm/react-diagrams-core@7.0.2
|
||||
- @projectstorm/react-canvas-core@7.0.2
|
||||
- @projectstorm/react-diagrams@7.0.3
|
||||
|
||||
## 7.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b8a4cbd: Inline sources in sourcemap
|
||||
- Updated dependencies [b8a4cbd]
|
||||
- @projectstorm/react-canvas-core@7.0.1
|
||||
- @projectstorm/react-diagrams@7.0.2
|
||||
- @projectstorm/react-diagrams-core@7.0.1
|
||||
- @projectstorm/react-diagrams-defaults@7.1.1
|
||||
|
||||
## 7.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- e0d21f1: - [feature] new ability to refresh links in auto distribute system [PR 756](https://github.com/projectstorm/react-diagrams/pull/756)
|
||||
|
||||
- [fix] Default link now uses the correct method for creating a point allowing this to be overridden [PR 939](https://github.com/projectstorm/react-diagrams/pull/939)
|
||||
|
||||
Big thanks to @ToTheHit and @h0111in for your help on these, even though its very delayed on my part :)
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e0d21f1]
|
||||
- @projectstorm/react-diagrams-defaults@7.1.0
|
||||
- @projectstorm/react-diagrams@7.0.1
|
||||
|
||||
## 7.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- b051697: - [internal] moves to `Pnpm` (instead of yarn -\_-)
|
||||
- [internal]moves to `Changesets` for releases
|
||||
- [internal]removes `Lerna`
|
||||
- [internal] upgrades all dependencies
|
||||
- [internal] switches to workspace protocol syntax (Changesets will bake in the correct version when a publish occurs)
|
||||
- [internal] Changesets will open a release PR which can wrap up several changes in 1 go
|
||||
- [internal] Changesets will run the storybook deploy automatically upon merging the release PR
|
||||
- [internal] removes a lot of the stuff from the root package.json
|
||||
- [internal] cleans up the build and clean commands
|
||||
- [internal] remove E2E tests, they are a nightmare to maintain and the ROI is far too low
|
||||
- [fix] Wrong type name for react-canvas model listener
|
||||
- [fix] export more stuff form the main react-diagrams package
|
||||
- [fix] circular deps with Rectangle and Polygon (turns out this was a problem but only with UMD builds, sorry @everyone who I doubted, but this is also why I could never reproduce the issue)
|
||||
- [breaking change] compile both ES6 and UMD
|
||||
- [breaking change] moves dependencies back to each package. (After years of working on libraries, I've come to actually hate peer dependencies, and this is easily solved with build systems / package managers).
|
||||
- [breaking change] static methods on `Polygon` and `Rectangle` moved to standalone methods
|
||||
- [breaking change] static construction methods to rather deal with different Rectangle constructor overloads (I now consider this bad design)
|
||||
- [breaking change] introduce `Bounds` as a simpler point-array type to deal with boundary computation instead
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b051697]
|
||||
- @projectstorm/react-diagrams-defaults@7.0.0
|
||||
- @projectstorm/react-diagrams-core@7.0.0
|
||||
- @projectstorm/react-canvas-core@7.0.0
|
||||
- @projectstorm/react-diagrams@7.0.0
|
||||
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
@@ -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
@@ -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
@@ -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;
|
||||
@@ -0,0 +1,89 @@
|
||||
import { Action, ActionEvent, InputType, State } from '@projectstorm/react-canvas-core';
|
||||
import { PortModel, LinkModel, DiagramEngine } from '@projectstorm/react-diagrams-core';
|
||||
import { MouseEvent, KeyboardEvent } from 'react';
|
||||
|
||||
/**
|
||||
* This state is controlling the creation of a link.
|
||||
*/
|
||||
export class CreateLinkState extends State<DiagramEngine> {
|
||||
sourcePort: PortModel;
|
||||
link: LinkModel;
|
||||
|
||||
constructor() {
|
||||
super({ name: 'create-new-link' });
|
||||
|
||||
this.registerAction(
|
||||
new Action({
|
||||
type: InputType.MOUSE_UP,
|
||||
fire: (actionEvent: ActionEvent<MouseEvent>) => {
|
||||
const element = this.engine.getActionEventBus().getModelForEvent(actionEvent);
|
||||
const {
|
||||
event: { clientX, clientY }
|
||||
} = actionEvent;
|
||||
const ox = this.engine.getModel().getOffsetX();
|
||||
const oy = this.engine.getModel().getOffsetY();
|
||||
|
||||
if (element instanceof PortModel && !this.sourcePort) {
|
||||
this.sourcePort = element;
|
||||
|
||||
/* would be cool if link creating could be done somewhat like
|
||||
const link = createLink({
|
||||
sourcePort: this.sourcePort,
|
||||
points: [{ x: clientX, y: clientY }, { x: clientX, y: clientY }]
|
||||
})
|
||||
*/
|
||||
const link = this.sourcePort.createLinkModel();
|
||||
link.setSourcePort(this.sourcePort);
|
||||
link.getFirstPoint().setPosition(clientX - ox, clientY - oy);
|
||||
link.getLastPoint().setPosition(clientX - ox + 20, clientY - oy + 20);
|
||||
|
||||
this.link = this.engine.getModel().addLink(link);
|
||||
} else if (element instanceof PortModel && this.sourcePort && element != this.sourcePort) {
|
||||
if (this.sourcePort.canLinkToPort(element)) {
|
||||
this.link.setTargetPort(element);
|
||||
element.reportPosition();
|
||||
this.clearState();
|
||||
this.eject();
|
||||
}
|
||||
} else if (element === this.link.getLastPoint()) {
|
||||
this.link.point(clientX - ox, clientY - oy, -1);
|
||||
}
|
||||
|
||||
this.engine.repaintCanvas();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this.registerAction(
|
||||
new Action({
|
||||
type: InputType.MOUSE_MOVE,
|
||||
fire: (actionEvent: ActionEvent<React.MouseEvent>) => {
|
||||
if (!this.link) return;
|
||||
const { event } = actionEvent;
|
||||
this.link.getLastPoint().setPosition(event.clientX, event.clientY);
|
||||
this.engine.repaintCanvas();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this.registerAction(
|
||||
new Action({
|
||||
type: InputType.KEY_UP,
|
||||
fire: (actionEvent: ActionEvent<KeyboardEvent>) => {
|
||||
// on esc press remove any started link and pop back to default state
|
||||
if (actionEvent.event.keyCode === 27) {
|
||||
this.link.remove();
|
||||
this.clearState();
|
||||
this.eject();
|
||||
this.engine.repaintCanvas();
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
clearState() {
|
||||
this.link = undefined;
|
||||
this.sourcePort = undefined;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import { MouseEvent, TouchEvent } from 'react';
|
||||
import {
|
||||
SelectingState,
|
||||
State,
|
||||
Action,
|
||||
InputType,
|
||||
ActionEvent,
|
||||
DragCanvasState
|
||||
} from '@projectstorm/react-canvas-core';
|
||||
import { PortModel, DiagramEngine, DragDiagramItemsState } from '@projectstorm/react-diagrams-core';
|
||||
import { CreateLinkState } from './CreateLinkState';
|
||||
|
||||
export class DefaultState extends State<DiagramEngine> {
|
||||
dragCanvas: DragCanvasState;
|
||||
createLink: CreateLinkState;
|
||||
dragItems: DragDiagramItemsState;
|
||||
|
||||
constructor() {
|
||||
super({ name: 'starting-state' });
|
||||
this.childStates = [new SelectingState()];
|
||||
this.dragCanvas = new DragCanvasState();
|
||||
this.createLink = new CreateLinkState();
|
||||
this.dragItems = new DragDiagramItemsState();
|
||||
|
||||
// determine what was clicked on
|
||||
this.registerAction(
|
||||
new Action({
|
||||
type: InputType.MOUSE_DOWN,
|
||||
fire: (event: ActionEvent<MouseEvent>) => {
|
||||
const element = this.engine.getActionEventBus().getModelForEvent(event);
|
||||
|
||||
// the canvas was clicked on, transition to the dragging canvas state
|
||||
if (!element) {
|
||||
this.transitionWithEvent(this.dragCanvas, event);
|
||||
}
|
||||
// initiate dragging a new link
|
||||
else if (element instanceof PortModel) {
|
||||
return;
|
||||
}
|
||||
// move the items (and potentially link points)
|
||||
else {
|
||||
this.transitionWithEvent(this.dragItems, event);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// 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,
|
||||
fire: (event: ActionEvent<MouseEvent>) => {
|
||||
const element = this.engine.getActionEventBus().getModelForEvent(event);
|
||||
|
||||
if (element instanceof PortModel) this.transitionWithEvent(this.createLink, event);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import * as React from 'react';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
import { DefaultState } from './DefaultState';
|
||||
|
||||
export default () => {
|
||||
const engine = createEngine();
|
||||
const model = new DiagramModel();
|
||||
|
||||
const node1 = new DefaultNodeModel('Node 1', 'rgb(0,192,255)');
|
||||
node1.addOutPort('Out');
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
const node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
node2.addInPort('In');
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
model.addAll(node1, node2);
|
||||
|
||||
engine.setModel(model);
|
||||
|
||||
// Use this custom "DefaultState" instead of the actual default state we get with the engine
|
||||
engine.getStateMachine().pushState(new DefaultState());
|
||||
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
86
diagrams-demo-gallery/demos/demo-animation/index.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import gsap from 'gsap';
|
||||
import { DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
* Tests the grid size
|
||||
*/
|
||||
class NodeDelayedPosition extends React.Component<any, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { engine } = this.props;
|
||||
return (
|
||||
<DemoWorkspaceWidget>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = createEngine({ repaintDebounceMs: 12 });
|
||||
|
||||
//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) create another default node
|
||||
var node3 = new DefaultNodeModel('Node 3', 'rgb(192,255,0)');
|
||||
node2.setPosition(200, 300);
|
||||
|
||||
//3-D) create another default node
|
||||
var node4 = new DefaultNodeModel('Node 4', 'rgb(192,255,0)');
|
||||
node2.setPosition(400, 400);
|
||||
|
||||
//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, node3, node4);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setModel(model);
|
||||
|
||||
var interval = setInterval(() => {
|
||||
[node1, node2, node3, node4].map((node) => {
|
||||
var obj = { x: 0, y: 0 };
|
||||
gsap.fromTo(
|
||||
obj,
|
||||
{
|
||||
x: node.getPosition().x,
|
||||
y: node.getPosition().y
|
||||
},
|
||||
{
|
||||
x: Math.floor(Math.random() * 500),
|
||||
y: Math.floor(Math.random() * 500),
|
||||
duration: 0.8,
|
||||
onUpdate: () => {
|
||||
node.setPosition(obj.x, obj.y);
|
||||
engine.repaintCanvas();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}, 2000);
|
||||
|
||||
//6) render the diagram!
|
||||
return <NodeDelayedPosition engine={engine} model={model} />;
|
||||
};
|
||||
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} />;
|
||||
};
|
||||
@@ -1,14 +1,9 @@
|
||||
import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
NodeModel,
|
||||
DiagramWidget,
|
||||
BaseModel
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, LinkModel, NodeModel } from '@projectstorm/react-diagrams';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import { DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { BaseModel, CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
* Tests cloning
|
||||
@@ -22,10 +17,10 @@ class CloneSelected extends React.Component<any, any> {
|
||||
cloneSelected() {
|
||||
let { engine } = this.props;
|
||||
let offset = { x: 100, y: 100 };
|
||||
let model = engine.getDiagramModel();
|
||||
let model = engine.getModel();
|
||||
|
||||
let itemMap = {};
|
||||
_.forEach(model.getSelectedItems(), (item: BaseModel<any>) => {
|
||||
_.forEach(model.getSelectedEntities(), (item: BaseModel<any>) => {
|
||||
let newItem = item.clone(itemMap);
|
||||
|
||||
// offset the nodes slightly
|
||||
@@ -34,12 +29,12 @@ 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);
|
||||
}
|
||||
newItem.selected = false;
|
||||
(newItem as BaseModel).setSelected(false);
|
||||
});
|
||||
|
||||
this.forceUpdate();
|
||||
@@ -48,8 +43,10 @@ class CloneSelected extends React.Component<any, any> {
|
||||
render() {
|
||||
const { engine } = this.props;
|
||||
return (
|
||||
<DemoWorkspaceWidget buttons={<button onClick={this.cloneSelected}>Clone Selected</button>}>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
|
||||
<DemoWorkspaceWidget buttons={<DemoButton onClick={this.cloneSelected}>Clone Selected</DemoButton>}>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
}
|
||||
@@ -79,7 +76,7 @@ export default () => {
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <CloneSelected engine={engine} model={model} />;
|
||||
73
diagrams-demo-gallery/demos/demo-custom-action/index.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
import * as React from 'react';
|
||||
import * as _ from 'lodash';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DefaultLinkModel } from '@projectstorm/react-diagrams';
|
||||
import { CanvasWidget, Action, ActionEvent, InputType } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
interface CustomDeleteItemsActionOptions {
|
||||
keyCodes?: number[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all selected items, but asks for confirmation first
|
||||
*/
|
||||
class CustomDeleteItemsAction extends Action {
|
||||
constructor(options: CustomDeleteItemsActionOptions = {}) {
|
||||
options = {
|
||||
keyCodes: [46, 8],
|
||||
...options
|
||||
};
|
||||
super({
|
||||
type: InputType.KEY_DOWN,
|
||||
fire: (event: ActionEvent<React.KeyboardEvent>) => {
|
||||
if (options.keyCodes.indexOf(event.event.keyCode) !== -1) {
|
||||
const selectedEntities = this.engine.getModel().getSelectedEntities();
|
||||
if (selectedEntities.length > 0) {
|
||||
const confirm = window.confirm('Are you sure you want to delete?');
|
||||
|
||||
if (confirm) {
|
||||
_.forEach(selectedEntities, (model) => {
|
||||
// only delete items which are not locked
|
||||
if (!model.isLocked()) {
|
||||
model.remove();
|
||||
}
|
||||
});
|
||||
this.engine.repaintCanvas();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default () => {
|
||||
// create an engine without registering DeleteItemsAction
|
||||
const engine = createEngine({ registerDefaultDeleteItemsAction: false });
|
||||
const model = new DiagramModel();
|
||||
|
||||
const node1 = new DefaultNodeModel({ name: 'Node 1', color: 'rgb(0,192,255)' });
|
||||
node1.setPosition(100, 100);
|
||||
const port1 = node1.addOutPort('Out');
|
||||
|
||||
const node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
const port2 = node2.addInPort('In');
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
const link1 = port1.link<DefaultLinkModel>(port2);
|
||||
link1.getOptions().testName = 'Test';
|
||||
link1.addLabel('Hello World!');
|
||||
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
engine.setModel(model);
|
||||
|
||||
// register an DeleteItemsAction with custom keyCodes (in this case, only Delete key)
|
||||
engine.getActionEventBus().registerAction(new CustomDeleteItemsAction());
|
||||
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
@@ -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
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -2,13 +2,12 @@ import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
DefaultPortModel,
|
||||
DiagramWidget,
|
||||
DefaultLinkWidget,
|
||||
DefaultLinkFactory,
|
||||
LinkModel,
|
||||
DefaultLinkModel
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
export class AdvancedLinkModel extends DefaultLinkModel {
|
||||
constructor() {
|
||||
@@ -70,7 +69,8 @@ export class AdvancedLinkSegment extends React.Component<{ model: AdvancedLinkMo
|
||||
return (
|
||||
<>
|
||||
<path
|
||||
ref={ref => {
|
||||
fill="none"
|
||||
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}
|
||||
@@ -91,15 +91,14 @@ export class AdvancedLinkSegment extends React.Component<{ model: AdvancedLinkMo
|
||||
|
||||
export class AdvancedLinkFactory extends DefaultLinkFactory {
|
||||
constructor() {
|
||||
super();
|
||||
this.type = 'advanced';
|
||||
super('advanced');
|
||||
}
|
||||
|
||||
generateModel(): AdvancedLinkModel {
|
||||
return new AdvancedLinkModel();
|
||||
}
|
||||
|
||||
generateLinkSegment(model: AdvancedLinkModel, widget: DefaultLinkWidget, selected: boolean, path: string) {
|
||||
generateLinkSegment(model: AdvancedLinkModel, selected: boolean, path: string) {
|
||||
return (
|
||||
<g>
|
||||
<AdvancedLinkSegment model={model} path={path} />
|
||||
@@ -147,8 +146,12 @@ export default () => {
|
||||
model.addAll(node1, node2, node3, node4);
|
||||
|
||||
// load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
// render the diagram!
|
||||
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
168
diagrams-demo-gallery/demos/demo-custom-link2/index.tsx
Normal file
@@ -0,0 +1,168 @@
|
||||
import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
DefaultPortModel,
|
||||
DefaultLinkFactory,
|
||||
DefaultLinkModel,
|
||||
DefaultLinkWidget
|
||||
} from '@projectstorm/react-diagrams';
|
||||
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() {
|
||||
super({
|
||||
type: 'advanced',
|
||||
width: 4
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class AdvancedPortModel extends DefaultPortModel {
|
||||
createLinkModel(): AdvancedLinkModel | null {
|
||||
return new AdvancedLinkModel();
|
||||
}
|
||||
}
|
||||
|
||||
const CustomLinkArrowWidget = (props) => {
|
||||
const { point, previousPoint } = props;
|
||||
|
||||
const angle =
|
||||
90 +
|
||||
(Math.atan2(
|
||||
point.getPosition().y - previousPoint.getPosition().y,
|
||||
point.getPosition().x - previousPoint.getPosition().x
|
||||
) *
|
||||
180) /
|
||||
Math.PI;
|
||||
|
||||
//translate(50, -10),
|
||||
return (
|
||||
<g className="arrow" transform={'translate(' + point.getPosition().x + ', ' + point.getPosition().y + ')'}>
|
||||
<g style={{ transform: 'rotate(' + angle + 'deg)' }}>
|
||||
<g transform={'translate(0, -3)'}>
|
||||
<polygon
|
||||
points="0,10 8,30 -8,30"
|
||||
fill={props.color}
|
||||
data-id={point.getID()}
|
||||
data-linkid={point.getLink().getID()}
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
);
|
||||
};
|
||||
|
||||
export class AdvancedLinkWidget extends DefaultLinkWidget {
|
||||
generateArrow(point: PointModel, previousPoint: PointModel): JSX.Element {
|
||||
return (
|
||||
<CustomLinkArrowWidget
|
||||
key={point.getID()}
|
||||
point={point as any}
|
||||
previousPoint={previousPoint as any}
|
||||
colorSelected={this.props.link.getOptions().selectedColor}
|
||||
color={this.props.link.getOptions().color}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
//ensure id is present for all points on the path
|
||||
var points = this.props.link.getPoints();
|
||||
var paths = [];
|
||||
this.refPaths = [];
|
||||
|
||||
//draw the multiple anchors and complex line instead
|
||||
for (let j = 0; j < points.length - 1; j++) {
|
||||
paths.push(
|
||||
this.generateLink(
|
||||
LinkWidget.generateLinePath(points[j], points[j + 1]),
|
||||
{
|
||||
'data-linkid': this.props.link.getID(),
|
||||
'data-point': j,
|
||||
onMouseDown: (event: MouseEvent) => {
|
||||
this.addPointToLink(event, j + 1);
|
||||
}
|
||||
},
|
||||
j
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//render the circles
|
||||
for (let i = 1; i < points.length - 1; i++) {
|
||||
paths.push(this.generatePoint(points[i]));
|
||||
}
|
||||
|
||||
if (this.props.link.getTargetPort() !== null) {
|
||||
paths.push(this.generateArrow(points[points.length - 1], points[points.length - 2]));
|
||||
} else {
|
||||
paths.push(this.generatePoint(points[points.length - 1]));
|
||||
}
|
||||
|
||||
return <g data-default-link-test={this.props.link.getOptions().testName}>{paths}</g>;
|
||||
}
|
||||
}
|
||||
|
||||
export class AdvancedLinkFactory extends DefaultLinkFactory {
|
||||
constructor() {
|
||||
super('advanced');
|
||||
}
|
||||
|
||||
generateModel(): AdvancedLinkModel {
|
||||
return new AdvancedLinkModel();
|
||||
}
|
||||
|
||||
generateReactWidget(event): JSX.Element {
|
||||
return <AdvancedLinkWidget link={event.model} diagramEngine={this.engine} />;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Simple link styling demo
|
||||
*
|
||||
* @Author kfrajtak
|
||||
*/
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = createEngine();
|
||||
engine.getLinkFactories().registerFactory(new AdvancedLinkFactory());
|
||||
|
||||
// create some nodes
|
||||
var node1 = new DefaultNodeModel('Source', 'rgb(0,192,255)');
|
||||
let port1 = node1.addPort(new AdvancedPortModel(false, 'out'));
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
var node2 = new DefaultNodeModel('Target', 'rgb(192,255,0)');
|
||||
var port2 = node2.addPort(new AdvancedPortModel(true, 'in'));
|
||||
node2.setPosition(500, 350);
|
||||
|
||||
var node3 = new DefaultNodeModel('Source', 'rgb(0,192,255)');
|
||||
let port3 = node3.addPort(new AdvancedPortModel(false, 'out'));
|
||||
node3.setPosition(100, 500);
|
||||
|
||||
var node4 = new DefaultNodeModel('Target', 'rgb(192,255,0)');
|
||||
var port4 = node4.addPort(new AdvancedPortModel(true, 'in'));
|
||||
node4.setPosition(500, 450);
|
||||
|
||||
var model = new DiagramModel();
|
||||
|
||||
model.addAll(port1.link(port2), port3.link(port4));
|
||||
|
||||
// add everything else
|
||||
model.addAll(node1, node2, node3, node4);
|
||||
|
||||
// load model into engine
|
||||
engine.setModel(model);
|
||||
|
||||
// render the diagram!
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
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 {
|
||||
return <DiamondNodeWidget engine={this.engine} size={50} node={event.model} />;
|
||||
}
|
||||
|
||||
generateModel(event) {
|
||||
return new DiamondNodeModel();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
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: 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);
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Dylan Vorster
|
||||
*/
|
||||
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>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { DiagramEngine, PortModel } from '@projectstorm/react-diagrams';
|
||||
import { AbstractModelFactory } from '@projectstorm/react-canvas-core';
|
||||
|
||||
export class SimplePortFactory extends AbstractModelFactory<PortModel, DiagramEngine> {
|
||||
cb: (initialConfig?: any) => PortModel;
|
||||
|
||||
constructor(type: string, cb: (initialConfig?: any) => PortModel) {
|
||||
super(type);
|
||||
this.cb = cb;
|
||||
}
|
||||
|
||||
generateModel(event): PortModel {
|
||||
return this.cb(event.initialConfig);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,12 @@
|
||||
import createEngine, {
|
||||
DefaultNodeModel,
|
||||
DiagramModel,
|
||||
DiagramWidget,
|
||||
PortModelAlignment
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DefaultNodeModel, DiagramModel, PortModelAlignment } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
// import the custom models
|
||||
import { DiamondNodeModel } from './DiamondNodeModel';
|
||||
import { DiamondNodeFactory } from './DiamondNodeFactory';
|
||||
import { SimplePortFactory } from './SimplePortFactory';
|
||||
import { DiamondPortModel } from './DiamondPortModel';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
* @Author Dylan Vorster
|
||||
@@ -21,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
|
||||
@@ -60,8 +57,12 @@ export default () => {
|
||||
model.addAll(node1, node2, node3, link1, link2, node4, link3, link4, node5);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
import * as React from 'react';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DefaultLinkModel } from '@projectstorm/react-diagrams';
|
||||
import { CanvasWidget, DeleteItemsAction } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
export default () => {
|
||||
// create an engine without registering DeleteItemsAction
|
||||
const engine = createEngine({ registerDefaultDeleteItemsAction: false });
|
||||
const model = new DiagramModel();
|
||||
|
||||
const node1 = new DefaultNodeModel({ name: 'Node 1', color: 'rgb(0,192,255)' });
|
||||
node1.setPosition(100, 100);
|
||||
const port1 = node1.addOutPort('Out');
|
||||
|
||||
const node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
const port2 = node2.addInPort('In');
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
const link1 = port1.link<DefaultLinkModel>(port2);
|
||||
link1.getOptions().testName = 'Test';
|
||||
link1.addLabel('Hello World!');
|
||||
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
engine.setModel(model);
|
||||
|
||||
// register an DeleteItemsAction with custom keyCodes (in this case, only Delete key)
|
||||
engine.getActionEventBus().registerAction(new DeleteItemsAction({ keyCodes: [46] }));
|
||||
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
@@ -2,14 +2,15 @@ import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
DefaultPortModel,
|
||||
DiagramWidget,
|
||||
NodeModel,
|
||||
DagreEngine,
|
||||
DiagramEngine,
|
||||
PathFindingLinkFactory
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
function createNode(name): any {
|
||||
return new DefaultNodeModel(name, 'rgb(0,192,255)');
|
||||
@@ -32,7 +33,7 @@ function connectNodes(nodeFrom, nodeTo, engine: DiagramEngine) {
|
||||
/**
|
||||
* Tests auto distribution
|
||||
*/
|
||||
class Demo8Widget extends React.Component<{ model: DiagramModel; engine: DiagramEngine }, any> {
|
||||
class DemoWidget extends React.Component<{ model: DiagramModel; engine: DiagramEngine }, any> {
|
||||
engine: DagreEngine;
|
||||
|
||||
constructor(props) {
|
||||
@@ -40,9 +41,12 @@ class Demo8Widget extends React.Component<{ model: DiagramModel; engine: Diagram
|
||||
this.engine = new DagreEngine({
|
||||
graph: {
|
||||
rankdir: 'RL',
|
||||
ranker: 'longest-path'
|
||||
ranker: 'longest-path',
|
||||
marginx: 25,
|
||||
marginy: 25
|
||||
},
|
||||
includeLinks: true
|
||||
includeLinks: true,
|
||||
nodeMargin: 25
|
||||
});
|
||||
}
|
||||
|
||||
@@ -54,6 +58,13 @@ class Demo8Widget extends React.Component<{ model: DiagramModel; engine: Diagram
|
||||
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();
|
||||
@@ -69,15 +80,17 @@ class Demo8Widget extends React.Component<{ model: DiagramModel; engine: Diagram
|
||||
|
||||
render() {
|
||||
return (
|
||||
<DemoWorkspaceWidget buttons={<button onClick={this.autoDistribute}>Re-distribute</button>}>
|
||||
<DiagramWidget
|
||||
className="srd-demo-canvas"
|
||||
diagramEngine={this.props.engine}
|
||||
actionStoppedFiring={() => {
|
||||
// only happens if pathfing is enabled (check line 25)
|
||||
this.reroute();
|
||||
}}
|
||||
/>
|
||||
<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>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
}
|
||||
@@ -108,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) => {
|
||||
@@ -123,11 +138,11 @@ export default () => {
|
||||
model.addNode(node);
|
||||
});
|
||||
|
||||
links.forEach(link => {
|
||||
links.forEach((link) => {
|
||||
model.addLink(link);
|
||||
});
|
||||
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
return <Demo8Widget model={model} engine={engine} />;
|
||||
return <DemoWidget model={model} engine={engine} />;
|
||||
};
|
||||
@@ -14,7 +14,7 @@ export class Application {
|
||||
|
||||
public newModel() {
|
||||
this.activeModel = new SRD.DiagramModel();
|
||||
this.diagramEngine.setDiagramModel(this.activeModel);
|
||||
this.diagramEngine.setModel(this.activeModel);
|
||||
|
||||
//3-A) create a default node
|
||||
var node1 = new SRD.DefaultNodeModel('Node 1', 'rgb(0,192,255)');
|
||||
@@ -0,0 +1,87 @@
|
||||
import * as React from 'react';
|
||||
import * as _ from 'lodash';
|
||||
import { TrayWidget } from './TrayWidget';
|
||||
import { Application } from '../Application';
|
||||
import { TrayItemWidget } from './TrayItemWidget';
|
||||
import { DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../../helpers/DemoCanvasWidget';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
export interface BodyWidgetProps {
|
||||
app: Application;
|
||||
}
|
||||
|
||||
namespace S {
|
||||
export const Body = styled.div`
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100%;
|
||||
`;
|
||||
|
||||
export const Header = styled.div`
|
||||
display: flex;
|
||||
background: rgb(30, 30, 30);
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
color: white;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
padding: 10px;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
export const Content = styled.div`
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
`;
|
||||
|
||||
export const Layer = styled.div`
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
`;
|
||||
}
|
||||
|
||||
export class BodyWidget extends React.Component<BodyWidgetProps> {
|
||||
render() {
|
||||
return (
|
||||
<S.Body>
|
||||
<S.Header>
|
||||
<div className="title">Storm React Diagrams - DnD demo</div>
|
||||
</S.Header>
|
||||
<S.Content>
|
||||
<TrayWidget>
|
||||
<TrayItemWidget model={{ type: 'in' }} name="In Node" color="rgb(192,255,0)" />
|
||||
<TrayItemWidget model={{ type: 'out' }} name="Out Node" color="rgb(0,192,255)" />
|
||||
</TrayWidget>
|
||||
<S.Layer
|
||||
onDrop={(event) => {
|
||||
var data = JSON.parse(event.dataTransfer.getData('storm-diagram-node'));
|
||||
var nodesCount = _.keys(this.props.app.getDiagramEngine().getModel().getNodes()).length;
|
||||
|
||||
var node: DefaultNodeModel = null;
|
||||
if (data.type === 'in') {
|
||||
node = new DefaultNodeModel('Node ' + (nodesCount + 1), 'rgb(192,255,0)');
|
||||
node.addInPort('In');
|
||||
} else {
|
||||
node = new DefaultNodeModel('Node ' + (nodesCount + 1), 'rgb(0,192,255)');
|
||||
node.addOutPort('Out');
|
||||
}
|
||||
var point = this.props.app.getDiagramEngine().getRelativeMousePoint(event);
|
||||
node.setPosition(point);
|
||||
this.props.app.getDiagramEngine().getModel().addNode(node);
|
||||
this.forceUpdate();
|
||||
}}
|
||||
onDragOver={(event) => {
|
||||
event.preventDefault();
|
||||
}}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={this.props.app.getDiagramEngine()} />
|
||||
</DemoCanvasWidget>
|
||||
</S.Layer>
|
||||
</S.Content>
|
||||
</S.Body>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import * as React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
export interface TrayItemWidgetProps {
|
||||
model: any;
|
||||
color?: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
namespace S {
|
||||
export const Tray = styled.div<{ color: string }>`
|
||||
color: white;
|
||||
font-family: Helvetica, Arial;
|
||||
padding: 5px;
|
||||
margin: 0px 10px;
|
||||
border: solid 1px ${(p) => p.color};
|
||||
border-radius: 5px;
|
||||
margin-bottom: 2px;
|
||||
cursor: pointer;
|
||||
`;
|
||||
}
|
||||
|
||||
export class TrayItemWidget extends React.Component<TrayItemWidgetProps> {
|
||||
render() {
|
||||
return (
|
||||
<S.Tray
|
||||
color={this.props.color}
|
||||
draggable={true}
|
||||
onDragStart={(event) => {
|
||||
event.dataTransfer.setData('storm-diagram-node', JSON.stringify(this.props.model));
|
||||
}}
|
||||
className="tray-item"
|
||||
>
|
||||
{this.props.name}
|
||||
</S.Tray>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import * as React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
namespace S {
|
||||
export const Tray = styled.div`
|
||||
min-width: 200px;
|
||||
background: rgb(20, 20, 20);
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
}
|
||||
|
||||
export class TrayWidget extends React.Component {
|
||||
render() {
|
||||
return <S.Tray>{this.props.children}</S.Tray>;
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,7 @@ import * as React from 'react';
|
||||
import { BodyWidget } from './components/BodyWidget';
|
||||
import { Application } from './Application';
|
||||
|
||||
import './sass/main.scss';
|
||||
|
||||
export default () => {
|
||||
var app = new Application();
|
||||
|
||||
return <BodyWidget app={app} />;
|
||||
};
|
||||
@@ -1,12 +1,9 @@
|
||||
import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
DiagramWidget,
|
||||
DiagramEngine
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DiagramEngine } from '@projectstorm/react-diagrams';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import { DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
class CloneSelected extends React.Component<{ model: DiagramModel; engine: DiagramEngine }, any> {
|
||||
addPorts = () => {
|
||||
@@ -24,8 +21,10 @@ class CloneSelected extends React.Component<{ model: DiagramModel; engine: Diagr
|
||||
render() {
|
||||
const { engine } = this.props;
|
||||
return (
|
||||
<DemoWorkspaceWidget buttons={<button onClick={this.addPorts}>Add more ports</button>}>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
|
||||
<DemoWorkspaceWidget buttons={<DemoButton onClick={this.addPorts}>Add more ports</DemoButton>}>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
}
|
||||
@@ -52,7 +51,7 @@ export default () => {
|
||||
model.addAll(node1, node2);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <CloneSelected engine={engine} model={model} />;
|
||||
@@ -1,5 +1,7 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DiagramWidget } from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
* Tests the grid size
|
||||
@@ -29,8 +31,12 @@ export default () => {
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
@@ -1,12 +1,9 @@
|
||||
import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
DiagramWidget,
|
||||
DefaultLinkModel
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DefaultLinkModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
export default () => {
|
||||
// setup the diagram engine
|
||||
@@ -48,19 +45,23 @@ export default () => {
|
||||
model.addAll(node1, node2, node3, node4, link1, link2, link3);
|
||||
|
||||
// load model into engine and render
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={
|
||||
<button
|
||||
<DemoButton
|
||||
onClick={() => {
|
||||
action('Serialized Graph')(JSON.stringify(model.serializeDiagram(), null, 2));
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Serialize Graph
|
||||
</button>
|
||||
}>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
|
||||
</DemoButton>
|
||||
}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
};
|
||||
@@ -1,11 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import createEngine, {
|
||||
DiagramModel,
|
||||
DiagramProps,
|
||||
DefaultNodeModel,
|
||||
DiagramWidget
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
* Shows some of the events triggered when elements are selected
|
||||
@@ -37,23 +34,21 @@ 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({
|
||||
selectionChanged: action('selectionChanged')
|
||||
eventDidFire: action('element eventDidFire')
|
||||
});
|
||||
});
|
||||
|
||||
engine.setDiagramModel(model);
|
||||
model.registerListener({
|
||||
eventDidFire: action('model eventDidFire')
|
||||
});
|
||||
|
||||
var props = {
|
||||
diagramEngine: engine,
|
||||
maxNumberPointsPerLink: 0 // no extra points so link selection is fired straight away
|
||||
} as DiagramProps;
|
||||
engine.setModel(model);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>Click the diagram elements to inspect some of the possible events.</p>
|
||||
<DiagramWidget className="srd-demo-canvas" {...props} />
|
||||
</div>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
@@ -1,10 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
DiagramWidget,
|
||||
DiagramProps
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -47,19 +44,17 @@ export default () => {
|
||||
|
||||
model.addAll(node3, node4, link2);
|
||||
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
//!========================================= <<<<<<<
|
||||
|
||||
model.setLocked(true);
|
||||
var props = {
|
||||
diagramEngine: engine,
|
||||
allowLooseLinks: false,
|
||||
allowCanvasTranslation: false,
|
||||
allowCanvasZoom: false
|
||||
} as DiagramProps;
|
||||
|
||||
//!========================================= <<<<<<<
|
||||
|
||||
return <DiagramWidget className="srd-demo-canvas" {...props} />;
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,9 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DiagramWidget } from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, NodeModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import * as _ from 'lodash';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
* Tests the grid size
|
||||
@@ -14,25 +17,25 @@ class NodeDelayedPosition extends React.Component<any, any> {
|
||||
|
||||
updatePosition() {
|
||||
const { engine } = this.props;
|
||||
let model = engine.getDiagramModel();
|
||||
let model = engine.getModel();
|
||||
const nodes = model.getNodes();
|
||||
let node = nodes[Object.keys(nodes)[0]];
|
||||
node.setPosition(node.x + 30, node.y + 30);
|
||||
this.forceUpdate();
|
||||
node.setPosition(node.getX() + 30, node.getY() + 30);
|
||||
engine.repaintCanvas();
|
||||
}
|
||||
|
||||
updatePositionViaSerialize() {
|
||||
let { engine } = this.props;
|
||||
let model = engine.getDiagramModel();
|
||||
let str = JSON.stringify(model.serializeDiagram());
|
||||
let model = engine.getModel();
|
||||
let str = JSON.stringify(model.serialize());
|
||||
let model2 = new DiagramModel();
|
||||
let obj = JSON.parse(str);
|
||||
let node = obj.nodes[0];
|
||||
let obj: ReturnType<DiagramModel['serialize']> = JSON.parse(str);
|
||||
let node: ReturnType<NodeModel['serialize']> = _.values(obj.layers[1].models)[0] as any;
|
||||
node.x += 30;
|
||||
node.y += 30;
|
||||
model2.deSerializeDiagram(obj, engine);
|
||||
engine.setDiagramModel(model2);
|
||||
this.forceUpdate();
|
||||
|
||||
model2.deserializeModel(obj, engine);
|
||||
engine.setModel(model2);
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -40,14 +43,17 @@ class NodeDelayedPosition extends React.Component<any, any> {
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={[
|
||||
<button key={1} onClick={this.updatePosition}>
|
||||
<DemoButton key={1} onClick={this.updatePosition}>
|
||||
Update position
|
||||
</button>,
|
||||
<button key={2} onClick={this.updatePositionViaSerialize}>
|
||||
</DemoButton>,
|
||||
<DemoButton key={2} onClick={this.updatePositionViaSerialize}>
|
||||
Update position via serialize
|
||||
</button>
|
||||
]}>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
|
||||
</DemoButton>
|
||||
]}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
}
|
||||
@@ -77,7 +83,7 @@ export default () => {
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <NodeDelayedPosition engine={engine} model={model} />;
|
||||
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} />;
|
||||
};
|
||||
@@ -1,5 +1,7 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DiagramWidget } from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -22,10 +24,14 @@ export default () => {
|
||||
}
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
|
||||
function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) {
|
||||
@@ -0,0 +1,72 @@
|
||||
import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
DefaultPortModel,
|
||||
RightAngleLinkFactory,
|
||||
LinkModel,
|
||||
RightAngleLinkModel
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { AbstractModelFactory, CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
// When new link is created by clicking on port the RightAngleLinkModel needs to be returned.
|
||||
export class RightAnglePortModel extends DefaultPortModel {
|
||||
createLinkModel(factory?: AbstractModelFactory<LinkModel>) {
|
||||
return new RightAngleLinkModel();
|
||||
}
|
||||
}
|
||||
|
||||
export default () => {
|
||||
// setup the diagram engine
|
||||
const engine = createEngine();
|
||||
engine.getLinkFactories().registerFactory(new RightAngleLinkFactory());
|
||||
|
||||
// setup the diagram model
|
||||
const model = new DiagramModel();
|
||||
|
||||
// create four nodes in a way that straight links wouldn't work
|
||||
const node1 = new DefaultNodeModel('Node A', 'rgb(0,192,255)');
|
||||
const port1 = node1.addPort(new RightAnglePortModel(false, 'out-1', 'Out'));
|
||||
node1.setPosition(340, 350);
|
||||
|
||||
const node2 = new DefaultNodeModel('Node B', 'rgb(255,255,0)');
|
||||
const port2 = node2.addPort(new RightAnglePortModel(false, 'out-1', 'Out'));
|
||||
node2.setPosition(240, 80);
|
||||
const node3 = new DefaultNodeModel('Node C', 'rgb(192,255,255)');
|
||||
const port3 = node3.addPort(new RightAnglePortModel(true, 'in-1', 'In'));
|
||||
node3.setPosition(540, 180);
|
||||
const node4 = new DefaultNodeModel('Node D', 'rgb(192,0,255)');
|
||||
const port4 = node4.addPort(new RightAnglePortModel(true, 'in-1', 'In'));
|
||||
node4.setPosition(95, 185);
|
||||
|
||||
// linking things together
|
||||
const link1 = port1.link(port4);
|
||||
const link2 = port2.link(port3);
|
||||
|
||||
// add all to the main model
|
||||
model.addAll(node1, node2, node3, node4, link1, link2);
|
||||
|
||||
// load model into engine and render
|
||||
engine.setModel(model);
|
||||
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={
|
||||
<DemoButton
|
||||
onClick={() => {
|
||||
action('Serialized Graph')(JSON.stringify(model.serialize(), null, 2));
|
||||
}}
|
||||
>
|
||||
Serialize Graph
|
||||
</DemoButton>
|
||||
}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
};
|
||||
@@ -1,8 +1,10 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DiagramWidget } from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DefaultLabelModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import * as beautify from 'json-beautify';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
@@ -23,35 +25,39 @@ 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);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
//!------------- SERIALIZING ------------------
|
||||
|
||||
var str = JSON.stringify(model.serializeDiagram());
|
||||
console.log(model.serializeDiagram());
|
||||
var str = JSON.stringify(model.serialize());
|
||||
|
||||
//!------------- DESERIALIZING ----------------
|
||||
|
||||
var model2 = new DiagramModel();
|
||||
model2.deSerializeDiagram(JSON.parse(str), engine);
|
||||
engine.setDiagramModel(model2);
|
||||
model2.deserializeModel(JSON.parse(str), engine);
|
||||
engine.setModel(model2);
|
||||
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={
|
||||
<button
|
||||
<DemoButton
|
||||
onClick={() => {
|
||||
action('Serialized Graph')(beautify(model2.serializeDiagram(), null, 2, 80));
|
||||
}}>
|
||||
action('Serialized Graph')(beautify(model2.serialize(), null, 2, 80));
|
||||
}}
|
||||
>
|
||||
Serialize Graph
|
||||
</button>
|
||||
}>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
|
||||
</DemoButton>
|
||||
}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
};
|
||||
@@ -1,17 +1,17 @@
|
||||
import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
DiagramWidget,
|
||||
MoveItemsActionFactory
|
||||
} from "@projectstorm/react-diagrams";
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DefaultDiagramState } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = createEngine();
|
||||
|
||||
// ############################################ MAGIC HAPPENS HERE
|
||||
engine.getActionFactories().registerFactory(new MoveItemsActionFactory({allowLooseLinks: false}));
|
||||
const state = engine.getStateMachine().getCurrentState();
|
||||
if (state instanceof DefaultDiagramState) {
|
||||
state.dragNewLink.config.allowLooseLinks = false;
|
||||
}
|
||||
// ############################################ MAGIC HAPPENS HERE
|
||||
|
||||
//2) setup the diagram model
|
||||
@@ -39,8 +39,12 @@ export default () => {
|
||||
model.addAll(node1, node2, node3, link1);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} allowLooseLinks={false} />;
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
@@ -1,10 +1,7 @@
|
||||
import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
DiagramWidget,
|
||||
DefaultLinkModel
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DefaultLinkModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
@@ -14,9 +11,12 @@ export default () => {
|
||||
var model = new DiagramModel();
|
||||
|
||||
//3-A) create a default node
|
||||
var node1 = new DefaultNodeModel('Node 1', 'rgb(0,192,255)');
|
||||
let port1 = node1.addOutPort('Out');
|
||||
var node1 = new DefaultNodeModel({
|
||||
name: 'Node 1',
|
||||
color: 'rgb(0,192,255)'
|
||||
});
|
||||
node1.setPosition(100, 100);
|
||||
let port1 = node1.addOutPort('Out');
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
@@ -24,15 +24,20 @@ export default () => {
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
// link the ports
|
||||
let link1 = port1.link(port2);
|
||||
(link1 as DefaultLinkModel).addLabel('Hello World!');
|
||||
let link1 = port1.link<DefaultLinkModel>(port2);
|
||||
link1.getOptions().testName = 'Test';
|
||||
link1.addLabel('Hello World!');
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
@@ -2,13 +2,14 @@ import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
DefaultPortModel,
|
||||
DiagramWidget,
|
||||
PathFindingLinkFactory,
|
||||
DefaultLabelModel
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
export default () => {
|
||||
// setup the diagram engine
|
||||
@@ -51,25 +52,23 @@ export default () => {
|
||||
model.addAll(node1, node2, node3, node4, node5, link1, link2);
|
||||
|
||||
// load model into engine and render
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={
|
||||
<button
|
||||
<DemoButton
|
||||
onClick={() => {
|
||||
action('Serialized Graph')(JSON.stringify(model.serializeDiagram(), null, 2));
|
||||
}}>
|
||||
action('Serialized Graph')(JSON.stringify(model.serialize(), null, 2));
|
||||
}}
|
||||
>
|
||||
Serialize Graph
|
||||
</button>
|
||||
}>
|
||||
<DiagramWidget
|
||||
actionStoppedFiring={() => {
|
||||
pathfinding.calculateRoutingMatrix();
|
||||
}}
|
||||
className="srd-demo-canvas"
|
||||
diagramEngine={engine}
|
||||
/>
|
||||
</DemoButton>
|
||||
}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
};
|
||||
57
diagrams-demo-gallery/demos/demo-zoom-to-fit-nodes/index.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { DemoWorkspaceWidget, DemoButton } from '../helpers/DemoWorkspaceWidget';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
*
|
||||
* Simple stress test of the system plus zoom to fit function
|
||||
*
|
||||
* @Author Dylan Vorster
|
||||
*/
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = createEngine();
|
||||
|
||||
//2) setup the diagram model
|
||||
var model = new DiagramModel();
|
||||
|
||||
for (var i = 0; i < 8; i++) {
|
||||
for (var j = 0; j < 8; j++) {
|
||||
generateNodes(model, i * 200, j * 100);
|
||||
}
|
||||
}
|
||||
|
||||
//5) load model into engine
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={<DemoButton onClick={() => engine.zoomToFitSelectedNodes(50)}>Zoom to fit</DemoButton>}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
};
|
||||
|
||||
function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) {
|
||||
//3-A) create a default node
|
||||
var node1 = new DefaultNodeModel('Node 1', 'rgb(0,192,255)');
|
||||
var port1 = node1.addOutPort('Out');
|
||||
node1.setPosition(100 + offsetX, 100 + offsetY);
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
var port2 = node2.addInPort('In');
|
||||
node2.setPosition(200 + offsetX, 100 + offsetY);
|
||||
|
||||
//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);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DiagramWidget } from '@projectstorm/react-diagrams';
|
||||
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { DemoWorkspaceWidget, DemoButton } from '../helpers/DemoWorkspaceWidget';
|
||||
import { CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -22,12 +24,14 @@ export default () => {
|
||||
}
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return (
|
||||
<DemoWorkspaceWidget buttons={<button onClick={() => engine.zoomToFit()}>Zoom to fit</button>}>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
|
||||
<DemoWorkspaceWidget buttons={<DemoButton onClick={() => engine.zoomToFit()}>Zoom to fit</DemoButton>}>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
};
|
||||
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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
55
diagrams-demo-gallery/demos/helpers/DemoWorkspaceWidget.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import * as React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
export interface DemoWorkspaceWidgetProps {
|
||||
buttons?: any;
|
||||
}
|
||||
|
||||
namespace S {
|
||||
export const Toolbar = styled.div`
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
export const Content = styled.div`
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
export const Container = styled.div`
|
||||
background: black;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
`;
|
||||
}
|
||||
|
||||
export const DemoButton = styled.button`
|
||||
background: rgb(60, 60, 60);
|
||||
font-size: 14px;
|
||||
padding: 5px 10px;
|
||||
border: none;
|
||||
color: white;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
margin: 2px;
|
||||
border-radius: 3px;
|
||||
|
||||
&:hover {
|
||||
background: rgb(0, 192, 255);
|
||||
}
|
||||
`;
|
||||
|
||||
export class DemoWorkspaceWidget extends React.Component<React.PropsWithChildren<DemoWorkspaceWidgetProps>> {
|
||||
render() {
|
||||
return (
|
||||
<S.Container>
|
||||
<S.Toolbar>{this.props.buttons}</S.Toolbar>
|
||||
<S.Content>{this.props.children}</S.Content>
|
||||
</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);
|
||||
});
|
||||
7
diagrams-demo-gallery/demos/helpers/index.css
Normal file
@@ -0,0 +1,7 @@
|
||||
html,
|
||||
body,
|
||||
#storybook-root {
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
53
diagrams-demo-gallery/package.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "@projectstorm/react-diagrams-gallery",
|
||||
"version": "7.1.2",
|
||||
"author": "dylanvorster",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/projectstorm/react-diagrams.git"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "pnpm storybook dev",
|
||||
"storybook:build": "./node_modules/.bin/build-storybook -c .storybook -o .out"
|
||||
},
|
||||
"keywords": [
|
||||
"web",
|
||||
"diagram",
|
||||
"diagrams",
|
||||
"react",
|
||||
"typescript",
|
||||
"flowchart",
|
||||
"simple",
|
||||
"links",
|
||||
"nodes"
|
||||
],
|
||||
"dependencies": {
|
||||
"@projectstorm/react-canvas-core": "workspace:*",
|
||||
"@projectstorm/react-diagrams": "workspace:*",
|
||||
"@projectstorm/react-diagrams-core": "workspace:*",
|
||||
"@projectstorm/react-diagrams-defaults": "workspace:*",
|
||||
"gsap": "^3.12.2",
|
||||
"json-beautify": "^1.1.1",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.22.20",
|
||||
"@babel/preset-react": "^7.22.15",
|
||||
"@babel/preset-typescript": "^7.22.15",
|
||||
"@storybook/addon-actions": "^7.4.4",
|
||||
"@storybook/addon-options": "^5.3.21",
|
||||
"@storybook/addons": "^7.4.4",
|
||||
"@storybook/react": "^7.4.4",
|
||||
"@storybook/react-webpack5": "^7.4.4",
|
||||
"@storybook/storybook-deployer": "^2.8.16",
|
||||
"@storybook/theming": "^7.4.4",
|
||||
"@types/lodash": "^4.14.199",
|
||||
"@types/react": "^18.2.22",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"storybook": "^7.4.4"
|
||||
}
|
||||
}
|
||||
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"
|
||||
]
|
||||
}
|
||||
50
diagrams-demo-project/CHANGELOG.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# @projectstorm/react-diagrams-demo
|
||||
|
||||
## 7.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 66c687a: Upgrade all dependencies and fix Storybook after upgrade
|
||||
- @projectstorm/react-diagrams@7.0.3
|
||||
|
||||
## 7.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b8a4cbd: Inline sources in sourcemap
|
||||
- Updated dependencies [b8a4cbd]
|
||||
- @projectstorm/react-diagrams@7.0.2
|
||||
|
||||
## 7.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @projectstorm/react-diagrams@7.0.1
|
||||
|
||||
## 7.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- b051697: - [internal] moves to `Pnpm` (instead of yarn -\_-)
|
||||
- [internal]moves to `Changesets` for releases
|
||||
- [internal]removes `Lerna`
|
||||
- [internal] upgrades all dependencies
|
||||
- [internal] switches to workspace protocol syntax (Changesets will bake in the correct version when a publish occurs)
|
||||
- [internal] Changesets will open a release PR which can wrap up several changes in 1 go
|
||||
- [internal] Changesets will run the storybook deploy automatically upon merging the release PR
|
||||
- [internal] removes a lot of the stuff from the root package.json
|
||||
- [internal] cleans up the build and clean commands
|
||||
- [internal] remove E2E tests, they are a nightmare to maintain and the ROI is far too low
|
||||
- [fix] Wrong type name for react-canvas model listener
|
||||
- [fix] export more stuff form the main react-diagrams package
|
||||
- [fix] circular deps with Rectangle and Polygon (turns out this was a problem but only with UMD builds, sorry @everyone who I doubted, but this is also why I could never reproduce the issue)
|
||||
- [breaking change] compile both ES6 and UMD
|
||||
- [breaking change] moves dependencies back to each package. (After years of working on libraries, I've come to actually hate peer dependencies, and this is easily solved with build systems / package managers).
|
||||
- [breaking change] static methods on `Polygon` and `Rectangle` moved to standalone methods
|
||||
- [breaking change] static construction methods to rather deal with different Rectangle constructor overloads (I now consider this bad design)
|
||||
- [breaking change] introduce `Bounds` as a simpler point-array type to deal with boundary computation instead
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b051697]
|
||||
- @projectstorm/react-diagrams@7.0.0
|
||||
@@ -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
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "@projectstorm/react-diagrams-demo",
|
||||
"version": "7.0.3",
|
||||
"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.3",
|
||||
"@babel/core": "^7.22.20",
|
||||
"@babel/preset-react": "^7.22.15",
|
||||
"@types/react": "^18.2.22",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"babel-loader": "^9.1.3",
|
||||
"css-loader": "^6.8.1",
|
||||
"style-loader": "^3.3.3",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^4.15.1"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 263 KiB After Width: | Height: | Size: 263 KiB |
@@ -1,5 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { DiagramEngine, DiagramWidget } from '@projectstorm/react-diagrams';
|
||||
import { DiagramEngine, CanvasWidget } from '@projectstorm/react-diagrams';
|
||||
|
||||
export interface BodyWidgetProps {
|
||||
engine: DiagramEngine;
|
||||
@@ -7,6 +7,6 @@ export interface BodyWidgetProps {
|
||||
|
||||
export class BodyWidget extends React.Component<BodyWidgetProps> {
|
||||
render() {
|
||||
return <DiagramWidget className="diagram-container" diagramEngine={this.props.engine} />;
|
||||
return <CanvasWidget className="diagram-container" engine={this.props.engine} />;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { AbstractReactFactory } from '@projectstorm/react-diagrams';
|
||||
import { JSCustomNodeModel } from './JSCustomNodeModel';
|
||||
import { JSCustomNodeWidget } from './JSCustomNodeWidget';
|
||||
import { AbstractReactFactory } from '@projectstorm/react-diagrams';
|
||||
|
||||
export class JSCustomNodeFactory extends AbstractReactFactory {
|
||||
constructor() {
|
||||
@@ -29,12 +29,12 @@ export class JSCustomNodeModel extends NodeModel {
|
||||
serialize() {
|
||||
return {
|
||||
...super.serialize(),
|
||||
color: this.options.color
|
||||
color: this.color
|
||||
};
|
||||
}
|
||||
|
||||
deSerialize(ob, engine) {
|
||||
super.deSerialize(ob, engine);
|
||||
deserialize(ob, engine) {
|
||||
super.deserialize(ob, engine);
|
||||
this.color = ob.color;
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,12 @@ export class JSCustomNodeWidget extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="custom-node">
|
||||
<PortWidget engine={this.props.engine} port={this.props.node.getPort('in')} />
|
||||
<PortWidget engine={this.props.engine} port={this.props.node.getPort('out')} />
|
||||
<PortWidget engine={this.props.engine} port={this.props.node.getPort('in')}>
|
||||
<div className="circle-port" />
|
||||
</PortWidget>
|
||||
<PortWidget engine={this.props.engine} port={this.props.node.getPort('out')}>
|
||||
<div className="circle-port" />
|
||||
</PortWidget>
|
||||
<div className="custom-node-color" style={{ backgroundColor: this.props.node.color }} />
|
||||
</div>
|
||||
);
|
||||
@@ -1,9 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import { AbstractReactFactory } from '@projectstorm/react-diagrams';
|
||||
import { TSCustomNodeModel } from './TSCustomNodeModel';
|
||||
import { TSCustomNodeWidget } from './TSCustomNodeWidget';
|
||||
import { AbstractReactFactory } from '@projectstorm/react-diagrams';
|
||||
import { DiagramEngine } from '@projectstorm/react-diagrams';
|
||||
|
||||
export class TSCustomNodeFactory extends AbstractReactFactory<TSCustomNodeModel> {
|
||||
export class TSCustomNodeFactory extends AbstractReactFactory<TSCustomNodeModel, DiagramEngine> {
|
||||
constructor() {
|
||||
super('ts-custom-node');
|
||||
}
|
||||
@@ -13,6 +14,6 @@ export class TSCustomNodeFactory extends AbstractReactFactory<TSCustomNodeModel>
|
||||
}
|
||||
|
||||
generateReactWidget(event): JSX.Element {
|
||||
return <TSCustomNodeWidget engine={this.engine} node={event.model} />;
|
||||
return <TSCustomNodeWidget engine={this.engine as DiagramEngine} node={event.model} />;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { DiagramEngine, NodeModel, DefaultPortModel, BaseModelOptions } from '@projectstorm/react-diagrams';
|
||||
import { BaseModelOptions, DefaultPortModel, NodeModel } from '@projectstorm/react-diagrams';
|
||||
|
||||
export interface TSCustomNodeModelOptions extends BaseModelOptions {
|
||||
color?: string;
|
||||
@@ -36,8 +36,8 @@ export class TSCustomNodeModel extends NodeModel {
|
||||
};
|
||||
}
|
||||
|
||||
deSerialize(ob: any, engine: DiagramEngine): void {
|
||||
super.deSerialize(ob, engine);
|
||||
this.color = ob.color;
|
||||
deserialize(event): void {
|
||||
super.deserialize(event);
|
||||
this.color = event.data.color;
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
@@ -18,8 +18,12 @@ export class TSCustomNodeWidget extends React.Component<TSCustomNodeWidgetProps,
|
||||
render() {
|
||||
return (
|
||||
<div className="custom-node">
|
||||
<PortWidget engine={this.props.engine} port={this.props.node.getPort('in')} />
|
||||
<PortWidget engine={this.props.engine} port={this.props.node.getPort('out')} />
|
||||
<PortWidget engine={this.props.engine} port={this.props.node.getPort('in')}>
|
||||
<div className="circle-port" />
|
||||
</PortWidget>
|
||||
<PortWidget engine={this.props.engine} port={this.props.node.getPort('out')}>
|
||||
<div className="circle-port" />
|
||||
</PortWidget>
|
||||
<div className="custom-node-color" style={{ backgroundColor: this.props.node.color }} />
|
||||
</div>
|
||||
);
|
||||
@@ -34,3 +34,16 @@ html, body, #application{
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.circle-port{
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin: 2px;
|
||||
border-radius: 4px;
|
||||
background: darkgray;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.circle-port:hover{
|
||||
background: mediumpurple;
|
||||
}
|
||||
@@ -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';
|
||||
@@ -12,7 +12,7 @@ import { BodyWidget } from './BodyWidget';
|
||||
const engine = createEngine();
|
||||
|
||||
// register the two engines
|
||||
engine.getNodeFactories().registerFactory(new JSCustomNodeFactory());
|
||||
engine.getNodeFactories().registerFactory(new JSCustomNodeFactory() as any);
|
||||
engine.getNodeFactories().registerFactory(new TSCustomNodeFactory());
|
||||
|
||||
// create a diagram model
|
||||
@@ -36,8 +36,9 @@ model.addAll(node1, node2, link1);
|
||||
//####################################################
|
||||
|
||||
// install the model into the engine
|
||||
engine.setDiagramModel(model);
|
||||
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
|
||||
}
|
||||
};
|
||||
@@ -1,76 +0,0 @@
|
||||
# Architecture Questions
|
||||
|
||||
Here I will try to answer any questions relating to the design of the system
|
||||
|
||||
### What was the inspiration for this library?
|
||||
|
||||
Joint JS (a fantastic library) + my need for rich HTML nodes + LabView + Blender Composite sub system
|
||||
|
||||
### 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.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
### Why Typescript?
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
### 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.
|
||||
|
||||
### Why cant the Default models and widgets do this or that ?
|
||||
|
||||
They are intended to illustrate __how__ to use this library and act as a good starting point
|
||||
to extend and show the capability. Ultimately I designed this library to be completely
|
||||
pluggable in a way that you can use it as a library and not a framework. If the default widgets
|
||||
are not good enough, then a good place to start is with creating your own models/factories/widgets.
|
||||
|
||||
### Model vs Widget
|
||||
|
||||
For those that are new to [Scene Graphs](https://en.wikipedia.org/wiki/Scene_graph) or are not familiar with concepts
|
||||
such as [MVC](https://en.wikipedia.org/wiki/Model–view–controller), this library represents your entire graph as a model.
|
||||
The model is a traversable graph that represents the nodes and links between them in a virtual manner. Your program (aka the business logic/layer)
|
||||
can mutate this model imperatively or store snapshots decoratively of the complete model (via serialization) and then the engine and react
|
||||
widgets will take care of the rendering. For this reason every model in the library is represented by a widget, and the factories glue it all together.
|
||||
|
||||
|
||||
### How do I make my own elements?
|
||||
|
||||
Take a look at the __demos__ directory, with specific attention to the __DefaultNodeWidget__
|
||||
|
||||
That being said, the demos directory is an _example_ of how you can create your own elements.
|
||||
A number of people want to use the defaults as is, which is cool,
|
||||
but is recommended to create your own models/factories/widgets.
|
||||
|
||||
### How do I use the library?
|
||||
|
||||
Take a look at the demo folders, they have simple and complex examples of the complete usage.
|
||||
|
||||
A good example of a real-world example is Demo 5
|
||||
@@ -1,142 +0,0 @@
|
||||
# Getting started
|
||||
|
||||
## Installation via NPM
|
||||
|
||||
The first thing you need to do, is grab the distribution files on NPM. You can do this either using yarn or npm
|
||||
|
||||
**Via yarn:**
|
||||
|
||||
```
|
||||
yarn add storm-react-diagrams
|
||||
```
|
||||
|
||||
**Via npm:**
|
||||
|
||||
```
|
||||
npm install storm-react-diagrams
|
||||
```
|
||||
|
||||
When you run this in your project directory, this will install the library into node\_modules/storm-react-diagrams. You will then find a dist folder that contains all the minified and production ready code.
|
||||
|
||||
This will also install React and a few other dependencies that you need in order to use this library.
|
||||
|
||||
## Including the library
|
||||
|
||||
When including the library you will need both the javascript files as well as the raw BEM styles. Both are included in the dist folder and there are numerous ways to integrate them into your project:
|
||||
|
||||
#### Getting the javascript files
|
||||
|
||||
**Using Typescript / ES6: \(recommended\)**
|
||||
|
||||
```js
|
||||
import * as SRD from "storm-react-diagrams"
|
||||
```
|
||||
|
||||
**Using RequireJS:**
|
||||
|
||||
```js
|
||||
var SRD = require("storm-react-diagrams)
|
||||
```
|
||||
|
||||
**As a script tag \(not recommended\)**
|
||||
|
||||
```html
|
||||
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
|
||||
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
|
||||
<script src="node_modules/storm-react-diagrams/dist/main.js">
|
||||
```
|
||||
|
||||
#### Getting the CSS
|
||||
|
||||
**Using RequireJS / Typescript/ ES6 \(recommended\)**
|
||||
|
||||
Make sure you have the style-loader enabled and then:
|
||||
|
||||
```js
|
||||
require("storm-react-diagrams/dist/style.min.css");
|
||||
```
|
||||
|
||||
or make sure you have the sass-loader enabled and then:
|
||||
|
||||
```js
|
||||
require("storm-react-diagrams/src/sass/main.scss");
|
||||
```
|
||||
|
||||
If you are using typescript and get a "require function not found" then make sure to
|
||||
|
||||
```
|
||||
yarn add @types/node
|
||||
```
|
||||
|
||||
which will give you the typescript definition files for requireJS
|
||||
|
||||
**Using SASS:**
|
||||
|
||||
setup your include paths on webpack or lib sass using the following option
|
||||
|
||||
```
|
||||
includePaths: ["node_modules"]
|
||||
```
|
||||
|
||||
and then if you want the raw sass source code:
|
||||
|
||||
```sass
|
||||
@import "~storm-react-diagrams/src/sass/main";
|
||||
```
|
||||
|
||||
or if you want the minified css
|
||||
|
||||
```sass
|
||||
@import "~storm-react-diagrams/dist/style.min";
|
||||
```
|
||||
|
||||
**Using a style tag**
|
||||
|
||||
or if you want the minified css
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="node_modules/dist/style.min.css">
|
||||
```
|
||||
|
||||
## Render your first diagram
|
||||
|
||||
In your library code
|
||||
|
||||
```js
|
||||
// 1) setup the diagram engine
|
||||
var engine = new SRD.DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
// 2) setup the diagram model
|
||||
var model = new SRD.DiagramModel();
|
||||
|
||||
// 3) create a default node
|
||||
var node1 = new SRD.DefaultNodeModel("Node 1", "rgb(0,192,255)");
|
||||
let port1 = node1.addOutPort("Out");
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
// 4) create another default node
|
||||
var node2 = new SRD.DefaultNodeModel("Node 2", "rgb(192,255,0)");
|
||||
let port2 = node2.addInPort("In");
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
// 5) link the ports
|
||||
let link1 = port1.link(port2);
|
||||
|
||||
// 6) add the models to the root graph
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
// 7) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
```
|
||||
|
||||
And then create an instance of the diagram widget. An example of the simplest possible react widget to do this would be:
|
||||
|
||||
```jsx
|
||||
function SimpleDiagramWidget(props) {
|
||||
return <SRD.DiagramWidget diagramEngine={props.engine} />;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# End user usage
|
||||
|
||||
__Delete__ removes any selected items
|
||||

|
||||
|
||||
__Shift + Mouse Drag__ triggers a multi-selection box
|
||||

|
||||
|
||||
__Shift + Mouse Click__ selects the item (items can be multi-selected)
|
||||

|
||||
|
||||
__Mouse Drag__ drags the entire diagram
|
||||

|
||||
|
||||
__Mouse Wheel__ zooms the diagram in / out
|
||||

|
||||
|
||||
__Click Link + Drag__ creates a new link point
|
||||

|
||||
|
||||
__Click Node Port + Drag__ creates a new link
|
||||

|
||||
13
docs/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Table of contents
|
||||
|
||||
* [Introduction](README.md)
|
||||
* [Getting Started](getting-started/README.md)
|
||||
* [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)
|
||||
* [Architecture Questions](about-the-project/architecture-questions.md)
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# Testing
|
||||
|
||||
STORM React diagrams is tested two main ways.
|
||||
|
||||
## JEST Snapshot testing
|
||||
|
||||
With Jest snapshots, we render all the demos in the demo folder by automatically
|
||||
looking into each `demo-*` folder and searching for an __index.tsx__ file.
|
||||
|
||||
For each file we find, we dynamically include it as a storybook story and assemble one big test.
|
||||
This test then renders each demo in a deterministic way and compares it to the snapshot file
|
||||
situated in __snapshots__. If the snapshots don't match, then something has changed and either the snapshot
|
||||
needs to be updated, or the test is failing in which case we need to fix the code.
|
||||
|
||||
Snapshot testing does not test the functionality of the program but it is a first important step
|
||||
to make sure that changes aren't having a drastic effect on the overall system.
|
||||
|
||||
In the event that the snapshot needs to be updated, please run `yarn run test -u` to overwrite
|
||||
the snapshot file, and then make sure to your branch.
|
||||
|
||||
## 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.
|
||||
|
||||
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.
|
||||