Skip to content

Commit

Permalink
feat(linkTools): add Control and RotateLabel link tool (#2723)
Browse files Browse the repository at this point in the history
  • Loading branch information
kumilingus authored Sep 3, 2024
1 parent f842946 commit f5df2d1
Show file tree
Hide file tree
Showing 25 changed files with 612 additions and 22 deletions.
3 changes: 3 additions & 0 deletions examples/link-labels-ts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build/
dist/
node_modules/
21 changes: 21 additions & 0 deletions examples/link-labels-ts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# JointJS Link Label Rotation
## 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
```

## License

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

Copyright © 2013-2024 client IO
13 changes: 13 additions & 0 deletions examples/link-labels-ts/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en" style="height:100%;">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content="The JointJS Link Label Rotation demo serves as a template to help bring your idea to life in no time."/>
<title>Link Labels Typescript | JointJS</title>
</head>
<body style="height:100%;display:flex;justify-content:center;align-items:center;margin:0;overflow-y:hidden;">
<div id="paper"></div>
<script src="dist/bundle.js"></script>
</body>
</html>
36 changes: 36 additions & 0 deletions examples/link-labels-ts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "@joint/demo-link-labels-ts",
"version": "4.0.4",
"main": "src/index.ts",
"homepage": "https://jointjs.com",
"author": {
"name": "client IO",
"url": "https://client.io"
},
"license": "MPL-2.0",
"private": true,
"installConfig": {
"hoistingLimits": "workspaces"
},
"scripts": {
"start": "webpack-dev-server",
"tsc": "tsc"
},
"dependencies": {
"@joint/core": "workspace:^"
},
"devDependencies": {
"css-loader": "3.5.3",
"style-loader": "1.2.1",
"ts-loader": "^9.2.5",
"typescript": "^4.4.3",
"webpack": "^5.61.0",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.2.1"
},
"volta": {
"node": "16.18.1",
"npm": "8.19.2",
"yarn": "3.4.1"
}
}
254 changes: 254 additions & 0 deletions examples/link-labels-ts/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
import { dia, shapes, linkTools, util } from '@joint/core';

const graph = new dia.Graph({}, {
cellNamespace: shapes
});

const paper = new dia.Paper({
el: document.getElementById('paper'),
width: 800,
height: 900,
overflow: true,
model: graph,
cellViewNamespace: shapes,
interactive: {
labelMove: true
},
snapLabels: true,
gridSize: 10,
async: true,
});

// Example 1
// Rotate labels on a link.

const el1 = new shapes.standard.Rectangle({
position: {
x: 10,
y: 270
},
size: {
width: 80,
height: 80
},
attrs: {
body: {
strokeWidth: 3
}
}
});
const el2 = new shapes.standard.Rectangle({
position: {
x: 400,
y: 170
},
size: {
width: 80,
height: 80
},
attrs: {
body: {
strokeWidth: 3
}
}
});

const l1 = new shapes.standard.Link({
source: {
id: el1.id
},
target: {
id: el2.id
},
attrs: {
line: {
strokeWidth: 3
}
},
labels: [{
markup: util.svg/* xml */`
<path @selector="labelPath" />
<circle @selector="labelCircle" />
`,
attrs: {
labelPath: {
fill: 'none',
stroke: '#333',
strokeWidth: 4,
strokeLinecap: 'round',
strokeLinejoin: 'round',
d: 'M 0 0 V -100 M -20 -100 v 20 H 20 v -20'
},
labelCircle: {
fill: '#333',
stroke: '#FFF',
r: 3,
}
},
position: {
distance: 0.5,
args: {
keepGradient: true
}
}
}, {
markup: util.svg/* xml */`
<path @selector="labelPath" />
<circle @selector="labelCircle" />
`,
attrs: {
labelPath: {
fill: 'none',
stroke: '#999',
strokeWidth: 2,
strokeDasharray: '5 5',
d: 'M 0 0 V -100 M -20 -80 v -20 H 20 v 20'
},
labelCircle: {
fill: '#333',
stroke: '#FFF',
r: 5,
}
},
position: {
distance: 0.8,
args: {
keepGradient: true
}
}
}, {
markup: util.svg/* xml */`
<path @selector="labelPath" />
<circle @selector="labelCircle" />
`,
attrs: {
labelPath: {
fill: 'none',
stroke: '#333',
strokeWidth: 3,
d: 'M 0 0 V -100 M -20 -80 L 0 -100 l 20 20'
},
labelCircle: {
fill: '#333',
stroke: '#FFF',
r: 3,
}
},
position: {
distance: 0.2,
args: {
keepGradient: false
}
}
}]
});

graph.addCells([el1, el2, l1]);

l1.findView(paper).addTools(new dia.ToolsView({
tools: [
new linkTools.RotateLabel({
labelIndex: 0,
offset: -60,
}),
new linkTools.RotateLabel({
labelIndex: 1,
offset: -125,
buttonColor: '#fff',
iconColor: '#333',
outlineColor: '#333',
scale: 1.5,
}),
new linkTools.RotateLabel({
labelIndex: 2,
offset: -115,
})
]
}));

// Example 2
// Add or remove labels on a link with buttons.

const l2 = new shapes.standard.Link({
source: {
x: 10,
y: 500
},
target: {
x: 400,
y: 570
},
attrs: {
line: {
strokeWidth: 3
}
}
});

graph.addCells([l2]);

l2.findView(paper).addTools(new dia.ToolsView({
tools: [
new linkTools.Button({
attributes: {
cursor: 'pointer'
},
markup: util.svg/* xml */`
<circle r="10" fill="#266DD3" />
<path d="M -5 0 5 0 M 0 -5 0 5" stroke="#fff" stroke-width="2" />
`,
distance: '50%',
visibility: (view) => !view.model.hasLabels(),
action: (_evt, view) => {
view.model.appendLabel({
markup: util.svg/* xml */`
<rect @selector="labelBody" />
<text @selector="labelText" />
`,
attrs: {
labelBody: {
ref: 'labelText',
fill: '#fff',
stroke: '#131E29',
strokeWidth: 2,
width: 'calc(w + 10)',
height: 'calc(h + 10)',
x: 'calc(x - 5)',
y: 'calc(y - 5)',
},
labelText: {
text: 'Label',
textAnchor: 'middle',
textVerticalAnchor: 'middle',
fill: '#131E29',
fontSize: 16,
fontFamily: 'sans-serif',
}
},
position: {
distance: 0.5,
args: {
keepGradient: true
}
}
});
},
}),
new linkTools.Button({
attributes: {
cursor: 'pointer'
},
markup: util.svg/* xml */`
<circle r="10" fill="#ED2637" />
<path d="M -5 0 5 0" stroke="#fff" stroke-width="2" />
`,
distance: '50%',
offset: -30,
visibility: (view) => view.model.hasLabels(),
action: (_evt, view) => {
view.model.removeLabel(0);
}
})
]
}));

9 changes: 9 additions & 0 deletions examples/link-labels-ts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"outDir": "./build"
}
}
30 changes: 30 additions & 0 deletions examples/link-labels-ts/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const path = require('path');

module.exports = {
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
entry: './src/index.ts',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/'
},
mode: 'development',
module: {
rules: [
{ test: /\.ts$/, loader: 'ts-loader' },
{
test: /\.css$/,
sideEffects: true,
use: ['style-loader', 'css-loader'],
}
]
},
devServer: {
static: {
directory: __dirname,
},
compress: true
},
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Connect } from '../linkTools/Connect.mjs';
import { Connect } from './Connect.mjs';
import V from '../V/index.mjs';
import $ from '../mvc/Dom/index.mjs';
import * as util from '../util/index.mjs';
Expand Down
2 changes: 1 addition & 1 deletion packages/joint-core/src/dia/LinkView.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const LinkView = CellView.extend({
attrs: [Flags.UPDATE],
router: [Flags.UPDATE],
connector: [Flags.CONNECTOR],
labels: [Flags.LABELS],
labels: [Flags.LABELS, Flags.TOOLS],
labelMarkup: [Flags.LABELS],
vertices: [Flags.UPDATE],
source: [Flags.SOURCE, Flags.UPDATE],
Expand Down
Loading

0 comments on commit f5df2d1

Please sign in to comment.