Compare commits

..

344 Commits

Author SHA1 Message Date
Dylan Vorster
4649597a97 v6.4.2 2021-03-14 13:00:53 +02:00
Dylan Vorster
89adc1ee38 more oops 2021-03-14 13:00:10 +02:00
Dylan Vorster
ff0f7188fa oops 2021-03-14 12:55:47 +02:00
Dylan Vorster
c6556d7475 v6.4.1 2021-03-13 23:54:50 +02:00
Dylan Vorster
8497c1bf6c Merge pull request #813 from projectstorm/updates
Project upgrade
2021-03-13 23:50:25 +02:00
Dylan Vorster
a15191bcef dont need watch 2021-03-13 23:49:34 +02:00
Dylan Vorster
d7c7dcf0b1 fix build script 2021-03-13 23:47:30 +02:00
Dylan Vorster
57a65aec20 lol 2021-03-13 23:43:40 +02:00
Dylan Vorster
b0343daf6f v6.4.0 2021-03-13 23:43:13 +02:00
Dylan Vorster
5d7bfd81d4 few fixes 2021-03-13 23:42:40 +02:00
Dylan Vorster
d42087a3ac fix tests 2021-03-13 12:31:32 +02:00
Dylan Vorster
6adff81ae7 fix demos 2021-03-13 12:30:49 +02:00
Dylan Vorster
4f3df60758 fixes 2021-03-12 23:55:45 +02:00
Dylan Vorster
2f366d21f7 fix storybook 2021-03-12 23:46:18 +02:00
Dylan Vorster
b7dfa6da21 fix demos 2021-03-12 22:58:46 +02:00
Dylan Vorster
293123b5c6 project updates 2021-03-12 22:35:25 +02:00
Dylan Vorster
63dbe41df0 v6.3.0 2020-12-03 22:02:46 +02:00
Dylan Vorster
c1485224ba Merge pull request #741 from artturik/patch-1
fix port background color
2020-10-29 19:05:30 +02:00
artturik
9b58fa3963 fix port background color
rgba(white, 0.1) is not valid css, changed it to valid
rgba syntax - <rgba()> = rgba( <percentage>{3} [ / <alpha-value> ]? ) | rgba( <number>{3} [ / <alpha-value> ]? ) from https://developer.mozilla.org/en-US/docs/Web/CSS/background-color
2020-10-12 23:52:13 +03:00
Dylan Vorster
3e69dafef9 Merge pull request #736 from adaladam/master
Fixed failing tests in CircleCI & fixing a typo
2020-10-11 13:39:59 +02:00
adaladam
442462af2d Merge pull request #1 from adaladam/dev
fixed failing tests
2020-09-28 16:04:27 +06:00
samat
0d9ba41c9a fixed failing tests 2020-09-28 16:01:22 +06:00
samat
73ef7df153 fixing a typo: should be LinkLayerModel instead of NodeLayerModel 2020-09-28 11:29:42 +06:00
Dylan Vorster
5fe7b37fc2 typo 2020-09-23 10:53:34 +02:00
Dylan Vorster
093e1f6a08 bump everything 2020-09-23 10:52:25 +02:00
Dylan Vorster
1e95edbc6f pretty 2020-09-23 10:24:36 +02:00
Alexander Nestorov
c92313f9b1 Remove ml-matrix 2020-09-14 00:35:03 +02:00
Dylan Vorster
b8b66642d5 Merge pull request #681 from paulocfjunior/fix-drag-canvas-state
Fix DragCanvasState to stop handling events after mouse is released
2020-08-01 16:23:12 +02:00
Paulo Junior
39dbbe3db9 Move MouseDown check from DragCanvasState to AbstractDisplacementState 2020-07-28 10:32:57 -03:00
Dylan Vorster
1ba35fd518 Merge pull request #682 from buddhikajay/master
Add missing dependencies in the documentation
2020-07-21 11:27:54 +02:00
Buddhika Jayawardhana
04443ad85e Merge pull request #1 from buddhikajay/add-missing-dependencies
Add Missing Dependencies
2020-07-21 18:29:17 +10:00
Buddhika Jayawardhana
17952c8829 Add Missing Dependencies
`@emotion/styled` and `resize-observer-polyfill` dependencies were missing from the doc
2020-07-21 18:28:37 +10:00
Paulo Junior
a8234a1a8d Fix DragCanvasState to stop handling events after mouse is released 2020-07-20 20:35:55 -03:00
Dylan Vorster
3f86c36c44 Merge pull request #668 from tkolanko/master
fix: closes #665. guard against null elements
2020-07-21 00:42:13 +02:00
Dylan Vorster
a2cf7483f1 Merge pull request #676 from Soarex16/master
Add custom link label demo #317
2020-07-21 00:39:55 +02:00
Lovpache Shumaf
72739dc3d3 Run code through 'yarn run pretty' 2020-07-17 11:06:13 +03:00
Lovpache Shumaf
07df1fd6f5 Add custom link label demo #317 2020-07-17 11:03:27 +03:00
tkolanko
ef9e72ed3a add yarn.lock to fix issue with is-promise module 2020-06-30 15:35:17 -04:00
tkolanko
8df5ff94b6 fix: closes #665. guard against null elements
elements can potentially be null if the mouse event opens a dialog
see #665 for details
2020-06-30 15:00:24 -04:00
Dylan Vorster
17c5a3cfb9 Merge pull request #656 from iddan/patch-1
Remove @next from installation instructions
2020-06-27 10:29:48 +02:00
Dylan Vorster
a69ec38a5a Merge pull request #660 from bogomya/fix-canvas
Enable/disable canvas drag
2020-06-27 10:29:38 +02:00
Dmitry Bogomya
2c66c18f6d Enable/disable canvas drag 2020-06-13 21:48:49 +03:00
Iddan Aaronsohn
012418741d Remove @next from installation instructions
Using @next incorrectly installs latest beta release instead of the latest stable release which is currently newer than the latest beta release.
2020-06-06 00:50:58 +03:00
Dylan Vorster
3d71f5a80b housekeeping 2020-06-03 21:13:39 +02:00
Dylan Vorster
c5b24f6e7b v6.2.0 2020-06-03 21:08:04 +02:00
Dylan Vorster
655462087f prettier 2020-06-03 21:02:49 +02:00
Dylan Vorster
6bdc21826d Merge pull request #639 from kobajs/master
fix: fixes listener mistypo
2020-06-03 20:31:34 +02:00
Dylan Vorster
27194cfd36 Merge pull request #651 from siosphere/master
remove mathjs, use ml-matrix in place for much smaller bundle size
2020-06-03 20:30:48 +02:00
Michael Kramer
61c8d7e610 Remove mathjs from root of repo, replace with ml-matrix 2020-06-01 18:34:19 -06:00
Michael Kramer
08f9ea6aa6 remove mathjs, use ml-matrix in place for much smaller bundle size 2020-06-01 18:00:15 -06:00
Yuri Tavares Kobashigawa
cef51577a3 fix: fixes listener mistypo 2020-05-19 00:43:10 -03:00
Dylan Vorster
e8fb8804a8 changelog 2020-04-25 19:59:53 +02:00
Dylan Vorster
ef822f5540 v6.1.1 2020-04-25 19:59:05 +02:00
Dylan Vorster
2a28368d5e v6.1.0 2020-04-25 19:57:09 +02:00
Dylan Vorster
987d3c84ab changes 2020-04-25 19:56:41 +02:00
Dylan Vorster
1ea06fb3d5 fixes 2020-04-25 19:50:41 +02:00
Dylan Vorster
3fdbe4c975 Merge pull request #576 from AnwarChakhar/zoomtofitnodes
Add zoom to fit nodes feature, fixes #568
2020-04-25 17:50:45 +02:00
Dylan Vorster
1aa1058eb5 Merge pull request #621 from SteveRuble/patch-1
Support deriving from DefaultLabelModel
2020-04-25 17:45:00 +02:00
Steve Ruble
ff2a668842 Support deriving from DefaultLabelModel
The DefaultLabelModel constructor deviated from pattern followed by the other Default*Model types, where `...options` is merged after the hardcoded values so that derived classes can override the options. This change makes it conform to that pattern.
2020-04-23 17:16:08 -04:00
Dylan Vorster
86b4c97e89 Merge pull request #603 from renato-bohler/listeners-fix
Listeners fix
2020-04-05 17:54:43 +02:00
Renato Böhler
696994f0ad fixes link widget trying to register listener on ports that aren't set yet 2020-04-05 12:15:27 -03:00
Renato Böhler
7d133abf58 fixes node selection not being deregistered upon deletion 2020-04-05 11:55:39 -03:00
Dylan Vorster
53068cbe1f Merge pull request #562 from kanav-raina/patch-1
Spelling mistake in readme
2020-03-20 10:18:25 +02:00
Anwar Chakhar
379e808d70 Add zoom to fit nodes feature, #568 2020-03-19 13:39:21 +01:00
Dylan Vorster
15d70e988e Update README.md 2020-03-19 00:05:57 +02:00
kanav-raina
355add35a8 Spelling mistake in readme
Signed-off-by: kanav-raina <kanavraina98@gmail.com>
2020-03-08 22:50:28 +05:30
Dylan Vorster
280a1fc0e4 v6.0.2 2020-03-06 10:12:11 +02:00
Dylan Vorster
eeece55c31 v6.0.1 2020-03-06 10:06:47 +02:00
Dylan Vorster
fb5f6e95e7 remove beta notice 2020-03-06 10:05:50 +02:00
Dylan Vorster
8d73d238fe Merge pull request #556 from VostroNet/es6-build
ES6 Module Support
2020-03-06 10:03:57 +02:00
Dylan Vorster
49242281e7 Merge pull request #558 from david-simon/master
fix DefaultNodeModel.removePort unbound splice #557
2020-03-06 09:50:49 +02:00
Dylan Vorster
f148b8e391 Merge pull request #542 from asashour/rimraf
Allow the build on MS Windows
2020-03-06 09:50:25 +02:00
David Simon
f78c5de4ae fix DefaultNodeModel.removePort unbound splice #557 2020-03-05 13:26:09 +01:00
Matthew Mckenzie
6e77f3503a adding es modules and including src for linking/reference 2020-03-04 10:06:13 +10:00
Dylan Vorster
4787163492 Merge pull request #550 from ajthinking/patch-3
Proposing a "built-with-react-diagrams" section
2020-02-25 10:00:45 +02:00
Anders Jürisoo
d8009f02a5 Proposing a "built-with-react-diagrams" section 2020-02-25 08:45:03 +01:00
Ahmed Ashour
aa186f7040 Allow the build on MS Windows 2020-02-20 10:25:55 +01:00
Dylan Vorster
09358d9b93 Merge pull request #529 from noahtren/patch-1
emotion styling for DemoCanvasWidget background
2020-02-17 00:18:04 +00:00
Dylan Vorster
b84265d802 Merge pull request #543 from ninenone/master
event modifiers for DeleteItemsAction
2020-02-17 00:00:30 +00:00
Sergey Nekrasov
410d6cfccf reverted commit (.gitignore) 2020-02-14 14:26:28 +03:00
Sergey Nekrasov
1dd26253b2 remove dist from .gitignore 2020-02-14 13:44:57 +03:00
Sergey Nekrasov
7e15c55a73 added modifiers to delete buttons 2020-02-14 11:12:34 +03:00
Noah Trenaman
61bc333658 emotion styling for DemoCanvasWidget background
Small fix to add support for customizing background color with `background` property.
2020-01-20 16:05:46 -05:00
Dylan Vorster
8cf6b0269c Merge pull request #515 from renato-bohler/custom-action-example
Adds custom action story as an example
2020-01-08 22:32:24 +02:00
Renato Böhler
51258b68b6 Adds custom action story as an example 2020-01-07 18:42:08 -03:00
Dylan Vorster
469dbc00af v6.0.1-beta.7 2019-12-20 12:23:08 +02:00
Dylan Vorster
dbe0e595b8 Merge pull request #510 from Letrab/master
Do deep clone instead of shallow clone.
2019-12-20 12:16:37 +02:00
Bartel Eerdekens
20a6bfe012 Do deep clone instead of shallow clone.
Fixes #436
2019-12-19 10:46:29 +01:00
Dylan Vorster
fd38a20c23 Merge pull request #508 from asashour/typos
fix a typo in demo class name
2019-12-19 11:30:44 +02:00
Dylan Vorster
5124c1a628 Merge pull request #509 from pierre-moire/master
Adds a demo for custom links with arrow heads
2019-12-19 11:30:24 +02:00
Pierre Moiré
46d7aa14b5 Revert package.json change 2019-12-18 23:24:16 +01:00
Pierre Moiré
971bae29f3 Adds arrow heads demo 2019-12-18 23:20:26 +01:00
Ahmed Ashour
5ec4327912 fix typo in demo class name 2019-12-18 15:15:30 +01:00
Dylan Vorster
1511bec663 Merge pull request #503 from Letrab/master
Unselect when not in Selection bounding box anymore.
2019-12-17 21:03:33 +02:00
Bartel Eerdekens
3e91dad2e1 Unselect when not in Selection bounding box anymore.
Performance optimisation to only fire event when value actually changed.

