- Go backend (server/)
- Frontend (web/, server/static/)
- Database and deployment files
- Scripts and docs
Co-Authored-By: 狸花猫/Claude-Qwen3.6-Plus 🐾
554 lines
16 KiB
JavaScript
554 lines
16 KiB
JavaScript
"use strict";
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
exports.default = void 0;
|
||
var _util = require("@antv/util");
|
||
var _base = _interopRequireDefault(require("../base"));
|
||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
||
var __extends = void 0 && (void 0).__extends || function () {
|
||
var _extendStatics = function extendStatics(d, b) {
|
||
_extendStatics = Object.setPrototypeOf || {
|
||
__proto__: []
|
||
} instanceof Array && function (d, b) {
|
||
d.__proto__ = b;
|
||
} || function (d, b) {
|
||
for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];
|
||
};
|
||
return _extendStatics(d, b);
|
||
};
|
||
return function (d, b) {
|
||
if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||
_extendStatics(d, b);
|
||
function __() {
|
||
this.constructor = d;
|
||
}
|
||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||
};
|
||
}();
|
||
var __assign = void 0 && (void 0).__assign || function () {
|
||
__assign = Object.assign || function (t) {
|
||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||
s = arguments[i];
|
||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
||
}
|
||
return t;
|
||
};
|
||
return __assign.apply(this, arguments);
|
||
};
|
||
var DELTA = 0.05;
|
||
var lensDelegateStyle = {
|
||
stroke: '#000',
|
||
strokeOpacity: 0.8,
|
||
lineWidth: 2,
|
||
fillOpacity: 0.1,
|
||
fill: '#ccc'
|
||
};
|
||
var Fisheye = /** @class */function (_super) {
|
||
__extends(Fisheye, _super);
|
||
function Fisheye(config) {
|
||
return _super.call(this, config) || this;
|
||
}
|
||
Fisheye.prototype.getDefaultCfgs = function () {
|
||
return {
|
||
trigger: 'mousemove',
|
||
d: 1.5,
|
||
r: 300,
|
||
delegateStyle: (0, _util.clone)(lensDelegateStyle),
|
||
showLabel: false,
|
||
maxD: 5,
|
||
minD: 0,
|
||
scaleRBy: 'unset',
|
||
scaleDBy: 'unset',
|
||
showDPercent: true
|
||
};
|
||
};
|
||
// class-methods-use-this
|
||
Fisheye.prototype.getEvents = function () {
|
||
var events;
|
||
switch (this.get('trigger')) {
|
||
case 'click':
|
||
events = {
|
||
click: 'magnify'
|
||
};
|
||
break;
|
||
case 'drag':
|
||
events = {
|
||
click: 'createDelegate'
|
||
};
|
||
break;
|
||
default:
|
||
events = {
|
||
mousemove: 'magnify'
|
||
};
|
||
break;
|
||
}
|
||
return events;
|
||
};
|
||
Fisheye.prototype.init = function () {
|
||
var self = this;
|
||
var r = self.get('r');
|
||
self.set('cachedMagnifiedModels', []);
|
||
self.set('cachedOriginPositions', {});
|
||
self.set('r2', r * r);
|
||
var d = self.get('d');
|
||
self.set('molecularParam', (d + 1) * r);
|
||
};
|
||
// Create the delegate when the trigger is drag
|
||
Fisheye.prototype.createDelegate = function (e) {
|
||
var _this = this;
|
||
var self = this;
|
||
var lensDelegate = self.get('delegate');
|
||
if (!lensDelegate || lensDelegate.destroyed) {
|
||
self.magnify(e);
|
||
lensDelegate = self.get('delegate');
|
||
// drag to move the lens
|
||
lensDelegate.on('dragstart', function (evt) {
|
||
self.set('delegateCenterDiff', {
|
||
x: lensDelegate.attr('x') - evt.x,
|
||
y: lensDelegate.attr('y') - evt.y
|
||
});
|
||
});
|
||
lensDelegate.on('drag', function (evt) {
|
||
self.magnify(evt);
|
||
});
|
||
// 绑定调整范围(r)和缩放系数(d)的监听
|
||
// 由于 drag 用于改变 lens 位置, 因此在此模式下, drag 不能用于调整 r 和 d
|
||
// scaling d
|
||
if (this.get('scaleDBy') === 'wheel') {
|
||
lensDelegate.on('mousewheel', function (evt) {
|
||
_this.scaleDByWheel(evt);
|
||
});
|
||
}
|
||
// scaling r
|
||
if (this.get('scaleRBy') === 'wheel') {
|
||
lensDelegate.on('mousewheel', function (evt) {
|
||
self.scaleRByWheel(evt);
|
||
});
|
||
}
|
||
}
|
||
};
|
||
/**
|
||
* Scale the range by wheel
|
||
* @param e mouse wheel event
|
||
*/
|
||
Fisheye.prototype.scaleRByWheel = function (e) {
|
||
var self = this;
|
||
if (!e || !e.originalEvent) return;
|
||
if (e.preventDefault) e.preventDefault();
|
||
var graph = self.get('graph');
|
||
var ratio;
|
||
var lensDelegate = self.get('delegate');
|
||
var lensCenter = lensDelegate ? {
|
||
x: lensDelegate.attr('x'),
|
||
y: lensDelegate.attr('y')
|
||
} : undefined;
|
||
var mousePos = lensCenter || graph.getPointByClient(e.clientX, e.clientY);
|
||
if (e.originalEvent.wheelDelta < 0) {
|
||
ratio = 1 - DELTA;
|
||
} else {
|
||
ratio = 1 / (1 - DELTA);
|
||
}
|
||
var maxR = self.get('maxR');
|
||
var minR = self.get('minR');
|
||
var r = self.get('r');
|
||
if (r > (maxR || graph.get('height')) && ratio > 1 || r < (minR || graph.get('height') * 0.05) && ratio < 1) {
|
||
ratio = 1;
|
||
}
|
||
r *= ratio;
|
||
self.set('r', r);
|
||
self.set('r2', r * r);
|
||
var d = self.get('d');
|
||
self.set('molecularParam', (d + 1) * r);
|
||
self.set('delegateCenterDiff', undefined);
|
||
self.magnify(e, mousePos);
|
||
};
|
||
/**
|
||
* Scale the range by dragging
|
||
* @param e mouse event
|
||
*/
|
||
Fisheye.prototype.scaleRByDrag = function (e) {
|
||
var self = this;
|
||
if (!e) return;
|
||
var dragPrePos = self.get('dragPrePos');
|
||
var graph = self.get('graph');
|
||
var ratio;
|
||
var mousePos = graph.getPointByClient(e.clientX, e.clientY);
|
||
if (e.x - dragPrePos.x < 0) {
|
||
ratio = 1 - DELTA;
|
||
} else {
|
||
ratio = 1 / (1 - DELTA);
|
||
}
|
||
var maxR = self.get('maxR');
|
||
var minR = self.get('minR');
|
||
var r = self.get('r');
|
||
if (r > (maxR || graph.get('height')) && ratio > 1 || r < (minR || graph.get('height') * 0.05) && ratio < 1) {
|
||
ratio = 1;
|
||
}
|
||
r *= ratio;
|
||
self.set('r', r);
|
||
self.set('r2', r * r);
|
||
var d = self.get('d');
|
||
self.set('molecularParam', (d + 1) * r);
|
||
self.magnify(e, mousePos);
|
||
self.set('dragPrePos', {
|
||
x: e.x,
|
||
y: e.y
|
||
});
|
||
};
|
||
/**
|
||
* Scale the magnifying factor by wheel
|
||
* @param e mouse wheel event
|
||
*/
|
||
Fisheye.prototype.scaleDByWheel = function (evt) {
|
||
var self = this;
|
||
if (!evt && !evt.originalEvent) return;
|
||
if (evt.preventDefault) evt.preventDefault();
|
||
var delta = 0;
|
||
if (evt.originalEvent.wheelDelta < 0) {
|
||
delta = -0.1;
|
||
} else {
|
||
delta = 0.1;
|
||
}
|
||
var d = self.get('d');
|
||
var newD = d + delta;
|
||
var maxD = self.get('maxD');
|
||
var minD = self.get('minD');
|
||
if (newD < maxD && newD > minD) {
|
||
self.set('d', newD);
|
||
var r = self.get('r');
|
||
self.set('molecularParam', (newD + 1) * r);
|
||
var lensDelegate = self.get('delegate');
|
||
var lensCenter = lensDelegate ? {
|
||
x: lensDelegate.attr('x'),
|
||
y: lensDelegate.attr('y')
|
||
} : undefined;
|
||
self.set('delegateCenterDiff', undefined);
|
||
self.magnify(evt, lensCenter);
|
||
}
|
||
};
|
||
/**
|
||
* Scale the magnifying factor by dragging
|
||
* @param e mouse event
|
||
*/
|
||
Fisheye.prototype.scaleDByDrag = function (e) {
|
||
var self = this;
|
||
var dragPrePos = self.get('dragPrePos');
|
||
var delta = e.x - dragPrePos.x > 0 ? 0.1 : -0.1;
|
||
var d = self.get('d');
|
||
var newD = d + delta;
|
||
var maxD = self.get('maxD');
|
||
var minD = self.get('minD');
|
||
if (newD < maxD && newD > minD) {
|
||
self.set('d', newD);
|
||
var r = self.get('r');
|
||
self.set('molecularParam', (newD + 1) * r);
|
||
self.magnify(e);
|
||
}
|
||
self.set('dragPrePos', {
|
||
x: e.x,
|
||
y: e.y
|
||
});
|
||
};
|
||
/**
|
||
* Response function for mousemove, click, or drag to magnify
|
||
* @param e mouse event
|
||
*/
|
||
Fisheye.prototype.magnify = function (e, mousePos) {
|
||
var self = this;
|
||
self.restoreCache();
|
||
var graph = self.get('graph');
|
||
var cachedMagnifiedModels = self.get('cachedMagnifiedModels');
|
||
var cachedOriginPositions = self.get('cachedOriginPositions');
|
||
var showLabel = self.get('showLabel');
|
||
var r = self.get('r');
|
||
var r2 = self.get('r2');
|
||
var d = self.get('d');
|
||
var molecularParam = self.get('molecularParam');
|
||
var nodes = graph.getNodes();
|
||
var nodeLength = nodes.length;
|
||
var mCenter = mousePos ? {
|
||
x: mousePos.x,
|
||
y: mousePos.y
|
||
} : {
|
||
x: e.x,
|
||
y: e.y
|
||
};
|
||
if (self.get('dragging') && (self.get('trigger') === 'mousemove' || self.get('trigger') === 'click')) {
|
||
mCenter = self.get('cacheCenter');
|
||
}
|
||
var delegateCenterDiff = self.get('delegateCenterDiff');
|
||
if (delegateCenterDiff) {
|
||
mCenter.x += delegateCenterDiff.x;
|
||
mCenter.y += delegateCenterDiff.y;
|
||
}
|
||
self.updateDelegate(mCenter, r);
|
||
for (var i = 0; i < nodeLength; i++) {
|
||
var model = nodes[i].getModel();
|
||
var x = model.x,
|
||
y = model.y;
|
||
if (isNaN(x) || isNaN(y)) continue;
|
||
// the square of the distance between the node and the magnified center
|
||
var dist2 = (x - mCenter.x) * (x - mCenter.x) + (y - mCenter.y) * (y - mCenter.y);
|
||
if (!isNaN(dist2) && dist2 < r2 && dist2 !== 0) {
|
||
var dist = Math.sqrt(dist2);
|
||
// (r * (d + 1) * (dist / r)) / (d * (dist / r) + 1);
|
||
var magnifiedDist = molecularParam * dist / (d * dist + r);
|
||
var cos = (x - mCenter.x) / dist;
|
||
var sin = (y - mCenter.y) / dist;
|
||
model.x = cos * magnifiedDist + mCenter.x;
|
||
model.y = sin * magnifiedDist + mCenter.y;
|
||
if (!cachedOriginPositions[model.id]) {
|
||
cachedOriginPositions[model.id] = {
|
||
x: x,
|
||
y: y,
|
||
texts: []
|
||
};
|
||
}
|
||
cachedMagnifiedModels.push(model);
|
||
if (showLabel && 2 * dist < r) {
|
||
var node = nodes[i];
|
||
var nodeGroup = node.getContainer();
|
||
var shapes = nodeGroup.getChildren();
|
||
var shapeLength = shapes.length;
|
||
for (var j = 0; j < shapeLength; j++) {
|
||
var shape = shapes[j];
|
||
if (shape.get('type') === 'text') {
|
||
cachedOriginPositions[model.id].texts.push({
|
||
visible: shape.get('visible'),
|
||
shape: shape
|
||
});
|
||
shape.set('visible', true);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
graph.refreshPositions();
|
||
};
|
||
/**
|
||
* Restore the cache nodes while magnifying
|
||
*/
|
||
Fisheye.prototype.restoreCache = function () {
|
||
var self = this;
|
||
var cachedMagnifiedModels = self.get('cachedMagnifiedModels');
|
||
var cachedOriginPositions = self.get('cachedOriginPositions');
|
||
var cacheLength = cachedMagnifiedModels.length;
|
||
for (var i = 0; i < cacheLength; i++) {
|
||
var node = cachedMagnifiedModels[i];
|
||
var id = node.id;
|
||
var ori = cachedOriginPositions[id];
|
||
node.x = ori.x;
|
||
node.y = ori.y;
|
||
var textLength = ori.texts.length;
|
||
for (var j = 0; j < textLength; j++) {
|
||
var text = ori.texts[j];
|
||
text.shape.set('visible', text.visible);
|
||
}
|
||
}
|
||
self.set('cachedMagnifiedModels', []);
|
||
self.set('cachedOriginPositions', {});
|
||
};
|
||
/**
|
||
* Adjust part of the parameters, including trigger, d, r, maxR, minR, maxD, minD, scaleRBy, and scaleDBy
|
||
* @param {FisheyeConfig} cfg
|
||
*/
|
||
Fisheye.prototype.updateParams = function (cfg) {
|
||
var self = this;
|
||
var r = cfg.r,
|
||
d = cfg.d,
|
||
trigger = cfg.trigger,
|
||
minD = cfg.minD,
|
||
maxD = cfg.maxD,
|
||
minR = cfg.minR,
|
||
maxR = cfg.maxR,
|
||
scaleDBy = cfg.scaleDBy,
|
||
scaleRBy = cfg.scaleRBy;
|
||
if (!isNaN(cfg.r)) {
|
||
self.set('r', r);
|
||
self.set('r2', r * r);
|
||
}
|
||
if (!isNaN(d)) {
|
||
self.set('d', d);
|
||
}
|
||
if (!isNaN(maxD)) {
|
||
self.set('maxD', maxD);
|
||
}
|
||
if (!isNaN(minD)) {
|
||
self.set('minD', minD);
|
||
}
|
||
if (!isNaN(maxR)) {
|
||
self.set('maxR', maxR);
|
||
}
|
||
if (!isNaN(minR)) {
|
||
self.set('minR', minR);
|
||
}
|
||
var nd = self.get('d');
|
||
var nr = self.get('r');
|
||
self.set('molecularParam', (nd + 1) * nr);
|
||
if (trigger === 'mousemove' || trigger === 'click' || trigger === 'drag') {
|
||
self.set('trigger', trigger);
|
||
}
|
||
if (scaleDBy === 'drag' || scaleDBy === 'wheel' || scaleDBy === 'unset') {
|
||
self.set('scaleDBy', scaleDBy);
|
||
self.get('delegate').remove();
|
||
self.get('delegate').destroy();
|
||
var dPercentText = self.get('dPercentText');
|
||
if (dPercentText) {
|
||
dPercentText.remove();
|
||
dPercentText.destroy();
|
||
}
|
||
}
|
||
if (scaleRBy === 'drag' || scaleRBy === 'wheel' || scaleRBy === 'unset') {
|
||
self.set('scaleRBy', scaleRBy);
|
||
self.get('delegate').remove();
|
||
self.get('delegate').destroy();
|
||
var dPercentText = self.get('dPercentText');
|
||
if (dPercentText) {
|
||
dPercentText.remove();
|
||
dPercentText.destroy();
|
||
}
|
||
}
|
||
};
|
||
/**
|
||
* Update the delegate shape of the lens
|
||
* @param {Point} mCenter the center of the shape
|
||
* @param {number} r the radius of the shape
|
||
*/
|
||
Fisheye.prototype.updateDelegate = function (mCenter, r) {
|
||
var _this = this;
|
||
var self = this;
|
||
var graph = self.get('graph');
|
||
var lensDelegate = self.get('delegate');
|
||
if (!lensDelegate || lensDelegate.destroyed) {
|
||
// 拖动多个
|
||
var parent_1 = graph.get('group');
|
||
var attrs = self.get('delegateStyle') || lensDelegateStyle;
|
||
// model上的x, y是相对于图形中心的, delegateShape是g实例, x,y是绝对坐标
|
||
lensDelegate = parent_1.addShape('circle', {
|
||
attrs: __assign({
|
||
r: r / 1.5,
|
||
x: mCenter.x,
|
||
y: mCenter.y
|
||
}, attrs),
|
||
name: 'lens-shape',
|
||
draggable: true
|
||
});
|
||
if (this.get('trigger') !== 'drag') {
|
||
// 调整范围 r 的监听
|
||
if (this.get('scaleRBy') === 'wheel') {
|
||
// 使用滚轮调整 r
|
||
lensDelegate.on('mousewheel', function (evt) {
|
||
self.scaleRByWheel(evt);
|
||
});
|
||
} else if (this.get('scaleRBy') === 'drag') {
|
||
// 使用拖拽调整 r
|
||
lensDelegate.on('dragstart', function (e) {
|
||
self.set('dragging', true);
|
||
self.set('cacheCenter', {
|
||
x: e.x,
|
||
y: e.y
|
||
});
|
||
self.set('dragPrePos', {
|
||
x: e.x,
|
||
y: e.y
|
||
});
|
||
});
|
||
lensDelegate.on('drag', function (evt) {
|
||
self.scaleRByDrag(evt);
|
||
});
|
||
lensDelegate.on('dragend', function (e) {
|
||
self.set('dragging', false);
|
||
});
|
||
}
|
||
// 调整缩放系数 d 的监听
|
||
if (this.get('scaleDBy') === 'wheel') {
|
||
// 使用滚轮调整 d
|
||
lensDelegate.on('mousewheel', function (evt) {
|
||
_this.scaleDByWheel(evt);
|
||
});
|
||
} else if (this.get('scaleDBy') === 'drag') {
|
||
// 使用拖拽调整 d
|
||
lensDelegate.on('dragstart', function (evt) {
|
||
self.set('dragging', true);
|
||
self.set('cacheCenter', {
|
||
x: evt.x,
|
||
y: evt.y
|
||
});
|
||
self.set('dragPrePos', {
|
||
x: evt.x,
|
||
y: evt.y
|
||
});
|
||
});
|
||
lensDelegate.on('drag', function (evt) {
|
||
_this.scaleDByDrag(evt);
|
||
});
|
||
lensDelegate.on('dragend', function (evt) {
|
||
self.set('dragging', false);
|
||
});
|
||
}
|
||
}
|
||
} else {
|
||
lensDelegate.attr({
|
||
x: mCenter.x,
|
||
y: mCenter.y,
|
||
r: r / 1.5
|
||
});
|
||
}
|
||
// 绘制缩放系数百分比文本
|
||
if (self.get('showDPercent')) {
|
||
var percent = Math.round((self.get('d') - self.get('minD')) / (self.get('maxD') - self.get('minD')) * 100);
|
||
var dPercentText = self.get('dPercentText');
|
||
var textY = mCenter.y + r / 1.5 + 16;
|
||
if (!dPercentText || dPercentText.destroyed) {
|
||
var parent_2 = graph.get('group');
|
||
dPercentText = parent_2.addShape('text', {
|
||
attrs: {
|
||
text: "".concat(percent, "%"),
|
||
x: mCenter.x,
|
||
y: textY,
|
||
fill: '#aaa',
|
||
stroke: '#fff',
|
||
lineWidth: 1,
|
||
fontSize: 12
|
||
}
|
||
});
|
||
self.set('dPercentText', dPercentText);
|
||
} else {
|
||
dPercentText.attr({
|
||
text: "".concat(percent, "%"),
|
||
x: mCenter.x,
|
||
y: textY
|
||
});
|
||
}
|
||
}
|
||
self.set('delegate', lensDelegate);
|
||
};
|
||
/**
|
||
* Clear the fisheye lens
|
||
*/
|
||
Fisheye.prototype.clear = function () {
|
||
var graph = this.get('graph');
|
||
this.restoreCache();
|
||
graph.refreshPositions();
|
||
var lensDelegate = this.get('delegate');
|
||
if (lensDelegate && !lensDelegate.destroyed) {
|
||
lensDelegate.remove();
|
||
lensDelegate.destroy();
|
||
}
|
||
var dPercentText = this.get('dPercentText');
|
||
if (dPercentText && !dPercentText.destroyed) {
|
||
dPercentText.remove();
|
||
dPercentText.destroy();
|
||
}
|
||
};
|
||
/**
|
||
* Destroy the component
|
||
*/
|
||
Fisheye.prototype.destroy = function () {
|
||
this.clear();
|
||
};
|
||
return Fisheye;
|
||
}(_base.default);
|
||
var _default = exports.default = Fisheye; |