Skip to content

Commit

Permalink
Merge branch 'master' into tool-view-visibility
Browse files Browse the repository at this point in the history
  • Loading branch information
kumilingus authored Aug 27, 2024
2 parents 2ab27c8 + dd0db32 commit 9895be4
Show file tree
Hide file tree
Showing 12 changed files with 1,555 additions and 1,145 deletions.
2 changes: 1 addition & 1 deletion packages/joint-core/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module.exports = {
'CDATASection': true
},
'parserOptions': {
'ecmaVersion': 6,
'ecmaVersion': 2022,
'sourceType': 'module'
}
};
50 changes: 23 additions & 27 deletions packages/joint-core/demo/custom-shapes/src/custom-shapes.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -96,37 +96,33 @@ const shapeAttribute = {
unset: 'd'
};

const progressDataAttribute = {
set: function(value, bbox) {

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
const angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

const progressDataAttribute = {
set: function(percentage, { x, y, width, height }) {
const startAngle = 0;
const endAngle = Math.max(360 / 100 * percentage, startAngle);
const radius = Math.min(width / 2, height / 2);
const origin = new g.Point(x + width / 2, y + height / 2);
// Angle === 360
if (endAngle >= 360) {
return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
d: `
M ${origin.x - radius} ${origin.y}
a ${radius},${radius} 0 1,1 ${radius * 2},0
a ${radius},${radius} 0 1,1 -${radius * 2},0
`
};
}

function describeArc(x, y, radius, startAngle, endAngle){
const start = polarToCartesian(x, y, radius, endAngle);
const end = polarToCartesian(x, y, radius, startAngle);
const largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1';
const d = [
'M', start.x, start.y,
'A', radius, radius, 0, largeArcFlag, 0, end.x, end.y
].join(' ');
return d;
}

const center = bbox.center();
// Angle <= 360
const p1 = g.Point.fromPolar(radius, g.toRad(-endAngle -90), origin);
const p2 = g.Point.fromPolar(radius, g.toRad(-startAngle -90), origin);
const largeArcFlag = endAngle - startAngle < 180 ? '0' : '1';
return {
d: describeArc(
center.x,
center.y,
Math.min(bbox.width / 2, bbox.height / 2),
0,
Math.min(360 / 100 * value, 359.99)
)
d: `
M ${p1.x} ${p1.y}
A ${radius} ${radius} 0 ${largeArcFlag} 0 ${p2.x} ${p2.y}
`
};
},
unset: 'd'
Expand Down Expand Up @@ -529,7 +525,7 @@ const Progress = joint.dia.Element.define('progress', {
progressForeground: {
stroke: 'red',
strokeWidth: 10,
strokeLinecap: 'round',
strokeLinecap: 'butt',
fill: 'none',
},
progressText: {
Expand Down
14 changes: 8 additions & 6 deletions packages/joint-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@
"./README.md"
],
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.2",
"@microsoft/api-extractor": "7.33.7",
"@rollup/plugin-babel": "^6.0.4",
"@typescript-eslint/eslint-plugin": "5.48.1",
"@typescript-eslint/parser": "5.48.1",
"async": "2.6.1",
Expand All @@ -82,11 +85,11 @@
"grunt-contrib-concat": "1.0.1",
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-qunit": "3.1.0",
"grunt-contrib-uglify": "4.0.0",
"grunt-contrib-uglify": "4.0.1",
"grunt-contrib-watch": "1.1.0",
"grunt-env": "0.4.4",
"grunt-eslint": "21.0.0",
"grunt-karma": "3.0.1",
"grunt-karma": "4.0.2",
"grunt-mocha-test": "0.13.3",
"grunt-newer": "1.3.0",
"grunt-shell": "3.0.1",
Expand All @@ -95,9 +98,9 @@
"handlebars": "4.7.7",
"jit-grunt": "0.10.0",
"jquery": "~3.7.1",
"karma": "3.1.4",
"karma-chrome-launcher": "2.2.0",
"karma-coverage": "1.1.2",
"karma": "6.4.4",
"karma-chrome-launcher": "3.2.0",
"karma-coverage": "2.2.1",
"karma-qunit": "2.1.0",
"karma-sinon": "1.0.5",
"load-grunt-config": "0.19.2",
Expand All @@ -110,7 +113,6 @@
"qunit": "2.8.0",
"requirejs": "2.3.6",
"rollup": "1.20.3",
"rollup-plugin-buble": "0.19.6",
"rollup-plugin-commonjs": "9.2.0",
"rollup-plugin-json": "4.0.0",
"rollup-plugin-node-resolve": "4.0.0",
Expand Down
18 changes: 16 additions & 2 deletions packages/joint-core/rollup.resources.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
import commonjs from 'rollup-plugin-commonjs';
import buble from 'rollup-plugin-buble';
import path from 'path';
import json from 'rollup-plugin-json';
import fs from 'fs';
import resolve from 'rollup-plugin-node-resolve';
import babel from '@rollup/plugin-babel';
const modules = require('./grunt/resources/esm');

let plugins = [
resolve(),
commonjs(),
buble()
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**',
presets: [
['@babel/preset-env', {
targets: '> 0.5%, last 2 versions, Firefox ESR, not dead',
modules: false,
useBuiltIns: 'usage',
corejs: {
version: 3,
proposals: false
}
}]
],
})
];

let JOINT_FOOTER = 'if (typeof joint !== \'undefined\') { var g = joint.g, V = joint.V, Vectorizer = joint.V; }';
Expand Down
6 changes: 3 additions & 3 deletions packages/joint-core/src/elementTools/Control.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export const Control = ToolView.extend({
const { clientX, clientY } = util.normalizeEvent(evt);
const coords = paper.clientToLocalPoint(clientX, clientY);
const relativeCoords = model.getRelativePointFromAbsolute(coords);
this.setPosition(relatedView, relativeCoords, this);
this.setPosition(relatedView, relativeCoords, evt);
this.update();
},
onPointerUp: function(_evt) {
Expand All @@ -144,9 +144,9 @@ export const Control = ToolView.extend({
this.toggleExtras(false);
relatedView.model.stopBatch('control-move', { ui: true, tool: this.cid });
},
onPointerDblClick: function() {
onPointerDblClick: function(evt) {
const { relatedView } = this;
this.resetPosition(relatedView, this);
this.resetPosition(relatedView, evt);
this.update();
}

Expand Down
5 changes: 4 additions & 1 deletion packages/joint-core/src/linkTools/Button.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ export const Button = ToolView.extend({
},
getLinkMatrix() {
const { relatedView: view, options } = this;
const { offset = 0, distance = 0, rotate, scale } = options;
const { offset = 0, distance: distanceOpt = 0, rotate, scale } = options;
const distance = (typeof distanceOpt === 'function')
? distanceOpt.call(this, view, this)
: distanceOpt;
let tangent, position, angle;
if (util.isPercentage(distance)) {
tangent = view.getTangentAtRatio(parseFloat(distance) / 100);
Expand Down
3 changes: 2 additions & 1 deletion packages/joint-core/src/util/utilHelpers.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,8 @@ const equalByTag = (object, other, tag, equalFunc, stack) => {
case stringTag:
return object == `${other}`;
case mapTag:
let convert = mapToArray;
// This use of 'var' is intentional. Don't remove if replacing all instances.
var convert = mapToArray;
// Intentional fallthrough
// eslint-disable-next-line no-fallthrough
case setTag:
Expand Down
36 changes: 35 additions & 1 deletion packages/joint-core/test/jointjs/dia/elementTools.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,12 @@ QUnit.module('elementTools', function(hooks) {
QUnit.test('position (angle ' + testCase.angle + ')', function(assert) {
var angle = testCase.angle;
var position = { x: 10, y: 10 };
const setPositionSpy = sinon.spy();
const resetPositionSpy = sinon.spy();
var CustomControl = joint.elementTools.Control.extend({
getPosition: function() { return position; }
getPosition: function() { return position; },
setPosition: setPositionSpy,
resetPosition: resetPositionSpy
});
var control = new CustomControl;
element.rotate(angle);
Expand All @@ -172,6 +176,36 @@ QUnit.module('elementTools', function(hooks) {
resultingPosition = control.vel.getBBox({ target: paper.svg }).center();
expectedPosition = element.position().offset(position).rotate(bbox.center(), -angle);
assert.ok(resultingPosition.round().equals(expectedPosition.round()));
// 3. `setPosition()`
const clientX = 11;
const clientY = 13;
const relativePosition = element.getRelativePointFromAbsolute(
paper.clientToLocalPoint(clientX, clientY)
);
simulate.mousedown({ clientX: 0, clientY: 0, el: control.el });
simulate.mousemove({ clientX, clientY, el: control.el });
simulate.mouseup({ clientX, clientY, el: control.el });
assert.ok(setPositionSpy.calledOnce);
assert.ok(
setPositionSpy.calledWithExactly(
elementView,
sinon.match(relativePosition.toJSON()),
sinon.match.instanceOf(joint.mvc.Event)
)
);
assert.notOk(resetPositionSpy.called);
// 4. `resetPosition()`
setPositionSpy.resetHistory();
resetPositionSpy.resetHistory();
simulate.mouseevent({ type: 'dblclick', el: control.el });
assert.ok(resetPositionSpy.calledOnce);
assert.ok(
resetPositionSpy.calledWithExactly(
elementView,
sinon.match.instanceOf(joint.mvc.Event)
)
);
assert.notOk(setPositionSpy.called);
});
});
});
Expand Down
28 changes: 28 additions & 0 deletions packages/joint-core/test/jointjs/dia/linkTools.js
Original file line number Diff line number Diff line change
Expand Up @@ -520,4 +520,32 @@ QUnit.module('linkTools', function(hooks) {
});
});

QUnit.module('Button', function() {

QUnit.test('distance as number', function(assert) {
const targetX = 333;
const distance = -17;
const button = new joint.linkTools.Button({ distance });
linkView.addTools(new joint.dia.ToolsView({ tools: [button] }));
// move the target cell to the right, to make the link horizontal
link.getTargetCell().position(targetX, link.getSourceCell().position().x);
assert.equal(button.el.getCTM().e, targetX + distance);
});

QUnit.test('distance as function', function(assert) {
const targetX = 333;
const distance = -17;
const distanceSpy = sinon.spy(() => distance);
const button = new joint.linkTools.Button({ distance: distanceSpy });
linkView.addTools(new joint.dia.ToolsView({ tools: [button] }));
assert.ok(distanceSpy.calledOnce);
assert.ok(distanceSpy.calledWithExactly(linkView, button));
assert.ok(distanceSpy.calledOn(button));
// move the target cell to the right, to make the link horizontal
link.getTargetCell().position(targetX, link.getSourceCell().position().x);
assert.ok(distanceSpy.calledTwice);
assert.equal(button.el.getCTM().e, targetX + distance);
});
});

});
4 changes: 4 additions & 0 deletions packages/joint-core/test/ts/toolsView.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,7 @@ new elementTools.HoverConnect({
trackWidth: 10,
trackPath: (view) => view.model.attr(['body', 'd']),
});

new linkTools.Button({
distance: (view) => view.getConnectionLength() < 100 ? 20 : '50%'
});
12 changes: 8 additions & 4 deletions packages/joint-core/types/joint.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4233,8 +4233,8 @@ export namespace elementTools {
constructor(opt?: T);

protected getPosition(view: dia.ElementView): dia.Point;
protected setPosition(view: dia.ElementView, coordinates: g.Point): void;
protected resetPosition(view: dia.ElementView): void;
protected setPosition(view: dia.ElementView, coordinates: g.Point, evt: dia.Event): void;
protected resetPosition(view: dia.ElementView, evt: dia.Event): void;

protected updateHandle(handleNode: SVGElement): void;
protected updateExtras(extrasNode: SVGElement): void;
Expand Down Expand Up @@ -4400,10 +4400,14 @@ export namespace linkTools {

namespace Button {

type ActionCallback = (evt: dia.Event, view: dia.LinkView, tool: dia.ToolView) => void;
type ActionCallback = (evt: dia.Event, view: dia.LinkView, tool: Button) => void;

type Distance = number | string;

type DistanceCallback = (this: Button, view: dia.LinkView, tool: Button) => Distance;

interface Options extends dia.ToolView.Options<dia.LinkView> {
distance?: number | string;
distance?: Distance | DistanceCallback;
offset?: number;
rotate?: boolean;
action?: ActionCallback;
Expand Down
Loading

0 comments on commit 9895be4

Please sign in to comment.