Compare commits
449 Commits
v5.2.2-0
...
@projectst
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
160b88fccf | ||
|
|
80cd9c9306 | ||
|
|
2de55fdf68 | ||
|
|
b8a4cbdf1a | ||
|
|
76a2659948 | ||
|
|
63e33c07d8 | ||
|
|
70b17a749c | ||
|
|
4ccc5d58f3 | ||
|
|
fb7d646bde | ||
|
|
e0d21f1435 | ||
|
|
6ed1e0f89d | ||
|
|
7da7fa4cc9 | ||
|
|
ed7988f722 | ||
|
|
e6b86321e2 | ||
|
|
17bb78b130 | ||
|
|
ddeea124b0 | ||
|
|
fcdbce54b5 | ||
|
|
f1c38fb84a | ||
|
|
74f9269869 | ||
|
|
a28bcc037d | ||
|
|
456e6b1b67 | ||
|
|
c9e819d78e | ||
|
|
8a2f5d198f | ||
|
|
251a1f9484 | ||
|
|
c1eac9873a | ||
|
|
95b35d6778 | ||
|
|
d2a197245b | ||
|
|
8f06e55127 | ||
|
|
b0e8e52077 | ||
|
|
0d23e933e8 | ||
|
|
4dfeb403be | ||
|
|
0e19827675 | ||
|
|
2b1f54bbc9 | ||
|
|
b3a6cc01fa | ||
|
|
918d8d741b | ||
|
|
d15fb13adf | ||
|
|
4f2b6132ba | ||
|
|
7d9d137c66 | ||
|
|
b051697791 | ||
|
|
8fc9fe3aae | ||
|
|
b4185dcb76 | ||
|
|
c1fa7ee865 | ||
|
|
05a5afb20e | ||
|
|
8bcc1436d3 | ||
|
|
9b39591d94 | ||
|
|
88296c28b4 | ||
|
|
2a810ca2d3 | ||
|
|
dfcf82e692 | ||
|
|
cd93bb96a3 | ||
|
|
5f49bbe5b1 | ||
|
|
d55790edcf | ||
|
|
a1b2f6a59e | ||
|
|
e7b352644d | ||
|
|
2f620ce4af | ||
|
|
897bde204e | ||
|
|
2d9fca171c | ||
|
|
77011af27a | ||
|
|
32d47270cb | ||
|
|
3060496db0 | ||
|
|
02a37fcf1f | ||
|
|
e4848b4784 | ||
|
|
c4d0136402 | ||
|
|
413838b841 | ||
|
|
9b5b14d144 | ||
|
|
f8fa5564c1 | ||
|
|
24ff005d9e | ||
|
|
04d5bc97f7 | ||
|
|
d7aa385cf5 | ||
|
|
b2fa681494 | ||
|
|
a2ac399632 | ||
|
|
3d0521cc93 | ||
|
|
1825076cd4 | ||
|
|
00d92392cc | ||
|
|
d07f3a3047 | ||
|
|
d21e8e8860 | ||
|
|
25bf056b0a | ||
|
|
5ebe6f84cd | ||
|
|
adc173f689 | ||
|
|
889108d7fd | ||
|
|
09c2014efc | ||
|
|
cd22725103 | ||
|
|
dd68d1fe67 | ||
|
|
8b2f5c8961 | ||
|
|
e23b68b2d1 | ||
|
|
77e1abba97 | ||
|
|
db25ec3cca | ||
|
|
61882f0637 | ||
|
|
c9098377dc | ||
|
|
a0bbde14cf | ||
|
|
ee30b45ff0 | ||
|
|
36a3eddca7 | ||
|
|
1ad8d79b4c | ||
|
|
87a75437c3 | ||
|
|
ad4efe70e7 | ||
|
|
9460ce8eeb | ||
|
|
8e7b7cd05e | ||
|
|
f661824282 | ||
|
|
5b2ceabfd4 | ||
|
|
bb6e1d52af | ||
|
|
be422431d2 | ||
|
|
66184bd0fa | ||
|
|
ef4439d895 | ||
|
|
ee66f8ad61 | ||
|
|
6a4e17aca6 | ||
|
|
10d6a286b4 | ||
|
|
1bdc6c7624 | ||
|
|
f5bc087e7a | ||
|
|
369ca9cf91 | ||
|
|
ba4fbe101d | ||
|
|
5b642a1d1b | ||
|
|
df9b076140 | ||
|
|
0f403bb71c | ||
|
|
abadce19ac | ||
|
|
eb59992bc3 | ||
|
|
b0f0379329 | ||
|
|
63a41c634f | ||
|
|
e34c73ca00 | ||
|
|
44fae73a52 | ||
|
|
81f26a19ca | ||
|
|
2d5ae2fb44 | ||
|
|
d2f05438b8 | ||
|
|
d9bd430f82 | ||
|
|
df308897b7 | ||
|
|
590ba09c3c | ||
|
|
3c8912bc86 | ||
|
|
291241cacb | ||
|
|
1ac3a8de78 | ||
|
|
e974627fd0 | ||
|
|
ade86f215c | ||
|
|
e7a606d987 | ||
|
|
67be47b4ae | ||
|
|
43b75505fe | ||
|
|
3c79850c85 | ||
|
|
8173b70834 | ||
|
|
53eee3f518 | ||
|
|
4649597a97 | ||
|
|
89adc1ee38 | ||
|
|
ff0f7188fa | ||
|
|
c6556d7475 | ||
|
|
8497c1bf6c | ||
|
|
a15191bcef | ||
|
|
d7c7dcf0b1 | ||
|
|
57a65aec20 | ||
|
|
b0343daf6f | ||
|
|
5d7bfd81d4 | ||
|
|
d42087a3ac | ||
|
|
6adff81ae7 | ||
|
|
4f3df60758 | ||
|
|
2f366d21f7 | ||
|
|
b7dfa6da21 | ||
|
|
293123b5c6 | ||
|
|
00c2a41c0c | ||
|
|
63dbe41df0 | ||
|
|
c1485224ba | ||
|
|
580a26c73d | ||
|
|
4c03583d91 | ||
|
|
9b58fa3963 | ||
|
|
3e69dafef9 | ||
|
|
442462af2d | ||
|
|
0d9ba41c9a | ||
|
|
73ef7df153 | ||
|
|
5fe7b37fc2 | ||
|
|
093e1f6a08 | ||
|
|
1e95edbc6f | ||
|
|
c92313f9b1 | ||
|
|
b8b66642d5 | ||
|
|
39dbbe3db9 | ||
|
|
1ba35fd518 | ||
|
|
04443ad85e | ||
|
|
17952c8829 | ||
|
|
a8234a1a8d | ||
|
|
3f86c36c44 | ||
|
|
a2cf7483f1 | ||
|
|
72739dc3d3 | ||
|
|
07df1fd6f5 | ||
|
|
ef9e72ed3a | ||
|
|
8df5ff94b6 | ||
|
|
17c5a3cfb9 | ||
|
|
a69ec38a5a | ||
|
|
2c66c18f6d | ||
|
|
012418741d | ||
|
|
3d71f5a80b | ||
|
|
c5b24f6e7b | ||
|
|
655462087f | ||
|
|
6bdc21826d | ||
|
|
27194cfd36 | ||
|
|
61c8d7e610 | ||
|
|
08f9ea6aa6 | ||
|
|
cef51577a3 | ||
|
|
e8fb8804a8 | ||
|
|
ef822f5540 | ||
|
|
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 | ||
|
|
45649146c9 | ||
|
|
74e24331ed | ||
|
|
0cc469fa44 | ||
|
|
0b78ba69c6 | ||
|
|
ca301b9d4d | ||
|
|
ad6c77da28 | ||
|
|
66b72b4465 | ||
|
|
bb878657ba | ||
|
|
1db1e21fc2 | ||
|
|
f4920ab4d0 | ||
|
|
ccfd8e026c | ||
|
|
702290d9b3 | ||
|
|
347377d3b4 | ||
|
|
44fd2ad91b | ||
|
|
39d49c9ee0 | ||
|
|
61c6d4b161 | ||
|
|
b324154eff | ||
|
|
17350a740a | ||
|
|
d7fc5370ab | ||
|
|
5fbe7ce9e4 | ||
|
|
3e37e34155 | ||
|
|
f46680596c | ||
|
|
3a2d3ccb73 | ||
|
|
f4aa1852ed | ||
|
|
e167885038 | ||
|
|
619e8a2347 | ||
|
|
4c1e67106a | ||
|
|
d08be537e1 | ||
|
|
8e5243da95 | ||
|
|
22236f8420 | ||
|
|
99fe94ae29 | ||
|
|
3b0c19d998 | ||
|
|
fc67d477a9 | ||
|
|
e4d427e0d3 | ||
|
|
bc2d444aee | ||
|
|
b15a326dab | ||
|
|
b54feb03e4 | ||
|
|
39eddc0a2a | ||
|
|
85a1fde2e5 | ||
|
|
c0dae87d02 | ||
|
|
fddec93370 | ||
|
|
01ffbce479 | ||
|
|
30790682d3 | ||
|
|
dc9c2eae66 | ||
|
|
969152a814 | ||
|
|
2e38a7cfd5 | ||
|
|
e3fe7319c1 | ||
|
|
c3a332ebab | ||
|
|
314bb908f9 | ||
|
|
9b16b3f4ed | ||
|
|
722b6d98f3 | ||
|
|
2c6971be9a | ||
|
|
ea0160cbcf | ||
|
|
efc53eec9b | ||
|
|
b5c86159d1 | ||
|
|
ea2070ec98 | ||
|
|
39c3611686 | ||
|
|
1ff63d4117 | ||
|
|
e80da8853f | ||
|
|
a06e23eaf6 | ||
|
|
4b599fc37f | ||
|
|
def92af022 | ||
|
|
01e9f5f2db | ||
|
|
aa1a02774d | ||
|
|
e60aac56db | ||
|
|
b2e74d8b97 | ||
|
|
e333a4f168 | ||
|
|
1d316409e1 | ||
|
|
9d947d40b7 | ||
|
|
7d80f15358 | ||
|
|
28844b86eb | ||
|
|
70c9aeac66 | ||
|
|
12a7bfbda5 | ||
|
|
650061db4a | ||
|
|
48c6d1f038 |
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,31 +0,0 @@
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: projectstorm/react-diagrams-ci
|
||||
|
||||
working_directory: ~/repo
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
# Download and cache dependencies
|
||||
- restore_cache:
|
||||
keys:
|
||||
- v1-dependencies-{{ checksum "package.json" }}
|
||||
|
||||
- run: yarn install
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
- node_modules
|
||||
key: v1-dependencies-{{ checksum "package.json" }}
|
||||
|
||||
# test building project
|
||||
- run: yarn run prepublishOnly
|
||||
|
||||
# test building storybook
|
||||
- run: yarn run storybook: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 |
33
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,27 +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 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?
|
||||
|
||||
(My awesome new feature does this really cool thing.)
|
||||
|
||||
## Why?
|
||||
|
||||
(Because obviously it could not do it before)
|
||||
|
||||
## How?
|
||||
|
||||
(Basically I did this and that because im a super 1337 hacker)
|
||||
|
||||
## Feel-Good "programming lol" image:
|
||||
|
||||
(Add your own one below :])
|
||||
|
||||

|
||||
## What, why and how?
|
||||
|
||||
|
||||
## Feel good image:
|
||||
|
||||
|
||||

