add some docs

This commit is contained in:
Dylan Vorster
2018-02-25 13:45:57 +02:00
parent 9b4f7d28d6
commit ac741d63a6
5 changed files with 152 additions and 68 deletions

View File

@ -11,79 +11,56 @@ A super simple, no-nonsense diagramming library written in React that just works
[![NPM](https://img.shields.io/npm/dt/storm-react-diagrams.svg)](https://npmjs.org/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)
![Demo2](./images/example1.png)
![Personal Project](./images/example1.png)
![Demo2](./images/example2.png)
![](./images/example2.png)
![Demo2](./images/example3.png)
![](./images/example3.png)
## Introduction
A no-nonsense diagramming library written entirely in React with the help of Lodash, and a single polyfill. It aims to be:
A no-nonsense diagramming library written entirely in React with the help of a few small libraries. It aims to be:
* Simple, and void of any fuss/complications when implementing it into your own application
* Customizable without having to hack the core (adapters/factories etc..)
* Simple to operate and understand without sugar and magic
* Fast and optimized to handle large diagrams with hundreds of nodes/links
* 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
## Usage
## Developer Usage
#### Installing
`npm install storm-react-diagrams` or `yarn add storm-react-diagrams`
### How to run demos
#### Getting started
The best place to start is by looking at the simple demos `demos/demo-simple` and going from there.
#### Run the demos
After running `yarn install` you must then run: `yarn run storybook`
### How to build
#### Building from source
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. __It will also compile the code for the demos__ .We use webpack for this because TSC cannot compile a single UMD file (TSC can currently only output multiple UMD files).
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).
_NOTE:_ We turn off name mangeling in production builds because we require class names to be left intact when serializing.
### Make your own nodes
## Make your own nodes
To see how to create your own nodes like the one below, take a look at __demo3__:
To see how to create your own nodes like the one below, take a look at __demos/demo-custom-link1__:
![Demo2](./images/demo3.png)
## How does it work
## Learn More
The library uses a Model Graph to represent the virtual diagram and then renders the diagram using
2 layers:
* Node Layer -> which is responsible for rendering nodes as HTML components
* Link Layer -> which renders the links as SVG paths
[Architecture Questions](docs/Architecture%20Questions.md)
Each node and link is fed into a factory that then generates the corresponding node or link react widget.
Therefore, to create custom nodes and links, register your own factories that return your own widgets.
[Interactive Questions](docs/Interactive%20Usage.md)
As long as a node contains at least one port and the corresponding NodeWidget contains at least one PortWidget,
a link can be connected to it.
[Testing the Library](docs/Testing.md)
## Questions
[Questions](docs/Questions.md)
## User Usage
__Delete__ removes any selected items
![__Delete__](./images/rjdDelete.gif)
__Shift + Mouse Drag__ triggers a multi-selection box
![Shift + Mouse Drag](./images/mouseDrag.gif)
__Shift + Mouse Click__ selects the item (items can be multi-selected)
![Shift + Mouse Click](./images/shiftClick.gif)
__Mouse Drag__ drags the entire diagram
![Mouse Drag](./images/canvasDrag.gif)
__Mouse Wheel__ zooms the diagram in / out
![Mouse Wheel](./images/mouseWheel.gif)
__Click Link + Drag__ creates a new link point
![Click Link + Drag](./images/createPoint.gif)
__Click Node Port + Drag__ creates a new link
![Click Node Port + Drag](./images/createLink.gif)

View File

@ -0,0 +1,76 @@
# Architecture Questions
Here I will try to answer any questions relating to the design of the system
### What was the inspiration for this library?
Joint JS (a fantastic library) + my need for rich HTML nodes + LabView + Blender Composite sub system
### Why render the nodes as HTML Elements and not SVG's?
My original requirement for this library stemmed from the requirement of wanting HTML nodes that would allow me to
embed rich controls such as input fields, drop downs and have the system treat such nodes as first class citizens.
I originally tried to make this work in JointJS, but ran into a number of problems of which this was a relatively big one.
JointJS does allow you to do this, but at the time of writing this library originally, I was having a lot of trouble
to make it work exactly like I needed it, and therefore decided from the very beginning that I would attempt this
with an HTML first mindset.
### Why Typescript?
Firstly, because it can transpile into any level of ECMAScript. This means that I don't need to break our the refactor tractor
every time ECMAScript decides it wants to add features which it should have done years ago.
I also ported it to Typescript to accommodate the heavy architectural changes I was starting to make. Since porting
the library to typescript, and seeing the project explode in size and complexity, I consider this the best decision
made with regards to this library so far.
Porting to typescript also afforded us a set of powerful features such as generics and static analysis that
all the project contributors have made exclusive use of.
Typescript is <3 typescript is life.
### Why not Flow instead of Typescript?
At the time when I first started evaluating languages that could transpile to ECMAScript, I was not so sold
on the supporting environment surrounding flow, and and found that there was better tooling to support
typescript, they are ultimately trying to do the same thing though, and I guess in the end, typescript just made
more sense.
### Why React ?
React is really efficient at rendering and managing HTML in a declarative manner. React has also become
one of the bigger industry standards and has a rich eco system that plays really well with typescript.
Apart from these notable points, I am really fond of React and wanted a diagramming library that takes full advantage of it,
and makes it easy for engineers to use its power as well, when extending this library.
### Why cant the Default models and widgets do this or that ?
They are intended to illustrate __how__ to use this library and act as a good starting point
to extend and show the capability. Ultimately I designed this library to be completely
pluggable in a way that you can use it as a library and not a framework. If the default widgets
are not good enough, then a good place to start is with creating your own models/factories/widgets.
### Model vs Widget
For those that are new to [Scene Graphs](https://en.wikipedia.org/wiki/Scene_graph) or are not familiar with concepts
such as [MVC](https://en.wikipedia.org/wiki/Modelviewcontroller), this library represents your entire graph as a model.
The model is a traversable graph that represents the nodes and links between them in a virtual manner. Your program (aka the business logic/layer)
can mutate this model imperatively or store snapshots decoratively of the complete model (via serialization) and then the engine and react
widgets will take care of the rendering. For this reason every model in the library is represented by a widget, and the factories glue it all together.
### How do I make my own elements?
Take a look at the __demos__ directory, with specific attention to the __DefaultNodeWidget__
That being said, the demos directory is an _example_ of how you can create your own elements.
A number of people want to use the defaults as is, which is cool,
but is recommended to create your own models/factories/widgets.
### How do I use the library?
Take a look at the demo folders, they have simple and complex examples of the complete usage.
A good example of a real-world example is Demo 5

22
docs/Interactive Usage.md Normal file
View File

@ -0,0 +1,22 @@
# End user usage
__Delete__ removes any selected items
![__Delete__](./images/rjdDelete.gif)
__Shift + Mouse Drag__ triggers a multi-selection box
![Shift + Mouse Drag](./images/mouseDrag.gif)
__Shift + Mouse Click__ selects the item (items can be multi-selected)
![Shift + Mouse Click](./images/shiftClick.gif)
__Mouse Drag__ drags the entire diagram
![Mouse Drag](./images/canvasDrag.gif)
__Mouse Wheel__ zooms the diagram in / out
![Mouse Wheel](./images/mouseWheel.gif)
__Click Link + Drag__ creates a new link point
![Click Link + Drag](./images/createPoint.gif)
__Click Node Port + Drag__ creates a new link
![Click Node Port + Drag](./images/createLink.gif)

View File

@ -1,24 +0,0 @@
## Questions
#### Why didnt I render the nodes as SVG's?
Because its vastly better to render nodes as standard HTML so that we can embed input controls and not have
to deal with the complexities of trying to get SVG to work like we want it to. I also created this primarily to embed into
enterprise applications where the nodes themselves are highly interactive with buttons and other controls that cave when I try to use SVG.
#### Why Typescript?
Because it can transpile into any level of ECMA Script, and the library got really complicated, so I ported it to Typescript
to accommodate the heavy architectural changes I was starting to make. <3 Type Script
#### How do I make my own elements?
Take a look at the __defaults__ directory, with specific attention to the __DefaultNodeWidget__
That being said, the defaults directory is an EXAMPLE of how you can create your own elements. A number of people want to use the defaults as is, which is cool, but is recommended to create your own base node like the onw you see
#### How do I use the library?
Take a look at the demo folders, they have simple and complex examples of the complete usage.
A good example of a real-world example is Demo 5

33
docs/Testing.md Normal file
View File

@ -0,0 +1,33 @@
# Testing
STORM React diagrams is tested two main ways.
## JEST Snapshot testing
With Jest snapshots, we render all the demos in the demo folder by automatically
looking into each `demo-*` folder and searching for an __index.tsx__ file.
For each file we find, we dynamically include it as a storybook story and assemble one big test.
This test then renders each demo in a deterministic way and compares it to the snapshot file
situated in __snapshots__. If the snapshots don't match, then something has changed and either the snapshot
needs to be updated, or the test is failing in which case we need to fix the code.
Snapshot testing does not test the functionality of the program but it is a first important step
to make sure that changes aren't having a drastic effect on the overall system.
In the event that the snapshot needs to be updated, please run `yarn run test -u` to overwrite
the snapshot file, and then make sure to your branch.
## End to end testing
To test the functionality of the library, we make use of e2e tests (end to end tests).
In this library, we spin up a headless chrome using pupeteer and interactively and programmatically
tell the mouse pointer to click and drag on various elements while making assertions along the way.
We use Jest for the assertions and the interactivity is handled by puppeteer. Due to the laborious nature
of writing e2e tests, there is a helper method that is provided in each test that makes interacting
with the diagrams a lot easier. Using this helper, you cna easily tell the mouse to drag links between nodes,
select them and also easily assert information about them. The important thing here, is that this helper
does not touch the model in any way, but is purely a helper for writing the tests themselves. Please
make use of this helper when writing tests, as it ensure that the tests are defensive in nature, and also
reduces the overhead of physically writing them.