@visactor/vrender-components
Version:
components library for dp visualization
227 lines (221 loc) • 16.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.Tooltip = void 0;
const vrender_core_1 = require("@visactor/vrender-core"), vutils_1 = require("@visactor/vutils"), base_1 = require("../core/base"), text_1 = require("../util/text"), util_1 = require("../util"), util_2 = require("./util"), config_1 = require("./config"), constant_1 = require("../constant"), register_1 = require("./register"), TOOLTIP_BACKGROUND_NAME = "tooltip-background", TOOLTIP_TITLE_NAME = "tooltip-title", TOOLTIP_CONTENT_NAME = "tooltip-content", TOOLTIP_SHAPE_NAME_SUFFIX = "shape", TOOLTIP_KEY_NAME_SUFFIX = "key", TOOLTIP_VALUE_NAME_SUFFIX = "value";
(0, register_1.loadTooltipComponent)();
class Tooltip extends base_1.AbstractComponent {
constructor(attributes, options) {
super((null == options ? void 0 : options.skipDefault) ? attributes : (0, vutils_1.merge)({}, Tooltip.defaultAttributes, attributes), options),
this.name = "tooltip";
}
render() {
var _a;
const {visible: visible, content: content, panel: panel, keyWidth: keyWidth, valueWidth: valueWidth, hasContentShape: hasContentShape, autoCalculatePosition: autoCalculatePosition, autoMeasure: autoMeasure, align: align} = this.attribute;
if (!visible) return void this.hideAll();
autoMeasure && Tooltip.measureTooltip(this.attribute), autoCalculatePosition && Tooltip.calculateTooltipPosition(this.attribute);
const padding = (0, vutils_1.normalizePadding)(this.attribute.padding);
this._tooltipPanel = this.createOrUpdateChild("tooltip-background", Object.assign({
visible: !0
}, panel), "rect"), this._tooltipTitleContainer = this.createOrUpdateChild("tooltip-title", {
visible: !0,
x: padding[3],
y: padding[0]
}, "group");
const titleAttr = Tooltip.getTitleAttr(this.attribute);
this._tooltipTitleSymbol = this._tooltipTitleContainer.createOrUpdateChild("tooltip-title-shape", (0,
vutils_1.merge)({
symbolType: "circle"
}, titleAttr.shape, {
visible: (0, util_1.isVisible)(titleAttr) && (0, util_1.isVisible)(titleAttr.shape)
}), "symbol"), "object" != typeof titleAttr.value.text || null === titleAttr.value.text || "rich" !== titleAttr.value.text.type && "html" !== titleAttr.value.text.type ? titleAttr.value.multiLine ? this._tooltipTitle = this._tooltipTitleContainer.createOrUpdateChild("tooltip-title-value", Object.assign({
visible: (0, util_1.isVisible)(titleAttr) && (0, util_1.isVisible)(titleAttr.value)
}, (0, util_2.getRichTextAttribute)(titleAttr.value)), "richtext") : this._tooltipTitle = this._tooltipTitleContainer.createOrUpdateChild("tooltip-title-value", Object.assign({
text: null !== (_a = titleAttr.value.text) && void 0 !== _a ? _a : "",
visible: (0, util_1.isVisible)(titleAttr) && (0, util_1.isVisible)(titleAttr.value)
}, titleAttr.value), "text") : "rich" === titleAttr.value.text.type ? this._tooltipTitle = this._tooltipTitleContainer.createOrUpdateChild("tooltip-title-value", Object.assign({
visible: (0, util_1.isVisible)(titleAttr) && (0, util_1.isVisible)(titleAttr.value)
}, (0, util_2.getRichTextAttribute)(titleAttr.value)), "richtext") : "html" === titleAttr.value.text.type && (this._tooltipTitle = this._tooltipTitleContainer.createOrUpdateChild("tooltip-title-value", Object.assign({
html: Object.assign(Object.assign({
dom: titleAttr.value.text.text
}, constant_1.DEFAULT_HTML_TEXT_SPEC), titleAttr.value),
visible: (0, util_1.isVisible)(titleAttr) && (0, util_1.isVisible)(titleAttr.value),
width: titleAttr.value.width,
height: titleAttr.value.height,
wordBreak: titleAttr.value.wordBreak,
textAlign: titleAttr.value.textAlign,
textBaseline: titleAttr.value.textBaseline,
singleLine: !1,
textConfig: []
}, titleAttr.value), "richtext"));
const titlePaddingLeft = (0, util_1.isVisible)(titleAttr.shape) ? titleAttr.shape.size + titleAttr.shape.spacing : 0, {textAlign: textAlign, textBaseline: textBaseline} = titleAttr.value, contentWidth = panel.width - padding[3] - padding[0] - titlePaddingLeft;
"center" === textAlign ? this._tooltipTitle.setAttribute("x", titlePaddingLeft + contentWidth / 2) : "right" === textAlign || "end" === textAlign ? this._tooltipTitle.setAttribute("x", titlePaddingLeft + contentWidth) : this._tooltipTitle.setAttribute("x", titlePaddingLeft),
"bottom" === textBaseline ? this._tooltipTitle.setAttribute("y", titleAttr.height) : "middle" === textBaseline ? this._tooltipTitle.setAttribute("y", titleAttr.height / 2) : this._tooltipTitle.setAttribute("y", 0);
const titleHeight = (0, util_1.isVisible)(titleAttr) ? titleAttr.height + titleAttr.spaceRow : 0;
if (this._tooltipContent = this.createOrUpdateChild("tooltip-content", {
visible: !0
}, "group"), this._tooltipContent.removeAllChild(!0), content && content.length) {
this._tooltipContent.setAttribute("x", padding[3]), this._tooltipContent.setAttribute("y", padding[0] + titleHeight);
let lastYPos = 0;
content.forEach(((item, i) => {
const itemAttr = Tooltip.getContentAttr(this.attribute, i);
if (!(0, util_1.isVisible)(itemAttr)) return;
const itemGroupName = `tooltip-content-${i}`, itemGroup = this._tooltipContent.createOrUpdateChild(itemGroupName, {
visible: !0,
x: 0,
y: lastYPos
}, "group"), shapeOffsetWidth = itemAttr.shape.size + itemAttr.shape.spacing;
let x = "right" === align ? (hasContentShape ? shapeOffsetWidth : 0) + ((0, util_1.isVisible)(itemAttr.key) ? keyWidth + itemAttr.key.spacing : 0) + ((0,
util_1.isVisible)(itemAttr.value) ? valueWidth : 0) : 0;
this._createShape("right" === align ? x - itemAttr.shape.size / 2 : x + itemAttr.shape.size / 2, itemAttr, itemGroup, itemGroupName),
hasContentShape && ("right" === align ? x -= shapeOffsetWidth : x += shapeOffsetWidth);
const keyGraphic = this._createKey(itemAttr, itemGroup, itemGroupName);
keyGraphic && ((0, text_1.alignTextInLine)(align, keyGraphic, itemAttr.key.textAlign, x, keyWidth),
keyGraphic.setAttribute("y", 0), "right" === align ? x -= keyWidth + itemAttr.key.spacing : x += keyWidth + itemAttr.key.spacing);
const valueGraphic = this._createValue(itemAttr, itemGroup, itemGroupName);
if (valueGraphic) {
let textAlign = "right";
(0, vutils_1.isValid)(itemAttr.value.textAlign) ? textAlign = itemAttr.value.textAlign : (0,
util_1.isVisible)(itemAttr.key) || "right" === align || (textAlign = "left"), valueGraphic.setAttribute("textAlign", textAlign),
(0, text_1.alignTextInLine)(align, valueGraphic, textAlign, x, valueWidth), valueGraphic.setAttribute("y", 0);
}
lastYPos += itemAttr.height + itemAttr.spaceRow;
}));
}
}
_createShape(x, itemAttr, itemGroup, itemGroupName) {
var _a;
if ((0, util_1.isVisible)(itemAttr.shape)) return itemGroup.createOrUpdateChild(`${itemGroupName}-shape`, Object.assign({
visible: !0,
x: x,
y: itemAttr.shape.size / 2 + ((null !== (_a = (0, vrender_core_1.calculateLineHeight)(itemAttr.key.lineHeight, itemAttr.key.fontSize)) && void 0 !== _a ? _a : itemAttr.key.fontSize) - itemAttr.shape.size) / 2
}, itemAttr.shape), "symbol");
}
_createKey(itemAttr, itemGroup, itemGroupName) {
var _a;
if ((0, util_1.isVisible)(itemAttr.key)) {
let element;
return element = itemAttr.key.multiLine ? itemGroup.createOrUpdateChild(`${itemGroupName}-key`, Object.assign(Object.assign({
visible: !0
}, (0, util_2.getRichTextAttribute)(itemAttr.key)), {
textBaseline: "top"
}), "richtext") : "object" != typeof itemAttr.key.text || null === itemAttr.key.text || "rich" !== itemAttr.key.text.type && "html" !== itemAttr.key.text.type ? itemGroup.createOrUpdateChild(`${itemGroupName}-key`, Object.assign(Object.assign({
visible: !0,
text: null !== (_a = itemAttr.key.text) && void 0 !== _a ? _a : ""
}, itemAttr.key), {
textBaseline: "top"
}), "text") : "rich" === itemAttr.key.text.type ? itemGroup.createOrUpdateChild(`${itemGroupName}-value`, Object.assign(Object.assign({
visible: !0
}, (0, util_2.getRichTextAttribute)(itemAttr.key)), {
textBaseline: "top"
}), "richtext") : itemGroup.createOrUpdateChild(`${itemGroupName}-value`, {
html: Object.assign(Object.assign({
dom: itemAttr.key.text.text
}, constant_1.DEFAULT_HTML_TEXT_SPEC), itemAttr.key)
}, "richtext"), element;
}
}
_createValue(itemAttr, itemGroup, itemGroupName) {
var _a;
if ((0, util_1.isVisible)(itemAttr.value)) {
let element;
return element = itemAttr.value.multiLine ? itemGroup.createOrUpdateChild(`${itemGroupName}-value`, Object.assign(Object.assign({
visible: !0
}, (0, util_2.getRichTextAttribute)(itemAttr.value)), {
textBaseline: "top"
}), "richtext") : "object" != typeof itemAttr.value.text || null === itemAttr.value.text || "rich" !== itemAttr.value.text.type && "html" !== itemAttr.value.text.type ? itemGroup.createOrUpdateChild(`${itemGroupName}-value`, Object.assign(Object.assign({
visible: !0,
text: null !== (_a = itemAttr.value.text) && void 0 !== _a ? _a : ""
}, itemAttr.value), {
textBaseline: "top"
}), "text") : "rich" === itemAttr.value.text.type ? itemGroup.createOrUpdateChild(`${itemGroupName}-value`, Object.assign(Object.assign({
visible: !0
}, (0, util_2.getRichTextAttribute)(itemAttr.value)), {
textBaseline: "top"
}), "richtext") : itemGroup.createOrUpdateChild(`${itemGroupName}-value`, {
html: Object.assign({
dom: itemAttr.value.text.text,
container: "",
width: 30,
height: 30,
style: {}
}, itemAttr.value)
}, "richtext"), element;
}
}
setAttributes(params, forceUpdateTag) {
const keys = Object.keys(params);
this.attribute.autoCalculatePosition && keys.every((key => config_1.TOOLTIP_POSITION_ATTRIBUTES.includes(key))) ? (this._mergeAttributes(params, keys),
(0, vutils_1.isNil)(this.attribute.panel.width) && this.attribute.autoMeasure && Tooltip.measureTooltip(this.attribute),
Tooltip.calculateTooltipPosition(this.attribute), super.setAttributes({
x: this.attribute.x,
y: this.attribute.y
}, forceUpdateTag)) : super.setAttributes(params, forceUpdateTag);
}
static calculateTooltipPosition(attribute) {
const {width: tooltipBoxWidth = 0, height: tooltipBoxHeight = 0} = attribute.panel, {offsetX: offsetX, offsetY: offsetY, pointerX: pointerX, pointerY: pointerY, positionX: positionX, positionY: positionY, parentBounds: parentBounds} = attribute;
let x = pointerX, y = pointerY;
return "left" === positionX ? x -= tooltipBoxWidth + offsetX : "center" === positionX ? x -= tooltipBoxWidth / 2 : x += offsetX,
"top" === positionY ? y -= tooltipBoxHeight + offsetY : "middle" === positionY ? y -= tooltipBoxHeight / 2 : y += offsetY,
x + tooltipBoxWidth > parentBounds.x2 && (x -= tooltipBoxWidth + offsetX), y + tooltipBoxHeight > parentBounds.y2 && (y -= tooltipBoxHeight + offsetY),
x < parentBounds.x1 && (x = parentBounds.x1), y < parentBounds.y1 && (y = parentBounds.y1),
attribute.x = x, attribute.y = y, attribute;
}
static measureTooltip(attribute) {
const {content: content, contentStyle: contentStyle} = attribute, padding = (0,
vutils_1.normalizePadding)(attribute.padding), titleAttr = Tooltip.getTitleAttr(attribute);
let maxWidth = 0, containerHeight = padding[0] + padding[2], titleMaxHeight = 0;
const {value: titleValue, shape: titleShape} = titleAttr, {visible: titleHasShape = !1, symbolType: titleShapeType = ""} = null != titleShape ? titleShape : {};
if ((0, vutils_1.isValid)(titleValue) && "object" != typeof titleAttr.value.text) {
const {width: width, height: height} = (0, text_1.initTextMeasure)(titleValue).quickMeasure(titleValue.text);
maxWidth = width, titleMaxHeight = height;
}
if (titleHasShape && vrender_core_1.builtinSymbolsMap[titleShapeType] && (maxWidth += titleShape.size + titleShape.spacing,
titleMaxHeight = Math.max(titleShape.size, titleMaxHeight)), attribute.title && (attribute.title.width = maxWidth,
attribute.title.height = titleMaxHeight), (0, util_1.isVisible)(titleAttr) && (containerHeight += titleMaxHeight + titleAttr.spaceRow),
content && content.length) {
const filteredContent = [];
if (content.forEach(((item, i) => {
const itemAttr = Tooltip.getContentAttr(attribute, i);
(item.key || item.value) && (0, util_1.isVisible)(itemAttr) && filteredContent.push([ item, itemAttr ]);
})), filteredContent.length) {
let hasContentShape = !1;
const shapeWidths = [], keyWidths = [], valueWidths = [];
filteredContent.forEach((([item, itemAttr], i) => {
var _a;
const {key: key, value: value, shape: shape, spaceRow: spaceRow} = itemAttr, itemHasShape = (0,
util_1.isVisible)(shape), itemShapeType = null !== (_a = null == shape ? void 0 : shape.symbolType) && void 0 !== _a ? _a : "", keyTextMeasure = (0,
text_1.initTextMeasure)(key), valueTextMeasure = (0, text_1.initTextMeasure)(value);
let itemHeight = 0;
if ((0, util_1.isVisible)(key)) {
const {width: width, height: height} = keyTextMeasure.quickMeasure(key.text);
keyWidths.push(width), itemHeight = Math.max(itemHeight, height);
}
if ((0, util_1.isVisible)(value)) {
const {width: width, height: height} = valueTextMeasure.quickMeasure(value.text);
valueWidths.push(width), itemHeight = Math.max(itemHeight, height);
}
itemHasShape && vrender_core_1.builtinSymbolsMap[itemShapeType] && (hasContentShape = !0,
shapeWidths.push(shape.size), itemHeight = Math.max(shape.size, itemHeight)), item.height = itemHeight,
containerHeight += itemHeight, i < filteredContent.length - 1 && (containerHeight += null != spaceRow ? spaceRow : contentStyle.spaceRow);
}));
const maxShapeWidth = shapeWidths.length ? Math.max(...shapeWidths) : 0, maxKeyWidth = keyWidths.length ? Math.max(...keyWidths) : 0, maxValueWidth = valueWidths.length ? Math.max(...valueWidths) : 0;
maxWidth = Math.max(maxKeyWidth + maxValueWidth + contentStyle.key.spacing + contentStyle.value.spacing + (hasContentShape ? maxShapeWidth + contentStyle.shape.spacing : 0), maxWidth),
content.forEach((item => {
item.width = maxWidth;
})), attribute.hasContentShape = hasContentShape, attribute.keyWidth = maxKeyWidth,
attribute.valueWidth = maxValueWidth;
}
}
return attribute.panel.width = maxWidth + padding[1] + padding[3], attribute.panel.height = containerHeight,
attribute;
}
static getTitleAttr(attribute) {
return (0, util_2.mergeRowAttrs)({}, Tooltip.defaultAttributes.titleStyle, Tooltip.defaultAttributes.title, attribute.titleStyle, attribute.title);
}
static getContentAttr(attribute, index) {
return (0, util_2.mergeRowAttrs)({}, Tooltip.defaultAttributes.contentStyle, attribute.contentStyle, attribute.content[index]);
}
}
exports.Tooltip = Tooltip, Tooltip.defaultAttributes = config_1.defaultAttributes;
//# sourceMappingURL=tooltip.js.map