|
||||
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
|
||||
201
.gitignore
vendored
@@ -1,194 +1,9 @@
|
||||
dist/
|
||||
dist/main.js
|
||||
dist/main.js.map
|
||||
/package
|
||||
*.tgz
|
||||
@types/
|
||||
|
||||
.out
|
||||
|
||||
# Created by https://www.gitignore.io/api/net,netbeans,sublimetext,phpstorm,windows,osx,node
|
||||
|
||||
#!! ERROR: net is undefined. Use list command to see defined gitignore types !!#
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
nbdist/
|
||||
nbactions.xml
|
||||
.nb-gradle/
|
||||
|
||||
|
||||
### SublimeText ###
|
||||
# cache files for sublime text
|
||||
*.tmlanguage.cache
|
||||
*.tmPreferences.cache
|
||||
*.stTheme.cache
|
||||
|
||||
# workspace files are user-specific
|
||||
*.sublime-workspace
|
||||
|
||||
# project files should be checked into the repository, unless a significant
|
||||
# proportion of contributors will probably not be using SublimeText
|
||||
# *.sublime-project
|
||||
|
||||
# sftp configuration file
|
||||
sftp-config.json
|
||||
|
||||
# Package control specific files
|
||||
Package Control.last-run
|
||||
Package Control.ca-list
|
||||
Package Control.ca-bundle
|
||||
Package Control.system-ca-bundle
|
||||
Package Control.cache/
|
||||
Package Control.ca-certs/
|
||||
bh_unicode_properties.cache
|
||||
|
||||
# Sublime-github package stores a github token in this file
|
||||
# https://packagecontrol.io/packages/sublime-github
|
||||
GitHub.sublime-settings
|
||||
|
||||
|
||||
### PhpStorm ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/dictionaries
|
||||
.idea/vcs.xml
|
||||
.idea/jsLibraryMappings.xml
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/dataSources.ids
|
||||
.idea/dataSources.xml
|
||||
.idea/dataSources.local.xml
|
||||
.idea/sqlDataSources.xml
|
||||
.idea/dynamic.xml
|
||||
.idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/gradle.xml
|
||||
.idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
### PhpStorm Patch ###
|
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||
|
||||
# *.iml
|
||||
# modules.xml
|
||||
|
||||
|
||||
### Windows ###
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
### OSX ###
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
jspm_packages
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
dist
|
||||
.DS_Store
|
||||
.idea
|
||||
.out
|
||||
*.zip
|
||||
.env
|
||||
node_modules
|
||||
tsconfig.tsbuildinfo
|
||||
.vscode
|
||||
194
.npmignore
@@ -1,194 +0,0 @@
|
||||
demos
|
||||
images
|
||||
docs
|
||||
.out
|
||||
.storybook
|
||||
.circleci
|
||||
tests
|
||||
*.md
|
||||
|
||||
# Created by https://www.gitignore.io/api/net,netbeans,sublimetext,phpstorm,windows,osx,node
|
||||
|
||||
#!! ERROR: net is undefined. Use list command to see defined gitignore types !!#
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
nbdist/
|
||||
nbactions.xml
|
||||
.nb-gradle/
|
||||
|
||||
|
||||
### SublimeText ###
|
||||
# cache files for sublime text
|
||||
*.tmlanguage.cache
|
||||
*.tmPreferences.cache
|
||||
*.stTheme.cache
|
||||
|
||||
# workspace files are user-specific
|
||||
*.sublime-workspace
|
||||
|
||||
# project files should be checked into the repository, unless a significant
|
||||
# proportion of contributors will probably not be using SublimeText
|
||||
# *.sublime-project
|
||||
|
||||
# sftp configuration file
|
||||
sftp-config.json
|
||||
|
||||
# Package control specific files
|
||||
Package Control.last-run
|
||||
Package Control.ca-list
|
||||
Package Control.ca-bundle
|
||||
Package Control.system-ca-bundle
|
||||
Package Control.cache/
|
||||
Package Control.ca-certs/
|
||||
bh_unicode_properties.cache
|
||||
|
||||
# Sublime-github package stores a github token in this file
|
||||
# https://packagecontrol.io/packages/sublime-github
|
||||
GitHub.sublime-settings
|
||||
|
||||
|
||||
### PhpStorm ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/dictionaries
|
||||
.idea/vcs.xml
|
||||
.idea/jsLibraryMappings.xml
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/dataSources.ids
|
||||
.idea/dataSources.xml
|
||||
.idea/dataSources.local.xml
|
||||
.idea/sqlDataSources.xml
|
||||
.idea/dynamic.xml
|
||||
.idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/gradle.xml
|
||||
.idea/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
### PhpStorm Patch ###
|
||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
||||
|
||||
# *.iml
|
||||
# modules.xml
|
||||
|
||||
|
||||
### Windows ###
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
|
||||
### OSX ###
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
|
||||
### Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
jspm_packages
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
.idea
|
||||
3
.prettierignore
Normal file
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
dist
|
||||
.out
|
||||
7
.prettierrc
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"useTabs": true,
|
||||
"printWidth": 120,
|
||||
"trailingComma": "none"
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
import '@storybook/addon-actions/register';
|
||||
import '@storybook/addon-options/register';
|
||||
@@ -1,8 +0,0 @@
|
||||
import { configure } from '@storybook/react';
|
||||
|
||||
function loadStories() {
|
||||
require('../demos/index.tsx');
|
||||
// You can require as many demos as you need.
|
||||
}
|
||||
|
||||
configure(loadStories, module);
|
||||
@@ -1,48 +0,0 @@
|
||||
const path = require('path');
|
||||
module.exports = async ({config, mode}) => {
|
||||
return {
|
||||
...config,
|
||||
resolve: {
|
||||
...config.resolve,
|
||||
extensions: ['.tsx', '.ts', '.js'],
|
||||
alias: {
|
||||
...config.resolve.alias,
|
||||
'storm-react-diagrams': path.join(__dirname, "..", "src", "main")
|
||||
}
|
||||
},
|
||||
module: {
|
||||
...config.module,
|
||||
rules: [
|
||||
...config.module.rules,
|
||||
...[
|
||||
{
|
||||
test: /\.scss$/,
|
||||
loaders: [
|
||||
'style-loader',
|
||||
'css-loader',
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {config: {path: path.join(__dirname, '..')}}
|
||||
},
|
||||
'sass-loader'
|
||||
]
|
||||
},
|
||||
{
|
||||
enforce: 'pre',
|
||||
test: /\.js$/,
|
||||
loader: 'source-map-loader',
|
||||
exclude: [/node_modules\//]
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true
|
||||
}
|
||||
},
|
||||
]
|
||||
]
|
||||
}
|
||||
};
|
||||
};
|
||||
234
CHANGELOG.md
@@ -1,73 +1,213 @@
|
||||
__V7!__
|
||||
|
||||
we are now using changesets! you can see the changes for individual packages in their corresponding folders.
|
||||
Here is the main changeset for the core package which depends on everything:
|
||||
|
||||
[Changelog for @projectstorm/react-diagrams](./packages/react-diagrams/CHANGELOG.md)
|
||||
|
||||
---
|
||||
|
||||
__6.7.4__
|
||||
|
||||
.0 -> .4 because I messed up the version / publishing
|
||||
|
||||
* (upgrade all dependencies, including a move to React 18)
|
||||
* https://github.com/projectstorm/react-diagrams/pull/947
|
||||
|
||||
__6.7.0__
|
||||
|
||||
bug fixes:
|
||||
* https://github.com/projectstorm/react-diagrams/pull/882
|
||||
* https://github.com/projectstorm/react-diagrams/pull/914
|
||||
* https://github.com/projectstorm/react-diagrams/pull/875
|
||||
|
||||
types
|
||||
* https://github.com/projectstorm/react-diagrams/pull/906
|
||||
|
||||
features:
|
||||
* https://github.com/projectstorm/react-diagrams/pull/915
|
||||
* https://github.com/projectstorm/react-diagrams/pull/877
|
||||
|
||||
__6.6.1__
|
||||
|
||||
bug fixes:
|
||||
* https://github.com/projectstorm/react-diagrams/pull/861
|
||||
* https://github.com/projectstorm/react-diagrams/pull/871
|
||||
* https://github.com/projectstorm/react-diagrams/pull/870
|
||||
|
||||
Some maintenance:
|
||||
* https://github.com/projectstorm/react-diagrams/pull/861
|
||||
|
||||
__6.6.0__
|
||||
|
||||
* (docs-broken) https://github.com/projectstorm/react-diagrams/pull/834
|
||||
* (bug) https://github.com/projectstorm/react-diagrams/pull/838
|
||||
* (docs-broken) https://github.com/projectstorm/react-diagrams/pull/847
|
||||
* (bug) https://github.com/projectstorm/react-diagrams/pull/852
|
||||
* (docs-broken) https://github.com/projectstorm/react-diagrams/pull/856
|
||||
* (improvement) https://github.com/projectstorm/react-diagrams/pull/857
|
||||
* (bug) https://github.com/projectstorm/react-diagrams/pull/860
|
||||
|
||||
Also includes a bump on all packages using `ncu` recursively.
|
||||
|
||||
__6.5.2__
|
||||
|
||||
https://github.com/projectstorm/react-diagrams/pull/830
|
||||
|
||||
* (fix) issue with zoom to fit selected
|
||||
* (improvement) properly export PathFinding
|
||||
* (maintenance) bump all dependencies
|
||||
|
||||
__6.5.1__
|
||||
|
||||
https://github.com/projectstorm/react-diagrams/pull/829
|
||||
|
||||
* (improved) zoom to fit now centers correctly
|
||||
* (fix) remove wrong peer dependency (@emotion/core)
|
||||
|
||||
__6.5.0__
|
||||
|
||||
https://github.com/projectstorm/react-diagrams/pull/814
|
||||
|
||||
* Some rendering fixes
|
||||
* small api change around `zoomToFit`
|
||||
* more api options with the `DefaultLink`
|
||||
|
||||
__6.4.0__
|
||||
|
||||
https://github.com/projectstorm/react-diagrams/pull/813
|
||||
|
||||
* Bump all packages and move to Emotion 11 and React 17
|
||||
* Move to the latest Storybook
|
||||
|
||||
__6.2.0__
|
||||
|
||||
* (improvement) Move away fromn math-js (https://github.com/projectstorm/react-diagrams/pull/651)
|
||||
* (fix) https://github.com/projectstorm/react-diagrams/pull/639
|
||||
* (fix) Fixing link spawning at (0,0) when clicking port once (inspired by https://github.com/projectstorm/react-diagrams/pull/637)
|
||||
|
||||
__6.1.1__
|
||||
|
||||
* (feature) https://github.com/projectstorm/react-diagrams/pull/576 [Add zoom to fit nodes feature, fixes #568]
|
||||
* (improvement) https://github.com/projectstorm/react-diagrams/pull/621 [Support deriving from DefaultLabelModel]
|
||||
* (fix) https://github.com/projectstorm/react-diagrams/pull/603
|
||||
[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__
|
||||
|
||||
* (maintenance) Upgrade :allthethings: (all the build tooling was upgrade)
|
||||
* (api) move to ES6 (JS now contains native classes)
|
||||
* (api) changed package name to @projectstorm/react-diagrams
|
||||
* (bug) (PR259)(https://github.com/projectstorm/react-diagrams/pull/259) Fixes #258
|
||||
* (refactor) (PR 306)(https://github.com/projectstorm/react-diagrams/pull/306) `:any` fix
|
||||
* (feature) (PR 178)(https://github.com/projectstorm/react-diagrams/pull/178) Trigger a positionChanged event when moving a Node that has the listener assigned.
|
||||
* (fix) (PR 356)(https://github.com/projectstorm/react-diagrams/pull/356) Fixed Type issue with 'PointModel()'
|
||||
* (demo) dark mode and upgrade storybook
|
||||
|
||||
__5.2.1__
|
||||
|
||||
* [fix] Always remove link from old source/target port on port change
|
||||
* [maintenance] upgrade node modules
|
||||
* [refactor] https://github.com/projectstorm/react-diagrams/commit/55f62587bd3b12513c7d37eff59edfc8bdb8d6c9
|
||||
* [bug] https://github.com/projectstorm/react-diagrams/commit/75ef02dd4d131a0e7c08b2680c69efc390e50b84
|
||||
* (fix) Always remove link from old source/target port on port change
|
||||
* (maintenance) upgrade node modules
|
||||
* (refactor) https://github.com/projectstorm/react-diagrams/commit/55f62587bd3b12513c7d37eff59edfc8bdb8d6c9
|
||||
* (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
|
||||
* [refactor] Each class now explicitely has its own class file (consistency)
|
||||
* [feature] Smooth vertical links (no longer limited to horizontal)
|
||||
* [feature] Dedicated documentation via gitbook
|
||||
* [bug] forgot to export some
|
||||
* [refactor] consistently use lodash where possible
|
||||
* [maintenance] upgrade node modules
|
||||
* (api) Rename XXXFactory into AbstractXXXFactory
|
||||
* (refactor) tslint and prettier are now the same
|
||||
* (refactor) Each class now explicitely has its own class file (consistency)
|
||||
* (feature) Smooth vertical links (no longer limited to horizontal)
|
||||
* (feature) Dedicated documentation via gitbook
|
||||
* (bug) forgot to export some
|
||||
* (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/
|
||||
|
||||
PR: https://github.com/projectstorm/react-diagrams/pull/145
|
||||
|
||||
* [refactor] Links completely overhauled
|
||||
* [feature] Smart Routing
|
||||
* [feature] Flow support
|
||||
* [demo] Smart Routing
|
||||
* [demo] Animated links
|
||||
* [api] Bootstrapping Improvements
|
||||
* [feature] add custom properties to all widgets
|
||||
* [refactor] use BEM for all css
|
||||
* [feature] Default Link factory hooks
|
||||
* [tests] e2e tests + helper framework
|
||||
* [tests] automatically load JEST Snapshots
|
||||
* [feature] Link labels!
|
||||
* (refactor) Links completely overhauled
|
||||
* (feature) Smart Routing
|
||||
* (feature) Flow support
|
||||
* (demo) Smart Routing
|
||||
* (demo) Animated links
|
||||
* (api) Bootstrapping Improvements
|
||||
* (feature) add custom properties to all widgets
|
||||
* (refactor) use BEM for all css
|
||||
* (feature) Default Link factory hooks
|
||||
* (tests) e2e tests + helper framework
|
||||
* (tests) automatically load JEST Snapshots
|
||||
* (feature) Link labels!
|
||||
|
||||
__4.0.0__ http://dylanv.blog/2018/01/18/storm-react-diagrams-v4-0-0/
|
||||
|
||||
* [refactor] Events system was completely overhauled
|
||||
* [demo] Custom Link Sizes
|
||||
* [refactor] Demos are now much more verbose and better managed
|
||||
* [update] node packages
|
||||
* [bug] Fix #129
|
||||
* [feature] Control link creation through ports
|
||||
* [refactor] Models are now in seperate files
|
||||
* [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
|
||||
* (refactor) Events system was completely overhauled
|
||||
* (demo) Custom Link Sizes
|
||||
* (refactor) Demos are now much more verbose and better managed
|
||||
* (update) node packages
|
||||
* (bug) Fix #129
|
||||
* (feature) Control link creation through ports
|
||||
* (refactor) Models are now in seperate files
|
||||
* (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
|
||||
|
||||
__3.2.0__ http://dylanv.blog/2017/11/22/storm-react-diagrams-3-2-0/
|
||||
* [feature] zoom to fit
|
||||
* (feature) zoom to fit
|
||||
* added Circle CI tests
|
||||
* [demo] dagre automatic layouts
|
||||
* [demo] zoom to fit
|
||||
* [demo] selection events
|
||||
* [demo] limit number of points
|
||||
* [demo] programmatic node updating
|
||||
* (demo) dagre automatic layouts
|
||||
* (demo) zoom to fit
|
||||
* (demo) selection events
|
||||
* (demo) limit number of points
|
||||
* (demo) programmatic node updating
|
||||
* updated dependencies
|
||||
* [bugs] swapping diagram models in engines
|
||||
* [bugs] issues with the rendering pipeline #107
|
||||
* (bugs) swapping diagram models in engines
|
||||
* (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)
|
||||
|
||||
@@ -76,7 +216,7 @@ __3.1.0__ http://dylanv.blog/2017/09/15/storm-react-diagrams-3-1-0/
|
||||
* Fixed links not connecting when grid is larger than port size
|
||||
* Prevented points from dragging when connected to a port and the node itself is not selected
|
||||
* API fixes
|
||||
* Code cleanup
|
||||
* Code cleanup
|
||||
|
||||
__3.0.0__ http://dylanv.blog/2017/09/13/storm-react-diagrams-v3/
|
||||
* Massive performance updates
|
||||
|
||||
101
README.md
@@ -1,49 +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/storm-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)
|
||||
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.
|
||||
|
||||
## Gallery
|
||||
|
||||
Example implementation using custom models: \(Dylan's personal code\)
|
||||
|
||||

|
||||

|
||||
|
||||
Example implementation using custom models:
|
||||

|
||||

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

|
||||
|
||||

|
||||
|
||||
## Installing
|
||||
|
||||
For all the bells and whistles:
|
||||
|
||||
```text
|
||||
yarn add @projectstorm/react-diagrams
|
||||
```
|
||||
|
||||
This includes all the packages listed below \(and works \(mostly and conceptually\) like it used to in version 5.0\)
|
||||
|
||||
### 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\)
|
||||
|
||||
```text
|
||||
yarn add @projectstorm/react-diagrams-core
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
## How to use
|
||||
|
||||
Before running any of the examples, please run `yarn build` in the root. This project is a monorepo, and the packages (including the demos) require the packages to first be built.
|
||||
|
||||
|
||||
## Introduction
|
||||
Take a look at the [diagram demos](https://github.com/projectstorm/react-diagrams/tree/master/diagrams-demo-gallery/demos)
|
||||
|
||||
A no-nonsense diagramming library written entirely in React with the help of a few small libraries. It aims to be:
|
||||
**or**
|
||||
|
||||
* 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
|
||||
* 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
|
||||
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
|
||||
|
||||
#### Run the demos
|
||||
**or**
|
||||
|
||||
After running `yarn install` you must then run: `yarn run storybook`
|
||||
[Checkout the docs](https://projectstorm.gitbook.io/react-diagrams/)
|
||||
|
||||
#### Building from source
|
||||
## Run the demos
|
||||
|
||||
Simply run `webpack` in the root directory \(or `export NODE_ENV=production && webpack` 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\).
|
||||
After running `yarn install` and `yarn build`, you must then run: `cd diagrams-demo-gallery && yarn run start`
|
||||
|
||||
## [Checkout the docs](https://projectstorm.gitbooks.io/react-diagrams)
|
||||
## Building from source
|
||||
|
||||
Simply run `yarn` then `yarn build` or `yarn build:prod` in the root directory and it will spit out the transpiled code and typescript definitions into the dist directory as a single file.
|
||||
|
||||
## Built with react-diagrams
|
||||
|
||||
> Do you have an interesting project built with *react-diagrams*? PR it into this section for others to see.
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import * as React from "react";
|
||||
|
||||
export interface DemoWorkspaceWidgetProps {
|
||||
buttons?: any;
|
||||
}
|
||||
|
||||
export interface DemoWorkspaceWidgetState {}
|
||||
|
||||
export class DemoWorkspaceWidget extends React.Component<DemoWorkspaceWidgetProps, DemoWorkspaceWidgetState> {
|
||||
constructor(props: DemoWorkspaceWidgetProps) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="srd-demo-workspace">
|
||||
<div className="srd-demo-workspace__toolbar">{this.props.buttons}</div>
|
||||
<div className="srd-demo-workspace__content">{this.props.children}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import * as React from "react";
|
||||
|
||||
export class Helper {
|
||||
/**
|
||||
* Logs the mouse position in the console, but overlays a div that consumes all events
|
||||
* since the actual story book stories are rendered as an iFrame.
|
||||
*/
|
||||
static logMousePosition() {
|
||||
let element = window.parent.document.createElement("mouse-position");
|
||||
element.style.position = "absolute";
|
||||
element.style.top = "0px";
|
||||
element.style.left = "0px";
|
||||
element.style.bottom = "0px";
|
||||
element.style.right = "0px";
|
||||
element.style.zIndex = "10";
|
||||
window.parent.document.body.appendChild(element);
|
||||
|
||||
window.parent.window.addEventListener("mousemove", event => {
|
||||
console.clear();
|
||||
console.log(event.clientX, event.clientY);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
@import "../../src/sass/main";
|
||||
|
||||
html, body, #root{
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.srd-demo-workspace{
|
||||
background: black;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
|
||||
&__toolbar{
|
||||
padding: 5px;
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__content{
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.srd-demo-canvas{
|
||||
height: 100%;
|
||||
min-height: 300px;
|
||||
background-color: rgb(60,60,60) !important;
|
||||
$color: rgba(white, .05);
|
||||
background-image:
|
||||
linear-gradient(0deg,
|
||||
transparent 24%,
|
||||
$color 25%,
|
||||
$color 26%,
|
||||
transparent 27%,
|
||||
transparent 74%,
|
||||
$color 75%,
|
||||
$color 76%,
|
||||
transparent 77%,
|
||||
transparent),
|
||||
linear-gradient(90deg,
|
||||
transparent 24%,
|
||||
$color 25%,
|
||||
$color 26%,
|
||||
transparent 27%,
|
||||
transparent 74%,
|
||||
$color 75%,
|
||||
$color 76%,
|
||||
transparent 77%,
|
||||
transparent);
|
||||
background-size:50px 50px;
|
||||
|
||||
.pointui{
|
||||
fill: rgba(white,0.5);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
import {
|
||||
DiagramEngine,
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
NodeModel,
|
||||
DiagramWidget,
|
||||
BaseModel
|
||||
} from "storm-react-diagrams";
|
||||
import * as _ from "lodash";
|
||||
import * as React from "react";
|
||||
import { DemoWorkspaceWidget } from "../.helpers/DemoWorkspaceWidget";
|
||||
|
||||
/**
|
||||
* Tests cloning
|
||||
*/
|
||||
class CloneSelected extends React.Component<any, any> {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.cloneSelected = this.cloneSelected.bind(this);
|
||||
}
|
||||
|
||||
cloneSelected() {
|
||||
let { engine } = this.props;
|
||||
let offset = { x: 100, y: 100 };
|
||||
let model = engine.getDiagramModel();
|
||||
|
||||
let itemMap = {};
|
||||
_.forEach(model.getSelectedItems(), (item: BaseModel<any>) => {
|
||||
let newItem = item.clone(itemMap);
|
||||
|
||||
// offset the nodes slightly
|
||||
if (newItem instanceof NodeModel) {
|
||||
newItem.setPosition(newItem.x + offset.x, newItem.y + offset.y);
|
||||
model.addNode(newItem);
|
||||
} else if (newItem instanceof LinkModel) {
|
||||
// offset the link points
|
||||
newItem.getPoints().forEach(p => {
|
||||
p.updateLocation({ x: p.getX() + offset.x, y: p.getY() + offset.y });
|
||||
});
|
||||
model.addLink(newItem);
|
||||
}
|
||||
newItem.selected = false;
|
||||
});
|
||||
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { engine } = this.props;
|
||||
return (
|
||||
<DemoWorkspaceWidget buttons={<button onClick={this.cloneSelected}>Clone Selected</button>}>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
//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)");
|
||||
let port = node1.addOutPort("Out");
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new DefaultNodeModel("Node 2", "rgb(192,255,0)");
|
||||
let port2 = node2.addInPort("In");
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
// link the ports
|
||||
let link1 = port.link(port2);
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <CloneSelected engine={engine} model={model} />;
|
||||
};
|
||||
@@ -1,18 +0,0 @@
|
||||
import * as SRD from "storm-react-diagrams";
|
||||
import { DiamonNodeWidget } from "./DiamondNodeWidget";
|
||||
import { DiamondNodeModel } from "./DiamondNodeModel";
|
||||
import * as React from "react";
|
||||
|
||||
export class DiamondNodeFactory extends SRD.AbstractNodeFactory {
|
||||
constructor() {
|
||||
super("diamond");
|
||||
}
|
||||
|
||||
generateReactWidget(diagramEngine: SRD.DiagramEngine, node: SRD.NodeModel): JSX.Element {
|
||||
return <DiamonNodeWidget node={node} />;
|
||||
}
|
||||
|
||||
getNewInstance() {
|
||||
return new DiamondNodeModel();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { NodeModel } from "storm-react-diagrams";
|
||||
import { DiamondPortModel } from "./DiamondPortModel";
|
||||
|
||||
export class DiamondNodeModel extends NodeModel {
|
||||
constructor() {
|
||||
super("diamond");
|
||||
this.addPort(new DiamondPortModel("top"));
|
||||
this.addPort(new DiamondPortModel("left"));
|
||||
this.addPort(new DiamondPortModel("bottom"));
|
||||
this.addPort(new DiamondPortModel("right"));
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { DiamondNodeModel } from "./DiamondNodeModel";
|
||||
import { PortWidget } from "storm-react-diagrams";
|
||||
|
||||
export interface DiamonNodeWidgetProps {
|
||||
node: DiamondNodeModel;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export interface DiamonNodeWidgetState {}
|
||||
|
||||
/**
|
||||
* @author Dylan Vorster
|
||||
*/
|
||||
export class DiamonNodeWidget extends React.Component<DiamonNodeWidgetProps, DiamonNodeWidgetState> {
|
||||
public static defaultProps: DiamonNodeWidgetProps = {
|
||||
size: 150,
|
||||
node: null
|
||||
};
|
||||
|
||||
constructor(props: DiamonNodeWidgetProps) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
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="purple" stroke="#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>
|
||||
`
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
zIndex: 10,
|
||||
top: this.props.size / 2 - 8,
|
||||
left: -8
|
||||
}}
|
||||
>
|
||||
<PortWidget name="left" node={this.props.node} />
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
zIndex: 10,
|
||||
left: this.props.size / 2 - 8,
|
||||
top: -8
|
||||
}}
|
||||
>
|
||||
<PortWidget name="top" node={this.props.node} />
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
zIndex: 10,
|
||||
left: this.props.size - 8,
|
||||
top: this.props.size / 2 - 8
|
||||
}}
|
||||
>
|
||||
<PortWidget name="right" node={this.props.node} />
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
zIndex: 10,
|
||||
left: this.props.size / 2 - 8,
|
||||
top: this.props.size - 8
|
||||
}}
|
||||
>
|
||||
<PortWidget name="bottom" node={this.props.node} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
import * as _ from "lodash";
|
||||
import { LinkModel, DiagramEngine, PortModel, DefaultLinkModel } from "storm-react-diagrams";
|
||||
|
||||
export class DiamondPortModel extends PortModel {
|
||||
position: string | "top" | "bottom" | "left" | "right";
|
||||
|
||||
constructor(pos: string = "top") {
|
||||
super(pos, "diamond");
|
||||
this.position = pos;
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return _.merge(super.serialize(), {
|
||||
position: this.position
|
||||
});
|
||||
}
|
||||
|
||||
deSerialize(data: any, engine: DiagramEngine) {
|
||||
super.deSerialize(data, engine);
|
||||
this.position = data.position;
|
||||
}
|
||||
|
||||
createLinkModel(): LinkModel {
|
||||
return new DefaultLinkModel();
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { PortModel, AbstractPortFactory } from "storm-react-diagrams";
|
||||
|
||||
export class SimplePortFactory extends AbstractPortFactory {
|
||||
cb: (initialConfig?: any) => PortModel;
|
||||
|
||||
constructor(type: string, cb: (initialConfig?: any) => PortModel) {
|
||||
super(type);
|
||||
this.cb = cb;
|
||||
}
|
||||
|
||||
getNewInstance(initialConfig?: any): PortModel {
|
||||
return this.cb(initialConfig);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import {
|
||||
DiagramEngine,
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
DefaultPortModel,
|
||||
DiagramWidget
|
||||
} from "storm-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";
|
||||
|
||||
/**
|
||||
* @Author Dylan Vorster
|
||||
*/
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
// register some other factories as well
|
||||
engine.registerPortFactory(new SimplePortFactory("diamond", config => new DiamondPortModel()));
|
||||
engine.registerNodeFactory(new DiamondNodeFactory());
|
||||
|
||||
//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, 150);
|
||||
|
||||
//3-B) create our new custom node
|
||||
var node2 = new DiamondNodeModel();
|
||||
node2.setPosition(250, 108);
|
||||
|
||||
var node3 = new DefaultNodeModel("Node 3", "red");
|
||||
var port3 = node3.addInPort("In");
|
||||
node3.setPosition(500, 150);
|
||||
|
||||
//3-C) link the 2 nodes together
|
||||
var link1 = port1.link(node2.getPort("left"));
|
||||
var link2 = port3.link(node2.getPort("right"));
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addAll(node1, node2, node3, link1, link2);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
|
||||
};
|
||||
@@ -1,56 +0,0 @@
|
||||
import * as dagre from "dagre";
|
||||
import * as _ from "lodash";
|
||||
|
||||
const size = {
|
||||
width: 60,
|
||||
height: 60
|
||||
};
|
||||
|
||||
export function distributeElements(model) {
|
||||
let clonedModel = _.cloneDeep(model);
|
||||
let nodes = distributeGraph(clonedModel);
|
||||
nodes.forEach(node => {
|
||||
let modelNode = clonedModel.nodes.find(item => item.id === node.id);
|
||||
modelNode.x = node.x - node.width / 2;
|
||||
modelNode.y = node.y - node.height / 2;
|
||||
});
|
||||
return clonedModel;
|
||||
}
|
||||
|
||||
function distributeGraph(model) {
|
||||
let nodes = mapElements(model);
|
||||
let edges = mapEdges(model);
|
||||
let graph = new dagre.graphlib.Graph();
|
||||
graph.setGraph({});
|
||||
graph.setDefaultEdgeLabel(() => ({}));
|
||||
//add elements to dagre graph
|
||||
nodes.forEach(node => {
|
||||
graph.setNode(node.id, node.metadata);
|
||||
});
|
||||
edges.forEach(edge => {
|
||||
if (edge.from && edge.to) {
|
||||
graph.setEdge(edge.from, edge.to);
|
||||
}
|
||||
});
|
||||
//auto-distribute
|
||||
dagre.layout(graph);
|
||||
return graph.nodes().map(node => graph.node(node));
|
||||
}
|
||||
|
||||
function mapElements(model) {
|
||||
// dagre compatible format
|
||||
return model.nodes.map(node => ({ id: node.id, metadata: { ...size, id: node.id } }));
|
||||
}
|
||||
|
||||
function mapEdges(model) {
|
||||
// returns links which connects nodes
|
||||
// we check are there both from and to nodes in the model. Sometimes links can be detached
|
||||
return model.links
|
||||
.map(link => ({
|
||||
from: link.source,
|
||||
to: link.target
|
||||
}))
|
||||
.filter(
|
||||
item => model.nodes.find(node => node.id === item.from) && model.nodes.find(node => node.id === item.to)
|
||||
);
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
import {
|
||||
DiagramEngine,
|
||||
DefaultNodeFactory,
|
||||
DefaultLinkFactory,
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
DefaultPortModel,
|
||||
DiagramWidget
|
||||
} from "storm-react-diagrams";
|
||||
import { distributeElements } from "./dagre-utils";
|
||||
import * as React from "react";
|
||||
import { DemoWorkspaceWidget } from "../.helpers/DemoWorkspaceWidget";
|
||||
|
||||
function createNode(name) {
|
||||
return new DefaultNodeModel(name, "rgb(0,192,255)");
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
|
||||
function connectNodes(nodeFrom, nodeTo) {
|
||||
//just to get id-like structure
|
||||
count++;
|
||||
const portOut = nodeFrom.addPort(new DefaultPortModel(true, `${nodeFrom.name}-out-${count}`, "Out"));
|
||||
const portTo = nodeTo.addPort(new DefaultPortModel(false, `${nodeFrom.name}-to-${count}`, "IN"));
|
||||
return portOut.link(portTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests auto distribution
|
||||
*/
|
||||
class Demo8Widget extends React.Component<any, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
this.autoDistribute = this.autoDistribute.bind(this);
|
||||
}
|
||||
|
||||
autoDistribute() {
|
||||
const { engine } = this.props;
|
||||
const model = engine.getDiagramModel();
|
||||
let distributedModel = getDistributedModel(engine, model);
|
||||
engine.setDiagramModel(distributedModel);
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { engine } = this.props;
|
||||
|
||||
return (
|
||||
<DemoWorkspaceWidget buttons={<button onClick={this.autoDistribute}>Re-distribute</button>}>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getDistributedModel(engine, model) {
|
||||
const serialized = model.serializeDiagram();
|
||||
const distributedSerializedDiagram = distributeElements(serialized);
|
||||
|
||||
//deserialize the model
|
||||
let deSerializedModel = new DiagramModel();
|
||||
deSerializedModel.deSerializeDiagram(distributedSerializedDiagram, engine);
|
||||
return deSerializedModel;
|
||||
}
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
let engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
//2) setup the diagram model
|
||||
let model = new DiagramModel();
|
||||
|
||||
//3) create a default nodes
|
||||
let nodesFrom = [];
|
||||
let nodesTo = [];
|
||||
|
||||
nodesFrom.push(createNode("from-1"));
|
||||
nodesFrom.push(createNode("from-2"));
|
||||
nodesFrom.push(createNode("from-3"));
|
||||
|
||||
nodesTo.push(createNode("to-1"));
|
||||
nodesTo.push(createNode("to-2"));
|
||||
nodesTo.push(createNode("to-3"));
|
||||
|
||||
//4) link nodes together
|
||||
let links = nodesFrom.map((node, index) => {
|
||||
return connectNodes(node, nodesTo[index]);
|
||||
});
|
||||
|
||||
// more links for more complicated diagram
|
||||
links.push(connectNodes(nodesFrom[0], nodesTo[1]));
|
||||
links.push(connectNodes(nodesTo[0], nodesFrom[1]));
|
||||
links.push(connectNodes(nodesFrom[1], nodesTo[2]));
|
||||
|
||||
// initial random position
|
||||
nodesFrom.forEach((node, index) => {
|
||||
node.x = index * 70;
|
||||
model.addNode(node);
|
||||
});
|
||||
|
||||
nodesTo.forEach((node, index) => {
|
||||
node.x = index * 70;
|
||||
node.y = 100;
|
||||
model.addNode(node);
|
||||
});
|
||||
|
||||
links.forEach(link => {
|
||||
model.addLink(link);
|
||||
});
|
||||
|
||||
//5) load model into engine
|
||||
let model2 = getDistributedModel(engine, model);
|
||||
|
||||
engine.setDiagramModel(model2);
|
||||
|
||||
return <Demo8Widget engine={engine} />;
|
||||
};
|
||||
@@ -1,72 +0,0 @@
|
||||
import * as React from "react";
|
||||
import * as _ from "lodash";
|
||||
import { TrayWidget } from "./TrayWidget";
|
||||
import { Application } from "../Application";
|
||||
import { TrayItemWidget } from "./TrayItemWidget";
|
||||
import { DefaultNodeModel, DiagramWidget } from "storm-react-diagrams";
|
||||
|
||||
export interface BodyWidgetProps {
|
||||
app: Application;
|
||||
}
|
||||
|
||||
export interface BodyWidgetState {}
|
||||
|
||||
/**
|
||||
* @author Dylan Vorster
|
||||
*/
|
||||
export class BodyWidget extends React.Component<BodyWidgetProps, BodyWidgetState> {
|
||||
constructor(props: BodyWidgetProps) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="body">
|
||||
<div className="header">
|
||||
<div className="title">Storm React Diagrams - Demo 5</div>
|
||||
</div>
|
||||
<div className="content">
|
||||
<TrayWidget>
|
||||
<TrayItemWidget model={{ type: "in" }} name="In Node" color="rgb(192,255,0)" />
|
||||
<TrayItemWidget model={{ type: "out" }} name="Out Node" color="rgb(0,192,255)" />
|
||||
</TrayWidget>
|
||||
<div
|
||||
className="diagram-layer"
|
||||
onDrop={event => {
|
||||
var data = JSON.parse(event.dataTransfer.getData("storm-diagram-node"));
|
||||
var nodesCount = _.keys(
|
||||
this.props.app
|
||||
.getDiagramEngine()
|
||||
.getDiagramModel()
|
||||
.getNodes()
|
||||
).length;
|
||||
|
||||
var node = 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 points = this.props.app.getDiagramEngine().getRelativeMousePoint(event);
|
||||
node.x = points.x;
|
||||
node.y = points.y;
|
||||
this.props.app
|
||||
.getDiagramEngine()
|
||||
.getDiagramModel()
|
||||
.addNode(node);
|
||||
this.forceUpdate();
|
||||
}}
|
||||
onDragOver={event => {
|
||||
event.preventDefault();
|
||||
}}
|
||||
>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={this.props.app.getDiagramEngine()} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import * as React from "react";
|
||||
|
||||
export interface TrayItemWidgetProps {
|
||||
model: any;
|
||||
color?: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface TrayItemWidgetState {}
|
||||
|
||||
export class TrayItemWidget extends React.Component<TrayItemWidgetProps, TrayItemWidgetState> {
|
||||
constructor(props: TrayItemWidgetProps) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
style={{ borderColor: this.props.color }}
|
||||
draggable={true}
|
||||
onDragStart={event => {
|
||||
event.dataTransfer.setData("storm-diagram-node", JSON.stringify(this.props.model));
|
||||
}}
|
||||
className="tray-item"
|
||||
>
|
||||
{this.props.name}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import * as React from "react";
|
||||
|
||||
export interface TrayWidgetProps {}
|
||||
|
||||
export interface TrayWidgetState {}
|
||||
|
||||
/**
|
||||
* @author Dylan Vorster
|
||||
*/
|
||||
export class TrayWidget extends React.Component<TrayWidgetProps, TrayWidgetState> {
|
||||
public static defaultProps: TrayWidgetProps = {};
|
||||
|
||||
constructor(props: TrayWidgetProps) {
|
||||
super(props);
|
||||
this.state = {};
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div className="tray">{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
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,47 +0,0 @@
|
||||
.body{
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100%;
|
||||
|
||||
.header{
|
||||
display: flex;
|
||||
background: rgb(30,30,30);
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
color: white;
|
||||
font-family: Helvetica, Arial;
|
||||
padding: 10px;
|
||||
>*{
|
||||
align-self:center;
|
||||
}
|
||||
}
|
||||
|
||||
.content{
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
|
||||
.diagram-layer{
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.tray{
|
||||
min-width: 200px;
|
||||
background: rgb(20,20,20);
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
.tray-item{
|
||||
color: white;
|
||||
font-family: Helvetica, Arial;
|
||||
padding: 5px;
|
||||
margin: 0px 10px;
|
||||
border: solid 1px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
import { DiagramEngine, DiagramModel, DefaultNodeModel, LinkModel, DiagramWidget } from "storm-react-diagrams";
|
||||
import * as React from "react";
|
||||
|
||||
/**
|
||||
* Tests the grid size
|
||||
*/
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
//2) setup the diagram model
|
||||
var model = new DiagramModel();
|
||||
model.setGridSize(50);
|
||||
|
||||
//3-A) create a default node
|
||||
var node1 = new DefaultNodeModel("Node 1", "rgb(0,192,255)");
|
||||
let port = node1.addOutPort("Out");
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new DefaultNodeModel("Node 2", "rgb(192,255,0)");
|
||||
let port2 = node2.addInPort("In");
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
// link the ports
|
||||
let link1 = port.link(port2);
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
|
||||
};
|
||||
@@ -1,72 +0,0 @@
|
||||
import {
|
||||
DiagramEngine,
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
DefaultPortModel,
|
||||
DiagramWidget,
|
||||
DefaultLinkModel
|
||||
} from "storm-react-diagrams";
|
||||
import * as React from "react";
|
||||
import { DemoWorkspaceWidget } from "../.helpers/DemoWorkspaceWidget";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
|
||||
export default () => {
|
||||
// setup the diagram engine
|
||||
const engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
// setup the diagram model
|
||||
const model = new DiagramModel();
|
||||
|
||||
// create four nodes
|
||||
const node1 = new DefaultNodeModel("Node A", "rgb(0,192,255)");
|
||||
const port1 = node1.addOutPort("Out");
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
const node2 = new DefaultNodeModel("Node B", "rgb(255,255,0)");
|
||||
const port2 = node2.addInPort("In");
|
||||
node2.setPosition(400, 50);
|
||||
|
||||
const node3 = new DefaultNodeModel("Node C (no label)", "rgb(192,255,255)");
|
||||
const port3 = node3.addInPort("In");
|
||||
node3.setPosition(450, 180);
|
||||
|
||||
const node4 = new DefaultNodeModel("Node D", "rgb(192,0,255)");
|
||||
const port4 = node4.addInPort("In");
|
||||
node4.setPosition(300, 250);
|
||||
|
||||
// link node A and B together and give it a label
|
||||
const link1 = port1.link(port2);
|
||||
(link1 as DefaultLinkModel).addLabel("Custom label 1");
|
||||
(link1 as DefaultLinkModel).addLabel("Custom label 2");
|
||||
|
||||
// no label for A and C, just a link
|
||||
const link2 = port1.link(port3);
|
||||
|
||||
// also a label for A and D
|
||||
const link3 = port1.link(port4);
|
||||
(link3 as DefaultLinkModel).addLabel("Emoji label: 🎉");
|
||||
|
||||
// add all to the main model
|
||||
model.addAll(node1, node2, node3, node4, link1, link2, link3);
|
||||
|
||||
// load model into engine and render
|
||||
engine.setDiagramModel(model);
|
||||
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={
|
||||
<button
|
||||
onClick={() => {
|
||||
action("Serialized Graph")(JSON.stringify(model.serializeDiagram(), null, 2));
|
||||
}}
|
||||
>
|
||||
Serialize Graph
|
||||
</button>
|
||||
}
|
||||
>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
};
|
||||
@@ -1,49 +0,0 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
DiagramEngine,
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
DiagramWidget,
|
||||
DiagramProps
|
||||
} from "storm-react-diagrams";
|
||||
|
||||
/**
|
||||
* Shows that a limit of points can be set for links
|
||||
*/
|
||||
export default () => {
|
||||
// setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
var model = new DiagramModel();
|
||||
|
||||
//3-A) create a default node
|
||||
var node1 = new DefaultNodeModel("Node 1", "rgb(0,192,255)");
|
||||
let port = node1.addOutPort("Out");
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new DefaultNodeModel("Node 2", "rgb(192,255,0)");
|
||||
let port2 = node2.addInPort("In");
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
// link the ports
|
||||
let link1 = port.link(port2);
|
||||
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
engine.setDiagramModel(model);
|
||||
|
||||
var props = {
|
||||
diagramEngine: engine,
|
||||
maxNumberPointsPerLink: 5
|
||||
} as DiagramProps;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>A maximum of 5 points can be created per link.</p>
|
||||
<DiagramWidget className="srd-demo-canvas" {...props} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,62 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import {
|
||||
DiagramEngine,
|
||||
DiagramModel,
|
||||
DiagramProps,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
DiagramWidget
|
||||
} from "storm-react-diagrams";
|
||||
|
||||
/**
|
||||
* Shows some of the events triggered when elements are selected
|
||||
*/
|
||||
export default () => {
|
||||
// setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
var model = new DiagramModel();
|
||||
|
||||
// sample for link with simple line
|
||||
var node1 = new DefaultNodeModel("Node 1", "rgb(255,99,66)");
|
||||
var port1 = node1.addOutPort("Out");
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
var node2 = new DefaultNodeModel("Node 2", "rgb(192,255,0)");
|
||||
var port2 = node2.addInPort("In");
|
||||
node2.setPosition(400, 40);
|
||||
|
||||
var node3 = new DefaultNodeModel("Node 3", "rgb(128,99,255)");
|
||||
var port3 = node3.addInPort("In");
|
||||
node3.setPosition(300, 160);
|
||||
|
||||
//link the nodes
|
||||
let link1 = port1.link(port2);
|
||||
let link2 = port1.link(port3);
|
||||
|
||||
// add all the models
|
||||
let models = model.addAll(node1, node2, node3, link1, link2);
|
||||
|
||||
// add a selection listener to each
|
||||
models.forEach(item => {
|
||||
item.addListener({
|
||||
selectionChanged: action("selectionChanged")
|
||||
});
|
||||
});
|
||||
|
||||
engine.setDiagramModel(model);
|
||||
|
||||
var props = {
|
||||
diagramEngine: engine,
|
||||
maxNumberPointsPerLink: 0 // no extra points so link selection is fired straight away
|
||||
} as DiagramProps;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>Click the diagram elements to inspect some of the possible events.</p>
|
||||
<DiagramWidget className="srd-demo-canvas" {...props} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,69 +0,0 @@
|
||||
import * as React from "react";
|
||||
import {
|
||||
DiagramEngine,
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
PointModel,
|
||||
DiagramWidget,
|
||||
DiagramProps
|
||||
} from "storm-react-diagrams";
|
||||
|
||||
/**
|
||||
*
|
||||
* Shows how you can lock down the system so that the entire scene cant be interacted with.
|
||||
*
|
||||
* @Author Dylan Vorster
|
||||
*/
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
var model = new DiagramModel();
|
||||
|
||||
// sample for link with simple line (no additional points)
|
||||
var node1 = new DefaultNodeModel("Node 1", "rgb(0,192,255)");
|
||||
var port1 = node1.addOutPort("Out");
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
var node2 = new DefaultNodeModel("Node 2", "rgb(192,255,0)");
|
||||
var port2 = node2.addInPort("In");
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
let link1 = port1.link(port2);
|
||||
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
// sample for link with complex line (additional points)
|
||||
var node3 = new DefaultNodeModel("Node 3", "rgb(0,192,255)");
|
||||
var port3 = node3.addOutPort("Out");
|
||||
node3.setPosition(100, 250);
|
||||
|
||||
var node4 = new DefaultNodeModel("Node 4", "rgb(192,255,0)");
|
||||
var port4 = node4.addInPort("In");
|
||||
node4.setPosition(400, 250);
|
||||
|
||||
var link2 = port3.link(port4);
|
||||
|
||||
link2.point(350, 225);
|
||||
link2.point(200, 225);
|
||||
|
||||
model.addAll(node3, node4, link2);
|
||||
|
||||
engine.setDiagramModel(model);
|
||||
|
||||
//!========================================= <<<<<<<
|
||||
|
||||
model.setLocked(true);
|
||||
var props = {
|
||||
diagramEngine: engine,
|
||||
allowLooseLinks: false,
|
||||
allowCanvasTranslation: false,
|
||||
allowCanvasZoom: false
|
||||
} as DiagramProps;
|
||||
|
||||
//!========================================= <<<<<<<
|
||||
|
||||
return <DiagramWidget className="srd-demo-canvas" {...props} />;
|
||||
};
|
||||
@@ -1,86 +0,0 @@
|
||||
import { DiagramEngine, DiagramModel, DefaultNodeModel, LinkModel, DiagramWidget } from "storm-react-diagrams";
|
||||
import * as React from "react";
|
||||
import { DemoWorkspaceWidget } from "../.helpers/DemoWorkspaceWidget";
|
||||
|
||||
/**
|
||||
* Tests the grid size
|
||||
*/
|
||||
class NodeDelayedPosition extends React.Component<any, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.updatePosition = this.updatePosition.bind(this);
|
||||
this.updatePositionViaSerialize = this.updatePositionViaSerialize.bind(this);
|
||||
}
|
||||
|
||||
updatePosition() {
|
||||
const { engine } = this.props;
|
||||
let model = engine.getDiagramModel();
|
||||
const nodes = model.getNodes();
|
||||
let node = nodes[Object.keys(nodes)[0]];
|
||||
node.setPosition(node.x + 30, node.y + 30);
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
updatePositionViaSerialize() {
|
||||
let { engine } = this.props;
|
||||
let model = engine.getDiagramModel();
|
||||
let str = JSON.stringify(model.serializeDiagram());
|
||||
let model2 = new DiagramModel();
|
||||
let obj = JSON.parse(str);
|
||||
let node = obj.nodes[0];
|
||||
node.x += 30;
|
||||
node.y += 30;
|
||||
model2.deSerializeDiagram(obj, engine);
|
||||
engine.setDiagramModel(model2);
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { engine } = this.props;
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={[
|
||||
<button key={1} onClick={this.updatePosition}>
|
||||
Update position
|
||||
</button>,
|
||||
<button key={2} onClick={this.updatePositionViaSerialize}>
|
||||
Update position via serialize
|
||||
</button>
|
||||
]}
|
||||
>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
//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.setDiagramModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <NodeDelayedPosition engine={engine} model={model} />;
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
import { DiagramEngine, DiagramModel, DefaultNodeModel, LinkModel, DiagramWidget } from "storm-react-diagrams";
|
||||
import * as React from "react";
|
||||
import { DemoWorkspaceWidget } from "../.helpers/DemoWorkspaceWidget";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import * as beautify from "json-beautify";
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
//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.setDiagramModel(model);
|
||||
|
||||
//!------------- SERIALIZING ------------------
|
||||
|
||||
var str = JSON.stringify(model.serializeDiagram());
|
||||
|
||||
//!------------- DESERIALIZING ----------------
|
||||
|
||||
var model2 = new DiagramModel();
|
||||
model2.deSerializeDiagram(JSON.parse(str), engine);
|
||||
engine.setDiagramModel(model2);
|
||||
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={
|
||||
<button
|
||||
onClick={() => {
|
||||
action("Serialized Graph")(beautify(model2.serializeDiagram(), null, 2, 80));
|
||||
}}
|
||||
>
|
||||
Serialize Graph
|
||||
</button>
|
||||
}
|
||||
>
|
||||
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
};
|
||||
@@ -1,38 +0,0 @@
|
||||
import { DiagramEngine, DiagramModel, DefaultNodeModel, LinkModel, DiagramWidget } from "storm-react-diagrams";
|
||||
import * as React from "react";
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
//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);
|
||||
|
||||
//3-D) create an orphaned node
|
||||
var node3 = new DefaultNodeModel("Node 3", "rgb(0,192,255)");
|
||||
node3.addOutPort("Out");
|
||||
node3.setPosition(100, 200);
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addAll(node1, node2, node3, link1);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} allowLooseLinks={false} />;
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
# Simple Usage
|
||||
|
||||
Welcome to STORM React Diagrams (SRD). SRD is a no-nonsense easy to use library for creating
|
||||
flow diagrams in the web that can ultimately represent any type of process/network/graph etc..
|
||||
|
||||
<!-- STORY -->
|
||||
|
||||
Try moving around one of the nodes or clicking and dragging the links to create new link anchors (points).
|
||||
You can also zoom the canvas using the mouse wheel / scroll gesture and drag to select multiple entities on the graph by shift + dragging the mouse.
|
||||
@@ -1,41 +0,0 @@
|
||||
import {
|
||||
DiagramEngine,
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
DiagramWidget,
|
||||
DefaultLinkModel
|
||||
} from "storm-react-diagrams";
|
||||
import * as React from "react";
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
//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)");
|
||||
let port1 = node1.addOutPort("Out");
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new DefaultNodeModel("Node 2", "rgb(192,255,0)");
|
||||
let port2 = node2.addInPort("In");
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
// link the ports
|
||||
let link1 = port1.link(port2);
|
||||
(link1 as DefaultLinkModel).addLabel("Hello World!");
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setDiagramModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
|
||||
};
|
||||
@@ -1,68 +0,0 @@
|
||||
import {
|
||||
DiagramEngine,
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
DefaultPortModel,
|
||||
DiagramWidget
|
||||
} from "storm-react-diagrams";
|
||||
import * as React from "react";
|
||||
import { DemoWorkspaceWidget } from "../.helpers/DemoWorkspaceWidget";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
|
||||
export default () => {
|
||||
// setup the diagram engine
|
||||
const engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
|
||||
// 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 DefaultPortModel(false, "out-1", "Out"));
|
||||
node1.setPosition(340, 350);
|
||||
|
||||
const node2 = new DefaultNodeModel("Node B", "rgb(255,255,0)");
|
||||
const port2 = node2.addPort(new DefaultPortModel(false, "out-1", "Out"));
|
||||
node2.setPosition(240, 80);
|
||||
const node3 = new DefaultNodeModel("Node C", "rgb(192,255,255)");
|
||||
const port3 = node3.addPort(new DefaultPortModel(true, "in-1", "In"));
|
||||
node3.setPosition(540, 180);
|
||||
const node4 = new DefaultNodeModel("Node D", "rgb(192,0,255)");
|
||||
const port4 = node4.addPort(new DefaultPortModel(true, "in-1", "In"));
|
||||
node4.setPosition(95, 185);
|
||||
const node5 = new DefaultNodeModel("Node E", "rgb(192,255,0)");
|
||||
node5.setPosition(250, 180);
|
||||
|
||||
// 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, node5, link1, link2);
|
||||
|
||||
// load model into engine and render
|
||||
engine.setDiagramModel(model);
|
||||
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={
|
||||
<button
|
||||
onClick={() => {
|
||||
action("Serialized Graph")(JSON.stringify(model.serializeDiagram(), null, 2));
|
||||
}}
|
||||
>
|
||||
Serialize Graph
|
||||
</button>
|
||||
}
|
||||
>
|
||||
<DiagramWidget
|
||||
className="srd-demo-canvas"
|
||||
diagramEngine={engine}
|
||||
smartRouting={true}
|
||||
maxNumberPointsPerLink={0}
|
||||
/>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
};
|
||||
@@ -1,71 +0,0 @@
|
||||
import * as React from "react";
|
||||
import {storiesOf, addDecorator, addParameters} from "@storybook/react";
|
||||
import {setOptions} from "@storybook/addon-options";
|
||||
import {host} from "storybook-host";
|
||||
import {Helper} from "./.helpers/Helper";
|
||||
import {Toolkit} from "../src/Toolkit";
|
||||
import {themes} from '@storybook/theming';
|
||||
|
||||
addParameters({
|
||||
options: {
|
||||
theme: themes.dark,
|
||||
},
|
||||
});
|
||||
|
||||
//include the SCSS for the demo
|
||||
import "./.helpers/demo.scss";
|
||||
|
||||
setOptions({
|
||||
name: "STORM React Diagrams",
|
||||
url: "https://github.com/projectstorm/react-diagrams",
|
||||
addonPanelInRight: true
|
||||
});
|
||||
|
||||
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_limit_points from "./demo-limit-points";
|
||||
import demo_listeners from "./demo-listeners";
|
||||
import demo_zoom from "./demo-zoom-to-fit";
|
||||
import demo_labels from "./demo-labelled-links";
|
||||
|
||||
storiesOf("Simple Usage", module)
|
||||
.add("Simple example", demo_simple)
|
||||
.add("Simple flow example", demo_flow)
|
||||
.add("Performance demo", demo_performance)
|
||||
.add("Locked widget", demo_locks)
|
||||
.add("Canvas grid size", demo_grid)
|
||||
.add("Limiting link points", demo_limit_points)
|
||||
.add("Events and listeners", demo_listeners)
|
||||
.add("Zoom to fit", demo_zoom)
|
||||
.add("Links with labels", demo_labels);
|
||||
|
||||
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";
|
||||
|
||||
storiesOf("Advanced Techniques", module)
|
||||
.add("Clone Selected", demo_adv_clone_selected)
|
||||
.add("Serializing and de-serializing", demo_adv_ser_des)
|
||||
.add("Programatically modifying graph", demo_adv_prog)
|
||||
.add("Drag and drop", demo_adv_dnd)
|
||||
.add("Smart routing", demo_smart_routing);
|
||||
|
||||
import demo_cust_nodes from "./demo-custom-node1";
|
||||
import demo_cust_links from "./demo-custom-link1";
|
||||
|
||||
storiesOf("Custom Models", module)
|
||||
.add("Custom diamond node", demo_cust_nodes)
|
||||
.add("Custom animated links", demo_cust_links);
|
||||
|
||||
import demo_3rd_dagre from "./demo-dagre";
|
||||
|
||||
storiesOf("3rd party libraries", module)
|
||||
.add("Auto Distribute (Dagre)", demo_3rd_dagre);
|
||||
|
||||
// enable this to log mouse location when writing new puppeteer tests
|
||||
//Helper.logMousePosition()
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"extends": [
|
||||
"../tslint.json"
|
||||
],
|
||||
"rules": {
|
||||
"no-console": false,
|
||||
"max-classes-per-file": false,
|
||||
"no-var-requires": false
|
||||
}
|
||||
}
|
||||
7
diagrams-demo-gallery/.storybook/main.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
stories: ['../demos/*.stories.tsx'],
|
||||
core: {
|
||||
builder: 'webpack5'
|
||||
},
|
||||
addons: ['@storybook/addon-actions']
|
||||
};
|
||||
7
diagrams-demo-gallery/.storybook/manager.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import { addons } from '@storybook/addons';
|
||||
|
||||
import diagramsTheme from './theme';
|
||||
|
||||
addons.setConfig({
|
||||
theme: diagramsTheme
|
||||
});
|
||||
3
diagrams-demo-gallery/.storybook/preview.js
Normal file
@@ -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'
|
||||
});
|
||||
59
diagrams-demo-gallery/CHANGELOG.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# @projectstorm/react-diagrams-gallery
|
||||
|
||||
## 7.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b8a4cbd: Inline sources in sourcemap
|
||||
- Updated dependencies [b8a4cbd]
|
||||
- @projectstorm/react-canvas-core@7.0.1
|
||||
- @projectstorm/react-diagrams@7.0.2
|
||||
- @projectstorm/react-diagrams-core@7.0.1
|
||||
- @projectstorm/react-diagrams-defaults@7.1.1
|
||||
|
||||
## 7.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- e0d21f1: - [feature] new ability to refresh links in auto distribute system [PR 756](https://github.com/projectstorm/react-diagrams/pull/756)
|
||||
|
||||
- [fix] Default link now uses the correct method for creating a point allowing this to be overridden [PR 939](https://github.com/projectstorm/react-diagrams/pull/939)
|
||||
|
||||
Big thanks to @ToTheHit and @h0111in for your help on these, even though its very delayed on my part :)
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [e0d21f1]
|
||||
- @projectstorm/react-diagrams-defaults@7.1.0
|
||||
- @projectstorm/react-diagrams@7.0.1
|
||||
|
||||
## 7.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- b051697: - [internal] moves to `Pnpm` (instead of yarn -\_-)
|
||||
- [internal]moves to `Changesets` for releases
|
||||
- [internal]removes `Lerna`
|
||||
- [internal] upgrades all dependencies
|
||||
- [internal] switches to workspace protocol syntax (Changesets will bake in the correct version when a publish occurs)
|
||||
- [internal] Changesets will open a release PR which can wrap up several changes in 1 go
|
||||
- [internal] Changesets will run the storybook deploy automatically upon merging the release PR
|
||||
- [internal] removes a lot of the stuff from the root package.json
|
||||
- [internal] cleans up the build and clean commands
|
||||
- [internal] remove E2E tests, they are a nightmare to maintain and the ROI is far too low
|
||||
- [fix] Wrong type name for react-canvas model listener
|
||||
- [fix] export more stuff form the main react-diagrams package
|
||||
- [fix] circular deps with Rectangle and Polygon (turns out this was a problem but only with UMD builds, sorry @everyone who I doubted, but this is also why I could never reproduce the issue)
|
||||
- [breaking change] compile both ES6 and UMD
|
||||
- [breaking change] moves dependencies back to each package. (After years of working on libraries, I've come to actually hate peer dependencies, and this is easily solved with build systems / package managers).
|
||||
- [breaking change] static methods on `Polygon` and `Rectangle` moved to standalone methods
|
||||
- [breaking change] static construction methods to rather deal with different Rectangle constructor overloads (I now consider this bad design)
|
||||
- [breaking change] introduce `Bounds` as a simpler point-array type to deal with boundary computation instead
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [b051697]
|
||||
- @projectstorm/react-diagrams-defaults@7.0.0
|
||||
- @projectstorm/react-diagrams-core@7.0.0
|
||||
- @projectstorm/react-canvas-core@7.0.0
|
||||
- @projectstorm/react-diagrams@7.0.0
|
||||
32
diagrams-demo-gallery/demos/1_SimpleUsage.stories.tsx
Normal file
@@ -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} />;
|
||||
};
|
||||
83
diagrams-demo-gallery/demos/demo-cloning/index.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, LinkModel, NodeModel } from '@projectstorm/react-diagrams';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { BaseModel, CanvasWidget } from '@projectstorm/react-canvas-core';
|
||||
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
|
||||
|
||||
/**
|
||||
* Tests cloning
|
||||
*/
|
||||
class CloneSelected extends React.Component<any, any> {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.cloneSelected = this.cloneSelected.bind(this);
|
||||
}
|
||||
|
||||
cloneSelected() {
|
||||
let { engine } = this.props;
|
||||
let offset = { x: 100, y: 100 };
|
||||
let model = engine.getModel();
|
||||
|
||||
let itemMap = {};
|
||||
_.forEach(model.getSelectedEntities(), (item: BaseModel<any>) => {
|
||||
let newItem = item.clone(itemMap);
|
||||
|
||||
// offset the nodes slightly
|
||||
if (newItem instanceof NodeModel) {
|
||||
newItem.setPosition(newItem.getX() + offset.x, newItem.getY() + offset.y);
|
||||
model.addNode(newItem);
|
||||
} else if (newItem instanceof LinkModel) {
|
||||
// offset the link points
|
||||
newItem.getPoints().forEach((p) => {
|
||||
p.setPosition(p.getX() + offset.x, p.getY() + offset.y);
|
||||
});
|
||||
model.addLink(newItem);
|
||||
}
|
||||
(newItem as BaseModel).setSelected(false);
|
||||
});
|
||||
|
||||
this.forceUpdate();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { engine } = this.props;
|
||||
return (
|
||||
<DemoWorkspaceWidget buttons={<DemoButton onClick={this.cloneSelected}>Clone Selected</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)');
|
||||
let port = node1.addOutPort('Out');
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
let port2 = node2.addInPort('In');
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
// link the ports
|
||||
let link1 = port.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 <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>
|
||||
);
|
||||
};
|
||||
@@ -1,23 +1,20 @@
|
||||
import {
|
||||
DiagramEngine,
|
||||
import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
LinkModel,
|
||||
DefaultPortModel,
|
||||
DiagramWidget,
|
||||
LinkWidget,
|
||||
LinkProps,
|
||||
DefaultLinkWidget,
|
||||
DefaultLinkModel,
|
||||
DefaultLinkFactory
|
||||
} from "storm-react-diagrams";
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import * as React from "react";
|
||||
DefaultLinkFactory,
|
||||
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() {
|
||||
super("advanced");
|
||||
this.width = 10;
|
||||
super({
|
||||
type: 'advanced',
|
||||
width: 10
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +51,8 @@ export class AdvancedLinkSegment extends React.Component<{ model: AdvancedLinkMo
|
||||
|
||||
let point = this.path.getPointAtLength(this.path.getTotalLength() * (this.percent / 100.0));
|
||||
|
||||
this.circle.setAttribute("cx", "" + point.x);
|
||||
this.circle.setAttribute("cy", "" + point.y);
|
||||
this.circle.setAttribute('cx', '' + point.x);
|
||||
this.circle.setAttribute('cy', '' + point.y);
|
||||
|
||||
if (this.mounted) {
|
||||
requestAnimationFrame(this.callback);
|
||||
@@ -72,15 +69,16 @@ export class AdvancedLinkSegment extends React.Component<{ model: AdvancedLinkMo
|
||||
return (
|
||||
<>
|
||||
<path
|
||||
ref={ref => {
|
||||
fill="none"
|
||||
ref={(ref) => {
|
||||
this.path = ref;
|
||||
}}
|
||||
strokeWidth={this.props.model.width}
|
||||
strokeWidth={this.props.model.getOptions().width}
|
||||
stroke="rgba(255,0,0,0.5)"
|
||||
d={this.props.path}
|
||||
/>
|
||||
<circle
|
||||
ref={ref => {
|
||||
ref={(ref) => {
|
||||
this.circle = ref;
|
||||
}}
|
||||
r={10}
|
||||
@@ -93,15 +91,14 @@ export class AdvancedLinkSegment extends React.Component<{ model: AdvancedLinkMo
|
||||
|
||||
export class AdvancedLinkFactory extends DefaultLinkFactory {
|
||||
constructor() {
|
||||
super();
|
||||
this.type = "advanced";
|
||||
super('advanced');
|
||||
}
|
||||
|
||||
getNewInstance(initialConfig?: any): AdvancedLinkModel {
|
||||
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} />
|
||||
@@ -117,29 +114,28 @@ export class AdvancedLinkFactory extends DefaultLinkFactory {
|
||||
*/
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
engine.registerLinkFactory(new AdvancedLinkFactory());
|
||||
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-1", "Out thick"));
|
||||
let port2 = node1.addPort(new DefaultPortModel(false, "out-2", "Out default"));
|
||||
var node1 = new DefaultNodeModel('Source', 'rgb(0,192,255)');
|
||||
let port1 = node1.addPort(new AdvancedPortModel(false, 'out-1', 'Out thick'));
|
||||
let port2 = node1.addPort(new DefaultPortModel(false, 'out-2', 'Out default'));
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
var node2 = new DefaultNodeModel("Target", "rgb(192,255,0)");
|
||||
var port3 = node2.addPort(new AdvancedPortModel(true, "in-1", "In thick"));
|
||||
var port4 = node2.addPort(new DefaultPortModel(true, "in-2", "In default"));
|
||||
var node2 = new DefaultNodeModel('Target', 'rgb(192,255,0)');
|
||||
var port3 = node2.addPort(new AdvancedPortModel(true, 'in-1', 'In thick'));
|
||||
var port4 = node2.addPort(new DefaultPortModel(true, 'in-2', 'In default'));
|
||||
node2.setPosition(300, 100);
|
||||
|
||||
var node3 = new DefaultNodeModel("Source", "rgb(0,192,255)");
|
||||
node3.addPort(new AdvancedPortModel(false, "out-1", "Out thick"));
|
||||
node3.addPort(new DefaultPortModel(false, "out-2", "Out default"));
|
||||
var node3 = new DefaultNodeModel('Source', 'rgb(0,192,255)');
|
||||
node3.addPort(new AdvancedPortModel(false, 'out-1', 'Out thick'));
|
||||
node3.addPort(new DefaultPortModel(false, 'out-2', 'Out default'));
|
||||
node3.setPosition(100, 200);
|
||||
|
||||
var node4 = new DefaultNodeModel("Target", "rgb(192,255,0)");
|
||||
node4.addPort(new AdvancedPortModel(true, "in-1", "In thick"));
|
||||
node4.addPort(new DefaultPortModel(true, "in-2", "In default"));
|
||||
var node4 = new DefaultNodeModel('Target', 'rgb(192,255,0)');
|
||||
node4.addPort(new AdvancedPortModel(true, 'in-1', 'In thick'));
|
||||
node4.addPort(new DefaultPortModel(true, 'in-2', 'In default'));
|
||||
node4.setPosition(300, 200);
|
||||
|
||||
var model = new DiagramModel();
|
||||
@@ -150,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,18 @@
|
||||
import { NodeModel, NodeModelGenerics, PortModelAlignment } from '@projectstorm/react-diagrams';
|
||||
import { DiamondPortModel } from './DiamondPortModel';
|
||||
|
||||
export interface DiamondNodeModelGenerics {
|
||||
PORT: DiamondPortModel;
|
||||
}
|
||||
|
||||
export class DiamondNodeModel extends NodeModel<NodeModelGenerics & DiamondNodeModelGenerics> {
|
||||
constructor() {
|
||||
super({
|
||||
type: 'diamond'
|
||||
});
|
||||
this.addPort(new DiamondPortModel(PortModelAlignment.TOP));
|
||||
this.addPort(new DiamondPortModel(PortModelAlignment.LEFT));
|
||||
this.addPort(new DiamondPortModel(PortModelAlignment.BOTTOM));
|
||||
this.addPort(new DiamondPortModel(PortModelAlignment.RIGHT));
|
||||
}
|
||||
}
|
||||
@@ -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 { LinkModel, PortModel, DefaultLinkModel, PortModelAlignment } from '@projectstorm/react-diagrams';
|
||||
|
||||
export class DiamondPortModel extends PortModel {
|
||||
constructor(alignment: PortModelAlignment) {
|
||||
super({
|
||||
type: 'diamond',
|
||||
name: alignment,
|
||||
alignment: alignment
|
||||
});
|
||||
}
|
||||
|
||||
createLinkModel(): LinkModel {
|
||||
return new DefaultLinkModel();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
68
diagrams-demo-gallery/demos/demo-custom-node1/index.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
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
|
||||
*/
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = createEngine();
|
||||
|
||||
// register some other factories as well
|
||||
engine
|
||||
.getPortFactories()
|
||||
.registerFactory(new SimplePortFactory('diamond', (config) => new DiamondPortModel(PortModelAlignment.LEFT)));
|
||||
engine.getNodeFactories().registerFactory(new DiamondNodeFactory());
|
||||
|
||||
//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, 200);
|
||||
|
||||
//3-B) create our new custom node
|
||||
var node2 = new DiamondNodeModel();
|
||||
node2.setPosition(250, 108);
|
||||
|
||||
var node3 = new DefaultNodeModel('Node 3', 'red');
|
||||
var port3 = node3.addInPort('In');
|
||||
node3.setPosition(500, 100);
|
||||
|
||||
//3-C) link the 2 nodes together
|
||||
var link1 = port1.link(node2.getPort(PortModelAlignment.LEFT));
|
||||
var link2 = port3.link(node2.getPort(PortModelAlignment.RIGHT));
|
||||
|
||||
var node4 = new DefaultNodeModel('Node 4', 'rgb(0,192,255)');
|
||||
var port4 = node4.addOutPort('Out');
|
||||
node4.setPosition(200, 10);
|
||||
|
||||
var link3 = port4.link(node2.getPort(PortModelAlignment.TOP));
|
||||
|
||||
var node5 = new DefaultNodeModel('Node 5', 'mediumpurple');
|
||||
var port5 = node5.addInPort('In');
|
||||
node5.setPosition(400, 300);
|
||||
|
||||
var link4 = port5.link(node2.getPort(PortModelAlignment.BOTTOM));
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addAll(node1, node2, node3, link1, link2, node4, link3, link4, node5);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
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>
|
||||
);
|
||||
};
|
||||
148
diagrams-demo-gallery/demos/demo-dagre/index.tsx
Normal file
@@ -0,0 +1,148 @@
|
||||
import createEngine, {
|
||||
DiagramModel,
|
||||
DefaultNodeModel,
|
||||
DefaultPortModel,
|
||||
NodeModel,
|
||||
DagreEngine,
|
||||
DiagramEngine,
|
||||
PathFindingLinkFactory
|
||||
} from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
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)');
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
|
||||
function connectNodes(nodeFrom, nodeTo, engine: DiagramEngine) {
|
||||
//just to get id-like structure
|
||||
count++;
|
||||
const portOut = nodeFrom.addPort(new DefaultPortModel(true, `${nodeFrom.name}-out-${count}`, 'Out'));
|
||||
const portTo = nodeTo.addPort(new DefaultPortModel(false, `${nodeFrom.name}-to-${count}`, 'IN'));
|
||||
return portOut.link(portTo);
|
||||
|
||||
// ################# UNCOMMENT THIS LINE FOR PATH FINDING #############################
|
||||
// return portOut.link(portTo, engine.getLinkFactories().getFactory(PathFindingLinkFactory.NAME));
|
||||
// #####################################################################################
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests auto distribution
|
||||
*/
|
||||
class DemoWidget extends React.Component<{ model: DiagramModel; engine: DiagramEngine }, any> {
|
||||
engine: DagreEngine;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.engine = new DagreEngine({
|
||||
graph: {
|
||||
rankdir: 'RL',
|
||||
ranker: 'longest-path',
|
||||
marginx: 25,
|
||||
marginy: 25
|
||||
},
|
||||
includeLinks: true,
|
||||
nodeMargin: 25
|
||||
});
|
||||
}
|
||||
|
||||
autoDistribute = () => {
|
||||
this.engine.redistribute(this.props.model);
|
||||
|
||||
// only happens if pathfing is enabled (check line 25)
|
||||
this.reroute();
|
||||
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();
|
||||
}, 500);
|
||||
}
|
||||
|
||||
reroute() {
|
||||
this.props.engine
|
||||
.getLinkFactories()
|
||||
.getFactory<PathFindingLinkFactory>(PathFindingLinkFactory.NAME)
|
||||
.calculateRoutingMatrix();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
let engine = createEngine();
|
||||
|
||||
//2) setup the diagram model
|
||||
let model = new DiagramModel();
|
||||
|
||||
//3) create a default nodes
|
||||
let nodesFrom: NodeModel[] = [];
|
||||
let nodesTo: NodeModel[] = [];
|
||||
|
||||
nodesFrom.push(createNode('from-1'));
|
||||
nodesFrom.push(createNode('from-2'));
|
||||
nodesFrom.push(createNode('from-3'));
|
||||
|
||||
nodesTo.push(createNode('to-1'));
|
||||
nodesTo.push(createNode('to-2'));
|
||||
nodesTo.push(createNode('to-3'));
|
||||
|
||||
//4) link nodes together
|
||||
let links = nodesFrom.map((node, index) => {
|
||||
return connectNodes(node, nodesTo[index], engine);
|
||||
});
|
||||
|
||||
// more links for more complicated diagram
|
||||
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) => {
|
||||
node.setPosition(index * 70, index * 70);
|
||||
model.addNode(node);
|
||||
});
|
||||
|
||||
nodesTo.forEach((node, index) => {
|
||||
node.setPosition(index * 70, 100);
|
||||
model.addNode(node);
|
||||
});
|
||||
|
||||
links.forEach((link) => {
|
||||
model.addLink(link);
|
||||
});
|
||||
|
||||
engine.setModel(model);
|
||||
|
||||
return <DemoWidget model={model} engine={engine} />;
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as SRD from "storm-react-diagrams";
|
||||
import * as SRD from '@projectstorm/react-diagrams';
|
||||
|
||||
/**
|
||||
* @author Dylan Vorster
|
||||
@@ -8,24 +8,22 @@ export class Application {
|
||||
protected diagramEngine: SRD.DiagramEngine;
|
||||
|
||||
constructor() {
|
||||
this.diagramEngine = new SRD.DiagramEngine();
|
||||
this.diagramEngine.installDefaultFactories();
|
||||
|
||||
this.diagramEngine = SRD.default();
|
||||
this.newModel();
|
||||
}
|
||||
|
||||
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)");
|
||||
let port = node1.addOutPort("Out");
|
||||
var node1 = new SRD.DefaultNodeModel('Node 1', 'rgb(0,192,255)');
|
||||
let port = node1.addOutPort('Out');
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new SRD.DefaultNodeModel("Node 2", "rgb(192,255,0)");
|
||||
let port2 = node2.addInPort("In");
|
||||
var node2 = new SRD.DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
let port2 = node2.addInPort('In');
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
// link the ports
|
||||
@@ -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>;
|
||||
}
|
||||
}
|
||||
9
diagrams-demo-gallery/demos/demo-drag-and-drop/index.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { BodyWidget } from './components/BodyWidget';
|
||||
import { Application } from './Application';
|
||||
|
||||
export default () => {
|
||||
var app = new Application();
|
||||
return <BodyWidget app={app} />;
|
||||
};
|
||||
58
diagrams-demo-gallery/demos/demo-dynamic-ports/index.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DiagramEngine } from '@projectstorm/react-diagrams';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
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 = () => {
|
||||
const nodes: DefaultNodeModel[] = _.values(this.props.model.getNodes()) as DefaultNodeModel[];
|
||||
for (let node of nodes) {
|
||||
if (node.getOptions().name === 'Node 2') {
|
||||
node.addInPort(`in-${node.getInPorts().length + 1}`, false);
|
||||
} else {
|
||||
node.addOutPort(`out-${node.getOutPorts().length + 1}`, false);
|
||||
}
|
||||
}
|
||||
this.props.engine.repaintCanvas();
|
||||
};
|
||||
|
||||
render() {
|
||||
const { engine } = this.props;
|
||||
return (
|
||||
<DemoWorkspaceWidget buttons={<DemoButton onClick={this.addPorts}>Add more ports</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)');
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
// link the ports
|
||||
|
||||
//4) add the models to the root graph
|
||||
model.addAll(node1, node2);
|
||||
|
||||
//5) load model into engine
|
||||
engine.setModel(model);
|
||||
|
||||
//6) render the diagram!
|
||||
return <CloneSelected engine={engine} model={model} />;
|
||||
};
|
||||
42
diagrams-demo-gallery/demos/demo-grid/index.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
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
|
||||
*/
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = createEngine();
|
||||
|
||||
//2) setup the diagram model
|
||||
var model = new DiagramModel();
|
||||
model.setGridSize(50);
|
||||
|
||||
//3-A) create a default node
|
||||
var node1 = new DefaultNodeModel('Node 1', 'rgb(0,192,255)');
|
||||
let port = node1.addOutPort('Out');
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
//3-B) create another default node
|
||||
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
let port2 = node2.addInPort('In');
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
// link the ports
|
||||
let link1 = port.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 (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
67
diagrams-demo-gallery/demos/demo-labelled-links/index.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DefaultLinkModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
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
|
||||
const engine = createEngine();
|
||||
|
||||
// setup the diagram model
|
||||
const model = new DiagramModel();
|
||||
|
||||
// create four nodes
|
||||
const node1 = new DefaultNodeModel('Node A', 'rgb(0,192,255)');
|
||||
const port1 = node1.addOutPort('Out');
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
const node2 = new DefaultNodeModel('Node B', 'rgb(255,255,0)');
|
||||
const port2 = node2.addInPort('In');
|
||||
node2.setPosition(400, 50);
|
||||
|
||||
const node3 = new DefaultNodeModel('Node C (no label)', 'rgb(192,255,255)');
|
||||
const port3 = node3.addInPort('In');
|
||||
node3.setPosition(450, 180);
|
||||
|
||||
const node4 = new DefaultNodeModel('Node D', 'rgb(192,0,255)');
|
||||
const port4 = node4.addInPort('In');
|
||||
node4.setPosition(300, 250);
|
||||
|
||||
// link node A and B together and give it a label
|
||||
const link1 = port1.link(port2);
|
||||
(link1 as DefaultLinkModel).addLabel('Custom label 1');
|
||||
(link1 as DefaultLinkModel).addLabel('Custom label 2');
|
||||
|
||||
// no label for A and C, just a link
|
||||
const link2 = port1.link(port3);
|
||||
|
||||
// also a label for A and D
|
||||
const link3 = port1.link(port4);
|
||||
(link3 as DefaultLinkModel).addLabel('Emoji label: 🎉');
|
||||
|
||||
// add all to the main model
|
||||
model.addAll(node1, node2, node3, node4, link1, link2, link3);
|
||||
|
||||
// load model into engine and render
|
||||
engine.setModel(model);
|
||||
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={
|
||||
<DemoButton
|
||||
onClick={() => {
|
||||
action('Serialized Graph')(JSON.stringify(model.serializeDiagram(), null, 2));
|
||||
}}
|
||||
>
|
||||
Serialize Graph
|
||||
</DemoButton>
|
||||
}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
};
|
||||
54
diagrams-demo-gallery/demos/demo-listeners/index.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import * as React from 'react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
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
|
||||
*/
|
||||
export default () => {
|
||||
// setup the diagram engine
|
||||
var engine = createEngine();
|
||||
|
||||
var model = new DiagramModel();
|
||||
|
||||
// sample for link with simple line
|
||||
var node1 = new DefaultNodeModel('Node 1', 'rgb(255,99,66)');
|
||||
var port1 = node1.addOutPort('Out');
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
var port2 = node2.addInPort('In');
|
||||
node2.setPosition(400, 40);
|
||||
|
||||
var node3 = new DefaultNodeModel('Node 3', 'rgb(128,99,255)');
|
||||
var port3 = node3.addInPort('In');
|
||||
node3.setPosition(300, 160);
|
||||
|
||||
//link the nodes
|
||||
let link1 = port1.link(port2);
|
||||
let link2 = port1.link(port3);
|
||||
|
||||
// add all the models
|
||||
let models = model.addAll(node1, node2, node3, link1, link2);
|
||||
|
||||
// add a selection listener to each
|
||||
models.forEach((item) => {
|
||||
item.registerListener({
|
||||
eventDidFire: action('element eventDidFire')
|
||||
});
|
||||
});
|
||||
|
||||
model.registerListener({
|
||||
eventDidFire: action('model eventDidFire')
|
||||
});
|
||||
|
||||
engine.setModel(model);
|
||||
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
60
diagrams-demo-gallery/demos/demo-locks/index.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
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';
|
||||
|
||||
/**
|
||||
*
|
||||
* Shows how you can lock down the system so that the entire scene cant be interacted with.
|
||||
*
|
||||
* @Author Dylan Vorster
|
||||
*/
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = createEngine();
|
||||
|
||||
var model = new DiagramModel();
|
||||
|
||||
// sample for link with simple line (no additional points)
|
||||
var node1 = new DefaultNodeModel('Node 1', 'rgb(0,192,255)');
|
||||
var port1 = node1.addOutPort('Out');
|
||||
node1.setPosition(100, 100);
|
||||
|
||||
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
|
||||
var port2 = node2.addInPort('In');
|
||||
node2.setPosition(400, 100);
|
||||
|
||||
let link1 = port1.link(port2);
|
||||
|
||||
model.addAll(node1, node2, link1);
|
||||
|
||||
// sample for link with complex line (additional points)
|
||||
var node3 = new DefaultNodeModel('Node 3', 'rgb(0,192,255)');
|
||||
var port3 = node3.addOutPort('Out');
|
||||
node3.setPosition(100, 250);
|
||||
|
||||
var node4 = new DefaultNodeModel('Node 4', 'rgb(192,255,0)');
|
||||
var port4 = node4.addInPort('In');
|
||||
node4.setPosition(400, 250);
|
||||
|
||||
var link2 = port3.link(port4);
|
||||
|
||||
link2.point(350, 225);
|
||||
link2.point(200, 225);
|
||||
|
||||
model.addAll(node3, node4, link2);
|
||||
|
||||
engine.setModel(model);
|
||||
|
||||
//!========================================= <<<<<<<
|
||||
|
||||
model.setLocked(true);
|
||||
|
||||
//!========================================= <<<<<<<
|
||||
|
||||
return (
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
);
|
||||
};
|
||||
90
diagrams-demo-gallery/demos/demo-mutate-graph/index.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, NodeModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
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
|
||||
*/
|
||||
class NodeDelayedPosition extends React.Component<any, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.updatePosition = this.updatePosition.bind(this);
|
||||
this.updatePositionViaSerialize = this.updatePositionViaSerialize.bind(this);
|
||||
}
|
||||
|
||||
updatePosition() {
|
||||
const { engine } = this.props;
|
||||
let model = engine.getModel();
|
||||
const nodes = model.getNodes();
|
||||
let node = nodes[Object.keys(nodes)[0]];
|
||||
node.setPosition(node.getX() + 30, node.getY() + 30);
|
||||
engine.repaintCanvas();
|
||||
}
|
||||
|
||||
updatePositionViaSerialize() {
|
||||
let { engine } = this.props;
|
||||
let model = engine.getModel();
|
||||
let str = JSON.stringify(model.serialize());
|
||||
let model2 = new DiagramModel();
|
||||
let obj: ReturnType<DiagramModel['serialize']> = JSON.parse(str);
|
||||
let node: ReturnType<NodeModel['serialize']> = _.values(obj.layers[1].models)[0] as any;
|
||||
node.x += 30;
|
||||
node.y += 30;
|
||||
|
||||
model2.deserializeModel(obj, engine);
|
||||
engine.setModel(model2);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { engine } = this.props;
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={[
|
||||
<DemoButton key={1} onClick={this.updatePosition}>
|
||||
Update position
|
||||
</DemoButton>,
|
||||
<DemoButton key={2} onClick={this.updatePositionViaSerialize}>
|
||||
Update position via serialize
|
||||
</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 <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 { DiagramEngine, DiagramModel, DefaultNodeModel, LinkModel, DiagramWidget } from "storm-react-diagrams";
|
||||
import * as React from "react";
|
||||
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';
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -10,8 +12,7 @@ import * as React from "react";
|
||||
*/
|
||||
export default () => {
|
||||
//1) setup the diagram engine
|
||||
var engine = new DiagramEngine();
|
||||
engine.installDefaultFactories();
|
||||
var engine = createEngine();
|
||||
|
||||
//2) setup the diagram model
|
||||
var model = new DiagramModel();
|
||||
@@ -23,21 +24,25 @@ 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) {
|
||||
//3-A) create a default node
|
||||
var node1 = new DefaultNodeModel("Node 1", "rgb(0,192,255)");
|
||||
var port1 = node1.addOutPort("Out");
|
||||
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");
|
||||
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
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
63
diagrams-demo-gallery/demos/demo-serializing/index.tsx
Normal file
@@ -0,0 +1,63 @@
|
||||
import createEngine, { DiagramModel, DefaultNodeModel, DefaultLabelModel } from '@projectstorm/react-diagrams';
|
||||
import * as React from 'react';
|
||||
import { DemoButton, DemoWorkspaceWidget } from '../helpers/DemoWorkspaceWidget';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
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
|
||||
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);
|
||||
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.setModel(model);
|
||||
|
||||
//!------------- SERIALIZING ------------------
|
||||
|
||||
var str = JSON.stringify(model.serialize());
|
||||
|
||||
//!------------- DESERIALIZING ----------------
|
||||
|
||||
var model2 = new DiagramModel();
|
||||
model2.deserializeModel(JSON.parse(str), engine);
|
||||
engine.setModel(model2);
|
||||
|
||||
return (
|
||||
<DemoWorkspaceWidget
|
||||
buttons={
|
||||
<DemoButton
|
||||
onClick={() => {
|
||||
action('Serialized Graph')(beautify(model2.serialize(), null, 2, 80));
|
||||
}}
|
||||
>
|
||||
Serialize Graph
|
||||
</DemoButton>
|
||||
}
|
||||
>
|
||||
<DemoCanvasWidget>
|
||||
<CanvasWidget engine={engine} />
|
||||
</DemoCanvasWidget>
|
||||
</DemoWorkspaceWidget>
|
||||
);
|
||||
};
|
||||