Solves #417
2019-12-12 16:01:36 +01:00
Dylan Vorster
1d5ab683c3 Merge pull request #483 from antonioru/hotfix/debounced-canvas-repaint
Allow CanvasEngine to possibly have debouncing options for smooth animations
2019-12-06 11:44:19 +02:00
Antonio Russo
96d6d0dcf2 removing repaintDebounce from animation demo 2019-12-03 08:40:05 +00:00
Pierre Moiré
ddc17a8dc3 Renames index file 2019-12-02 22:22:41 +01:00
Antonio Russo
a9e5575646 removing the repaintDebounce boolean option 2019-11-26 12:50:53 +00:00
Antonio Russo
d0331cb205 Updating the CanvasEngine to have extended repaintDebounce and repaintDebounceMs options 2019-11-24 14:50:04 +00:00
Antonio Russo
8556937ff1 Wrap the repaint method intoa 60ms debounce to improve performances, closes #478 2019-11-24 14:27:24 +00:00
Dylan Vorster
341e540af6 v6.0.1-beta.6 2019-11-23 23:56:32 +02:00
Dylan Vorster
9bd86480e9 Merge pull request #482 from antonioru/hotfix/wrong-link-appereance
Clicking on a source port causes a nonsense link segment, fixing #481
2019-11-23 23:48:21 +02:00
Dylan Vorster
5e0a75d4ed Merge pull request #484 from pierre-moire/master
Adds animation demo
2019-11-23 23:45:19 +02:00
Pierre Moiré
91789729c4 Adds animation demo 2019-11-23 20:08:08 +01:00
Antonio Russo
361fbe4ffe Removing unused imports 2019-11-23 17:49:45 +00:00
Antonio Russo
80e9bdcfc0 Clicking on a source port causes a nonsense link segment, fixing #481 2019-11-23 15:58:06 +00:00
Dylan Vorster
97c66b99ab Merge pull request #471 from mathiasbaldissera/master
Fixing #470
2019-11-21 01:30:52 +02:00
Mathias
220852697f Fixing #470
After the #469 PR, a bug when the zoom level is != from 1 make the link go far the mouse. Now it's considering the zoom level in the calculation
2019-11-20 16:38:24 -03:00
Dylan Vorster
8e05f28931 Merge pull request #465 from neolite/master
Remove error when creating a new canvas without node
2019-11-19 20:34:02 +02:00
Dylan Vorster
a450c9b5b5 Merge pull request #469 from antonioru/hotfix/new-link-far-end
link far end aligns with the mouse pointer position
2019-11-19 20:33:40 +02:00
Dylan Vorster
508fbf2777 Merge pull request #468 from mathiasbaldissera/master
Export DeleteItemsAction and function to deregister the default DeleteItemsAction
2019-11-19 20:30:25 +02:00
Mathias
11dc57a834 Fixing example 2019-11-19 15:04:19 -03:00
Antonio Russo
ed63bf151c keeping the engine offset into account when calculating a new link position 2019-11-19 15:39:13 +00:00
Antonio Russo
6dd0677b28 Using initialRelative coordinates when creating a new link makes it more precise 2019-11-19 14:03:24 +00:00
Antonio Russo
ea6130d1a9 getting the initial click position from the AbstractDisplacementState 2019-11-18 20:23:51 +00:00
Mathias
3c8839a1ec More bug fixes 2019-11-18 14:23:58 -03:00
Mathias
a7ab686463 Some BugFix 2019-11-18 14:07:53 -03:00
Mathias
11c2c70ec6 Options to NOT REGISTER default DeleteItemsAction and ZoomCanvasAction 2019-11-18 14:02:30 -03:00
Antonio Russo
a3ca75d039 link far end alignes with the mouse pointer position, fixes #467 2019-11-18 08:48:05 +00:00
Mathias
dedc627294 Export DeleteItemsAction and event to deregister the default DeleteI...
DeleteItemsAction and ZoomCanvasAction are now exported;
Now there is 2 functions to deregister the default ZoomCanvas and DeleteItems actions;
A exemple with how to deregister and register another DeleteItemsAction
2019-11-16 21:58:12 -03:00
Rafkat
c000ffc3cd Remove error when creating a new canvas without node 2019-11-06 18:36:09 +03:00
Dylan Vorster
37babb3bb2 Merge pull request #448 from christianbuehlmeyer/checkCanLinkToPort
Fix: Also check canLinkToPort in DragDiagramItemsState
2019-10-11 18:25:46 +02:00
Dylan Vorster
33651b22a1 Merge pull request #451 from matthax/master
Fix #450 by exporting SmartLayerWidget from react-canvas-core
2019-10-11 18:24:53 +02:00
Matt Bark
dfc7102b1c export SmartLayerWIdget from react-canvas-core
Fixes #450
2019-10-07 12:39:02 -04:00
Christian Bühlmeyer
a399f135ba Added the canLinkToPort check also to DragDiagramItemsState to prevent Port to Port connection that is not allowed 2019-10-04 21:40:03 +02:00
Dylan Vorster
36e097cb70 Merge pull request #443 from larshp/readme
README: fix links under "how to use"
2019-10-01 01:11:51 +02:00
Dylan Vorster
23e1742e99 Merge pull request #434 from DanieLazarLDAPPS/bugfix/#428-after-deserialize-fixes
bugfix after deserialize link has no source or target port and code i…
2019-10-01 01:11:29 +02:00
Lars Hvam
5d913f28ba README: fix links under "how to use"
firs one was broken, plus second was only to the readme for an old tree
2019-09-27 12:33:20 +02:00
Daniel Lazar
1c955b4d12 bugfix after deserialize link has no source or target port and code in body of condition should not be called. This is quick fix. Better will be handle it in fireMouseMoved of DragNewLinkState 2019-09-19 10:25:56 +02:00
Dylan Vorster
741851b855 v6.0.1-beta.5 2019-09-12 11:59:17 +02:00
Dylan Vorster
4729bbedc9 Merge pull request #429 from DanieLazarLDAPPS/bugfix/#428-after-deserialize-fixes
issue #428 fixing by moving entityRemoved registration to addModel
2019-09-12 11:57:04 +02:00
Daniel Lazar
994ff7c714 formatting fixes 2019-09-12 07:38:52 +02:00
Dylan Vorster
05f1345e62 Merge pull request #426 from vidjuheffex/patch-1
issue #407 update css to remove first-child unsafe warning
2019-09-12 00:36:44 +02:00
Dylan Vorster
5079188b99 Merge pull request #425 from duhruh/bug/unique-key
fix for unique key maps
2019-09-12 00:36:05 +02:00
Daniel Lazar
13dd53f185 after deserialize rightAngleLinkModel the first and last path must be set by points if doesnt links right angles are broken 2019-09-11 13:05:36 +02:00
Daniel Lazar
502faeef5a issue #428 fixing by moving entityRemoved registration to addModel 2019-09-11 12:17:01 +02:00
Julián Herrera
39c4f37d12 update css to remove first-of-type unsafe warning 2019-09-10 22:30:20 -05:00
David Rivera
1dccace7e2 fix for unique key maps 2019-09-10 16:49:13 -07:00
Dylan Vorster
85857afd31 Merge pull request #423 from mx2323/dagreFix2
use top left instead of center with dagre
2019-09-07 19:53:02 +02:00
Michael Xu
c875ce6e22 use top left instead of center with dagre 2019-09-06 17:27:29 +00:00
Dylan Vorster
422b967be7 Merge pull request #410 from ppoffice/patch-1
fix diagrams-demo-gallery generation issue on windows and use resize-observer-polyfill
2019-09-06 17:37:32 +02:00
Dylan Vorster
1a8b3caca4 Merge pull request #419 from sljuka/click-linking
Make custom state demo where linking is done by clicking ports
2019-09-06 17:36:25 +02:00
David Sljukic
116a296bf5 Clear state props before ejecting state 2019-09-05 22:38:31 +02:00
David Sljukic
57f4e2d832 Fix tabs with prettier 2019-09-03 23:30:29 +02:00
David Sljukic
b0089662aa Update demo name 2019-09-03 23:00:29 +02:00
David Sljukic
8ded9cd30e Make custom state demo where linking is done by clicking ports 2019-09-03 22:55:53 +02:00
ppoffice
14a76ffbf5 place resize observer polyfill in peer deps 2019-09-03 11:29:51 -04:00
Dylan Vorster
1a7acafdc8 v6.0.1-beta.4 2019-09-03 09:48:37 +02:00
Dylan Vorster
ad25420166 v6.0.1-beta.3 2019-09-03 09:46:24 +02:00
Dylan Vorster
1fb622366b Merge pull request #416 from DanieLazarLDAPPS/features/labview-style-of-routes
Features/labview style of routes
2019-09-03 09:39:59 +02:00
Daniel Lazar
761ac41901 improvment of handling first and last path direction 2019-09-02 11:05:18 +02:00
Daniel Lazar
c8aa7a67ac some after merge fixes and another fixes for linking 2019-09-02 09:44:43 +02:00
Daniel Lazar
e923245f6d better to keep boolean for last and first path direction private for widget 2019-09-02 09:29:32 +02:00
Daniel Lazar
0cb6c66b1f when node is moving better path from its port cannot change direction to keep 90 angles all the time 2019-09-02 09:29:32 +02:00
Daniel Lazar
f20bb0bd2e improved new links to have better experience 2019-09-02 09:27:57 +02:00
Daniel Lazar
0deaec246d added usefull variable that gives last known index of path 2019-09-02 09:26:31 +02:00
ppoffice
cb79d4e390 add resize-observer-polyfill 2019-08-21 14:57:58 -04:00
Ruipeng Zhang
35a53c8134 fix storybook failed to build issue on windows 2019-08-21 00:44:11 -04:00
Dylan Vorster
326567c290 v6.0.1-beta.2 2019-08-19 07:26:28 +02:00
Dylan Vorster
7fa51d5ea0 Merge branch 'master' of github.com:projectstorm/react-diagrams 2019-08-19 07:25:15 +02:00
Dylan Vorster
e72e7e999c fix relative import 2019-08-19 07:24:10 +02:00
Dylan Vorster
25fe2a8e64 Merge pull request #403 from kuldar/patch-1
Update README.md
2019-08-17 11:39:33 +02:00
Dylan Vorster
e59edefbeb v6.0.1-beta.1 2019-08-17 11:30:44 +02:00
Dylan Vorster
27022d2965 Fixed up link selecting 2019-08-17 11:27:54 +02:00
Kuldar Kalvik
897237c9ca Update README.md 2019-08-17 11:07:58 +02:00
Dylan Vorster
f0242c7924 add listeners to root model in demo 2019-08-17 11:05:48 +02:00
Dylan Vorster
cf9f9cb01d Merge pull request #401 from zacharyzhy/patch-1
Export DragDiagramItemsState
2019-08-17 10:52:40 +02:00
Dylan Vorster
4c90895bcd Merge pull request #398 from flomllr/patch-2
Update using-the-library.md
2019-08-17 10:52:26 +02:00
zacharyzhy
3f6d04521d Export DragDiagramItemsState
Export DragDiagramItemsState in the react-diagrams-core's index
2019-08-15 16:03:25 -07:00
Florian Müller
3a46047ee8 Update using-the-library.md 2019-08-15 18:58:50 +02:00
Dylan Vorster
77418ee8e7 v6.0.1-beta.0 2019-08-13 22:46:26 +02:00
Dylan Vorster
07c74d850f v6.0.0-beta.2 2019-08-13 22:10:22 +02:00
Dylan Vorster
75d1b6bb5d Merge pull request #387 from DanieLazarLDAPPS/features/labview-style-of-routes
Features/labview style of routes
2019-08-13 00:07:26 +02:00
Daniel Lazar
4cae28c808 of course there must be || to check positions if moving is too fast 2019-08-12 19:45:43 +02:00
Daniel Lazar
cff54426c9 update for new links ... port model needs RightAngleLinkModel 2019-08-12 12:57:04 +02:00
Daniel Lazar
3dd329b209 migrate to new six version 2019-08-12 11:59:50 +02:00
Daniel Lazar
6396abc17c remove node5 2019-08-12 09:31:44 +02:00
Daniel Lazar
16f6b484b5 renamed due to restriction with labview 2019-08-12 09:31:44 +02:00
Daniel Lazar
68c2c76d72 Right angles routes added 2019-08-12 09:31:30 +02:00
Daniel Lazar
16033a658c issue-277 few null checks to avoid crash when node went under bottom of screen 2019-08-12 09:31:08 +02:00
Dylan Vorster
96655baff2 v6.0.0-beta.1 2019-08-11 17:20:32 +02:00
Dylan Vorster
630467cf97 small display issue with ports 2019-08-11 17:19:15 +02:00
Dylan Vorster
23b174736c more info on ports 2019-08-11 15:49:09 +02:00
Dylan Vorster
9de0708535 more custom link docs 2019-08-11 15:41:02 +02:00
Dylan Vorster
4786208fe6 more port docs 2019-08-11 13:25:35 +02:00
Dylan Vorster
98888f6d96 more fixes 2019-08-11 13:20:02 +02:00
Dylan Vorster
f017873cdc docs 2019-08-11 13:17:09 +02:00
Dylan Vorster
d14f1a3bb3 Fixed doc issue 2019-08-11 11:16:53 +02:00
Dylan Vorster
cdda07b026 trying to fix gitbook 2019-08-11 11:12:30 +02:00
Dylan Vorster
fa6bebce6f upset 2019-08-11 11:07:22 +02:00
Dylan Vorster
04362b8da8 lets try this again -_- 2019-08-11 10:52:53 +02:00
Dylan Vorster
0dbdee9f18 gitbook y 2019-08-11 10:50:17 +02:00
Dylan Vorster
a5c4d917eb Revert "gitbook"
This reverts commit 962883ce4a.
2019-08-11 10:47:41 +02:00
Dylan Vorster
93cc419767 GitBook: [master] 2 pages modified 2019-08-11 08:30:40 +00:00
Dylan Vorster
7a7fef85d0 GitBook: [master] 7 pages and 4 assets modified 2019-08-11 08:24:24 +00:00
Dylan Vorster
4eccdbdc8a restructure 2019-08-11 10:20:22 +02:00
Dylan Vorster
962883ce4a gitbook 2019-08-11 10:18:43 +02:00
Dylan Vorster
6571dbe159 GitBook: [master] 12 pages and 4 assets modified 2019-08-11 08:14:28 +00:00
Dylan Vorster
8fbd87df8c Readme 2019-08-11 09:47:02 +02:00
Dylan Vorster
ce38f77027 Merge pull request #373 from projectstorm/lerna
Version 6 [Lerna, rearchitect, better design]
2019-08-11 01:11:21 +02:00
Dylan Vorster
bec82cd92c more readme 2019-08-11 01:06:15 +02:00
Dylan Vorster
d2c5bac65c v6.0.0-beta.0 2019-08-11 00:57:16 +02:00
Dylan Vorster
5fc17b6217 changelog 2019-08-11 00:53:52 +02:00
Dylan Vorster
d2e1cf2dd1 yaml is a piece of s*** 2019-08-11 00:35:56 +02:00
Dylan Vorster
9e2f6ffb0f sigh 2019-08-11 00:35:00 +02:00
Dylan Vorster
cc900b2a90 sigh 2019-08-11 00:32:39 +02:00
Dylan Vorster
51c6bd2391 fix tests 2019-08-11 00:31:49 +02:00
Dylan Vorster
a8c6031166 more restructuring 2019-08-10 22:33:06 +02:00
Dylan Vorster
a6655dbf2d more restructuring 2019-08-10 22:30:01 +02:00
Dylan Vorster
37532edd01 more readme 2019-08-10 22:24:46 +02:00
Dylan Vorster
4538884a96 Readme 2019-08-10 21:59:49 +02:00
Dylan Vorster
c9f7d2c516 ITS DONE 2019-08-10 21:18:29 +02:00
Dylan Vorster
5c66c84a31 I think we done 2019-08-10 16:58:56 +02:00
Dylan Vorster
4a57ecdc97 lik 99% there 2019-08-10 16:37:40 +02:00
Dylan Vorster
9fc65b7d7f added some nice apis to improve rendering and such 2019-08-10 15:04:43 +02:00
Dylan Vorster
2573c5d8cc Fixed up the custom node demo 2019-08-10 14:27:54 +02:00
Dylan Vorster
a46e17306b serialization is almost working again 2019-08-10 14:08:28 +02:00
Dylan Vorster
7045d75ae7 reworked deserialization 2019-08-10 12:46:59 +02:00
Dylan Vorster
47e4a14520 fixing serialization 2019-08-10 12:01:08 +02:00
Dylan Vorster
58eee117e9 we have parity with dragging and creating new links 2019-08-09 00:03:42 +02:00
Dylan Vorster
09d5b65e59 got more parity with moving points and such 2019-08-07 21:50:41 +02:00
Dylan Vorster
6512ca0eb0 Merge pull request #385 from flomllr/patch-1
Update Getting Started.md
2019-08-07 12:36:07 +02:00
Florian Müller
bfde4226ec Update Getting Started.md
storm-react-diagrams to @projectstorm/react-diagrams
2019-08-07 12:01:52 +02:00
Dylan Vorster
ea6adbe61b more parity 2019-08-06 23:56:17 +02:00
Dylan Vorster
5f74600157 some more parity work 2019-08-06 23:50:50 +02:00
Dylan Vorster
3590245f6c moving items works again 2019-08-05 00:24:43 +02:00
Dylan Vorster
46aa99b2ea selections are now event driven 2019-08-04 18:12:24 +02:00
Dylan Vorster
80f86867fd dragging and stuff is working again 2019-08-04 17:51:03 +02:00
Dylan Vorster
52f9105b1b state machines yay 2019-08-04 17:25:56 +02:00
Dylan Vorster
e9558919fb pretty 2019-08-04 13:28:38 +02:00
Dylan Vorster
dd5a0b7d8d break it up further into canvas 2019-08-04 13:27:55 +02:00
Dylan Vorster
0f7930e132 some minor things 2019-08-02 23:55:28 +02:00
Dylan Vorster
3823adc8e8 v6.0.0-alpha.4.2 2019-07-31 23:58:04 +02:00
Dylan Vorster
fce011a11b Merge pull request #379 from dudenamedjune/lerna
fixed path issue in lib-routing/src/link/PathFindingLinkWidget.tsx
2019-07-31 18:39:50 +02:00
dudenamedjune
4962343b54 fixed path issue in lib-routing/src/link/PathFindingLinkWidget.tsx 2019-07-31 11:22:29 -05:00
Dylan Vorster
45649146c9 v6.0.0-alpha.4.1 2019-07-30 22:53:42 +02:00
Dylan Vorster
74e24331ed fix flow demo 2019-07-30 22:48:57 +02:00
Dylan Vorster
0cc469fa44 storybook 2019-07-30 22:43:29 +02:00
Dylan Vorster
0b78ba69c6 fix up the builds 2019-07-30 22:36:44 +02:00
Dylan Vorster
ca301b9d4d v6.0.0-alpha.4.0 2019-07-30 22:23:18 +02:00
Dylan Vorster
ad6c77da28 v6.0.0-alpha.3.0 2019-07-30 22:15:19 +02:00
Dylan Vorster
66b72b4465 v6.0.0-y.0 2019-07-30 22:06:26 +02:00
Dylan Vorster
bb878657ba v6.0.0-alpha.1 2019-07-30 21:58:06 +02:00
Dylan Vorster
1db1e21fc2 hmm 2019-07-30 21:57:27 +02:00
Dylan Vorster
f4920ab4d0 v6.0.0-alpha.0 2019-07-30 20:18:37 +02:00
Dylan Vorster
ccfd8e026c some work 2019-07-30 20:18:21 +02:00
Dylan Vorster
702290d9b3 leaking logs 2019-07-30 01:54:47 +02:00
Dylan Vorster
347377d3b4 fixed a bunch of issues with links, and moved it all to styled components 2019-07-30 01:53:07 +02:00
Dylan Vorster
44fd2ad91b fix type issues 2019-07-30 00:12:30 +02:00
Dylan Vorster
39d49c9ee0 type issue fixes 2019-07-29 23:34:36 +02:00
Dylan Vorster
61c6d4b161 massive performance wins 2019-07-29 00:40:22 +02:00
Dylan Vorster
b324154eff pretty 2019-07-28 22:32:29 +02:00
Dylan Vorster
17350a740a fix points 2019-07-28 22:32:08 +02:00
Dylan Vorster
d7fc5370ab improved routing 2019-07-28 21:52:48 +02:00
Dylan Vorster
5fbe7ce9e4 pretty 2019-07-28 21:29:45 +02:00
Dylan Vorster
3e37e34155 generics 2019-07-28 20:23:15 +02:00
Dylan Vorster
f46680596c Fixed bugs after refactor 2019-07-28 18:28:18 +02:00
Dylan Vorster
3a2d3ccb73 make all the things pluggable 2019-07-28 18:13:03 +02:00
Dylan Vorster
f4aa1852ed improved actions 2019-07-28 16:08:37 +02:00
Dylan Vorster
e167885038 Start improving the action system 2019-07-28 14:56:47 +02:00
Dylan Vorster
619e8a2347 more parity 2019-07-27 23:07:04 +02:00
Dylan Vorster
4c1e67106a make the widgets report their dimensions 2019-07-27 22:53:04 +02:00
Dylan Vorster
d08be537e1 use geometry 2019-07-27 16:12:37 +02:00
Dylan Vorster
8e5243da95 more resize stuffs 2019-07-27 00:31:30 +02:00
Dylan Vorster
22236f8420 oops 2019-07-27 00:25:13 +02:00
Dylan Vorster
99fe94ae29 resize observers 2019-07-27 00:23:19 +02:00
Dylan Vorster
3b0c19d998 fixes 2019-07-26 23:15:24 +02:00
Dylan Vorster
fc67d477a9 start using better geometry 2019-07-26 22:38:21 +02:00
Dylan Vorster
e4d427e0d3 formatting 2019-07-26 17:33:45 +02:00
Dylan Vorster
bc2d444aee dagre stuffs 2019-07-26 17:33:27 +02:00
Dylan Vorster
b15a326dab Fixed labels 2019-07-26 16:17:46 +02:00
Dylan Vorster
b54feb03e4 fixed more stuff 2019-07-26 14:31:18 +02:00
Dylan Vorster
39eddc0a2a Fixed up the demos 2019-07-26 14:11:05 +02:00
Dylan Vorster
85a1fde2e5 fixes and improvements 2019-07-26 13:54:09 +02:00
Dylan Vorster
c0dae87d02 cleanup 2019-07-26 13:38:34 +02:00
Dylan Vorster
fddec93370 more generics 2019-07-26 13:37:30 +02:00
Dylan Vorster
01ffbce479 saftey push 2019-07-25 22:29:47 +02:00
Dylan Vorster
30790682d3 spacing 2019-07-25 15:58:34 +02:00
Dylan Vorster
dc9c2eae66 API improvements and start moving to emotion 2019-07-25 15:57:39 +02:00
Dylan Vorster
969152a814 links 2019-07-25 01:15:01 +02:00
Dylan Vorster
2e38a7cfd5 space 2019-07-25 01:13:04 +02:00
Dylan Vorster
e3fe7319c1 changelog 2019-07-25 01:12:19 +02:00
Dylan Vorster
c3a332ebab fine ill add it again 2019-07-25 01:00:59 +02:00
Dylan Vorster
314bb908f9 sigh 2019-07-25 00:59:04 +02:00
Dylan Vorster
9b16b3f4ed try this out for size 2019-07-25 00:56:13 +02:00
Dylan Vorster
722b6d98f3 tests work globally again 2019-07-25 00:54:48 +02:00
Dylan Vorster
2c6971be9a remove snapshot testing 2019-07-25 00:44:14 +02:00
Dylan Vorster
ea0160cbcf e2e tests 2019-07-25 00:32:56 +02:00
Dylan Vorster
efc53eec9b spelling 2019-07-24 16:40:43 +02:00
Dylan Vorster
b5c86159d1 some docs 2019-07-24 16:37:05 +02:00
Dylan Vorster
ea2070ec98 more cleanup 2019-07-24 16:32:05 +02:00
Dylan Vorster
39c3611686 formatting 2019-07-24 16:26:46 +02:00
Dylan Vorster
1ff63d4117 routing works again :yey: 2019-07-24 16:19:31 +02:00
Dylan Vorster
e80da8853f got the demos working again 2019-07-24 15:31:19 +02:00
Dylan Vorster
a06e23eaf6 more lerna work 2019-07-24 15:17:48 +02:00
Dylan Vorster
4b599fc37f getting started 2019-07-24 13:40:19 +02:00
Dylan Vorster
def92af022 lerna 2019-07-24 00:31:31 +02:00
Dylan Vorster
01e9f5f2db changes 2019-07-22 23:27:55 +02:00
Dylan Vorster
aa1a02774d 5.3.2 2019-07-22 23:26:57 +02:00
Dylan Vorster
e60aac56db 5.3.1 2019-07-22 23:26:54 +02:00
Dylan Vorster
b2e74d8b97 badge 2019-07-22 23:08:24 +02:00
Dylan Vorster
e333a4f168 correct version 2019-07-22 22:59:31 +02:00
Dylan Vorster
1d316409e1 npm 2019-07-22 22:57:10 +02:00
Dylan Vorster
9d947d40b7 5.3.1 2019-07-22 22:55:55 +02:00
Dylan Vorster
7d80f15358 improvements 2019-07-22 22:55:33 +02:00
Dylan Vorster
28844b86eb 5.3.0 2019-07-22 22:48:40 +02:00
Dylan Vorster
70c9aeac66 please 2 2019-07-22 22:44:15 +02:00
Dylan Vorster
12a7bfbda5 please 2019-07-22 21:58:46 +02:00
Dylan Vorster
650061db4a fix jest 2019-07-22 21:05:28 +02:00
Dylan Vorster
48c6d1f038 changelog 2019-07-22 20:42:53 +02:00
Dylan Vorster
7cea7032f0 5.2.2-0 2019-07-22 18:49:46 +02:00
Dylan Vorster
2b346aa326 Merge branch 'master' of https://github.com/svssrinivas/react-diagrams into 5.3 2019-07-22 18:44:43 +02:00
Dylan Vorster
0f7f8853d1 docs 2019-07-22 18:43:53 +02:00
Dylan Vorster
3a57ea711e docs 2019-07-22 18:41:11 +02:00
Dylan Vorster
de208e3250 fixes and such 2019-07-22 18:37:17 +02:00
Dylan Vorster
2df09edb7e Merge pull request #331 from sahilit/patch-1
typo error
2019-07-22 16:39:08 +02:00
Dylan Vorster
ba1401a8f2 Merge pull request #356 from frank-martinez-27/5.2.0
Fixed "Type 'PointModel[]' is not assignable to type 'ConcatArray<BaseModel<any, T>>'" error
2019-07-22 16:38:44 +02:00
Francisco
c6137d03ce Fixed broken snapshots 2019-06-27 19:27:02 -07:00
Francisco
ead43957e3 Fixed 'Return type of public method from exported class has or is using name PointModel from external module' error 2019-06-27 19:21:29 -07:00
Francisco
b7d8ffa793 First commit 2019-06-27 19:08:05 -07:00
Srinivas2794
a289c73b68 fix line direction while maintaining smoothening 2019-05-26 18:26:04 +05:30
Sahil Singh
b75976d091 Update Getting Started.md 2019-03-18 13:02:39 +05:30
Dylan Vorster
a95010652d Merge pull request #178 from smeijer/feature/add-position-changed-event
feat(events): add `positionChanged` event to `NodeModel`
2019-02-28 22:08:23 +02:00
Dylan Vorster
4cd24940c8 Merge pull request #305 from JoasE/master
Fixed a small positioning issue with dagre demo
2018-12-02 00:40:07 +02:00
Dylan Vorster
0f1dec1ebc Merge pull request #299 from igauravsehrawat/typo-fix
--fix: Typo.
2018-12-02 00:39:29 +02:00
Dylan Vorster
eedc21cc87 Merge pull request #306 from thepocp/change-link-extras-type
Impossible to set extra properties
2018-12-02 00:39:13 +02:00
JoasE
b719178f44 Fixed up storybook snapshot 2018-12-01 17:30:41 +01:00
Mihail Novikov
12724748e6 Impossible to set extra porperties 2018-11-30 17:29:16 +03:00
JoasE
0ebd6d918f Ran prettier 2018-11-30 14:24:51 +01:00
JoasE
591ec2e76e Fixed a small positioning issue with dagre demo
The dagre example doesn't take into account that dagre works with center of position for nodes but react-diagrams works with top left of position for nodes.

