README
ArtistJS">
ArtistJS is a versatile JavaScript diagramming library that provides the core elements for implementing your own domain-specific visual languages, using figures with customizable templates and layouts.
- Client-side technology: It runs completely in the browser (no server-side requirements), rendering in compliance with web standards (HTML, CSS and SVG).
- Object-oriented JS: It encourages faster and more efficient code reuse and maintenance.
- No third-party libraries: It requires no plugins and can be integrated in virtually any project.
Content
Main elements
- Graph: It consists of a set of nodes, together with a set of connections. A
Graph
is graphically represented by aDiagram
. - Node: It is a vertex of the
Graph
that contains its incoming and outgoing connections. ANode
is graphically represented by aFigure
. - Connection: It is a directed arc between two nodes (source and target). A
Connection
is graphically represented by aConnectionFigure
. - Diagram: It renders the root element that contains the representation of the
Graph
elements. - Figure: It represents a
Node
element using basic figures (RectangleFigure
,EllipseFigure
,TextFigure
,LineFigure
...). AFigure
can be composed of other figures (complex figure). The area where aFigure
is rendered is called bounds (x, y, width, height). - ConnectionFigure: It represents a
Connection
element as a line from the source to the targetFigure
. - Decoration:
Figure
that is situated at the beginning, middle or end of aConnectionFigure
. - Layout: It manages the position and the ideal size of each
Figure
of theDiagram
and eachFigure
that makes up a complex figure. - Anchor: It determines the connection point of a
Figure
. - Router: It calculates the path to draw a
ConnectionFigure
from the source to the target.
Getting started
Installation
You can install the latest version of ArtistJS using npm:
npm install artistjs --save
TypeScript external module definition files are included. They will be automatically picked up by the TypeScript compiler when importing from the npm package.
Or you can directly download the browser version: artist.js and artist.min.js (minified version).
How to use
In this minimal example, we are going to show the basic usage of Node
, Connection
, Figure
and ConnectionFigure
to build the next simple, custom diagram:
This diagram is composed of two Figure
(and, subsequently, two Node
) and one ConnectionFigure
(and, subsequently, one Connection
). Additionally, each Figure
is a complex figure formed by two Figure
.
Firstly, we are going to create the Hello figure and the corresponding Hello node. Therefore, we extend the Figure
class to build our complex figure called MyHelloFigure
. This figure is formed by two Figure
: a RectangleFigure
to draw the outline and a TextFigure
to draw the text "Hello". Note that the update method has to be overloaded to update the bounds of the figures.
import {Figure, RectangleFigure, TextFigure, Area} from 'artistjs';
export default class MyHelloFigure extends Figure {
constructor() {
super();
this.addChild(new RectangleFigure());
this.addChild(new TextFigure('Hello'));
(<TextFigure>this.children[1]).alignment = 'center';
}
update(domNode: any): void {
super.update(domNode);
this.children[0].bounds = new Area(this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
this.children[1].bounds = new Area(this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height * 0.6); // text occupies the 60% the figure height
}
}
Then, we extend Node
class to create our custom Hello node called MyHelloNode
. This node is configured to be represented by MyHelloFigure
.
import {Node, Dimension} from 'artistjs';
import MyHelloFigure from './MyHelloFigure';
export default class MyHelloNode extends Node {
constructor() {
super();
this.figure = new MyHelloFigure();
this.figure.size = new Dimension(50, 50); // default size
}
}
Similarly, we create MyWorldFigure
extending Figure
class. This custom Figure
is formed by a CircleFigure
to draw the outline and a TextFigure
to draw the text "World!".
import {Figure, CircleFigure, TextFigure, Area} from 'artistjs';
export default class MyWorldFigure extends Figure {
constructor() {
super();
this.addChild(new CircleFigure());
this.addChild(new TextFigure('World!'));
(<TextFigure>this.children[1]).alignment = 'center';
}
update(domNode: any): void {
super.update(domNode);
this.children[0].bounds = new Area(this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
this.children[1].bounds = new Area(this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height * 0.6); // text occupies the 60% the figure height
}
}
Once the MyWorldFigure
is created, we implement MyWorldNode
extending Node
class, which will be rendered using MyWorldFigure
.
import {Node, Dimension} from 'artistjs';
import MyWorldFigure from './MyWorldFigure';
export default class MyWorldNode extends Node {
constructor() {
super();
this.figure = new MyWorldFigure();
this.figure.size = new Dimension(50, 50); // default size
}
}
Next, we extend Connection
class to build our custom connection called MyConnection
. This connection is configured to be rendered by a ConnectionFigure
with a DiamondDecoration
in the source and an ArrowDecoration
in the target.
import {Connection, Node, DiamondDecoration, ArrowDecoration, Dimension} from 'artistjs';
export default class MyConnection extends Connection {
constructor(source: Node, target: Node) {
super(source, target);
this.connectionFigure.sourceDecoration = new DiamondDecoration();
this.connectionFigure.targetDecoration = new ArrowDecoration();
}
}
Now, we are able to model and render an instance of our custom diagram, using all previously implemented elements.
const example = new Artist.Graph(); // default graph
const hello = new HelloWorld.MyHelloNode();
const world = new HelloWorld.MyWorldNode();
const conn = new HelloWorld.MyConnection(hello, world);
example.nodes = [hello, world];
example.connections = [conn];
hello.figure.position = new Artist.Point(1.5, 1.5);
world.figure.position = new Artist.Point(100.5, 1.5);
example.render(document.getElementById('div1'));
The diagram is rendered according to the SVG web standard.
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="500">
<g>
<rect x="1.5" y="1.5" width="50" height="50" rx="0" ry="0"></rect>
<text x="26.5" y="31.5" text-anchor="middle">Hello</text>
</g>
<g>
<circle cx="125.5" cy="26.5" r="25"></circle>
<text x="125.5" y="31.5" text-anchor="middle">World!</text>
</g>
<g>
<path class="connection" d="M51.5,26.5 L100.5,26.5" marker-start="url(#6dec8930-5f89-4edd-878c-4430b395d9d3)" marker-end="url(#a43e8281-068b-4e61-a097-a3a8ff8018c7)" id="9f46d922-5e3b-4016-b0e4-20c9d179f351"></path>
<g>
<marker id="6dec8930-5f89-4edd-878c-4430b395d9d3" markerWidth="10" markerHeight="10" refX="0" refY="5" orient="auto">
<polygon points="5 0,10 5,5 10,0 5"></polygon>
</marker>
<marker id="a43e8281-068b-4e61-a097-a3a8ff8018c7" markerWidth="10" markerHeight="10" refX="10" refY="5" orient="auto">
<path d="M0,0 L0,10 L10,5 L0,0"></path>
</marker>
</g>
</g>
</svg>
Demos
Take a look at the demos
folder to learn more about how to implement fully custom ArtistJS diagrams.
Open the
index.html
file in your browser to see the demo in action.
UML
BPMN
Git History
Network
Contributing
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :smiley:
License
This project is licensed under the terms of the BSD 3-Clause license.