Gathering detailed insights and metrics for elkjs
Gathering detailed insights and metrics for elkjs
Gathering detailed insights and metrics for elkjs
Gathering detailed insights and metrics for elkjs
@jupyrdf/jupyter-elk
ElkJS widget for Jupyter
@qix/elkjs-patched
Automatic graph layout based on Sugiyama's algorithm. Specialized for data flow diagrams and ports.
elkjs-svg
Simple SVG renderer for elkjs
@electron-lang/schematic-diagram
Netlist viewer for Theia using sprotty and elkjs.
npm install elkjs
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
1,814 Stars
139 Commits
97 Forks
32 Watching
26 Branches
22 Contributors
Updated on 27 Nov 2024
Minified
Minified + Gzipped
JavaScript (76.66%)
Java (17.42%)
Xtend (4.77%)
HTML (1.15%)
Cumulative downloads
Total Downloads
Last day
1.3%
157,239
Compared to previous day
Last week
0.2%
759,927
Compared to previous week
Last month
6.7%
3,312,016
Compared to previous month
Last year
172.5%
34,745,340
Compared to previous year
The Eclipse Layout Kernel (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.
You can see elkjs live in action in conjunction with TypeFox's sprotty diagramming framework. In case elklive happens to be down you can use the published docker container to run and host it yourself.
The following list includes some recurring topics that may have been addressed in issues already:
#100, elk#355, elk#627 - How to consider previous layout results, including
elk#315: Standalone edge routing.
#85 elkjs itself is a graph layout engine only. In other words, no rendering, styling, etc. is provided.
#127, #141, #142 - 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
, andThe latest released version:
1npm install elkjs
Development version based on ELK's master
branch.
1npm install elkjs@next
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.
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 <script>
tag. The file is processed by browserify 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.A small example using node.js, for further use cases see the next section.
1const ELK = require('elkjs') 2const elk = new ELK() 3 4const graph = { 5 id: "root", 6 layoutOptions: { 'elk.algorithm': 'layered' }, 7 children: [ 8 { id: "n1", width: 30, height: 30 }, 9 { id: "n2", width: 30, height: 30 }, 10 { id: "n3", width: 30, height: 30 } 11 ], 12 edges: [ 13 { id: "e1", sources: [ "n1" ], targets: [ "n2" ] }, 14 { id: "e2", sources: [ "n1" ], targets: [ "n3" ] } 15 ] 16} 17 18elk.layout(graph) 19 .then(console.log) 20 .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.
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.
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:
1elk.layout(graph, { 2 layoutOptions: { ... } 3})
Additionally, ELK
's constructor accepts an object
with layout options that is used with every
layout
call that does not specify layout options:
1const elk = new ELK({ 2 defaultLayoutOptions: { ... } 3})
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.
1const ELK = require('elkjs') 2// without web worker 3const elk = new ELK() 4 5elk.layout(graph) 6 .then(console.log)
1const ELK = require('elkjs')
2// with web worker
3const elk = new ELK({
4 workerUrl: './node_modules/elkjs/lib/elk-worker.min.js'
5})
6
7elk.layout(graph)
8 .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.
1<html> 2 <script src="./elk.bundled.js"></script> 3 <script type="text/javascript"> 4 const elk = new ELK() 5 6 elk.layout(graph) 7 .then(function(g) { 8 document.body.innerHTML = "<pre>" + JSON.stringify(g, null, " ") + "</pre>" 9 }) 10 </script> 11</html>
1<html> 2 <script src="./elk-api.js"></script> <!-- use elk-api.js here! --> 3 <script type="text/javascript"> 4 const elk = new ELK({ 5 workerUrl: './elk-worker.js' 6 }) 7 8 elk.layout(graph) 9 .then(function(g) { 10 document.body.innerHTML = "<pre>" + JSON.stringify(g, null, " ") + "</pre>" 11 }) 12 </script> 13</html>
1import ELK from 'elkjs/lib/elk.bundled.js' 2const elk = new ELK() 3 4 5import ELK from 'elkjs/lib/elk-api' 6const elk = new ELK({ 7 workerUrl: './elk-worker.min.js' 8})
For debugging purposes you may want to use the non-minified versions that are available as well. In this case the non-minified webworker version can be configured like so:
1const ELK = require('elkjs/lib/elk-api.js') 2const elk = new ELK({ 3 workerFactory: function(url) { // the value of 'url' is irrelevant here 4 const { Worker } = require('elkjs/lib/elk-worker.js') // non-minified 5 return new Worker(url) 6 } 7})
The elkjs library provides a single object: the ELK
. The ELK
has a constructor that can be used
to construct it:
new ELK(options)
- the ELK
can be fed with options, all of which are optional:
defaultLayoutOptions
- an object with default layout options specified as key/value pairs
that are used if no further layout options are passed to the layout(graph, options)
method (see below). Default: {}
.algorithms
- an array of algorithm ids (only the suffix). Default: [ 'layered', 'stress', 'mrtree', 'radial', 'force', 'disco' ]
. Note that the box
, fixed
, and random
layouters are always included.workerUrl
- a path to the elk-worker.js
script. As a consequence the ELK
will use a Web Worker to execute the layout. Default: undefined
.Apart from that the ELK
offers the following methods:
layout(graph, options)
graph
- the graph to be laid out in ELK JSON. Mandatory!options
- a configuration object. Optional.
layoutOptions
: its most important purpose is to pass global layout options.
That is, layout options that are applied to every graph element unless the element specifies the option itself.logging
: boolean (since 0.6.0). Whether logging information shall be passed back as part of the laid out graph. false
by default.measureExecutionTime
: boolean (since 0.6.0). Whether execution time (in seconds) information shall be passed back as part of the laid out graph. false
by default.Promise
, which passes either the laid out graph on success or a (hopefully helpful) error on failure.knownLayoutOptions()
id
and group
is given.knownLayoutAlgorithms()
knownLayoutCategories()
terminateWorker()
- in case a Web Worker is used, the worker's terminate()
method is called.The three methods starting with known
basically return information
that, in the Java world, would be retrieved from the LayoutMetaDataService
.
(Since 0.6.0)
ELK provides some means to log debug information during layout algorithm execution.
The details can be found in the Algorithm Debugging section of ELK's documentation.
Not all of it is available in elkjs though, for instance, it is not possible to save intermediate results of the laid out graphs.
Furthermore, while internally execution time is measured in nanoseconds on the Java side,
in elkjs we have to resort to milliseconds.
Note that the returned execution times are in seconds.
For small graphs this may often result in execution times being reported as 0
.
See below an example call and the example output.
1elk.layout(simpleGraph, { 2 layoutOptions: { 3 'algorithm': 'layered' 4 }, 5 logging: true, 6 measureExecutionTime: true 7})
1{ 2 "id": "root", 3 "children": [ ... ], 4 "edges": [ ... ], 5 "logging": { 6 "name": "Recursive Graph Layout", 7 "executionTime": 0.000096, 8 "children": [ { 9 "name": "Layered layout", 10 "logs": [ 11 "ELK Layered uses the following 17 modules:", 12 " Slot 01: org.eclipse.elk.alg.layered.p1cycles.GreedyCycleBreaker", 13 [ ... ] 14 " Slot 16: org.eclipse.elk.alg.layered.intermediate.ReversedEdgeRestorer" 15 ], 16 "executionTime": 0.000072, 17 "children": [ { "name": "Greedy cycle removal", "executionTime": 0.000002 }, 18 [ ... ] 19 { "name": "Restoring reversed edges", "executionTime": 0 } ] 20 } ] 21 } 22}
For building, a checkout of the ELK repository is required and should be located in the same directory as the checkout of this repository. Like so:
some_dir/
├── elkjs
└── elk
1npm install 2npm run build
For a new release, the following version numbers have to be changed:
version
in package.json
,melk
in build.gradle
, andAfterwards you can find the created files in the lib
folder.
Current procedure
1git checkout -b releases/0.x.x 2# Check that the version numbers are correct, if necessary update versions and commit the changes 3npm install 4npm run build 5npm run test 6# Add ./lib/ directory and commit 7git tag 0.x.x 8# Push release branch and tags to remote 9git push --tags --set-upstream origin releases/0.x.x 10# Create a new release on Github for the new tag and afterwards publish to npm 11npm publish --tag=latest
Afterwards the following version numbers have to be changed to the next release number:
version
in package.json
,melk
in build.gradle
.Incorrectly tagged versions on npm can be updated with
npm dist-tag add elkjs@<version> <latest/next>
.
In the following a list of asorted links to other projects and sites that may prove helpful:
Note: We are happy to extend this list further, so please contact us if you have a project to add
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
0 commit(s) and 12 issue activity found in the last 90 days -- score normalized to 10
Reason
0 existing vulnerabilities detected
Reason
binaries present in source code
Details
Reason
license file detected
Details
Reason
Found 15/25 approved changesets -- score normalized to 6
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
security policy file not detected
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More