To correctly position the nodes, half of the width and height should be subtracted from the x and y axis respectively.
2018-11-30 14:12:24 +01:00
G
9f95ac8451 --fix: Typo. 2018-10-31 20:55:10 +05:30
Dylan Vorster
e3fc996092 Actually fix it this time lol 2018-08-01 22:57:43 +02:00
Dylan Vorster
de9765358f Fix Demo URL 2018-08-01 22:57:19 +02:00
Dylan Vorster
fa34f5c98b Merge pull request #259 from brian-eightsolutions/patch-1
Update DiagramWidget.tsx
2018-07-13 13:28:15 +02:00
brian-eightsolutions
f4ac467056 Update DiagramWidget.tsx
This is the proposed fix for the issue that I just logged: https://github.com/projectstorm/react-diagrams/issues/258
2018-07-10 12:42:03 -07:00
Dylan Vorster
5b142c1c61 update changelog 2018-05-05 18:00:41 +02:00
Dylan Vorster
40219d7a4d 5.2.1 2018-05-05 17:52:31 +02:00
Dylan Vorster
0eb432b302 lol 2018-05-05 17:52:27 +02:00
Dylan Vorster
ad5e7a4b4d 5.2.0 2018-05-05 17:49:04 +02:00
Dylan Vorster
0583db1c74 bump all the things, fix small issue 2018-05-05 17:44:31 +02:00
Dylan Vorster
0b92e939ab Merge pull request #236 from ajthinking/patch-2
Added notes to example images
2018-05-01 12:18:44 +02:00
Anders Jürisoo
8997eba4b4 Added notes to example images
See #157, #56
2018-05-01 12:13:35 +02:00
Stephan Meijer
3fbbeb82de feat(events): add positionChanged event to NodeModel 2018-03-01 22:01:52 +01:00
320 changed files with 23363 additions and 28732 deletions

