Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/avoid-router/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build/
dist/
node_modules/
31 changes: 31 additions & 0 deletions examples/avoid-router/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# JointJS Libavoid Standalone Routing Demo

<img width="709" alt="image" src="https://github.com/clientIO/joint/assets/3967880/acb322cb-8913-429b-aaa9-87322f3aad9a">

## Setup

Use Yarn to run this demo.

You need to build *JointJS* first. Navigate to the root folder and run:
```bash
yarn install
yarn run build
```

Navigate to this directory, then run:
```bash
yarn start
```

For web workers version, run:
```bash
yarn run start-web-worker
```

## License

The *JointJS* library is licensed under the [Mozilla Public License 2.0](https://github.com/clientIO/joint/blob/master/LICENSE).

Copyright © 2013-2026 client IO

The *Libavoid-js* library is licensed under the [LGPL-2.1 license](https://github.com/Aksem/libavoid-js?tab=LGPL-2.1-1-ov-file#readme).
27 changes: 27 additions & 0 deletions examples/avoid-router/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description"
content="The JointJS Libavoid routing demo serves as a template to help bring your idea to life in no time.">
<title>Libavoid routing | JointJS</title>
<link rel="stylesheet" type="text/css" href="css/styles.css">
</head>

<body>
<div class="tabs">
<button class="tab-button active" data-tab="simple" type="button">Simple graph</button>
<button class="tab-button" data-tab="simpleExtra" type="button">Simple graph extra</button>
<button class="tab-button" data-tab="large" type="button">Large graph</button>
</div>
<div class="tab">
<div id="canvas-simple" class="canvas"></div>
<div id="canvas-simple-extra" class="canvas" style="display: none;"></div>
<div id="canvas-large" class="canvas" style="display: none;"></div>
</div>
<script src="bundle.js"></script>
</body>

</html>
40 changes: 40 additions & 0 deletions examples/avoid-router/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "@joint/demo-avoid-router",
"version": "4.3.0",
"main": "src/index.js",
"homepage": "https://jointjs.com",
"author": {
"name": "client IO",
"url": "https://client.io"
},
"license": "LGPL-2.1-or-later",
"private": true,
"installConfig": {
"hoistingLimits": "workspaces"
},
"scripts": {
"start": "webpack-dev-server",
"build": "webpack"
},
"dependencies": {
"@joint/core": "workspace:~",
"@joint/router-avoid": "workspace:~",
"libavoid-js": "0.4.5"
},
"devDependencies": {
"copy-webpack-plugin": "5.1.1",
"css-loader": "3.5.3",
"file-loader": "6.0.0",
"sass": "1.26.8",
"sass-loader": "8.0.2",
"style-loader": "1.2.1",
"webpack": "5.98.0",
"webpack-cli": "6.0.1",
"webpack-dev-server": "5.2.0"
},
"volta": {
"node": "22.14.0",
"npm": "11.2.0",
"yarn": "4.7.0"
}
}
95 changes: 95 additions & 0 deletions examples/avoid-router/src/common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { dia, linkTools, highlighters } from '@joint/core';

// Avoid Docs
// https://www.adaptagrams.org/documentation/annotated.html

// There is a bug in JointJS, that does not allow you to use port
// ids that are numbers.

export function createPaper(canvasEl, cellNamespace, paperOptions = {}) {
const graph = new dia.Graph({}, { cellNamespace });

const paper = new dia.Paper({
model: graph,
cellViewNamespace: cellNamespace,
width: '100%',
height: '100%',
gridSize: 10,
interactive: { linkMove: false },
linkPinning: false,
async: true,
frozen: true,
background: { color: '#F3F7F6' },
snapLinks: { radius: 30 },
overflow: true,
interactive: { labelMove: false, linkMove: false },
defaultConnector: {
name: 'straight',
args: {
cornerType: 'cubic',
cornerRadius: 4,
},
},
highlighting: {
default: {
name: 'mask',
options: {
padding: 2,
attrs: {
stroke: '#EA3C24',
strokeWidth: 2,
},
},
},
},
...paperOptions,
});

canvasEl.appendChild(paper.el);

return { graph, paper };
}

export function addLinkInteractionHandlers(paper) {
// Add a class to the links when they are being interacted with.
// See `styles.css` for the styles.

paper.on('link:mouseenter', (linkView) => {
linkView.addTools(
new dia.ToolsView({
tools: [
new linkTools.Remove(),
new linkTools.TargetArrowhead(),
],
})
);
});

paper.on('link:mouseleave', (linkView) => {
linkView.removeTools();
});

paper.on('link:pointerdown', (linkView) => {
highlighters.addClass.add(linkView, 'line', 'active-link', {
className: 'active-link'
});
});

paper.on('link:pointerup', (linkView) => {
highlighters.addClass.remove(linkView);
});
}

export function addPaperZoomHandlers(paper) {
const MIN_SCALE = 0.1;
const MAX_SCALE = 5;

// Trackpad pinch gestures are reported by the browser as a wheel event
// with `ctrlKey` set; the paper turns that into a `paper:pinch` event
// with the pointer position (in paper coordinates) and a scale delta.
paper.on('paper:pinch', (evt, x, y, scale) => {
const { sx: currentScale } = paper.scale();
const newScale = Math.min(MAX_SCALE, Math.max(MIN_SCALE, currentScale * scale));
paper.scaleUniformAtPoint(newScale, { x, y });
});
}
38 changes: 38 additions & 0 deletions examples/avoid-router/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import '../styles.scss';
import { initSimpleExample } from './simple-graph/example';
import { initLargeGraphExample } from './large-graph/example';
import { initSimpleExample as initSimpleExampleExtra } from './simple-graph-extra/example';

const panels = {
simple: document.getElementById('canvas-simple'),
large: document.getElementById('canvas-large'),
simpleExtra: document.getElementById('canvas-simple-extra'),
};

const initializers = {
simple: initSimpleExample,
large: initLargeGraphExample,
simpleExtra: initSimpleExampleExtra,
};

const initialized = {};

function activateTab(name) {
document.querySelectorAll('.tab-button').forEach((button) => {
button.classList.toggle('active', button.dataset.tab === name);
});

Object.entries(panels).forEach(([tabName, panelEl]) => {
panelEl.style.display = tabName === name ? '' : 'none';
});

if (!initialized[name]) {
initialized[name] = initializers[name](panels[name]);
}
}

document.querySelectorAll('.tab-button').forEach((button) => {
button.addEventListener('click', () => activateTab(button.dataset.tab));
});

activateTab('simple');
Loading