Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/kieler/elkjs

ELK's layout algorithms for JavaScript
https://github.com/kieler/elkjs

diagram-layout graph-layout layered-layout layout-algorithm

Last synced: 3 days ago
JSON representation

ELK's layout algorithms for JavaScript

Awesome Lists containing this project

README

        



[![npm version](https://badge.fury.io/js/elkjs.svg)](https://badge.fury.io/js/elkjs)

The [Eclipse Layout Kernel (ELK)](https://www.eclipse.org/elk/) implements an infrastructure to connect diagram editors or viewers to automatic layout algorithms. This library takes the layout-relevant part of ELK and makes it available to the JavaScript world.
ELK's flagship is a layer-based layout algorithm that is particularly suited for node-link diagrams with an inherent direction and ports (explicit attachment points on a node's border). It is based on the ideas originally introduced by Sugiyama et al. An example can be seen in the screenshot below.

Note that elkjs is not a diagramming framework itself - it computes positions for the elements of a diagram.

elkjs is the successor of [klayjs](https://github.com/kieler/klayjs).

#### Demonstrator
You can see elkjs [live in action](https://rtsys.informatik.uni-kiel.de/elklive/) in conjunction with TypeFox's [sprotty](https://github.com/eclipse/sprotty) diagramming framework. In case elklive happens to be down you can use the published [docker container](https://github.com/kieler/elk-live/pkgs/container/elk-live) to run and host it yourself.

![](https://raw.githubusercontent.com/kieler/elkjs/master/doc/example_complexRouter.svg)

# FAQs and Recurring Issues
The following list includes some recurring topics that may have been addressed in issues already:

* [#100][ejs100], [elk#355][e355], [elk#627][e627] - How to consider previous layout results, including
* dynamic layout, and
* incrementally adding nodes and edges to an existing layout.

* [elk#315][e315]: Standalone edge routing.

* [#85][ejs85] elkjs itself is a graph layout engine _only_. In other words, no rendering, styling, etc. is provided.

* [#127][ejs127], [#141][ejs141], [#142][ejs142] - Issues due to the underlying code transpilation by GWT and/or due to the outdated usage of js modules:
* `g is not defined`,
* `Can't resolve web-worker`, and
* general usage as part of react, webpack, etc.
* [#6][ejs6] Poor modularization
* Contributions here are welcome!

[ejs6]: https://github.com/kieler/elkjs/issues/6
[ejs85]: https://github.com/kieler/elkjs/issues/85
[ejs100]: https://github.com/kieler/elkjs/issues/100
[ejs127]: https://github.com/kieler/elkjs/issues/127
[ejs141]: https://github.com/kieler/elkjs/issues/141
[ejs142]: https://github.com/kieler/elkjs/issues/142
[e315]: https://github.com/eclipse/elk/issues/315
[e355]: https://github.com/eclipse/elk/issues/355
[e627]: https://github.com/eclipse/elk/issues/627

# Installation
The latest released version:
```bash
npm install elkjs
```
Development version based on ELK's `master` branch.
```bash
npm install elkjs@next
```

# Releases and Versioning

Releases are partly synchronized with ELK's versions: the minor version number is always the same but the revision number may diverge. For instance, elkjs 0.3.0 equals the functionality of ELK 0.3.0 but elkjs 0.3.2 may be different from ELK 0.3.2. This is necessary as there may be fixes that solely concern elkjs and should be released independently of ELK.

# Files
The library consists of two main files:
* `elk-api.js`: Provides the API and only the API.
* `elk-worker.js`: Provides the code that actually knows how to lay out a graph. This is the file that is generated from ELK's Java code base using GWT.

Two further files are provided:
* `elk.bundled.js`: A bundled version of the two previous files, ready to be dropped into a browser's `` tag. The file is processed by [browserify](http://browserify.org/) and the `ELK` is exposed as a global variable (if run in a browser).
* `main.js`: Main file of the node.js module. Allows to conveniently write `require('elkjs')` instead of composing the files from above.

# Example
A small example using node.js,
for further use cases see the next section.
```js
const ELK = require('elkjs')
const elk = new ELK()

const graph = {
id: "root",
layoutOptions: { 'elk.algorithm': 'layered' },
children: [
{ id: "n1", width: 30, height: 30 },
{ id: "n2", width: 30, height: 30 },
{ id: "n3", width: 30, height: 30 }
],
edges: [
{ id: "e1", sources: [ "n1" ], targets: [ "n2" ] },
{ id: "e2", sources: [ "n1" ], targets: [ "n3" ] }
]
}

elk.layout(graph)
.then(console.log)
.catch(console.error)
```
Note that in case you get errors, you may want to switch to the non-minified version
to get a proper stack trace.

## Layout Options

You can use _layout options_ to configure the layout algorithm.
For that you attach a `layoutOptions` object
to the graph element that holds key/value pairs
representing the desired layout options.
See, for instance, `root` in the example above.
It is possible to only use the suffix of a layout option:
`algorithm` instead of `org.eclipse.elk.layered`.
However, if the suffix is not unique the layout option
may be ignored. To be safe, you should always start the
layout options with the `elk.` part.
A list of all options and further details of their exact effects
is available in [ELK's documentation](http://www.eclipse.org/elk/reference.html).

It is possible to pass global layout options
as part of the `layout` method's second argument.
The options are then applied to every graph element
unless the element specifies the option itself:
```js
elk.layout(graph, {
layoutOptions: { ... }
})
```

Additionally, `ELK`'s constructor accepts an object
with layout options that is used with every
`layout` call that does not specify layout options:
```js
const elk = new ELK({
defaultLayoutOptions: { ... }
})
```

# Usage

Since laying out diagrams can be a time-consuming job
(even for the computer),
and since we don't want to freeze your UI,
Web Workers are supported out of the box.
The following examples illustrate how the library can be used either
with and without a Web Worker.

## node.js

```js
const ELK = require('elkjs')
// without web worker
const elk = new ELK()

elk.layout(graph)
.then(console.log)
```

```js
const ELK = require('elkjs')
// with web worker
const elk = new ELK({
workerUrl: './node_modules/elkjs/lib/elk-worker.min.js'
})

elk.layout(graph)
.then(console.log)
```

Since version 10.x, node.js comes with a worker threads implementation that is similar to,
but not equal to, a browser's `Worker` class.
To ease implementation on our side, we use a library, `web-worker`,
that provides a wrapper around node's `worker_threads`, which is API-compatible to a browser's `Worker.
Any other library that provides the standard Web Worker methods should be fine though.
The package is not installed automatically to avoid
the unnecessary dependency for everyone who is not
interested in using a web worker.
A warning is raised if one requests a web worker
without having installed the package.
elkjs falls back to the non-Web Worker version in that case.

## Browser

```html
<html>
<script src="./elk.bundled.js">

const elk = new ELK()

elk.layout(graph)
.then(function(g) {
document.body.innerHTML = "<pre>" + JSON.stringify(g, null, " ") + "</pre>"
})