View File

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

View File

@@ -1,9 +1,9 @@
[*]
indent_style = tab
indent_size = 4
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
View File

@@ -0,0 +1,4 @@
root: ./docs/
structure:
summary: README.md

View File

Before

Width:  |  Height:  |  Size: 438 KiB

After

Width:  |  Height:  |  Size: 438 KiB

View File

Before

Width:  |  Height:  |  Size: 313 KiB

After

Width:  |  Height:  |  Size: 313 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

BIN
.gitbook/assets/logo.jpg Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

View File

@@ -4,21 +4,18 @@
- [ ] 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
- [ ] Had a beer/coffee because you are awesome
## 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:
## Feel good image:
(Add your own one below :])

201
.gitignore vendored
View File

@@ -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
yarn-error.log
tsconfig.tsbuildinfo

View File

@@ -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
View File

@@ -0,0 +1,3 @@
node_modules
dist
.out

8
.prettierrc Normal file
View File

@@ -0,0 +1,8 @@
{
"semi": true,
"singleQuote": true,
"jsxBracketSameLine": true,
"useTabs": true,
"printWidth": 120,
"trailingComma": "none"
}

View File

@@ -1,14 +0,0 @@
import React from 'react';
import addons from '@storybook/addons';
export class WithCode extends React.Component {
render() {
const { children, code } = this.props;
const channel = addons.getChannel();
// send the notes to the channel.
channel.emit('storybook/code/set_code', code);
// return children elements.
return children;
}
}

