"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _util = require("@antv/util");
var _g6Core = require("@antv/g6-core");
var _domUtil = require("@antv/dom-util");
var _insertCss = _interopRequireDefault(require("insert-css"));
var _gCanvas = require("@antv/g-canvas");
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 __rest = void 0 && (void 0).__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;
};
typeof document !== 'undefined' && (0, _insertCss.default)("\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 ? "
+
" : "-
";
var contentDOM = collapsed ? '' : " ".concat(content, "
");
var closeDOM = "x
";
var borderRadius = collapsed ? "".concat(r, "px") : "".concat(r, "px ").concat(r, "px 0 0");
return "\n \n ").concat(contentDOM, "\n
");
};
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 _gCanvas.Canvas({
container: graphCantainer,
width: graphContainerBBox.right - graphContainerBBox.left,
height: graphContainerBBox.bottom - graphContainerBBox.top
});
(0, _domUtil.modifyCSS)(linkCanvas.get('el'), {
position: 'absolute',
top: 0,
left: 0,
pointerEvents: 'none'
});
// 需要传入 self,无法 removeEventListener,只能在内部判断 self 被销毁则不继续
window.addEventListener('resize', (0, _util.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 = (0, _domUtil.createDom)(""));
(0, _domUtil.modifyCSS)(container, __assign(__assign({
position: 'absolute',
display: position === 'top' || position === 'bottom' ? 'inline-flex' : 'unset',
width: (0, _util.isNumber)(width) ? "".concat(width, "px") : width,
height: (0, _util.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;
}
(0, _domUtil.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 = (0, _domUtil.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 = (0, _util.isNumber)(minHeight) ? "".concat(minHeight, "px") : minHeight;
(0, _domUtil.modifyCSS)(newCard, {
minHeight: collapsed ? 'unset' : minHeightPx,
minWidth: (0, _util.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 = (0, _util.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;
}
(0, _domUtil.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':
(0, _domUtil.modifyCSS)(card, {
marginLeft: containerWidth ? "".concat(containerWidth - cardWidth, "px") : '0px'
});
break;
case 'top':
case 'bottom':
(0, _domUtil.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;
(0, _domUtil.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 = (0, _domUtil.createDom)("<".concat(inputTag, " class=\"").concat(targetClass, "-input\" type=\"textarea\" style=\"width:").concat(width, "px; height: ").concat(height, "px; min-width: 16px;\"/>"));
var inputWrapper = (0, _domUtil.createDom)(""));
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;
// 更新卡片位置
(0, _domUtil.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;
(0, _domUtil.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;
(0, _domUtil.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.default);
var _default = exports.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 = _g6Core.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;
};