Files
lan-manager/web/node_modules/@antv/g6-plugin/es/annotation/index.js
openclaw 0a5f6a8047 Initial commit: Lan-manager project code
- Go backend (server/)
- Frontend (web/, server/static/)
- Database and deployment files
- Scripts and docs

Co-Authored-By: 狸花猫/Claude-Qwen3.6-Plus 🐾
2026-04-20 00:52:58 +08:00

1061 lines
40 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
var __extends = this && this.__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 = this && this.__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 __rest = this && this.__rest || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
};
import { isNumber, debounce } from '@antv/util';
import { Util } from '@antv/g6-core';
import { modifyCSS, createDom } from '@antv/dom-util';
import insertCss from 'insert-css';
import { Canvas } from '@antv/g-canvas';
import Base from '../base';
typeof document !== 'undefined' && insertCss("\n .g6-annotation-container {\n background-color: rgba(255, 255, 255, 0.3);\n padding: 8px;\n }\n .g6-annotation-wrapper {\n background-color: #fff;\n box-shadow: 0 0 8px rgba(0, 0, 0, 0.85);\n }\n .g6-annotation-header-wapper {\n height: fit-content;\n width: 100%;\n background-color: #5B8FF9;\n display: inline-flex;\n cursor: move;\n }\n .g6-annotation-title {\n margin: 4px 40px 4px 8px;\n cursor: text;\n min-width: 32px;\n }\n .g6-annotation-collapse {\n margin: 4px;\n cursor: pointer;\n }\n .g6-annotation-expand {\n margin: 4px;\n cursor: pointer;\n }\n .g6-annotation-close {\n margin: 4px 8px 4px 0;\n cursor: pointer;\n }\n .g6-annotation-content {\n padding: 8px;\n width: fit-content;\n cursor: text;\n word-break: break-all;\n min-width: 32px;\n }\n .g6-annotation-title-input-wrapper {\n margin: 4px 40px 4px 8px;\n }\n .g6-annotation-content-input {\n height: 100%;\n word-break: break-all;\n }\n .g6-annotation-content-input-wrapper {\n margin: 8px;\n height: 100%;\n }\n");
var CANVAS_ANNOTATION_ID = 'canvas-annotation';
var Annotation = /** @class */function (_super) {
__extends(Annotation, _super);
function Annotation(config) {
return _super.call(this, config) || this;
}
Annotation.prototype.getDefaultCfgs = function () {
return {
trigger: 'click',
editable: true,
itemHighlightState: 'highlight',
linkHighlightStyle: {
shadowColor: '#5B8FF9',
shadowBlur: 10
},
cardCfg: {
minHeight: 60,
width: 'fit-content',
height: 'fit-content',
collapseType: 'minimize',
closeType: 'hide',
borderRadius: 5,
maxTitleLength: 20
}
};
};
// class-methods-use-this
Annotation.prototype.getEvents = function () {
var events = {
'viewportchange': 'updateLinks',
'afterlayout': 'updateLinks',
'aftergraphrefreshposition': 'updateLinks',
'afterupdateitem': 'updateLink',
'afterchangedata': 'onGraphDataChange',
'afteritemvisibilitychange': 'onGraphItemVisibilityChange'
};
switch (this.get('trigger')) {
case 'click':
events = __assign(__assign({}, events), {
'node:click': 'showAnnotation',
'edge:click': 'showAnnotation'
});
}
return events;
};
Annotation.prototype.getDOMContent = function (cfg) {
if (this.destroyed) return;
var collapsed = cfg.collapsed,
maxWidth = cfg.maxWidth,
_a = cfg.title,
title = _a === void 0 ? '' : _a,
_b = cfg.content,
content = _b === void 0 ? '' : _b,
_c = cfg.borderRadius,
r = _c === void 0 ? 5 : _c;
var collapseExpandDOM = collapsed ? "<p class='g6-annotation-expand'>+</p>" : "<p class='g6-annotation-collapse'>-</p>";
var contentDOM = collapsed ? '' : " <p class='g6-annotation-content'>".concat(content, "</p>");
var closeDOM = "<p class='g6-annotation-close'>x</p>";
var borderRadius = collapsed ? "".concat(r, "px") : "".concat(r, "px ").concat(r, "px 0 0");
return "<div class=\"g6-annotation-wrapper\" style=\"border-radius: ".concat(r, "px; max-width: ").concat(maxWidth, "px\">\n <div\n class=\"g6-annotation-header-wapper\"\n style=\"border-radius: ").concat(borderRadius, ";\"\n >\n <h4 class='g6-annotation-title'>").concat(title, "</h4>\n ").concat(collapseExpandDOM, "\n ").concat(closeDOM, "\n </div>\n ").concat(contentDOM, "\n </div>");
};
Annotation.prototype.init = function () {
var self = this;
if (self.destroyed) return;
var graph = self.get('graph');
var graphCantainer = graph.getContainer();
var container = self.get('container');
var containerCfg = this.get('containerCfg');
if (containerCfg) {
container = this.createContainer();
graphCantainer.appendChild(container);
} else {
container = graphCantainer;
}
this.set('container', container);
// 绘制连接 annotation 和元素的连线的画布
var graphContainerBBox = graphCantainer.getBoundingClientRect();
var linkCanvas = new Canvas({
container: graphCantainer,
width: graphContainerBBox.right - graphContainerBBox.left,
height: graphContainerBBox.bottom - graphContainerBBox.top
});
modifyCSS(linkCanvas.get('el'), {
position: 'absolute',
top: 0,
left: 0,
pointerEvents: 'none'
});
// 需要传入 self无法 removeEventListener只能在内部判断 self 被销毁则不继续
window.addEventListener('resize', debounce(function () {
return self.resizeCanvas(self);
}, 100));
var linkGroup = linkCanvas.addGroup({
id: 'annotation-link-group'
});
self.set('linkGroup', linkGroup);
self.set('canvas', linkCanvas);
if (!self.get('getTitle')) {
self.set('getTitle', function (item) {
var _a;
var _b = ((_a = item === null || item === void 0 ? void 0 : item.getModel) === null || _a === void 0 ? void 0 : _a.call(item)) || {},
label = _b.label,
id = _b.id;
return label || id || '-';
});
}
if (!self.get('getContent')) {
self.set('getContent', function (item) {
var _a, _b;
if (!item) return '-';
var _c = ((_a = item.getModel) === null || _a === void 0 ? void 0 : _a.call(item)) || {},
label = _c.label,
id = _c.id;
var type = (_b = item.getType) === null || _b === void 0 ? void 0 : _b.call(item);
var suffix = type ? "".concat(type, ": ") : '';
return "".concat(suffix).concat(label || id || '');
});
}
// init with defaultData
var defaultData = self.get('defaultData');
if (defaultData) this.readData(defaultData);
};
Annotation.prototype.createContainer = function () {
var _this = this;
if (this.destroyed) return;
var containerCfg = this.get('containerCfg');
var graph = this.get('graph');
var graphContainer = graph.getContainer();
var _a = graphContainer.getBoundingClientRect(),
gLeft = _a.left,
gRight = _a.right,
gTop = _a.top,
gBottom = _a.bottom;
var graphContainerHeight = gBottom - gTop;
var graphContainerWidth = gRight - gLeft;
var _b = containerCfg.position,
position = _b === void 0 ? 'top' : _b,
_c = containerCfg.offsetX,
offsetX = _c === void 0 ? 0 : _c,
_d = containerCfg.offsetY,
offsetY = _d === void 0 ? 0 : _d,
otherStyle = __rest(containerCfg, ["position", "offsetX", "offsetY"]);
var _e = containerCfg.height,
height = _e === void 0 ? 'fit-content' : _e,
_f = containerCfg.width,
width = _f === void 0 ? graph.getWidth() : _f;
if (height === '100%') height = graphContainerHeight;
if (width === '100%') width = graphContainerWidth;
var maxHeight = 'unset',
maxWidth = 'unset';
var containerPosition = {};
switch (position) {
case 'right':
maxHeight = "".concat(graphContainerHeight, "px");
containerPosition = {
top: 0,
right: 0
};
containerPosition.right += gLeft + offsetX;
containerPosition.top += gTop + offsetY;
break;
case 'bottom':
maxWidth = "".concat(graphContainerWidth, "px");
containerPosition = {
bottom: 0,
left: 0
};
containerPosition.left += gLeft + offsetX;
containerPosition.bottom += gTop + offsetY;
break;
case 'top':
maxWidth = "".concat(graphContainerWidth, "px");
case 'left':
maxHeight = "".concat(graphContainerHeight, "px");
default:
containerPosition = {
top: 0,
left: 0
};
containerPosition.left += gLeft + offsetX;
containerPosition.top += gTop + offsetY;
break;
}
Object.keys(containerPosition).forEach(function (key) {
containerPosition[key] = "".concat(containerPosition[key], "px");
});
var container = createDom("<div class='".concat(containerCfg.className, " g6-annotation-container'></div>"));
modifyCSS(container, __assign(__assign({
position: 'absolute',
display: position === 'top' || position === 'bottom' ? 'inline-flex' : 'unset',
width: isNumber(width) ? "".concat(width, "px") : width,
height: isNumber(height) ? "".concat(height, "px") : height,
maxHeight: maxHeight,
maxWidth: maxWidth,
overflow: 'scroll'
}, containerPosition), otherStyle));
graphContainer.appendChild(container);
container.addEventListener('scroll', function (e) {
_this.updateLinks();
});
return container;
};
Annotation.prototype.resizeCanvas = function (self) {
// 仅在 resize 完成后进行调整
clearTimeout(self.resizeTimer);
self.resizeTimer = setTimeout(function () {
if (!self || self.destroyed) return;
var cBBox = self.get('container').getBoundingClientRect();
var newWidth = cBBox.right - cBBox.left;
var newHeight = cBBox.bottom - cBBox.top;
self.get('canvas').changeSize(newWidth, newHeight);
self.updateOutsideCards(self);
}, 250);
};
/**
* 更新超出视口范围的卡片位置
* @param selfObj 当前 annotation 插件对象。外部调用不需要传入该参数
*/
Annotation.prototype.updateOutsideCards = function (selfObj) {
var self = selfObj || this;
var cardInfoMap = self.get('cardInfoMap') || {};
var graph = self.get('graph');
var graphLeftTopCanvas = graph.getPointByCanvas(0, 0);
var graphRightBottomCanvas = graph.getPointByCanvas(graph.getWidth(), graph.getHeight());
var _a = graph.getClientByPoint(graphLeftTopCanvas.x, graphLeftTopCanvas.y),
graphLeft = _a.x,
graphTop = _a.y;
var _b = graph.getClientByPoint(graphRightBottomCanvas.x, graphRightBottomCanvas.y),
graphRight = _b.x,
graphBottom = _b.y;
Object.values(cardInfoMap).forEach(function (cardInfo) {
var card = cardInfo.card;
if (!card) return;
var style = card.style;
var left = px2Num(style.left);
var top = px2Num(style.top);
var _a = card.getBoundingClientRect(),
width = _a.width,
height = _a.height;
var newLeft = left;
var newTop = top;
if (left + width > graphRight - graphLeft) {
newLeft = graphRight - graphLeft - width;
}
if (left < 0) {
newLeft = 0;
}
if (top + height > graphBottom - graphTop) {
newTop = graphBottom - graphTop - height;
}
if (top < 0) {
newTop = 0;
}
modifyCSS(card, {
left: "".concat(newLeft, "px"),
top: "".concat(newTop, "px")
});
});
self.updateLinks();
};
Annotation.prototype.showAnnotation = function (evt) {
if (this.destroyed) return;
var item = evt.item;
this.toggleAnnotation(item);
};
Annotation.prototype.hideCards = function () {
var self = this;
if (self.destroyed) return;
var cardInfoMap = self.get('cardInfoMap') || {};
Object.keys(cardInfoMap).forEach(function (itemId) {
self.hideCard(itemId);
});
};
Annotation.prototype.toggleAnnotation = function (item, cfg) {
var _a, _b;
if (cfg === void 0) {
cfg = {};
}
var self = this;
if (self.destroyed) return;
var cardInfoMap = self.get('cardInfoMap') || {};
var graph = self.get('graph');
var container = self.get('container');
var containerCfg = self.get('containerCfg');
var _c = Object.assign({}, self.get('cardCfg') || {}, cfg),
minHeight = _c.minHeight,
minWidth = _c.minWidth,
width = _c.width,
height = _c.height,
_d = _c.collapsed,
collapsed = _d === void 0 ? false : _d,
propsX = _c.x,
propsY = _c.y,
propsTitle = _c.title,
propsContent = _c.content,
maxTitleLength = _c.maxTitleLength,
defaultBegin = _c.defaultBegin,
otherCardCfg = __rest(_c, ["minHeight", "minWidth", "width", "height", "collapsed", "x", "y", "title", "content", "maxTitleLength", "defaultBegin"]);
var linkGroup = self.get('linkGroup');
var rows = this.get('rows') || [[]];
var isCanvas = (_a = item.isCanvas) === null || _a === void 0 ? void 0 : _a.call(item);
var itemId = isCanvas ? CANVAS_ANNOTATION_ID : item.getID();
var _e = cardInfoMap[itemId] || {},
card = _e.card,
link = _e.link,
x = _e.x,
y = _e.y,
title = _e.title,
content = _e.content;
var getTitle = this.get('getTitle');
var getContent = this.get('getContent');
var getContentPlaceholder = this.get('getContentPlaceholder') || function () {
return '';
};
var getTitlePlaceHolder = this.get('getTitlePlaceHolder') || function () {
return '';
};
var contentPlaceholder = getContentPlaceholder(item);
var titlePlaceholder = getTitlePlaceHolder(item);
var newCard = createDom(this.getDOMContent(__assign({
itemId: itemId,
collapsed: collapsed,
title: ((_b = title || propsTitle || (getTitle === null || getTitle === void 0 ? void 0 : getTitle(item))) === null || _b === void 0 ? void 0 : _b.substr(0, maxTitleLength)) || titlePlaceholder,
content: content || propsContent || (getContent === null || getContent === void 0 ? void 0 : getContent(item)) || contentPlaceholder
}, otherCardCfg)));
var minHeightPx = isNumber(minHeight) ? "".concat(minHeight, "px") : minHeight;
modifyCSS(newCard, {
minHeight: collapsed ? 'unset' : minHeightPx,
minWidth: isNumber(minWidth) ? "".concat(minWidth, "px") : minWidth,
height: height,
width: width
});
var exist = !!card;
if (exist) {
// 移除相应连线
link === null || link === void 0 ? void 0 : link.remove(true);
// 替换原来的卡片
container.replaceChild(newCard, card);
} else {
container.appendChild(newCard);
}
var containerBBox;
if (!containerCfg) {
containerBBox = container.getBoundingClientRect() || {};
if (propsX !== undefined && propsY !== undefined) {
// 使用配置的位置
x = propsX;
y = propsY;
} else if (!exist && !isCanvas) {
// 第一次创建,且无 conatiner初始化位置
var containerTop = containerBBox.top;
var _f = defaultBegin || {},
beginLeft = _f.left,
_g = _f.right,
propsBeginRight = _g === void 0 ? 16 : _g,
_h = _f.top,
propsBeginTop = _h === void 0 ? 8 : _h,
beginBottom = _f.bottom;
var beginRight = propsBeginRight;
var beginTop = propsBeginTop;
if (!isNaN(beginLeft)) {
beginRight = container.scrollWidth - beginLeft;
}
if (!isNaN(beginBottom)) {
beginTop = container.scrollHeight - beginBottom;
}
var cardWidth = isNumber(minWidth) ? minWidth : 100;
x = container.scrollWidth - newCard.scrollWidth - (rows.length - 1) * cardWidth - beginRight;
var currentRow = rows[rows.length - 1];
var lastCardBBox = (currentRow[currentRow.length - 1] || {}).bbox;
y = (lastCardBBox === null || lastCardBBox === void 0 ? void 0 : lastCardBBox.bottom) - containerTop || beginTop;
}
modifyCSS(newCard, {
position: 'absolute',
left: "".concat(x, "px"),
top: "".concat(y, "px"),
cusor: containerCfg ? 'unset' : 'move'
});
}
this.bindListener(newCard, itemId);
var cardBBox = newCard.getBoundingClientRect();
if (!isCanvas) {
// 创建相关连线
var path = getPathItem2Card(item, cardBBox, graph, this.get('canvas'));
var linkStyle = this.get('linkStyle');
link = linkGroup.addShape('path', {
attrs: __assign({
lineWidth: 1,
lineDash: [5, 5],
stroke: '#ccc',
path: path
}, linkStyle)
});
}
cardInfoMap[itemId] = __assign(__assign({}, cardInfoMap[itemId] || {}), {
id: itemId,
collapsed: collapsed,
card: newCard,
link: link,
x: x,
y: y,
cardBBox: cardBBox,
content: content || propsContent,
title: title || propsTitle,
contentPlaceholder: contentPlaceholder,
titlePlaceholder: titlePlaceholder,
isCanvas: isCanvas
});
self.set('cardInfoMap', cardInfoMap);
if (containerCfg) {
this.updateCardPositionsInConatainer();
this.updateLinks();
} else {
var hasPropsPosition = !isNaN(propsX) && !isNaN(propsY);
if (!exist && !isCanvas && !hasPropsPosition) {
// 没有 container、新增 card 时,记录当前列中最下方位置,方便换行
var _j = containerBBox.bottom,
containerBottom = _j === void 0 ? 0 : _j,
containerTop = containerBBox.top;
rows[rows.length - 1].push({
id: itemId,
bbox: cardBBox
});
if (cardBBox.top > containerBottom - containerTop - cardBBox.height - 16) rows.push([]);
this.set('rows', rows);
}
}
this.updateCardSize(itemId);
var onAnnotationChange = this.get('onAnnotationChange');
onAnnotationChange === null || onAnnotationChange === void 0 ? void 0 : onAnnotationChange(cardInfoMap[itemId], exist ? 'update' : 'create');
};
Annotation.prototype.updateCardPositionsInConatainer = function () {
if (this.destroyed) return;
var cardInfoMap = this.get('cardInfoMap');
if (!cardInfoMap) return;
var container = this.get('container');
var position = this.get('containerCfg').position;
var containerWidth = container.getBoundingClientRect().width;
var computeStyle = getComputedStyle(container);
var sidePadding = px2Num(computeStyle['paddingLeft']) + px2Num(computeStyle['paddingRight']);
containerWidth -= sidePadding;
Object.values(cardInfoMap).forEach(function (_a) {
var card = _a.card;
var cardWidth = card.getBoundingClientRect().width;
switch (position) {
case 'right':
modifyCSS(card, {
marginLeft: containerWidth ? "".concat(containerWidth - cardWidth, "px") : '0px'
});
break;
case 'top':
case 'bottom':
modifyCSS(card, {
marginLeft: '8px'
});
default:
break;
}
});
};
Annotation.prototype.handleExpandCollapseCard = function (id) {
if (this.destroyed) return;
var graph = this.get('graph');
var cardInfoMap = this.get('cardInfoMap');
if (!cardInfoMap) return;
var collapsed = cardInfoMap[id].collapsed;
var item = graph.findById(id);
if (!item) return;
var collapseType = this.get('cardCfg').collapseType;
if (collapseType === 'hide' && !collapsed) {
// collapse 行为被配置为隐藏
this.hideCard(id);
} else {
this.toggleAnnotation(item, {
collapsed: !collapsed
});
}
cardInfoMap[id] = __assign(__assign({}, cardInfoMap[id]), {
collapsed: !collapsed
});
};
/**
* 隐藏标注卡片,下次打开还保留隐藏前的配置,包括文本内容、位置等
* @param id 卡片 id即元素(节点/边)的 id
* @returns
*/
Annotation.prototype.hideCard = function (id) {
if (this.destroyed) return;
var cardInfoMap = this.get('cardInfoMap');
if (!cardInfoMap || !cardInfoMap[id]) return;
var _a = cardInfoMap[id],
card = _a.card,
link = _a.link;
modifyCSS(card, {
display: 'none'
});
link === null || link === void 0 ? void 0 : link.hide();
var onAnnotationChange = this.get('onAnnotationChange');
onAnnotationChange(cardInfoMap[id], 'hide');
};
/**
* 移除标注卡片,下一次生成时将被初始化
* @param id 卡片 id即元素(节点/边)的 id
* @returns
*/
Annotation.prototype.removeCard = function (id) {
if (this.destroyed) return;
var cardInfoMap = this.get('cardInfoMap');
if (!cardInfoMap) return;
var cardInfo = cardInfoMap[id];
var card = cardInfo.card,
link = cardInfo.link;
var container = this.get('container');
container.removeChild(card);
link === null || link === void 0 ? void 0 : link.remove(true);
delete cardInfoMap[id];
var onAnnotationChange = this.get('onAnnotationChange');
onAnnotationChange(cardInfo, 'remove');
};
Annotation.prototype.bindListener = function (card, itemId) {
var _this = this;
if (this.destroyed) return;
card.addEventListener('mousemove', function (e) {
// icon 的鼠标进入监听,方便外部加 tooltip
var iconType;
if (e.target.className === 'g6-annotation-collapse') {
iconType = 'collapse';
} else if (e.target.className === 'g6-annotation-expand') {
iconType = 'expand';
} else if (e.target.className === 'g6-annotation-close') {
iconType = 'close';
}
if (iconType) {
var _a = _this.get('cardCfg').onMouseEnterIcon,
onMouseEnterIcon = _a === void 0 ? function () {} : _a;
onMouseEnterIcon(e, itemId, iconType);
}
});
card.addEventListener('mouseout', function (e) {
// icon 的鼠标移出监听,方便外部加 tooltip
var iconType;
if (e.target.className === 'g6-annotation-collapse') {
iconType = 'collapse';
} else if (e.target.className === 'g6-annotation-expand') {
iconType = 'expand';
} else if (e.target.className === 'g6-annotation-close') {
iconType = 'close';
}
if (iconType) {
var _a = _this.get('cardCfg').onMouseLeaveIcon,
onMouseLeaveIcon = _a === void 0 ? function () {} : _a;
onMouseLeaveIcon(e, itemId, iconType);
}
});
// mouseenter and mouseleave to highlight the corresponding items
card.addEventListener('mouseenter', function (e) {
var cardInfoMap = _this.get('cardInfoMap');
if (!cardInfoMap) return;
var graph = _this.get('graph');
var item = graph.findById(itemId);
if (item) {
var itemHighlightState = _this.get('itemHighlightState');
graph.setItemState(item, itemHighlightState, true);
}
var link = cardInfoMap[itemId].link;
if (link) {
var linkHighlightStyle = _this.get('linkHighlightStyle') || {};
link.attr(linkHighlightStyle);
}
});
card.addEventListener('mouseleave', function (e) {
var cardInfoMap = _this.get('cardInfoMap');
if (!cardInfoMap) return;
var graph = _this.get('graph');
var item = graph.findById(itemId);
if (item) {
var itemHighlightState = _this.get('itemHighlightState');
graph.setItemState(item, itemHighlightState, false);
}
var link = cardInfoMap[itemId].link;
if (link) {
var linkHighlightStyle = _this.get('linkHighlightStyle') || {};
Object.keys(linkHighlightStyle).forEach(function (key) {
link.attr(key, undefined);
link.attr(key, undefined);
});
var linkStyle = _this.get('linkStyle');
link.attr(linkStyle);
}
});
card.addEventListener('click', function (e) {
var onClickIcon = (_this.get('cardCfg') || {}).onClickIcon;
if (e.target.className === 'g6-annotation-collapse' || e.target.className === 'g6-annotation-expand') {
// collapse & expand
var collapseType = _this.get('cardCfg').collapseType;
if (collapseType === 'hide') {
_this.hideCard(itemId);
} else {
_this.handleExpandCollapseCard(itemId);
}
onClickIcon === null || onClickIcon === void 0 ? void 0 : onClickIcon(e, itemId, e.target.className === 'g6-annotation-collapse' ? 'collapse' : 'expand');
} else if (e.target.className === 'g6-annotation-close') {
// close
var closeType = _this.get('cardCfg').closeType;
if (closeType === 'remove') {
_this.removeCard(itemId);
} else {
_this.hideCard(itemId);
}
onClickIcon === null || onClickIcon === void 0 ? void 0 : onClickIcon(e, itemId, 'close');
}
});
// dblclick to edit the title and content text
var editable = this.get('editable');
if (editable) {
card.addEventListener('dblclick', function (e) {
var cardInfoMap = _this.get('cardInfoMap');
var _a = (_this.get('cardCfg') || {}).maxTitleLength,
maxTitleLength = _a === void 0 ? 20 : _a;
if (!cardInfoMap) return;
var target = e.target;
var targetClass = target.className;
if (targetClass !== 'g6-annotation-title' && targetClass !== 'g6-annotation-content') return;
var _b = targetClass === 'g6-annotation-title' ? target.getBoundingClientRect() : target.parentNode.getBoundingClientRect(),
width = _b.width,
height = _b.height;
var computeStyle = getComputedStyle(target);
var inputTag = targetClass === 'g6-annotation-title' ? 'input' : 'textarea';
var input = createDom("<".concat(inputTag, " class=\"").concat(targetClass, "-input\" type=\"textarea\" style=\"width:").concat(width, "px; height: ").concat(height, "px; min-width: 16px;\"/>"));
var inputWrapper = createDom("<div class=\"".concat(targetClass, "-input-wrapper\" style=\"width: ").concat(width, "px; height: ").concat(height, "px; min-width: 16px; margin-right: ").concat(computeStyle['marginRight'], "\" />"));
inputWrapper.appendChild(input);
target.parentNode.replaceChild(inputWrapper, target);
var cardInfo = cardInfoMap[itemId];
var contentPlaceholder = cardInfo.contentPlaceholder,
titlePlaceholder = cardInfo.titlePlaceholder,
content = cardInfo.content,
title = cardInfo.title;
var value = content;
if (targetClass === 'g6-annotation-title') {
input.name = 'title';
input.maxLength = maxTitleLength;
value = title;
} else {
input.name = 'content';
}
if (value) {
input.innerHTML = target.innerHTML;
input.value = target.innerHTML;
} else {
input.placeholder = targetClass === 'g6-annotation-title' ? titlePlaceholder : contentPlaceholder;
}
input.focus();
input.addEventListener('blur', function (blurEvt) {
if (input.value) {
target.innerHTML = input.value;
cardInfo[input.name || 'title'] = input.value;
}
inputWrapper.parentNode.replaceChild(target, inputWrapper);
_this.updateCardSize(itemId);
var onAnnotationChange = _this.get('onAnnotationChange');
onAnnotationChange === null || onAnnotationChange === void 0 ? void 0 : onAnnotationChange(cardInfo, 'update');
});
});
}
var unmovableClasses = ['g6-annotation-title', 'g6-annotation-content', 'g6-annotation-title-input', 'g6-annotation-content-input'];
card.draggable = true;
card.addEventListener('dragstart', function (e) {
var targetClass = e.target.className;
if (unmovableClasses.includes(targetClass)) return;
var style = card.style;
_this.set('dragging', {
card: card,
x: e.clientX,
y: e.clientY,
left: px2Num(style.left),
top: px2Num(style.top)
});
});
card.addEventListener('drag', function (e) {
e.preventDefault();
var cardInfoMap = _this.get('cardInfoMap');
if (!cardInfoMap) return;
var clientX = e.clientX,
clientY = e.clientY;
var dragging = _this.get('dragging');
if (isNaN(clientX) || isNaN(clientY) || !dragging) return;
var x = dragging.x,
y = dragging.y,
left = dragging.left,
top = dragging.top,
draggingCard = dragging.card;
var dx = clientX - x;
var dy = clientY - y;
left += dx;
top += dy;
var graph = _this.get('graph');
var graphLeftTopCanvas = graph.getPointByCanvas(0, 0);
var graphRightBottomCanvas = graph.getPointByCanvas(graph.getWidth(), graph.getHeight());
var _a = graph.getClientByPoint(graphLeftTopCanvas.x, graphLeftTopCanvas.y),
graphLeft = _a.x,
graphTop = _a.y;
var _b = graph.getClientByPoint(graphRightBottomCanvas.x, graphRightBottomCanvas.y),
graphRight = _b.x,
graphBottom = _b.y;
var cardBBox = draggingCard.getBoundingClientRect();
var cardWidth = cardBBox.right - cardBBox.left;
var cardHeight = cardBBox.bottom - cardBBox.top;
if (left > graphRight - graphLeft - cardWidth && dx > 0 || left < 0 && dx < 0) left -= dx;
if (top > graphBottom - graphTop - cardHeight && dy > 0 || top < 0 && dy < 0) top -= dy;
// 更新卡片位置
modifyCSS(draggingCard, {
left: "".concat(left, "px"),
top: "".concat(top, "px"),
visibility: 'hidden'
});
x = clientX;
y = clientY;
// 更新连线位置
var link = (cardInfoMap[itemId] || {}).link;
if (link) {
var item = graph.findById(itemId);
link.attr('path', getPathItem2Card(item, cardBBox, graph, _this.get('canvas')));
}
_this.set('dragging', {
x: x,
y: y,
left: left,
top: top,
card: draggingCard
});
});
var dragendListener = function dragendListener(e) {
var cardInfoMap = _this.get('cardInfoMap');
if (!cardInfoMap) return;
var dragging = _this.get('dragging');
if (dragging) {
// = dragend
var left = dragging.left,
top_1 = dragging.top,
draggingCard = dragging.card;
cardInfoMap[itemId].x = left;
cardInfoMap[itemId].y = top_1;
modifyCSS(draggingCard, {
visibility: 'visible'
});
_this.set('dragging', false);
// 移动过的卡片从 rows 中移除,避免影响后续卡片出生位置
var rows = _this.get("rows");
rows === null || rows === void 0 ? void 0 : rows.forEach(function (rowItems) {
for (var i = rowItems.length - 1; i >= 0; i--) {
if (rowItems[i].id === itemId) rowItems.splice(i, 1);
}
});
var onAnnotationChange = _this.get('onAnnotationChange');
onAnnotationChange === null || onAnnotationChange === void 0 ? void 0 : onAnnotationChange(cardInfoMap[itemId], 'update');
}
};
card.addEventListener('dragend', dragendListener);
};
Annotation.prototype.updateCardSize = function (id) {
var cardInfoMap = this.get('cardInfoMap');
if (!cardInfoMap) return;
var card = cardInfoMap[id].card;
var width = card.getBoundingClientRect().width;
var title = card.getElementsByClassName('g6-annotation-title')[0];
if (title) {
var computeStyle = getComputedStyle(title);
var sideMargin = px2Num(computeStyle['marginLeft']);
var titleWidth = title.getBoundingClientRect().width;
modifyCSS(title, {
marginRight: "".concat(width - sideMargin - 24 - 16 - titleWidth, "px")
});
}
};
Annotation.prototype.updateLink = function (_a) {
var item = _a.item;
if (!item) return;
var cardInfoMap = this.get('cardInfoMap');
if (!cardInfoMap) return;
var canvas = this.get('canvas');
var graph = this.get('graph');
var id = item.getID();
var _b = cardInfoMap[id] || {},
link = _b.link,
card = _b.card;
if (link) {
var path = getPathItem2Card(item, card.getBoundingClientRect(), graph, canvas);
link.attr('path', path);
}
};
Annotation.prototype.updateLinks = function () {
var _this = this;
if (this.destroyed) return;
var cardInfoMap = this.get('cardInfoMap');
if (!cardInfoMap) return;
var graph = this.get('graph');
Object.values(cardInfoMap).forEach(function (cardInfo) {
var id = cardInfo.id;
var item = graph.findById(id);
_this.updateLink({
item: item
});
});
};
Annotation.prototype.onGraphDataChange = function () {
var _this = this;
var cardInfoMap = this.get('cardInfoMap');
if (!cardInfoMap) return;
var graph = this.get('graph');
Object.values(cardInfoMap).forEach(function (info) {
var id = info.id,
card = info.card,
isCanvas = info.isCanvas;
if (!card || isCanvas || card.style.display === 'none') return;
var item = graph.findById(id);
if (item && item.isVisible()) {
_this.toggleAnnotation(item);
} else {
_this.hideCard(id);
}
});
};
Annotation.prototype.onGraphItemVisibilityChange = function (_a) {
var item = _a.item,
visible = _a.visible;
if (!item || item.destroyed) return;
var cardInfoMap = this.get('cardInfoMap');
if (!cardInfoMap) return;
var id = item.getID();
if (!cardInfoMap[id]) return;
if (!visible) this.hideCard(id);
};
Annotation.prototype.saveData = function (saveClosed) {
if (saveClosed === void 0) {
saveClosed = false;
}
var cardInfoMap = this.get('cardInfoMap');
if (!cardInfoMap) return;
var graph = this.get('graph');
var getTitle = this.get('getTitle');
var getContent = this.get('getContent');
var data = [];
Object.values(cardInfoMap).forEach(function (info) {
var title = info.title,
content = info.content,
x = info.x,
y = info.y,
id = info.id,
collapsed = info.collapsed,
card = info.card;
if (card && card.style.display === 'none' && !saveClosed) return;
var item = graph.findById(id) || graph.get('canvas');
data.push({
id: id,
x: x,
y: y,
collapsed: collapsed,
title: title || (getTitle === null || getTitle === void 0 ? void 0 : getTitle(item)),
content: content || (getContent === null || getContent === void 0 ? void 0 : getContent(item)),
visible: card && card.style.display !== 'none'
});
});
return data;
};
Annotation.prototype.readData = function (data) {
var _this = this;
var graph = this.get('graph');
data.forEach(function (info) {
var id = info.id,
x = info.x,
y = info.y,
title = info.title,
content = info.content,
collapsed = info.collapsed,
visible = info.visible;
var item = graph.findById(id);
if (!item && id === CANVAS_ANNOTATION_ID) {
item = graph.get('canvas');
}
if (!item) {
var cardInfoMap = _this.get('cardInfoMap') || {};
cardInfoMap[id] = info;
_this.set('cardInfoMap', cardInfoMap);
return;
}
_this.toggleAnnotation(item, {
x: x,
y: y,
title: title,
content: content,
collapsed: collapsed
});
if (!visible) _this.hideCard(id);
});
};
/**
* Clear the cards and links
*/
Annotation.prototype.clear = function () {
var cardInfoMap = this.get('cardInfoMap');
if (!cardInfoMap) return;
var container = this.get('container');
Object.values(cardInfoMap).forEach(function (cardInfo) {
var card = cardInfo.card,
link = cardInfo.link;
container.removeChild(card);
link === null || link === void 0 ? void 0 : link.remove(true);
});
this.set('cardInfoMap', {});
};
/**
* Destroy the component
*/
Annotation.prototype.destroy = function () {
var _a;
this.clear();
(_a = this.get('canvas')) === null || _a === void 0 ? void 0 : _a.destroy();
var graph = this.get('graph');
if (!graph || graph.destroyed) return;
if (this.get('containerCfg')) {
graph.getContainer().removeChild(this.get('container'));
}
this.destroyed = true;
};
return Annotation;
}(Base);
export default Annotation;
var getPath = function getPath(startPoints, endPoints) {
var startPoint,
endPoint,
posKeys,
distance = Infinity;
Object.keys(startPoints).forEach(function (skey) {
var spos = startPoints[skey];
Object.keys(endPoints).forEach(function (ekey) {
var epos = endPoints[ekey];
var xdist = spos.x - epos.x;
var ydist = spos.y - epos.y;
var dist = xdist * xdist + ydist * ydist;
if (distance > dist) {
distance = dist;
startPoint = spos;
endPoint = epos;
posKeys = [skey, ekey];
}
});
});
var curveOffset = 20;
var controlPoint = Util.getControlPoint(startPoint, endPoint, 0.5, curveOffset);
return [['M', startPoint.x, startPoint.y], ['Q', controlPoint.x, controlPoint.y, endPoint.x, endPoint.y]];
};
var getPathItem2Card = function getPathItem2Card(item, cardBBox, graph, annotationCanvas) {
var _a;
var itemLinkPoints;
var itemType = item.getType();
if (itemType === 'edge') {
itemLinkPoints = [item.getKeyShape().getPoint(0.5)];
} else {
var _b = (_a = item.getKeyShape) === null || _a === void 0 ? void 0 : _a.call(item).getBBox(),
minX = _b.minX,
minY = _b.minY,
maxX = _b.maxX,
maxY = _b.maxY;
var _c = item.getModel(),
x = _c.x,
y = _c.y;
minX += x;
minY += y;
maxX += x;
maxY += y;
itemLinkPoints = {
left: {
x: minX,
y: (minY + maxY) / 2
},
right: {
x: maxX,
y: (minY + maxY) / 2
},
top: {
x: (minX + maxX) / 2,
y: minY
},
bottom: {
x: (minX + maxX) / 2,
y: maxY
}
};
}
// 由 graph 所在 canvas 转换为 Client 坐标系,然后再由 annotation 所在 canvas 转换为绘制坐标系
Object.keys(itemLinkPoints).forEach(function (key) {
var _a = itemLinkPoints[key],
x = _a.x,
y = _a.y;
var clientPos = graph.getClientByPoint(x, y);
itemLinkPoints[key] = annotationCanvas.getPointByClient(clientPos.x, clientPos.y);
});
var _d = cardBBox.top,
cardTop = _d === void 0 ? 0 : _d,
_e = cardBBox.left,
cardLeft = _e === void 0 ? 0 : _e,
_f = cardBBox.right,
cardRight = _f === void 0 ? 0 : _f,
_g = cardBBox.bottom,
cardBottom = _g === void 0 ? 0 : _g;
var cardLinkPoints = {
left: annotationCanvas.getPointByClient(cardLeft, (cardTop + cardBottom) / 2),
right: annotationCanvas.getPointByClient(cardRight, (cardTop + cardBottom) / 2),
top: annotationCanvas.getPointByClient((cardLeft + cardRight) / 2, cardTop),
bottom: annotationCanvas.getPointByClient((cardLeft + cardRight) / 2, cardBottom)
};
return getPath(itemLinkPoints, cardLinkPoints);
};
var px2Num = function px2Num(px) {
return Number(px.replace(/\s+|px/gi, "")) || 0;
};