View File

@@ -1,69 +0,0 @@
import React from 'react';
import addons from '@storybook/addons';
import SyntaxHighlighter from 'react-syntax-highlighter';
import { github } from 'react-syntax-highlighter/styles/hljs';
/**
* @author Dylan
*
* Simple little addon for displaying code, might make this a seperate project at some point
*/
export class CodePreview extends React.Component {
constructor(...args) {
super(...args);
this.state = {
code: ''
};
}
componentDidMount() {
const { channel, api } = this.props;
// Listen to the notes and render it.
channel.on('storybook/code/set_code', (code) => {
this.onAddCode(code);
});
// Clear the current notes on every story change.
this.stopListeningOnStory = api.onStory(() => {
this.onAddCode('');
});
}
// This is some cleanup tasks when the Notes panel is unmounting.
componentWillUnmount() {
if (this.stopListeningOnStory) {
this.stopListeningOnStory();
}
this.unmounted = true;
const { channel } = this.props;
channel.removeListener('storybook/notes/add_notes', this.onAddCode);
}
onAddCode(code) {
this.setState({ code: code });
}
render() {
return (
<SyntaxHighlighter
customStyle={{width: '100%', overflowX:'hidden', tabSize: 4}}
showLineNumbers={true}
language='language-tsx'
style={github}
>
{this.state.code}
</SyntaxHighlighter>
);
}
}
// Register the addon with a unique name.
addons.register('storybook/code', api => {
// Also need to set a unique name to the panel.
addons.addPanel('storybook/code/panel', {
title: 'Code preview',
render: () => <CodePreview channel={addons.getChannel()} api={api} />,
});
});

View File

@@ -1,3 +0,0 @@
import './addon-code/register';
import '@storybook/addon-actions/register';
import '@storybook/addon-options/register';

View File

@@ -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);

View File

@@ -1,39 +0,0 @@
const path = require('path');
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader"],
include: path.resolve(__dirname, '../')
},
{
test: /\.css/,
loaders: ["style-loader", "css-loader"],
include: path.resolve(__dirname, '../')
},
{
enforce: 'pre',
test: /\.js$/,
loader: "source-map-loader",
exclude: [
/node_modules\//
]
},
{
test: /\.tsx?$/,
loader: 'awesome-typescript-loader?declaration=false',
},
{
test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
loader: "file-loader"
}
]
},
resolve: {
alias: {
'storm-react-diagrams': path.join(__dirname, "..", "src", "main")
},
extensions: [".tsx", ".ts", ".js"]
}
};

View File

@@ -1,65 +1,136 @@
__5.1.0__
__6.4.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
* 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
-> and other improvements, also checkout the foundation work happening over at https://github.com/projectstorm/react-canvas
__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
__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)
@@ -68,7 +139,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

102
README.md
View File

@@ -1,46 +1,98 @@
# STORM React Diagrams
# Introduction
**PSA**: React Diagrams is currently 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).
[![Join the chat at https://gitter.im/projectstorm/react-diagrams](https://badges.gitter.im/projectstorm/react-diagrams.svg)](https://gitter.im/projectstorm/react-diagrams?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![NPM](https://img.shields.io/npm/v/@projectstorm/react-diagrams.svg)](https://npmjs.org/package/@projectstorm/react-diagrams) [![Package Quality](https://npm.packagequality.com/shield/storm-react-diagrams.svg)](https://packagequality.com/#?package=storm-react-diagrams) [![CircleCI](https://circleci.com/gh/projectstorm/react-diagrams/tree/master.svg?style=svg)](https://circleci.com/gh/projectstorm/react-diagrams/tree/master) [![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)
---
![](.gitbook/assets/logo.jpg)
**DEMO**: [http://www.projectstorm.io/react-diagrams](http://www.projectstorm.io/react-diagrams)
[pssst! Looking for the old version 5?](https://github.com/projectstorm/react-diagrams/tree/v5.3.2)
**DOCS:** [https://projectstorm.gitbooks.io/react-diagrams](https://projectstorm.gitbooks.io/react-diagrams)
**DEMO**: [http://projectstorm.cloud/react-diagrams](http://projectstorm.cloud/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 \(wip\)** [https://projectstorm.gitbook.io/react-diagrams](https://projectstorm.gitbook.io/react-diagrams)
A super simple, no-nonsense diagramming library written in React that just works.
Docs are currently being worked on, along with a migration path.
[![Join the chat at https://gitter.im/projectstorm/react-diagrams](https://badges.gitter.im/projectstorm/react-diagrams.svg)](https://gitter.im/projectstorm/react-diagrams?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![NPM](https://img.shields.io/npm/v/storm-react-diagrams.svg)](https://npmjs.org/package/storm-react-diagrams) [![NPM](https://img.shields.io/npm/dt/storm-react-diagrams.svg)](https://npmjs.org/package/storm-react-diagrams) [![Package Quality](http://npm.packagequality.com/shield/storm-react-diagrams.svg)](http://packagequality.com/#?package=storm-react-diagrams) [![CircleCI](https://circleci.com/gh/projectstorm/react-diagrams/tree/master.svg?style=svg)](https://circleci.com/gh/projectstorm/react-diagrams/tree/master)
## What
![Personal Project](./images/example1.jpg)
A flow & process orientated diagramming library inspired by **Blender**, **Labview** and **Unreal engine**.
![](./images/example2.jpg)
* **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.
![](./images/example3.jpg)
## Gallery
## Introduction
Example implementation using custom models: \(Dylan's personal code\)
A no-nonsense diagramming library written entirely in React with the help of a few small libraries. It aims to be:
![Personal Project](.gitbook/assets/example1.jpg)
![](.gitbook/assets/example2.jpg)
* 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
Get started with the default models right out of the box:
#### Run the demos
![](.gitbook/assets/example3.jpg)
After running `yarn install` you must then run: `yarn run storybook`
## Installing
#### Building from source
For all the bells and whistles:
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\).
```text
yarn add @projectstorm/react-diagrams
```
## [Checkout the docs](https://projectstorm.gitbooks.io/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.
Take a look at the [diagram demos](https://github.com/projectstorm/react-diagrams/tree/master/packages/diagrams-demo-gallery/demos)
**or**
Take a look at the [demo project](https://github.com/projectstorm/react-diagrams/tree/master/packages/diagrams-demo-project) which contains an example for ES6 as well as Typescript
**or**
[Checkout the docs](https://projectstorm.gitbook.io/react-diagrams/)
## Run the demos
After running `yarn install` you must then run: `cd packages/diagrams-demo-gallery && yarn run start`
## Building from source
Simply run `yarn` then `yarn build` or `yarn build:prod` in the root directory and it will spit out the transpiled code and typescript definitions into the dist directory as a single file.
## Built with react-diagrams
> Do you have an interesting project built with *react-diagrams*? PR it into this section for others to see.

View File

@@ -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)

View File

@@ -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>
);
}
}

View File

@@ -1,37 +0,0 @@
import * as React from "react";
import { withDocs } from "storybook-readme";
import { WithCode } from "../../.storybook/addon-code/react.js";
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);
});
}
static makeDemo(widget, code, markdown?) {
let container = () => <WithCode code={code}>{widget}</WithCode>;
if (markdown) {
return withDocs({
PreviewComponent: ({ children }) => {
return <div className="docs-preview-wrapper">{children}</div>;
}
})(markdown, container);
}
return container;
}
}

View File

@@ -1,80 +0,0 @@
@import "../../src/sass/main";
.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%;
}
}
.docs-preview-wrapper{
background: rgb(60,60,60);
border-radius: 10px;
overflow: hidden;
padding: 10px;
margin-top: 20px;
margin-bottom: 20px;
}
.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);
}
}

View File

@@ -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();
}
}

View File

@@ -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"));
}
}

View File

@@ -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>
);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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.installDefaults();
// 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.setModel(model);
//6) render the diagram!
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
};

View File

@@ -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;
modelNode.y = node.y;
});
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)
);
}

View File

@@ -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.setModel(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.installDefaults();
//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.setModel(model2);
return <Demo8Widget engine={engine} />;
};

View File

@@ -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>
);
}
}

View File

@@ -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>
);
}
}

View File

@@ -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>;
}
}

View File

@@ -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} />;
};

View File

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

View File

@@ -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.installDefaults();
//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 <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
};

View File

@@ -1,73 +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.installDefaults();
// 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.setTargetPort(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={
<button
onClick={() => {
action("Serialized Graph")(JSON.stringify(model.serializeDiagram(), null, 2));
}}
>
Serialize Graph
</button>
}
>
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
</DemoWorkspaceWidget>
);
};

View File

@@ -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.installDefaults();
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.setModel(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>
);
};

View File

@@ -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.installDefaults();
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.setModel(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>
);
};

View File

@@ -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.installDefaults();
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);
var props = {
diagramEngine: engine,
allowLooseLinks: false,
allowCanvasTranslation: false,
allowCanvasZoom: false
} as DiagramProps;
//!========================================= <<<<<<<
return <DiagramWidget className="srd-demo-canvas" {...props} />;
};

View File

@@ -1,60 +0,0 @@
import { DiagramEngine, DiagramModel, DefaultNodeModel, LinkModel } 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";
import {DeserializeEvent} from "../../../react-canvas/src/models/BaseModel";
export default () => {
//1) setup the diagram engine
var engine = new DiagramEngine();
engine.installDefaults();
//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);
//!------------- SERIALIZING ------------------
var str = JSON.stringify(model.serialize());
//!------------- DESERIALIZING ----------------
var model2 = new DiagramModel();
model2.deSerialize(new DeserializeEvent(JSON.parse(str), engine));
engine.setModel(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>
);
};

View File

@@ -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.installDefaults();
//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.setModel(model);
//6) render the diagram!
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} allowLooseLinks={false} />;
};

View File

@@ -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.

View File

@@ -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.installDefaults();
//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.setModel(model);
//6) render the diagram!
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
};

View File

@@ -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.installDefaults();
// 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.setModel(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>
);
};

View File

@@ -1,129 +0,0 @@
import * as React from "react";
import { storiesOf, addDecorator } from "@storybook/react";
import { setOptions } from "@storybook/addon-options";
import { host } from "storybook-host";
import { Helper } from "./.helpers/Helper";
import { Toolkit } from "../src/Toolkit";
//include the SCSS for the demo
import "./.helpers/demo.scss";
Toolkit.TESTING = true;
addDecorator(
host({
cropMarks: false,
height: "100%",
width: "100%",
padding: 20
})
);
setOptions({
name: "STORM React Diagrams",
url: "https://github.com/projectstorm/react-diagrams",
addonPanelInRight: true
});
storiesOf("Simple Usage", module)
.add(
"Simple example",
Helper.makeDemo(
require("./demo-simple/index").default(),
require("!!raw-loader!./demo-simple/index"),
require("./demo-simple/docs.md")
)
)
// .add(
// "Simple flow example",
// Helper.makeDemo(require("./demo-simple-flow/index").default(), require("!!raw-loader!./demo-simple-flow/index"))
// )
// .add(
// "Performance demo",
// Helper.makeDemo(require("./demo-performance/index").default(), require("!!raw-loader!./demo-performance/index"))
// )
// .add(
// "Locked widget",
// Helper.makeDemo(require("./demo-locks/index").default(), require("!!raw-loader!./demo-locks/index"))
// )
// .add(
// "Canvas grid size",
// Helper.makeDemo(require("./demo-grid/index").default(), require("!!raw-loader!./demo-grid/index"))
// )
// .add(
// "Limiting link points",
// Helper.makeDemo(
// require("./demo-limit-points/index").default(),
// require("!!raw-loader!./demo-limit-points/index")
// )
// )
// .add(
// "Events and listeners",
// Helper.makeDemo(require("./demo-listeners/index").default(), require("!!raw-loader!./demo-listeners/index"))
// )
// .add(
// "Zoom to fit",
// Helper.makeDemo(require("./demo-zoom-to-fit/index").default(), require("!!raw-loader!./demo-zoom-to-fit/index"))
// )
// .add(
// "Links with labels",
// Helper.makeDemo(
// require("./demo-labelled-links/index").default(),
// require("!!raw-loader!./demo-labelled-links/index")
// )
// );
//
// storiesOf("Advanced Techniques", module)
// .add(
// "Clone Selected",
// Helper.makeDemo(require("./demo-cloning/index").default(), require("!!raw-loader!./demo-cloning/index"))
// )
// .add(
// "Serializing and de-serializing",
// Helper.makeDemo(require("./demo-serializing/index").default(), require("!!raw-loader!./demo-serializing/index"))
// )
// .add(
// "Programatically modifying graph",
// Helper.makeDemo(
// require("./demo-mutate-graph/index").default(),
// require("!!raw-loader!./demo-mutate-graph/index")
// )
// )
// .add(
// "Large application",
// Helper.makeDemo(
// require("./demo-drag-and-drop/index").default(),
// require("!!raw-loader!./demo-drag-and-drop/components/BodyWidget")
// )
// )
// .add(
// "Smart routing",
// Helper.makeDemo(
// require("./demo-smart-routing/index").default(),
// require("!!raw-loader!./demo-smart-routing/index")
// )
// );
//
// storiesOf("Custom Models", module)
// .add(
// "Custom diamond node",
// Helper.makeDemo(
// require("./demo-custom-node1/index").default(),
// require("!!raw-loader!./demo-custom-node1/index")
// )
// )
// .add(
// "Custom animated links",
// Helper.makeDemo(
// require("./demo-custom-link1/index").default(),
// require("!!raw-loader!./demo-custom-link1/index")
// )
// );
//
// storiesOf("3rd party libraries", module).add(
// "Auto Distribute (Dagre)",
// Helper.makeDemo(require("./demo-dagre/index").default(), require("!!raw-loader!./demo-dagre/index"))
// );
// enable this to log mouse location when writing new puppeteer tests
//Helper.logMousePosition()

View File

@@ -1,10 +0,0 @@
{
"extends": [
"../tslint.json"
],
"rules": {
"no-console": false,
"max-classes-per-file": false,
"no-var-requires": false
}
}

View File

@@ -0,0 +1,6 @@
module.exports = {
stories: ['../demos/*.stories.tsx'],
core: {
builder: "webpack5",
},
};

View File

@@ -0,0 +1,6 @@
import { addons } from '@storybook/addons';
import diagramsTheme from "./theme";
addons.setConfig({
theme: diagramsTheme,
});

View File

@@ -0,0 +1,3 @@
export const parameters = {
layout: 'fullscreen',
};

View 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'
});

View File

@@ -0,0 +1,30 @@
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_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 ZoomToFitNodes = demo_zoom_nodes;
export const CanvasDrag = demo_canvas_drag;
export const DynamicPorts = demo_dynamic_ports;
export const LinksWithLabels = demo_labels

View 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;

View 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;

View 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

View File

@@ -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;
}
}

View File

@@ -0,0 +1,59 @@
import { MouseEvent } 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);
}
}
})
);
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);
}
})
);
}
}

View File

@@ -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>
);
};

View 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} />;
};

View File

@@ -0,0 +1,71 @@
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} />;
};

View File

@@ -1,15 +1,9 @@
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";
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
@@ -23,24 +17,24 @@ class CloneSelected extends React.Component<any, any> {
cloneSelected() {
let { engine } = this.props;
let offset = { x: 100, y: 100 };
let model = engine.getDiagramModel();
let model = engine.getModel();
let itemMap = {};
_.forEach(model.getSelectedItems(), (item: BaseModel<any>) => {
_.forEach(model.getSelectedEntities(), (item: BaseModel<any>) => {
let newItem = item.clone(itemMap);
// offset the nodes slightly
if (newItem instanceof NodeModel) {
newItem.setPosition(newItem.x + offset.x, newItem.y + offset.y);
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.updateLocation({ x: p.getX() + offset.x, y: p.getY() + offset.y });
newItem.getPoints().forEach((p) => {
p.setPosition(p.getX() + offset.x, p.getY() + offset.y);
});
model.addLink(newItem);
}
newItem.selected = false;
(newItem as BaseModel).setSelected(false);
});
this.forceUpdate();
@@ -49,8 +43,10 @@ class CloneSelected extends React.Component<any, any> {
render() {
const { engine } = this.props;
return (
<DemoWorkspaceWidget buttons={<button onClick={this.cloneSelected}>Clone Selected</button>}>
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
<DemoWorkspaceWidget buttons={<DemoButton onClick={this.cloneSelected}>Clone Selected</DemoButton>}>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>
</DemoWorkspaceWidget>
);
}
@@ -58,20 +54,19 @@ class CloneSelected extends React.Component<any, any> {
export default () => {
//1) setup the diagram engine
var engine = new DiagramEngine();
engine.installDefaults();
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");
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");
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
let port2 = node2.addInPort('In');
node2.setPosition(400, 100);
// link the ports

View 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>
);
};

View File

@@ -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} />;
}
}

View File

@@ -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;
}
}

View File

@@ -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>
);
};

View 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>
);
};

View File

@@ -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.installDefaults();
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();
@@ -153,5 +149,9 @@ export default () => {
engine.setModel(model);
// render the diagram!
return <DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />;
return (
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>
);
};

View File

@@ -0,0 +1,172 @@
import createEngine, {
DiagramModel,
DefaultNodeModel,
DefaultPortModel,
DefaultLinkFactory,
DefaultLinkPointWidget,
DefaultLinkModel,
DefaultLinkWidget
} from '@projectstorm/react-diagrams';
import { DiagramEngine, LinkWidget, PointModel } from '@projectstorm/react-diagrams-core';
import * as React from 'react';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
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}
onMouseLeave={() => {
this.setState({ selected: false });
}}
onMouseEnter={() => {
this.setState({ selected: true });
}}
data-id={point.getID()}
data-linkid={point.getLink().getID()}></polygon>
</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>
);
};

View File

@@ -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();
}
}

View File

@@ -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));
}
}

View File

@@ -0,0 +1,111 @@
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>
);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View 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>
);
};

View File

@@ -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>
);
};

View File

@@ -0,0 +1,131 @@
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
});
}
autoDistribute = () => {
this.engine.redistribute(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={<DemoButton onClick={this.autoDistribute}>Re-distribute</DemoButton>}>
<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(nodesFrom[0], nodesTo[1], engine));
links.push(connectNodes(nodesTo[0], nodesFrom[1], engine));
links.push(connectNodes(nodesFrom[1], 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} />;
};

View File

@@ -1,4 +1,4 @@
import * as SRD from "storm-react-diagrams";
import * as SRD from '@projectstorm/react-diagrams';
/**
* @author Dylan Vorster
@@ -8,9 +8,7 @@ export class Application {
protected diagramEngine: SRD.DiagramEngine;
constructor() {
this.diagramEngine = new SRD.DiagramEngine();
this.diagramEngine.installDefaults();
this.diagramEngine = SRD.default();
this.newModel();
}
@@ -19,13 +17,13 @@ export class Application {
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

View File

@@ -0,0 +1,86 @@
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>
);
}
}

View File

@@ -0,0 +1,37 @@
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>
);
}
}

View File

@@ -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>;
}
}

View 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} />;
};

View 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} />;
};

View 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>
);
};

View File

@@ -0,0 +1,65 @@
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>
);
};

View 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>
);
};

View 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>
);
};

View File

@@ -1,6 +1,9 @@
import { DiagramEngine, DiagramModel, DefaultNodeModel, LinkModel, DiagramWidget } from "storm-react-diagrams";
import * as React from "react";
import { DemoWorkspaceWidget } from "../.helpers/DemoWorkspaceWidget";
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
@@ -14,25 +17,25 @@ class NodeDelayedPosition extends React.Component<any, any> {
updatePosition() {
const { engine } = this.props;
let model = engine.getDiagramModel();
let model = engine.getModel();
const nodes = model.getNodes();
let node = nodes[Object.keys(nodes)[0]];
node.setPosition(node.x + 30, node.y + 30);
this.forceUpdate();
node.setPosition(node.getX() + 30, node.getY() + 30);
engine.repaintCanvas();
}
updatePositionViaSerialize() {
let { engine } = this.props;
let model = engine.getDiagramModel();
let str = JSON.stringify(model.serializeDiagram());
let model = engine.getModel();
let str = JSON.stringify(model.serialize());
let model2 = new DiagramModel();
let obj = JSON.parse(str);
let node = obj.nodes[0];
let obj: ReturnType<DiagramModel['serialize']> = JSON.parse(str);
let node: ReturnType<NodeModel['serialize']> = _.values(obj.layers[1].models)[0] as any;
node.x += 30;
node.y += 30;
model2.deSerializeDiagram(obj, engine);
model2.deserializeModel(obj, engine);
engine.setModel(model2);
this.forceUpdate();
}
render() {
@@ -40,15 +43,16 @@ class NodeDelayedPosition extends React.Component<any, any> {
return (
<DemoWorkspaceWidget
buttons={[
<button key={1} onClick={this.updatePosition}>
<DemoButton key={1} onClick={this.updatePosition}>
Update position
</button>,
<button key={2} onClick={this.updatePositionViaSerialize}>
</DemoButton>,
<DemoButton key={2} onClick={this.updatePositionViaSerialize}>
Update position via serialize
</button>
]}
>
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
</DemoButton>
]}>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>
</DemoWorkspaceWidget>
);
}
@@ -56,20 +60,19 @@ class NodeDelayedPosition extends React.Component<any, any> {
export default () => {
//1) setup the diagram engine
var engine = new DiagramEngine();
engine.installDefaults();
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");
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");
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

View File

@@ -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.installDefaults();
var engine = createEngine();
//2) setup the diagram model
var model = new DiagramModel();
@@ -26,18 +27,22 @@ export default () => {
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

View File

@@ -0,0 +1,70 @@
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>
);
};

View File

@@ -0,0 +1,60 @@
import createEngine, { DiagramModel, DefaultNodeModel } 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);
//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>
);
};

View File

@@ -0,0 +1,50 @@
import createEngine, { DiagramModel, DefaultNodeModel, DefaultDiagramState } from '@projectstorm/react-diagrams';
import * as React from 'react';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
export default () => {
//1) setup the diagram engine
var engine = createEngine();
// ############################################ MAGIC HAPPENS HERE
const state = engine.getStateMachine().getCurrentState();
if (state instanceof DefaultDiagramState) {
state.dragNewLink.config.allowLooseLinks = false;
}
// ############################################ MAGIC HAPPENS HERE
//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.setModel(model);
//6) render the diagram!
return (
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>
);
};

View File

@@ -0,0 +1,43 @@
import createEngine, { DiagramModel, DefaultNodeModel, DefaultLinkModel } from '@projectstorm/react-diagrams';
import * as React from 'react';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
export default () => {
//1) setup the diagram engine
var engine = createEngine();
//2) setup the diagram model
var model = new DiagramModel();
//3-A) create a default node
var node1 = new DefaultNodeModel({
name: 'Node 1',
color: 'rgb(0,192,255)'
});
node1.setPosition(100, 100);
let port1 = node1.addOutPort('Out');
//3-B) create another default node
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
let port2 = node2.addInPort('In');
node2.setPosition(400, 100);
// link the ports
let link1 = port1.link<DefaultLinkModel>(port2);
link1.getOptions().testName = 'Test';
link1.addLabel('Hello World!');
//4) add the models to the root graph
model.addAll(node1, node2, link1);
//5) load model into engine
engine.setModel(model);
//6) render the diagram!
return (
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>
);
};

View File

@@ -0,0 +1,72 @@
import createEngine, {
DiagramModel,
DefaultNodeModel,
DefaultPortModel,
PathFindingLinkFactory,
DefaultLabelModel
} 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 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);
const pathfinding = engine.getLinkFactories().getFactory<PathFindingLinkFactory>(PathFindingLinkFactory.NAME);
// linking things together (specifically using the pathfinding link)
const link1 = port1.link(port4, pathfinding);
const link2 = port2.link(port3, pathfinding);
link1.addLabel(
new DefaultLabelModel({
label: 'I am a label!',
offsetY: 20
})
);
// add all to the main model
model.addAll(node1, node2, node3, node4, node5, 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>
);
};

View File

@@ -0,0 +1,55 @@
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
import * as React from 'react';
import { DemoWorkspaceWidget, DemoButton } from '../helpers/DemoWorkspaceWidget';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
/**
*
* Simple stress test of the system plus zoom to fit function
*
* @Author Dylan Vorster
*/
export default () => {
//1) setup the diagram engine
var engine = createEngine();
//2) setup the diagram model
var model = new DiagramModel();
for (var i = 0; i < 8; i++) {
for (var j = 0; j < 8; j++) {
generateNodes(model, i * 200, j * 100);
}
}
//5) load model into engine
engine.setModel(model);
//6) render the diagram!
return (
<DemoWorkspaceWidget buttons={<DemoButton onClick={() => engine.zoomToFitNodes(50)}>Zoom to fit</DemoButton>}>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>
</DemoWorkspaceWidget>
);
};
function generateNodes(model: DiagramModel, offsetX: number, offsetY: number) {
//3-A) create a default node
var node1 = new DefaultNodeModel('Node 1', 'rgb(0,192,255)');
var port1 = node1.addOutPort('Out');
node1.setPosition(100 + offsetX, 100 + offsetY);
//3-B) create another default node
var node2 = new DefaultNodeModel('Node 2', 'rgb(192,255,0)');
var port2 = node2.addInPort('In');
node2.setPosition(200 + offsetX, 100 + offsetY);
//3-C) link the 2 nodes together
var link1 = port1.link(port2);
//4) add the models to the root graph
model.addAll(node1, node2, link1);
}

View File

@@ -1,13 +1,8 @@
import {
DiagramEngine,
DiagramModel,
DefaultNodeModel,
LinkModel,
DefaultPortModel,
DiagramWidget
} from "storm-react-diagrams";
import * as React from "react";
import { DemoWorkspaceWidget } from "../.helpers/DemoWorkspaceWidget";
import createEngine, { DiagramModel, DefaultNodeModel } from '@projectstorm/react-diagrams';
import * as React from 'react';
import { DemoWorkspaceWidget, DemoButton } from '../helpers/DemoWorkspaceWidget';
import { CanvasWidget } from '@projectstorm/react-canvas-core';
import { DemoCanvasWidget } from '../helpers/DemoCanvasWidget';
/**
*
@@ -17,8 +12,7 @@ import { DemoWorkspaceWidget } from "../.helpers/DemoWorkspaceWidget";
*/
export default () => {
//1) setup the diagram engine
var engine = new DiagramEngine();
engine.installDefaults();
var engine = createEngine();
//2) setup the diagram model
var model = new DiagramModel();
@@ -34,23 +28,23 @@ export default () => {
//6) render the diagram!
return (
<DemoWorkspaceWidget
buttons={<button onClick={() => engine.getCanvasWidget().zoomToFit()}>Zoom to fit</button>}
>
<DiagramWidget className="srd-demo-canvas" diagramEngine={engine} />
<DemoWorkspaceWidget buttons={<DemoButton onClick={() => engine.zoomToFit()}>Zoom to fit</DemoButton>}>
<DemoCanvasWidget>
<CanvasWidget engine={engine} />
</DemoCanvasWidget>
</DemoWorkspaceWidget>
);
};
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

View File

@@ -0,0 +1,65 @@
import * as React from 'react';
import styled from '@emotion/styled';
import { css, Global } from '@emotion/react';
export interface DemoCanvasWidgetProps {
color?: string;
background?: string;
}
namespace S {
export const Container = styled.div<{ color: string; background: string }>`
height: 100%;
background-color: ${(p) => p.background};
background-size: 50px 50px;
display: flex;
> * {
height: 100%;
min-height: 100%;
width: 100%;
}
background-image: linear-gradient(0deg,
transparent 24%,
${(p) => p.color} 25%,
${(p) => p.color} 26%,
transparent 27%,
transparent 74%,
${(p) => p.color} 75%,
${(p) => p.color} 76%,
transparent 77%,
transparent),
linear-gradient(90deg,
transparent 24%,
${(p) => p.color} 25%,
${(p) => p.color} 26%,
transparent 27%,
transparent 74%,
${(p) => p.color} 75%,
${(p) => p.color} 76%,
transparent 77%,
transparent);
`;
export const Expand = css`
html, body, #root{
height: 100%;
}
`;
}
export class DemoCanvasWidget extends React.Component<DemoCanvasWidgetProps> {
render() {
return (
<>
<Global styles={S.Expand} />
<S.Container
background={this.props.background || 'rgb(60, 60, 60)'}
color={this.props.color || 'rgba(255,255,255, 0.05)'}>
{this.props.children}
</S.Container>
</>
);
}
}

View File

@@ -0,0 +1,55 @@
import * as React from 'react';
import styled from '@emotion/styled';
export interface DemoWorkspaceWidgetProps {
buttons?: any;
}
namespace S {
export const Toolbar = styled.div`
padding: 5px;
display: flex;
flex-shrink: 0;
`;
export const Content = styled.div`
flex-grow: 1;
height: 100%;
`;
export const Container = styled.div`
background: black;
display: flex;
flex-direction: column;
height: 100%;
border-radius: 5px;
overflow: hidden;
`;
}
export const DemoButton = styled.button`
background: rgb(60, 60, 60);
font-size: 14px;
padding: 5px 10px;
border: none;
color: white;
outline: none;
cursor: pointer;
margin: 2px;
border-radius: 3px;
&:hover {
background: rgb(0, 192, 255);
}
`;
export class DemoWorkspaceWidget extends React.Component<DemoWorkspaceWidgetProps> {
render() {
return (
<S.Container>
<S.Toolbar>{this.props.buttons}</S.Toolbar>
<S.Content>{this.props.children}</S.Content>
</S.Container>
);
}
}

View File

@@ -0,0 +1,23 @@
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);
});
}
}

View File

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

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