逐步完成前后端服务器
This commit is contained in:
400
frontend/node_modules/echarts/lib/component/tooltip/TooltipHTMLContent.js
generated
vendored
Normal file
400
frontend/node_modules/echarts/lib/component/tooltip/TooltipHTMLContent.js
generated
vendored
Normal file
@ -0,0 +1,400 @@
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { isString, indexOf, each, bind, isFunction, isArray, isDom, retrieve2 } from 'zrender/lib/core/util.js';
|
||||
import { normalizeEvent } from 'zrender/lib/core/event.js';
|
||||
import { transformLocalCoord } from 'zrender/lib/core/dom.js';
|
||||
import env from 'zrender/lib/core/env.js';
|
||||
import { convertToColorString, toCamelCase, normalizeCssArray } from '../../util/format.js';
|
||||
import { shouldTooltipConfine, toCSSVendorPrefix, getComputedStyle, TRANSFORM_VENDOR, TRANSITION_VENDOR } from './helper.js';
|
||||
import { getPaddingFromTooltipModel } from './tooltipMarkup.js';
|
||||
/* global document, window */
|
||||
var CSS_TRANSITION_VENDOR = toCSSVendorPrefix(TRANSITION_VENDOR, 'transition');
|
||||
var CSS_TRANSFORM_VENDOR = toCSSVendorPrefix(TRANSFORM_VENDOR, 'transform');
|
||||
// eslint-disable-next-line
|
||||
var gCssText = "position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;" + (env.transform3dSupported ? 'will-change:transform;' : '');
|
||||
function mirrorPos(pos) {
|
||||
pos = pos === 'left' ? 'right' : pos === 'right' ? 'left' : pos === 'top' ? 'bottom' : 'top';
|
||||
return pos;
|
||||
}
|
||||
function assembleArrow(tooltipModel, borderColor, arrowPosition) {
|
||||
if (!isString(arrowPosition) || arrowPosition === 'inside') {
|
||||
return '';
|
||||
}
|
||||
var backgroundColor = tooltipModel.get('backgroundColor');
|
||||
var borderWidth = tooltipModel.get('borderWidth');
|
||||
borderColor = convertToColorString(borderColor);
|
||||
var arrowPos = mirrorPos(arrowPosition);
|
||||
var arrowSize = Math.max(Math.round(borderWidth) * 1.5, 6);
|
||||
var positionStyle = '';
|
||||
var transformStyle = CSS_TRANSFORM_VENDOR + ':';
|
||||
var rotateDeg;
|
||||
if (indexOf(['left', 'right'], arrowPos) > -1) {
|
||||
positionStyle += 'top:50%';
|
||||
transformStyle += "translateY(-50%) rotate(" + (rotateDeg = arrowPos === 'left' ? -225 : -45) + "deg)";
|
||||
} else {
|
||||
positionStyle += 'left:50%';
|
||||
transformStyle += "translateX(-50%) rotate(" + (rotateDeg = arrowPos === 'top' ? 225 : 45) + "deg)";
|
||||
}
|
||||
var rotateRadian = rotateDeg * Math.PI / 180;
|
||||
var arrowWH = arrowSize + borderWidth;
|
||||
var rotatedWH = arrowWH * Math.abs(Math.cos(rotateRadian)) + arrowWH * Math.abs(Math.sin(rotateRadian));
|
||||
var arrowOffset = Math.round(((rotatedWH - Math.SQRT2 * borderWidth) / 2 + Math.SQRT2 * borderWidth - (rotatedWH - arrowWH) / 2) * 100) / 100;
|
||||
positionStyle += ";" + arrowPos + ":-" + arrowOffset + "px";
|
||||
var borderStyle = borderColor + " solid " + borderWidth + "px;";
|
||||
var styleCss = ["position:absolute;width:" + arrowSize + "px;height:" + arrowSize + "px;z-index:-1;", positionStyle + ";" + transformStyle + ";", "border-bottom:" + borderStyle, "border-right:" + borderStyle, "background-color:" + backgroundColor + ";"];
|
||||
return "<div style=\"" + styleCss.join('') + "\"></div>";
|
||||
}
|
||||
function assembleTransition(duration, onlyFade) {
|
||||
var transitionCurve = 'cubic-bezier(0.23,1,0.32,1)';
|
||||
var transitionOption = " " + duration / 2 + "s " + transitionCurve;
|
||||
var transitionText = "opacity" + transitionOption + ",visibility" + transitionOption;
|
||||
if (!onlyFade) {
|
||||
transitionOption = " " + duration + "s " + transitionCurve;
|
||||
transitionText += env.transformSupported ? "," + CSS_TRANSFORM_VENDOR + transitionOption : ",left" + transitionOption + ",top" + transitionOption;
|
||||
}
|
||||
return CSS_TRANSITION_VENDOR + ':' + transitionText;
|
||||
}
|
||||
function assembleTransform(x, y, toString) {
|
||||
// If using float on style, the final width of the dom might
|
||||
// keep changing slightly while mouse move. So `toFixed(0)` them.
|
||||
var x0 = x.toFixed(0) + 'px';
|
||||
var y0 = y.toFixed(0) + 'px';
|
||||
// not support transform, use `left` and `top` instead.
|
||||
if (!env.transformSupported) {
|
||||
return toString ? "top:" + y0 + ";left:" + x0 + ";" : [['top', y0], ['left', x0]];
|
||||
}
|
||||
// support transform
|
||||
var is3d = env.transform3dSupported;
|
||||
var translate = "translate" + (is3d ? '3d' : '') + "(" + x0 + "," + y0 + (is3d ? ',0' : '') + ")";
|
||||
return toString ? 'top:0;left:0;' + CSS_TRANSFORM_VENDOR + ':' + translate + ';' : [['top', 0], ['left', 0], [TRANSFORM_VENDOR, translate]];
|
||||
}
|
||||
/**
|
||||
* @param {Object} textStyle
|
||||
* @return {string}
|
||||
* @inner
|
||||
*/
|
||||
function assembleFont(textStyleModel) {
|
||||
var cssText = [];
|
||||
var fontSize = textStyleModel.get('fontSize');
|
||||
var color = textStyleModel.getTextColor();
|
||||
color && cssText.push('color:' + color);
|
||||
cssText.push('font:' + textStyleModel.getFont());
|
||||
// @ts-ignore, leave it to the tooltip refactor.
|
||||
var lineHeight = retrieve2(textStyleModel.get('lineHeight'), Math.round(fontSize * 3 / 2));
|
||||
fontSize && cssText.push('line-height:' + lineHeight + 'px');
|
||||
var shadowColor = textStyleModel.get('textShadowColor');
|
||||
var shadowBlur = textStyleModel.get('textShadowBlur') || 0;
|
||||
var shadowOffsetX = textStyleModel.get('textShadowOffsetX') || 0;
|
||||
var shadowOffsetY = textStyleModel.get('textShadowOffsetY') || 0;
|
||||
shadowColor && shadowBlur && cssText.push('text-shadow:' + shadowOffsetX + 'px ' + shadowOffsetY + 'px ' + shadowBlur + 'px ' + shadowColor);
|
||||
each(['decoration', 'align'], function (name) {
|
||||
var val = textStyleModel.get(name);
|
||||
val && cssText.push('text-' + name + ':' + val);
|
||||
});
|
||||
return cssText.join(';');
|
||||
}
|
||||
function assembleCssText(tooltipModel, enableTransition, onlyFade) {
|
||||
var cssText = [];
|
||||
var transitionDuration = tooltipModel.get('transitionDuration');
|
||||
var backgroundColor = tooltipModel.get('backgroundColor');
|
||||
var shadowBlur = tooltipModel.get('shadowBlur');
|
||||
var shadowColor = tooltipModel.get('shadowColor');
|
||||
var shadowOffsetX = tooltipModel.get('shadowOffsetX');
|
||||
var shadowOffsetY = tooltipModel.get('shadowOffsetY');
|
||||
var textStyleModel = tooltipModel.getModel('textStyle');
|
||||
var padding = getPaddingFromTooltipModel(tooltipModel, 'html');
|
||||
var boxShadow = shadowOffsetX + "px " + shadowOffsetY + "px " + shadowBlur + "px " + shadowColor;
|
||||
cssText.push('box-shadow:' + boxShadow);
|
||||
// Animation transition. Do not animate when transitionDuration is 0.
|
||||
enableTransition && transitionDuration && cssText.push(assembleTransition(transitionDuration, onlyFade));
|
||||
if (backgroundColor) {
|
||||
cssText.push('background-color:' + backgroundColor);
|
||||
}
|
||||
// Border style
|
||||
each(['width', 'color', 'radius'], function (name) {
|
||||
var borderName = 'border-' + name;
|
||||
var camelCase = toCamelCase(borderName);
|
||||
var val = tooltipModel.get(camelCase);
|
||||
val != null && cssText.push(borderName + ':' + val + (name === 'color' ? '' : 'px'));
|
||||
});
|
||||
// Text style
|
||||
cssText.push(assembleFont(textStyleModel));
|
||||
// Padding
|
||||
if (padding != null) {
|
||||
cssText.push('padding:' + normalizeCssArray(padding).join('px ') + 'px');
|
||||
}
|
||||
return cssText.join(';') + ';';
|
||||
}
|
||||
// If not able to make, do not modify the input `out`.
|
||||
function makeStyleCoord(out, zr, container, zrX, zrY) {
|
||||
var zrPainter = zr && zr.painter;
|
||||
if (container) {
|
||||
var zrViewportRoot = zrPainter && zrPainter.getViewportRoot();
|
||||
if (zrViewportRoot) {
|
||||
// Some APPs might use scale on body, so we support CSS transform here.
|
||||
transformLocalCoord(out, zrViewportRoot, container, zrX, zrY);
|
||||
}
|
||||
} else {
|
||||
out[0] = zrX;
|
||||
out[1] = zrY;
|
||||
// xy should be based on canvas root. But tooltipContent is
|
||||
// the sibling of canvas root. So padding of ec container
|
||||
// should be considered here.
|
||||
var viewportRootOffset = zrPainter && zrPainter.getViewportRootOffset();
|
||||
if (viewportRootOffset) {
|
||||
out[0] += viewportRootOffset.offsetLeft;
|
||||
out[1] += viewportRootOffset.offsetTop;
|
||||
}
|
||||
}
|
||||
out[2] = out[0] / zr.getWidth();
|
||||
out[3] = out[1] / zr.getHeight();
|
||||
}
|
||||
var TooltipHTMLContent = /** @class */function () {
|
||||
function TooltipHTMLContent(api, opt) {
|
||||
this._show = false;
|
||||
this._styleCoord = [0, 0, 0, 0];
|
||||
this._enterable = true;
|
||||
this._alwaysShowContent = false;
|
||||
this._firstShow = true;
|
||||
this._longHide = true;
|
||||
if (env.wxa) {
|
||||
return null;
|
||||
}
|
||||
var el = document.createElement('div');
|
||||
// TODO: TYPE
|
||||
el.domBelongToZr = true;
|
||||
this.el = el;
|
||||
var zr = this._zr = api.getZr();
|
||||
var appendTo = opt.appendTo;
|
||||
var container = appendTo && (isString(appendTo) ? document.querySelector(appendTo) : isDom(appendTo) ? appendTo : isFunction(appendTo) && appendTo(api.getDom()));
|
||||
makeStyleCoord(this._styleCoord, zr, container, api.getWidth() / 2, api.getHeight() / 2);
|
||||
(container || api.getDom()).appendChild(el);
|
||||
this._api = api;
|
||||
this._container = container;
|
||||
// FIXME
|
||||
// Is it needed to trigger zr event manually if
|
||||
// the browser do not support `pointer-events: none`.
|
||||
var self = this;
|
||||
el.onmouseenter = function () {
|
||||
// clear the timeout in hideLater and keep showing tooltip
|
||||
if (self._enterable) {
|
||||
clearTimeout(self._hideTimeout);
|
||||
self._show = true;
|
||||
}
|
||||
self._inContent = true;
|
||||
};
|
||||
el.onmousemove = function (e) {
|
||||
e = e || window.event;
|
||||
if (!self._enterable) {
|
||||
// `pointer-events: none` is set to tooltip content div
|
||||
// if `enterable` is set as `false`, and `el.onmousemove`
|
||||
// can not be triggered. But in browser that do not
|
||||
// support `pointer-events`, we need to do this:
|
||||
// Try trigger zrender event to avoid mouse
|
||||
// in and out shape too frequently
|
||||
var handler = zr.handler;
|
||||
var zrViewportRoot = zr.painter.getViewportRoot();
|
||||
normalizeEvent(zrViewportRoot, e, true);
|
||||
handler.dispatch('mousemove', e);
|
||||
}
|
||||
};
|
||||
el.onmouseleave = function () {
|
||||
// set `_inContent` to `false` before `hideLater`
|
||||
self._inContent = false;
|
||||
if (self._enterable) {
|
||||
if (self._show) {
|
||||
self.hideLater(self._hideDelay);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Update when tooltip is rendered
|
||||
*/
|
||||
TooltipHTMLContent.prototype.update = function (tooltipModel) {
|
||||
// FIXME
|
||||
// Move this logic to ec main?
|
||||
if (!this._container) {
|
||||
var container = this._api.getDom();
|
||||
var position = getComputedStyle(container, 'position');
|
||||
var domStyle = container.style;
|
||||
if (domStyle.position !== 'absolute' && position !== 'absolute') {
|
||||
domStyle.position = 'relative';
|
||||
}
|
||||
}
|
||||
// move tooltip if chart resized
|
||||
var alwaysShowContent = tooltipModel.get('alwaysShowContent');
|
||||
alwaysShowContent && this._moveIfResized();
|
||||
// update alwaysShowContent
|
||||
this._alwaysShowContent = alwaysShowContent;
|
||||
// update className
|
||||
this.el.className = tooltipModel.get('className') || '';
|
||||
// Hide the tooltip
|
||||
// PENDING
|
||||
// this.hide();
|
||||
};
|
||||
TooltipHTMLContent.prototype.show = function (tooltipModel, nearPointColor) {
|
||||
clearTimeout(this._hideTimeout);
|
||||
clearTimeout(this._longHideTimeout);
|
||||
var el = this.el;
|
||||
var style = el.style;
|
||||
var styleCoord = this._styleCoord;
|
||||
if (!el.innerHTML) {
|
||||
style.display = 'none';
|
||||
} else {
|
||||
style.cssText = gCssText + assembleCssText(tooltipModel, !this._firstShow, this._longHide)
|
||||
// initial transform
|
||||
+ assembleTransform(styleCoord[0], styleCoord[1], true) + ("border-color:" + convertToColorString(nearPointColor) + ";") + (tooltipModel.get('extraCssText') || '')
|
||||
// If mouse occasionally move over the tooltip, a mouseout event will be
|
||||
// triggered by canvas, and cause some unexpectable result like dragging
|
||||
// stop, "unfocusAdjacency". Here `pointer-events: none` is used to solve
|
||||
// it. Although it is not supported by IE8~IE10, fortunately it is a rare
|
||||
// scenario.
|
||||
+ (";pointer-events:" + (this._enterable ? 'auto' : 'none'));
|
||||
}
|
||||
this._show = true;
|
||||
this._firstShow = false;
|
||||
this._longHide = false;
|
||||
};
|
||||
TooltipHTMLContent.prototype.setContent = function (content, markers, tooltipModel, borderColor, arrowPosition) {
|
||||
var el = this.el;
|
||||
if (content == null) {
|
||||
el.innerHTML = '';
|
||||
return;
|
||||
}
|
||||
var arrow = '';
|
||||
if (isString(arrowPosition) && tooltipModel.get('trigger') === 'item' && !shouldTooltipConfine(tooltipModel)) {
|
||||
arrow = assembleArrow(tooltipModel, borderColor, arrowPosition);
|
||||
}
|
||||
if (isString(content)) {
|
||||
el.innerHTML = content + arrow;
|
||||
} else if (content) {
|
||||
// Clear previous
|
||||
el.innerHTML = '';
|
||||
if (!isArray(content)) {
|
||||
content = [content];
|
||||
}
|
||||
for (var i = 0; i < content.length; i++) {
|
||||
if (isDom(content[i]) && content[i].parentNode !== el) {
|
||||
el.appendChild(content[i]);
|
||||
}
|
||||
}
|
||||
// no arrow if empty
|
||||
if (arrow && el.childNodes.length) {
|
||||
// no need to create a new parent element, but it's not supported by IE 10 and older.
|
||||
// const arrowEl = document.createRange().createContextualFragment(arrow);
|
||||
var arrowEl = document.createElement('div');
|
||||
arrowEl.innerHTML = arrow;
|
||||
el.appendChild(arrowEl);
|
||||
}
|
||||
}
|
||||
};
|
||||
TooltipHTMLContent.prototype.setEnterable = function (enterable) {
|
||||
this._enterable = enterable;
|
||||
};
|
||||
TooltipHTMLContent.prototype.getSize = function () {
|
||||
var el = this.el;
|
||||
return el ? [el.offsetWidth, el.offsetHeight] : [0, 0];
|
||||
};
|
||||
TooltipHTMLContent.prototype.moveTo = function (zrX, zrY) {
|
||||
if (!this.el) {
|
||||
return;
|
||||
}
|
||||
var styleCoord = this._styleCoord;
|
||||
makeStyleCoord(styleCoord, this._zr, this._container, zrX, zrY);
|
||||
if (styleCoord[0] != null && styleCoord[1] != null) {
|
||||
var style_1 = this.el.style;
|
||||
var transforms = assembleTransform(styleCoord[0], styleCoord[1]);
|
||||
each(transforms, function (transform) {
|
||||
style_1[transform[0]] = transform[1];
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* when `alwaysShowContent` is true,
|
||||
* move the tooltip after chart resized
|
||||
*/
|
||||
TooltipHTMLContent.prototype._moveIfResized = function () {
|
||||
// The ratio of left to width
|
||||
var ratioX = this._styleCoord[2];
|
||||
// The ratio of top to height
|
||||
var ratioY = this._styleCoord[3];
|
||||
this.moveTo(ratioX * this._zr.getWidth(), ratioY * this._zr.getHeight());
|
||||
};
|
||||
TooltipHTMLContent.prototype.hide = function () {
|
||||
var _this = this;
|
||||
var style = this.el.style;
|
||||
style.visibility = 'hidden';
|
||||
style.opacity = '0';
|
||||
env.transform3dSupported && (style.willChange = '');
|
||||
this._show = false;
|
||||
this._longHideTimeout = setTimeout(function () {
|
||||
return _this._longHide = true;
|
||||
}, 500);
|
||||
};
|
||||
TooltipHTMLContent.prototype.hideLater = function (time) {
|
||||
if (this._show && !(this._inContent && this._enterable) && !this._alwaysShowContent) {
|
||||
if (time) {
|
||||
this._hideDelay = time;
|
||||
// Set show false to avoid invoke hideLater multiple times
|
||||
this._show = false;
|
||||
this._hideTimeout = setTimeout(bind(this.hide, this), time);
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
TooltipHTMLContent.prototype.isShow = function () {
|
||||
return this._show;
|
||||
};
|
||||
TooltipHTMLContent.prototype.dispose = function () {
|
||||
clearTimeout(this._hideTimeout);
|
||||
clearTimeout(this._longHideTimeout);
|
||||
var parentNode = this.el.parentNode;
|
||||
parentNode && parentNode.removeChild(this.el);
|
||||
this.el = this._container = null;
|
||||
};
|
||||
return TooltipHTMLContent;
|
||||
}();
|
||||
export default TooltipHTMLContent;
|
124
frontend/node_modules/echarts/lib/component/tooltip/TooltipModel.js
generated
vendored
Normal file
124
frontend/node_modules/echarts/lib/component/tooltip/TooltipModel.js
generated
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { __extends } from "tslib";
|
||||
import ComponentModel from '../../model/Component.js';
|
||||
var TooltipModel = /** @class */function (_super) {
|
||||
__extends(TooltipModel, _super);
|
||||
function TooltipModel() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.type = TooltipModel.type;
|
||||
return _this;
|
||||
}
|
||||
TooltipModel.type = 'tooltip';
|
||||
TooltipModel.dependencies = ['axisPointer'];
|
||||
TooltipModel.defaultOption = {
|
||||
// zlevel: 0,
|
||||
z: 60,
|
||||
show: true,
|
||||
// tooltip main content
|
||||
showContent: true,
|
||||
// 'trigger' only works on coordinate system.
|
||||
// 'item' | 'axis' | 'none'
|
||||
trigger: 'item',
|
||||
// 'click' | 'mousemove' | 'none'
|
||||
triggerOn: 'mousemove|click',
|
||||
alwaysShowContent: false,
|
||||
displayMode: 'single',
|
||||
renderMode: 'auto',
|
||||
// whether restraint content inside viewRect.
|
||||
// If renderMode: 'richText', default true.
|
||||
// If renderMode: 'html', defaut false (for backward compat).
|
||||
confine: null,
|
||||
showDelay: 0,
|
||||
hideDelay: 100,
|
||||
// Animation transition time, unit is second
|
||||
transitionDuration: 0.4,
|
||||
enterable: false,
|
||||
backgroundColor: '#fff',
|
||||
// box shadow
|
||||
shadowBlur: 10,
|
||||
shadowColor: 'rgba(0, 0, 0, .2)',
|
||||
shadowOffsetX: 1,
|
||||
shadowOffsetY: 2,
|
||||
// tooltip border radius, unit is px, default is 4
|
||||
borderRadius: 4,
|
||||
// tooltip border width, unit is px, default is 0 (no border)
|
||||
borderWidth: 1,
|
||||
// Tooltip inside padding, default is 5 for all direction
|
||||
// Array is allowed to set up, right, bottom, left, same with css
|
||||
// The default value: See `tooltip/tooltipMarkup.ts#getPaddingFromTooltipModel`.
|
||||
padding: null,
|
||||
// Extra css text
|
||||
extraCssText: '',
|
||||
// axis indicator, trigger by axis
|
||||
axisPointer: {
|
||||
// default is line
|
||||
// legal values: 'line' | 'shadow' | 'cross'
|
||||
type: 'line',
|
||||
// Valid when type is line, appoint tooltip line locate on which line. Optional
|
||||
// legal values: 'x' | 'y' | 'angle' | 'radius' | 'auto'
|
||||
// default is 'auto', chose the axis which type is category.
|
||||
// for multiply y axis, cartesian coord chose x axis, polar chose angle axis
|
||||
axis: 'auto',
|
||||
animation: 'auto',
|
||||
animationDurationUpdate: 200,
|
||||
animationEasingUpdate: 'exponentialOut',
|
||||
crossStyle: {
|
||||
color: '#999',
|
||||
width: 1,
|
||||
type: 'dashed',
|
||||
// TODO formatter
|
||||
textStyle: {}
|
||||
}
|
||||
// lineStyle and shadowStyle should not be specified here,
|
||||
// otherwise it will always override those styles on option.axisPointer.
|
||||
},
|
||||
textStyle: {
|
||||
color: '#666',
|
||||
fontSize: 14
|
||||
}
|
||||
};
|
||||
return TooltipModel;
|
||||
}(ComponentModel);
|
||||
export default TooltipModel;
|
209
frontend/node_modules/echarts/lib/component/tooltip/TooltipRichContent.js
generated
vendored
Normal file
209
frontend/node_modules/echarts/lib/component/tooltip/TooltipRichContent.js
generated
vendored
Normal file
@ -0,0 +1,209 @@
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import * as zrUtil from 'zrender/lib/core/util.js';
|
||||
import ZRText from 'zrender/lib/graphic/Text.js';
|
||||
import { getPaddingFromTooltipModel } from './tooltipMarkup.js';
|
||||
import { throwError } from '../../util/log.js';
|
||||
var TooltipRichContent = /** @class */function () {
|
||||
function TooltipRichContent(api) {
|
||||
this._show = false;
|
||||
this._styleCoord = [0, 0, 0, 0];
|
||||
this._alwaysShowContent = false;
|
||||
this._enterable = true;
|
||||
this._zr = api.getZr();
|
||||
makeStyleCoord(this._styleCoord, this._zr, api.getWidth() / 2, api.getHeight() / 2);
|
||||
}
|
||||
/**
|
||||
* Update when tooltip is rendered
|
||||
*/
|
||||
TooltipRichContent.prototype.update = function (tooltipModel) {
|
||||
var alwaysShowContent = tooltipModel.get('alwaysShowContent');
|
||||
alwaysShowContent && this._moveIfResized();
|
||||
// update alwaysShowContent
|
||||
this._alwaysShowContent = alwaysShowContent;
|
||||
};
|
||||
TooltipRichContent.prototype.show = function () {
|
||||
if (this._hideTimeout) {
|
||||
clearTimeout(this._hideTimeout);
|
||||
}
|
||||
this.el.show();
|
||||
this._show = true;
|
||||
};
|
||||
/**
|
||||
* Set tooltip content
|
||||
*/
|
||||
TooltipRichContent.prototype.setContent = function (content, markupStyleCreator, tooltipModel, borderColor, arrowPosition) {
|
||||
var _this = this;
|
||||
if (zrUtil.isObject(content)) {
|
||||
throwError(process.env.NODE_ENV !== 'production' ? 'Passing DOM nodes as content is not supported in richText tooltip!' : '');
|
||||
}
|
||||
if (this.el) {
|
||||
this._zr.remove(this.el);
|
||||
}
|
||||
var textStyleModel = tooltipModel.getModel('textStyle');
|
||||
this.el = new ZRText({
|
||||
style: {
|
||||
rich: markupStyleCreator.richTextStyles,
|
||||
text: content,
|
||||
lineHeight: 22,
|
||||
borderWidth: 1,
|
||||
borderColor: borderColor,
|
||||
textShadowColor: textStyleModel.get('textShadowColor'),
|
||||
fill: tooltipModel.get(['textStyle', 'color']),
|
||||
padding: getPaddingFromTooltipModel(tooltipModel, 'richText'),
|
||||
verticalAlign: 'top',
|
||||
align: 'left'
|
||||
},
|
||||
z: tooltipModel.get('z')
|
||||
});
|
||||
zrUtil.each(['backgroundColor', 'borderRadius', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'], function (propName) {
|
||||
_this.el.style[propName] = tooltipModel.get(propName);
|
||||
});
|
||||
zrUtil.each(['textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY'], function (propName) {
|
||||
_this.el.style[propName] = textStyleModel.get(propName) || 0;
|
||||
});
|
||||
this._zr.add(this.el);
|
||||
var self = this;
|
||||
this.el.on('mouseover', function () {
|
||||
// clear the timeout in hideLater and keep showing tooltip
|
||||
if (self._enterable) {
|
||||
clearTimeout(self._hideTimeout);
|
||||
self._show = true;
|
||||
}
|
||||
self._inContent = true;
|
||||
});
|
||||
this.el.on('mouseout', function () {
|
||||
if (self._enterable) {
|
||||
if (self._show) {
|
||||
self.hideLater(self._hideDelay);
|
||||
}
|
||||
}
|
||||
self._inContent = false;
|
||||
});
|
||||
};
|
||||
TooltipRichContent.prototype.setEnterable = function (enterable) {
|
||||
this._enterable = enterable;
|
||||
};
|
||||
TooltipRichContent.prototype.getSize = function () {
|
||||
var el = this.el;
|
||||
var bounding = this.el.getBoundingRect();
|
||||
// bounding rect does not include shadow. For renderMode richText,
|
||||
// if overflow, it will be cut. So calculate them accurately.
|
||||
var shadowOuterSize = calcShadowOuterSize(el.style);
|
||||
return [bounding.width + shadowOuterSize.left + shadowOuterSize.right, bounding.height + shadowOuterSize.top + shadowOuterSize.bottom];
|
||||
};
|
||||
TooltipRichContent.prototype.moveTo = function (x, y) {
|
||||
var el = this.el;
|
||||
if (el) {
|
||||
var styleCoord = this._styleCoord;
|
||||
makeStyleCoord(styleCoord, this._zr, x, y);
|
||||
x = styleCoord[0];
|
||||
y = styleCoord[1];
|
||||
var style = el.style;
|
||||
var borderWidth = mathMaxWith0(style.borderWidth || 0);
|
||||
var shadowOuterSize = calcShadowOuterSize(style);
|
||||
// rich text x, y do not include border.
|
||||
el.x = x + borderWidth + shadowOuterSize.left;
|
||||
el.y = y + borderWidth + shadowOuterSize.top;
|
||||
el.markRedraw();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* when `alwaysShowContent` is true,
|
||||
* move the tooltip after chart resized
|
||||
*/
|
||||
TooltipRichContent.prototype._moveIfResized = function () {
|
||||
// The ratio of left to width
|
||||
var ratioX = this._styleCoord[2];
|
||||
// The ratio of top to height
|
||||
var ratioY = this._styleCoord[3];
|
||||
this.moveTo(ratioX * this._zr.getWidth(), ratioY * this._zr.getHeight());
|
||||
};
|
||||
TooltipRichContent.prototype.hide = function () {
|
||||
if (this.el) {
|
||||
this.el.hide();
|
||||
}
|
||||
this._show = false;
|
||||
};
|
||||
TooltipRichContent.prototype.hideLater = function (time) {
|
||||
if (this._show && !(this._inContent && this._enterable) && !this._alwaysShowContent) {
|
||||
if (time) {
|
||||
this._hideDelay = time;
|
||||
// Set show false to avoid invoke hideLater multiple times
|
||||
this._show = false;
|
||||
this._hideTimeout = setTimeout(zrUtil.bind(this.hide, this), time);
|
||||
} else {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
};
|
||||
TooltipRichContent.prototype.isShow = function () {
|
||||
return this._show;
|
||||
};
|
||||
TooltipRichContent.prototype.dispose = function () {
|
||||
this._zr.remove(this.el);
|
||||
};
|
||||
return TooltipRichContent;
|
||||
}();
|
||||
function mathMaxWith0(val) {
|
||||
return Math.max(0, val);
|
||||
}
|
||||
function calcShadowOuterSize(style) {
|
||||
var shadowBlur = mathMaxWith0(style.shadowBlur || 0);
|
||||
var shadowOffsetX = mathMaxWith0(style.shadowOffsetX || 0);
|
||||
var shadowOffsetY = mathMaxWith0(style.shadowOffsetY || 0);
|
||||
return {
|
||||
left: mathMaxWith0(shadowBlur - shadowOffsetX),
|
||||
right: mathMaxWith0(shadowBlur + shadowOffsetX),
|
||||
top: mathMaxWith0(shadowBlur - shadowOffsetY),
|
||||
bottom: mathMaxWith0(shadowBlur + shadowOffsetY)
|
||||
};
|
||||
}
|
||||
function makeStyleCoord(out, zr, zrX, zrY) {
|
||||
out[0] = zrX;
|
||||
out[1] = zrY;
|
||||
out[2] = out[0] / zr.getWidth();
|
||||
out[3] = out[1] / zr.getHeight();
|
||||
}
|
||||
export default TooltipRichContent;
|
852
frontend/node_modules/echarts/lib/component/tooltip/TooltipView.js
generated
vendored
Normal file
852
frontend/node_modules/echarts/lib/component/tooltip/TooltipView.js
generated
vendored
Normal file
@ -0,0 +1,852 @@
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*/
|
||||
|
||||
import { __extends } from "tslib";
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { bind, each, clone, trim, isString, isFunction, isArray, isObject, extend } from 'zrender/lib/core/util.js';
|
||||
import env from 'zrender/lib/core/env.js';
|
||||
import TooltipHTMLContent from './TooltipHTMLContent.js';
|
||||
import TooltipRichContent from './TooltipRichContent.js';
|
||||
import { convertToColorString, encodeHTML, formatTpl } from '../../util/format.js';
|
||||
import { parsePercent } from '../../util/number.js';
|
||||
import { Rect } from '../../util/graphic.js';
|
||||
import findPointFromSeries from '../axisPointer/findPointFromSeries.js';
|
||||
import { getLayoutRect } from '../../util/layout.js';
|
||||
import Model from '../../model/Model.js';
|
||||
import * as globalListener from '../axisPointer/globalListener.js';
|
||||
import * as axisHelper from '../../coord/axisHelper.js';
|
||||
import * as axisPointerViewHelper from '../axisPointer/viewHelper.js';
|
||||
import { getTooltipRenderMode, preParseFinder, queryReferringComponents } from '../../util/model.js';
|
||||
import ComponentView from '../../view/Component.js';
|
||||
import { format as timeFormat } from '../../util/time.js';
|
||||
import { getECData } from '../../util/innerStore.js';
|
||||
import { shouldTooltipConfine } from './helper.js';
|
||||
import { normalizeTooltipFormatResult } from '../../model/mixin/dataFormat.js';
|
||||
import { createTooltipMarkup, buildTooltipMarkup, TooltipMarkupStyleCreator } from './tooltipMarkup.js';
|
||||
import { findEventDispatcher } from '../../util/event.js';
|
||||
import { clear, createOrUpdate } from '../../util/throttle.js';
|
||||
var proxyRect = new Rect({
|
||||
shape: {
|
||||
x: -1,
|
||||
y: -1,
|
||||
width: 2,
|
||||
height: 2
|
||||
}
|
||||
});
|
||||
var TooltipView = /** @class */function (_super) {
|
||||
__extends(TooltipView, _super);
|
||||
function TooltipView() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.type = TooltipView.type;
|
||||
return _this;
|
||||
}
|
||||
TooltipView.prototype.init = function (ecModel, api) {
|
||||
if (env.node || !api.getDom()) {
|
||||
return;
|
||||
}
|
||||
var tooltipModel = ecModel.getComponent('tooltip');
|
||||
var renderMode = this._renderMode = getTooltipRenderMode(tooltipModel.get('renderMode'));
|
||||
this._tooltipContent = renderMode === 'richText' ? new TooltipRichContent(api) : new TooltipHTMLContent(api, {
|
||||
appendTo: tooltipModel.get('appendToBody', true) ? 'body' : tooltipModel.get('appendTo', true)
|
||||
});
|
||||
};
|
||||
TooltipView.prototype.render = function (tooltipModel, ecModel, api) {
|
||||
if (env.node || !api.getDom()) {
|
||||
return;
|
||||
}
|
||||
// Reset
|
||||
this.group.removeAll();
|
||||
this._tooltipModel = tooltipModel;
|
||||
this._ecModel = ecModel;
|
||||
this._api = api;
|
||||
var tooltipContent = this._tooltipContent;
|
||||
tooltipContent.update(tooltipModel);
|
||||
tooltipContent.setEnterable(tooltipModel.get('enterable'));
|
||||
this._initGlobalListener();
|
||||
this._keepShow();
|
||||
// PENDING
|
||||
// `mousemove` event will be triggered very frequently when the mouse moves fast,
|
||||
// which causes that the `updatePosition` function was also called frequently.
|
||||
// In Chrome with devtools open and Firefox, tooltip looks laggy and shakes. See #14695 #16101
|
||||
// To avoid frequent triggering,
|
||||
// consider throttling it in 50ms when transition is enabled
|
||||
if (this._renderMode !== 'richText' && tooltipModel.get('transitionDuration')) {
|
||||
createOrUpdate(this, '_updatePosition', 50, 'fixRate');
|
||||
} else {
|
||||
clear(this, '_updatePosition');
|
||||
}
|
||||
};
|
||||
TooltipView.prototype._initGlobalListener = function () {
|
||||
var tooltipModel = this._tooltipModel;
|
||||
var triggerOn = tooltipModel.get('triggerOn');
|
||||
globalListener.register('itemTooltip', this._api, bind(function (currTrigger, e, dispatchAction) {
|
||||
// If 'none', it is not controlled by mouse totally.
|
||||
if (triggerOn !== 'none') {
|
||||
if (triggerOn.indexOf(currTrigger) >= 0) {
|
||||
this._tryShow(e, dispatchAction);
|
||||
} else if (currTrigger === 'leave') {
|
||||
this._hide(dispatchAction);
|
||||
}
|
||||
}
|
||||
}, this));
|
||||
};
|
||||
TooltipView.prototype._keepShow = function () {
|
||||
var tooltipModel = this._tooltipModel;
|
||||
var ecModel = this._ecModel;
|
||||
var api = this._api;
|
||||
var triggerOn = tooltipModel.get('triggerOn');
|
||||
// Try to keep the tooltip show when refreshing
|
||||
if (this._lastX != null && this._lastY != null
|
||||
// When user is willing to control tooltip totally using API,
|
||||
// self.manuallyShowTip({x, y}) might cause tooltip hide,
|
||||
// which is not expected.
|
||||
&& triggerOn !== 'none' && triggerOn !== 'click') {
|
||||
var self_1 = this;
|
||||
clearTimeout(this._refreshUpdateTimeout);
|
||||
this._refreshUpdateTimeout = setTimeout(function () {
|
||||
// Show tip next tick after other charts are rendered
|
||||
// In case highlight action has wrong result
|
||||
// FIXME
|
||||
!api.isDisposed() && self_1.manuallyShowTip(tooltipModel, ecModel, api, {
|
||||
x: self_1._lastX,
|
||||
y: self_1._lastY,
|
||||
dataByCoordSys: self_1._lastDataByCoordSys
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Show tip manually by
|
||||
* dispatchAction({
|
||||
* type: 'showTip',
|
||||
* x: 10,
|
||||
* y: 10
|
||||
* });
|
||||
* Or
|
||||
* dispatchAction({
|
||||
* type: 'showTip',
|
||||
* seriesIndex: 0,
|
||||
* dataIndex or dataIndexInside or name
|
||||
* });
|
||||
*
|
||||
* TODO Batch
|
||||
*/
|
||||
TooltipView.prototype.manuallyShowTip = function (tooltipModel, ecModel, api, payload) {
|
||||
if (payload.from === this.uid || env.node || !api.getDom()) {
|
||||
return;
|
||||
}
|
||||
var dispatchAction = makeDispatchAction(payload, api);
|
||||
// Reset ticket
|
||||
this._ticket = '';
|
||||
// When triggered from axisPointer.
|
||||
var dataByCoordSys = payload.dataByCoordSys;
|
||||
var cmptRef = findComponentReference(payload, ecModel, api);
|
||||
if (cmptRef) {
|
||||
var rect = cmptRef.el.getBoundingRect().clone();
|
||||
rect.applyTransform(cmptRef.el.transform);
|
||||
this._tryShow({
|
||||
offsetX: rect.x + rect.width / 2,
|
||||
offsetY: rect.y + rect.height / 2,
|
||||
target: cmptRef.el,
|
||||
position: payload.position,
|
||||
// When manully trigger, the mouse is not on the el, so we'd better to
|
||||
// position tooltip on the bottom of the el and display arrow is possible.
|
||||
positionDefault: 'bottom'
|
||||
}, dispatchAction);
|
||||
} else if (payload.tooltip && payload.x != null && payload.y != null) {
|
||||
var el = proxyRect;
|
||||
el.x = payload.x;
|
||||
el.y = payload.y;
|
||||
el.update();
|
||||
getECData(el).tooltipConfig = {
|
||||
name: null,
|
||||
option: payload.tooltip
|
||||
};
|
||||
// Manually show tooltip while view is not using zrender elements.
|
||||
this._tryShow({
|
||||
offsetX: payload.x,
|
||||
offsetY: payload.y,
|
||||
target: el
|
||||
}, dispatchAction);
|
||||
} else if (dataByCoordSys) {
|
||||
this._tryShow({
|
||||
offsetX: payload.x,
|
||||
offsetY: payload.y,
|
||||
position: payload.position,
|
||||
dataByCoordSys: dataByCoordSys,
|
||||
tooltipOption: payload.tooltipOption
|
||||
}, dispatchAction);
|
||||
} else if (payload.seriesIndex != null) {
|
||||
if (this._manuallyAxisShowTip(tooltipModel, ecModel, api, payload)) {
|
||||
return;
|
||||
}
|
||||
var pointInfo = findPointFromSeries(payload, ecModel);
|
||||
var cx = pointInfo.point[0];
|
||||
var cy = pointInfo.point[1];
|
||||
if (cx != null && cy != null) {
|
||||
this._tryShow({
|
||||
offsetX: cx,
|
||||
offsetY: cy,
|
||||
target: pointInfo.el,
|
||||
position: payload.position,
|
||||
// When manully trigger, the mouse is not on the el, so we'd better to
|
||||
// position tooltip on the bottom of the el and display arrow is possible.
|
||||
positionDefault: 'bottom'
|
||||
}, dispatchAction);
|
||||
}
|
||||
} else if (payload.x != null && payload.y != null) {
|
||||
// FIXME
|
||||
// should wrap dispatchAction like `axisPointer/globalListener` ?
|
||||
api.dispatchAction({
|
||||
type: 'updateAxisPointer',
|
||||
x: payload.x,
|
||||
y: payload.y
|
||||
});
|
||||
this._tryShow({
|
||||
offsetX: payload.x,
|
||||
offsetY: payload.y,
|
||||
position: payload.position,
|
||||
target: api.getZr().findHover(payload.x, payload.y).target
|
||||
}, dispatchAction);
|
||||
}
|
||||
};
|
||||
TooltipView.prototype.manuallyHideTip = function (tooltipModel, ecModel, api, payload) {
|
||||
var tooltipContent = this._tooltipContent;
|
||||
if (this._tooltipModel) {
|
||||
tooltipContent.hideLater(this._tooltipModel.get('hideDelay'));
|
||||
}
|
||||
this._lastX = this._lastY = this._lastDataByCoordSys = null;
|
||||
if (payload.from !== this.uid) {
|
||||
this._hide(makeDispatchAction(payload, api));
|
||||
}
|
||||
};
|
||||
// Be compatible with previous design, that is, when tooltip.type is 'axis' and
|
||||
// dispatchAction 'showTip' with seriesIndex and dataIndex will trigger axis pointer
|
||||
// and tooltip.
|
||||
TooltipView.prototype._manuallyAxisShowTip = function (tooltipModel, ecModel, api, payload) {
|
||||
var seriesIndex = payload.seriesIndex;
|
||||
var dataIndex = payload.dataIndex;
|
||||
// @ts-ignore
|
||||
var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo;
|
||||
if (seriesIndex == null || dataIndex == null || coordSysAxesInfo == null) {
|
||||
return;
|
||||
}
|
||||
var seriesModel = ecModel.getSeriesByIndex(seriesIndex);
|
||||
if (!seriesModel) {
|
||||
return;
|
||||
}
|
||||
var data = seriesModel.getData();
|
||||
var tooltipCascadedModel = buildTooltipModel([data.getItemModel(dataIndex), seriesModel, (seriesModel.coordinateSystem || {}).model], this._tooltipModel);
|
||||
if (tooltipCascadedModel.get('trigger') !== 'axis') {
|
||||
return;
|
||||
}
|
||||
api.dispatchAction({
|
||||
type: 'updateAxisPointer',
|
||||
seriesIndex: seriesIndex,
|
||||
dataIndex: dataIndex,
|
||||
position: payload.position
|
||||
});
|
||||
return true;
|
||||
};
|
||||
TooltipView.prototype._tryShow = function (e, dispatchAction) {
|
||||
var el = e.target;
|
||||
var tooltipModel = this._tooltipModel;
|
||||
if (!tooltipModel) {
|
||||
return;
|
||||
}
|
||||
// Save mouse x, mouse y. So we can try to keep showing the tip if chart is refreshed
|
||||
this._lastX = e.offsetX;
|
||||
this._lastY = e.offsetY;
|
||||
var dataByCoordSys = e.dataByCoordSys;
|
||||
if (dataByCoordSys && dataByCoordSys.length) {
|
||||
this._showAxisTooltip(dataByCoordSys, e);
|
||||
} else if (el) {
|
||||
var ecData = getECData(el);
|
||||
if (ecData.ssrType === 'legend') {
|
||||
// Don't trigger tooltip for legend tooltip item
|
||||
return;
|
||||
}
|
||||
this._lastDataByCoordSys = null;
|
||||
var seriesDispatcher_1;
|
||||
var cmptDispatcher_1;
|
||||
findEventDispatcher(el, function (target) {
|
||||
// Always show item tooltip if mouse is on the element with dataIndex
|
||||
if (getECData(target).dataIndex != null) {
|
||||
seriesDispatcher_1 = target;
|
||||
return true;
|
||||
}
|
||||
// Tooltip provided directly. Like legend.
|
||||
if (getECData(target).tooltipConfig != null) {
|
||||
cmptDispatcher_1 = target;
|
||||
return true;
|
||||
}
|
||||
}, true);
|
||||
if (seriesDispatcher_1) {
|
||||
this._showSeriesItemTooltip(e, seriesDispatcher_1, dispatchAction);
|
||||
} else if (cmptDispatcher_1) {
|
||||
this._showComponentItemTooltip(e, cmptDispatcher_1, dispatchAction);
|
||||
} else {
|
||||
this._hide(dispatchAction);
|
||||
}
|
||||
} else {
|
||||
this._lastDataByCoordSys = null;
|
||||
this._hide(dispatchAction);
|
||||
}
|
||||
};
|
||||
TooltipView.prototype._showOrMove = function (tooltipModel, cb) {
|
||||
// showDelay is used in this case: tooltip.enterable is set
|
||||
// as true. User intent to move mouse into tooltip and click
|
||||
// something. `showDelay` makes it easier to enter the content
|
||||
// but tooltip do not move immediately.
|
||||
var delay = tooltipModel.get('showDelay');
|
||||
cb = bind(cb, this);
|
||||
clearTimeout(this._showTimout);
|
||||
delay > 0 ? this._showTimout = setTimeout(cb, delay) : cb();
|
||||
};
|
||||
TooltipView.prototype._showAxisTooltip = function (dataByCoordSys, e) {
|
||||
var ecModel = this._ecModel;
|
||||
var globalTooltipModel = this._tooltipModel;
|
||||
var point = [e.offsetX, e.offsetY];
|
||||
var singleTooltipModel = buildTooltipModel([e.tooltipOption], globalTooltipModel);
|
||||
var renderMode = this._renderMode;
|
||||
var cbParamsList = [];
|
||||
var articleMarkup = createTooltipMarkup('section', {
|
||||
blocks: [],
|
||||
noHeader: true
|
||||
});
|
||||
// Only for legacy: `Serise['formatTooltip']` returns a string.
|
||||
var markupTextArrLegacy = [];
|
||||
var markupStyleCreator = new TooltipMarkupStyleCreator();
|
||||
each(dataByCoordSys, function (itemCoordSys) {
|
||||
each(itemCoordSys.dataByAxis, function (axisItem) {
|
||||
var axisModel = ecModel.getComponent(axisItem.axisDim + 'Axis', axisItem.axisIndex);
|
||||
var axisValue = axisItem.value;
|
||||
if (!axisModel || axisValue == null) {
|
||||
return;
|
||||
}
|
||||
var axisValueLabel = axisPointerViewHelper.getValueLabel(axisValue, axisModel.axis, ecModel, axisItem.seriesDataIndices, axisItem.valueLabelOpt);
|
||||
var axisSectionMarkup = createTooltipMarkup('section', {
|
||||
header: axisValueLabel,
|
||||
noHeader: !trim(axisValueLabel),
|
||||
sortBlocks: true,
|
||||
blocks: []
|
||||
});
|
||||
articleMarkup.blocks.push(axisSectionMarkup);
|
||||
each(axisItem.seriesDataIndices, function (idxItem) {
|
||||
var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
|
||||
var dataIndex = idxItem.dataIndexInside;
|
||||
var cbParams = series.getDataParams(dataIndex);
|
||||
// Can't find data.
|
||||
if (cbParams.dataIndex < 0) {
|
||||
return;
|
||||
}
|
||||
cbParams.axisDim = axisItem.axisDim;
|
||||
cbParams.axisIndex = axisItem.axisIndex;
|
||||
cbParams.axisType = axisItem.axisType;
|
||||
cbParams.axisId = axisItem.axisId;
|
||||
cbParams.axisValue = axisHelper.getAxisRawValue(axisModel.axis, {
|
||||
value: axisValue
|
||||
});
|
||||
cbParams.axisValueLabel = axisValueLabel;
|
||||
// Pre-create marker style for makers. Users can assemble richText
|
||||
// text in `formatter` callback and use those markers style.
|
||||
cbParams.marker = markupStyleCreator.makeTooltipMarker('item', convertToColorString(cbParams.color), renderMode);
|
||||
var seriesTooltipResult = normalizeTooltipFormatResult(series.formatTooltip(dataIndex, true, null));
|
||||
var frag = seriesTooltipResult.frag;
|
||||
if (frag) {
|
||||
var valueFormatter = buildTooltipModel([series], globalTooltipModel).get('valueFormatter');
|
||||
axisSectionMarkup.blocks.push(valueFormatter ? extend({
|
||||
valueFormatter: valueFormatter
|
||||
}, frag) : frag);
|
||||
}
|
||||
if (seriesTooltipResult.text) {
|
||||
markupTextArrLegacy.push(seriesTooltipResult.text);
|
||||
}
|
||||
cbParamsList.push(cbParams);
|
||||
});
|
||||
});
|
||||
});
|
||||
// In most cases, the second axis is displays upper on the first one.
|
||||
// So we reverse it to look better.
|
||||
articleMarkup.blocks.reverse();
|
||||
markupTextArrLegacy.reverse();
|
||||
var positionExpr = e.position;
|
||||
var orderMode = singleTooltipModel.get('order');
|
||||
var builtMarkupText = buildTooltipMarkup(articleMarkup, markupStyleCreator, renderMode, orderMode, ecModel.get('useUTC'), singleTooltipModel.get('textStyle'));
|
||||
builtMarkupText && markupTextArrLegacy.unshift(builtMarkupText);
|
||||
var blockBreak = renderMode === 'richText' ? '\n\n' : '<br/>';
|
||||
var allMarkupText = markupTextArrLegacy.join(blockBreak);
|
||||
this._showOrMove(singleTooltipModel, function () {
|
||||
if (this._updateContentNotChangedOnAxis(dataByCoordSys, cbParamsList)) {
|
||||
this._updatePosition(singleTooltipModel, positionExpr, point[0], point[1], this._tooltipContent, cbParamsList);
|
||||
} else {
|
||||
this._showTooltipContent(singleTooltipModel, allMarkupText, cbParamsList, Math.random() + '', point[0], point[1], positionExpr, null, markupStyleCreator);
|
||||
}
|
||||
});
|
||||
// Do not trigger events here, because this branch only be entered
|
||||
// from dispatchAction.
|
||||
};
|
||||
TooltipView.prototype._showSeriesItemTooltip = function (e, dispatcher, dispatchAction) {
|
||||
var ecModel = this._ecModel;
|
||||
var ecData = getECData(dispatcher);
|
||||
// Use dataModel in element if possible
|
||||
// Used when mouseover on a element like markPoint or edge
|
||||
// In which case, the data is not main data in series.
|
||||
var seriesIndex = ecData.seriesIndex;
|
||||
var seriesModel = ecModel.getSeriesByIndex(seriesIndex);
|
||||
// For example, graph link.
|
||||
var dataModel = ecData.dataModel || seriesModel;
|
||||
var dataIndex = ecData.dataIndex;
|
||||
var dataType = ecData.dataType;
|
||||
var data = dataModel.getData(dataType);
|
||||
var renderMode = this._renderMode;
|
||||
var positionDefault = e.positionDefault;
|
||||
var tooltipModel = buildTooltipModel([data.getItemModel(dataIndex), dataModel, seriesModel && (seriesModel.coordinateSystem || {}).model], this._tooltipModel, positionDefault ? {
|
||||
position: positionDefault
|
||||
} : null);
|
||||
var tooltipTrigger = tooltipModel.get('trigger');
|
||||
if (tooltipTrigger != null && tooltipTrigger !== 'item') {
|
||||
return;
|
||||
}
|
||||
var params = dataModel.getDataParams(dataIndex, dataType);
|
||||
var markupStyleCreator = new TooltipMarkupStyleCreator();
|
||||
// Pre-create marker style for makers. Users can assemble richText
|
||||
// text in `formatter` callback and use those markers style.
|
||||
params.marker = markupStyleCreator.makeTooltipMarker('item', convertToColorString(params.color), renderMode);
|
||||
var seriesTooltipResult = normalizeTooltipFormatResult(dataModel.formatTooltip(dataIndex, false, dataType));
|
||||
var orderMode = tooltipModel.get('order');
|
||||
var valueFormatter = tooltipModel.get('valueFormatter');
|
||||
var frag = seriesTooltipResult.frag;
|
||||
var markupText = frag ? buildTooltipMarkup(valueFormatter ? extend({
|
||||
valueFormatter: valueFormatter
|
||||
}, frag) : frag, markupStyleCreator, renderMode, orderMode, ecModel.get('useUTC'), tooltipModel.get('textStyle')) : seriesTooltipResult.text;
|
||||
var asyncTicket = 'item_' + dataModel.name + '_' + dataIndex;
|
||||
this._showOrMove(tooltipModel, function () {
|
||||
this._showTooltipContent(tooltipModel, markupText, params, asyncTicket, e.offsetX, e.offsetY, e.position, e.target, markupStyleCreator);
|
||||
});
|
||||
// FIXME
|
||||
// duplicated showtip if manuallyShowTip is called from dispatchAction.
|
||||
dispatchAction({
|
||||
type: 'showTip',
|
||||
dataIndexInside: dataIndex,
|
||||
dataIndex: data.getRawIndex(dataIndex),
|
||||
seriesIndex: seriesIndex,
|
||||
from: this.uid
|
||||
});
|
||||
};
|
||||
TooltipView.prototype._showComponentItemTooltip = function (e, el, dispatchAction) {
|
||||
var isHTMLRenderMode = this._renderMode === 'html';
|
||||
var ecData = getECData(el);
|
||||
var tooltipConfig = ecData.tooltipConfig;
|
||||
var tooltipOpt = tooltipConfig.option || {};
|
||||
var encodeHTMLContent = tooltipOpt.encodeHTMLContent;
|
||||
if (isString(tooltipOpt)) {
|
||||
var content = tooltipOpt;
|
||||
tooltipOpt = {
|
||||
content: content,
|
||||
// Fixed formatter
|
||||
formatter: content
|
||||
};
|
||||
// when `tooltipConfig.option` is a string rather than an object,
|
||||
// we can't know if the content needs to be encoded
|
||||
// for the sake of security, encode it by default.
|
||||
encodeHTMLContent = true;
|
||||
}
|
||||
if (encodeHTMLContent && isHTMLRenderMode && tooltipOpt.content) {
|
||||
// clone might be unnecessary?
|
||||
tooltipOpt = clone(tooltipOpt);
|
||||
tooltipOpt.content = encodeHTML(tooltipOpt.content);
|
||||
}
|
||||
var tooltipModelCascade = [tooltipOpt];
|
||||
var cmpt = this._ecModel.getComponent(ecData.componentMainType, ecData.componentIndex);
|
||||
if (cmpt) {
|
||||
tooltipModelCascade.push(cmpt);
|
||||
}
|
||||
// In most cases, component tooltip formatter has different params with series tooltip formatter,
|
||||
// so that they cannot share the same formatter. Since the global tooltip formatter is used for series
|
||||
// by convention, we do not use it as the default formatter for component.
|
||||
tooltipModelCascade.push({
|
||||
formatter: tooltipOpt.content
|
||||
});
|
||||
var positionDefault = e.positionDefault;
|
||||
var subTooltipModel = buildTooltipModel(tooltipModelCascade, this._tooltipModel, positionDefault ? {
|
||||
position: positionDefault
|
||||
} : null);
|
||||
var defaultHtml = subTooltipModel.get('content');
|
||||
var asyncTicket = Math.random() + '';
|
||||
// PENDING: this case do not support richText style yet.
|
||||
var markupStyleCreator = new TooltipMarkupStyleCreator();
|
||||
// Do not check whether `trigger` is 'none' here, because `trigger`
|
||||
// only works on coordinate system. In fact, we have not found case
|
||||
// that requires setting `trigger` nothing on component yet.
|
||||
this._showOrMove(subTooltipModel, function () {
|
||||
// Use formatterParams from element defined in component
|
||||
// Avoid users modify it.
|
||||
var formatterParams = clone(subTooltipModel.get('formatterParams') || {});
|
||||
this._showTooltipContent(subTooltipModel, defaultHtml, formatterParams, asyncTicket, e.offsetX, e.offsetY, e.position, el, markupStyleCreator);
|
||||
});
|
||||
// If not dispatch showTip, tip may be hide triggered by axis.
|
||||
dispatchAction({
|
||||
type: 'showTip',
|
||||
from: this.uid
|
||||
});
|
||||
};
|
||||
TooltipView.prototype._showTooltipContent = function (
|
||||
// Use Model<TooltipOption> insteadof TooltipModel because this model may be from series or other options.
|
||||
// Instead of top level tooltip.
|
||||
tooltipModel, defaultHtml, params, asyncTicket, x, y, positionExpr, el, markupStyleCreator) {
|
||||
// Reset ticket
|
||||
this._ticket = '';
|
||||
if (!tooltipModel.get('showContent') || !tooltipModel.get('show')) {
|
||||
return;
|
||||
}
|
||||
var tooltipContent = this._tooltipContent;
|
||||
tooltipContent.setEnterable(tooltipModel.get('enterable'));
|
||||
var formatter = tooltipModel.get('formatter');
|
||||
positionExpr = positionExpr || tooltipModel.get('position');
|
||||
var html = defaultHtml;
|
||||
var nearPoint = this._getNearestPoint([x, y], params, tooltipModel.get('trigger'), tooltipModel.get('borderColor'));
|
||||
var nearPointColor = nearPoint.color;
|
||||
if (formatter) {
|
||||
if (isString(formatter)) {
|
||||
var useUTC = tooltipModel.ecModel.get('useUTC');
|
||||
var params0 = isArray(params) ? params[0] : params;
|
||||
var isTimeAxis = params0 && params0.axisType && params0.axisType.indexOf('time') >= 0;
|
||||
html = formatter;
|
||||
if (isTimeAxis) {
|
||||
html = timeFormat(params0.axisValue, html, useUTC);
|
||||
}
|
||||
html = formatTpl(html, params, true);
|
||||
} else if (isFunction(formatter)) {
|
||||
var callback = bind(function (cbTicket, html) {
|
||||
if (cbTicket === this._ticket) {
|
||||
tooltipContent.setContent(html, markupStyleCreator, tooltipModel, nearPointColor, positionExpr);
|
||||
this._updatePosition(tooltipModel, positionExpr, x, y, tooltipContent, params, el);
|
||||
}
|
||||
}, this);
|
||||
this._ticket = asyncTicket;
|
||||
html = formatter(params, asyncTicket, callback);
|
||||
} else {
|
||||
html = formatter;
|
||||
}
|
||||
}
|
||||
tooltipContent.setContent(html, markupStyleCreator, tooltipModel, nearPointColor, positionExpr);
|
||||
tooltipContent.show(tooltipModel, nearPointColor);
|
||||
this._updatePosition(tooltipModel, positionExpr, x, y, tooltipContent, params, el);
|
||||
};
|
||||
TooltipView.prototype._getNearestPoint = function (point, tooltipDataParams, trigger, borderColor) {
|
||||
if (trigger === 'axis' || isArray(tooltipDataParams)) {
|
||||
return {
|
||||
color: borderColor || (this._renderMode === 'html' ? '#fff' : 'none')
|
||||
};
|
||||
}
|
||||
if (!isArray(tooltipDataParams)) {
|
||||
return {
|
||||
color: borderColor || tooltipDataParams.color || tooltipDataParams.borderColor
|
||||
};
|
||||
}
|
||||
};
|
||||
TooltipView.prototype._updatePosition = function (tooltipModel, positionExpr, x,
|
||||
// Mouse x
|
||||
y,
|
||||
// Mouse y
|
||||
content, params, el) {
|
||||
var viewWidth = this._api.getWidth();
|
||||
var viewHeight = this._api.getHeight();
|
||||
positionExpr = positionExpr || tooltipModel.get('position');
|
||||
var contentSize = content.getSize();
|
||||
var align = tooltipModel.get('align');
|
||||
var vAlign = tooltipModel.get('verticalAlign');
|
||||
var rect = el && el.getBoundingRect().clone();
|
||||
el && rect.applyTransform(el.transform);
|
||||
if (isFunction(positionExpr)) {
|
||||
// Callback of position can be an array or a string specify the position
|
||||
positionExpr = positionExpr([x, y], params, content.el, rect, {
|
||||
viewSize: [viewWidth, viewHeight],
|
||||
contentSize: contentSize.slice()
|
||||
});
|
||||
}
|
||||
if (isArray(positionExpr)) {
|
||||
x = parsePercent(positionExpr[0], viewWidth);
|
||||
y = parsePercent(positionExpr[1], viewHeight);
|
||||
} else if (isObject(positionExpr)) {
|
||||
var boxLayoutPosition = positionExpr;
|
||||
boxLayoutPosition.width = contentSize[0];
|
||||
boxLayoutPosition.height = contentSize[1];
|
||||
var layoutRect = getLayoutRect(boxLayoutPosition, {
|
||||
width: viewWidth,
|
||||
height: viewHeight
|
||||
});
|
||||
x = layoutRect.x;
|
||||
y = layoutRect.y;
|
||||
align = null;
|
||||
// When positionExpr is left/top/right/bottom,
|
||||
// align and verticalAlign will not work.
|
||||
vAlign = null;
|
||||
}
|
||||
// Specify tooltip position by string 'top' 'bottom' 'left' 'right' around graphic element
|
||||
else if (isString(positionExpr) && el) {
|
||||
var pos = calcTooltipPosition(positionExpr, rect, contentSize, tooltipModel.get('borderWidth'));
|
||||
x = pos[0];
|
||||
y = pos[1];
|
||||
} else {
|
||||
var pos = refixTooltipPosition(x, y, content, viewWidth, viewHeight, align ? null : 20, vAlign ? null : 20);
|
||||
x = pos[0];
|
||||
y = pos[1];
|
||||
}
|
||||
align && (x -= isCenterAlign(align) ? contentSize[0] / 2 : align === 'right' ? contentSize[0] : 0);
|
||||
vAlign && (y -= isCenterAlign(vAlign) ? contentSize[1] / 2 : vAlign === 'bottom' ? contentSize[1] : 0);
|
||||
if (shouldTooltipConfine(tooltipModel)) {
|
||||
var pos = confineTooltipPosition(x, y, content, viewWidth, viewHeight);
|
||||
x = pos[0];
|
||||
y = pos[1];
|
||||
}
|
||||
content.moveTo(x, y);
|
||||
};
|
||||
// FIXME
|
||||
// Should we remove this but leave this to user?
|
||||
TooltipView.prototype._updateContentNotChangedOnAxis = function (dataByCoordSys, cbParamsList) {
|
||||
var lastCoordSys = this._lastDataByCoordSys;
|
||||
var lastCbParamsList = this._cbParamsList;
|
||||
var contentNotChanged = !!lastCoordSys && lastCoordSys.length === dataByCoordSys.length;
|
||||
contentNotChanged && each(lastCoordSys, function (lastItemCoordSys, indexCoordSys) {
|
||||
var lastDataByAxis = lastItemCoordSys.dataByAxis || [];
|
||||
var thisItemCoordSys = dataByCoordSys[indexCoordSys] || {};
|
||||
var thisDataByAxis = thisItemCoordSys.dataByAxis || [];
|
||||
contentNotChanged = contentNotChanged && lastDataByAxis.length === thisDataByAxis.length;
|
||||
contentNotChanged && each(lastDataByAxis, function (lastItem, indexAxis) {
|
||||
var thisItem = thisDataByAxis[indexAxis] || {};
|
||||
var lastIndices = lastItem.seriesDataIndices || [];
|
||||
var newIndices = thisItem.seriesDataIndices || [];
|
||||
contentNotChanged = contentNotChanged && lastItem.value === thisItem.value && lastItem.axisType === thisItem.axisType && lastItem.axisId === thisItem.axisId && lastIndices.length === newIndices.length;
|
||||
contentNotChanged && each(lastIndices, function (lastIdxItem, j) {
|
||||
var newIdxItem = newIndices[j];
|
||||
contentNotChanged = contentNotChanged && lastIdxItem.seriesIndex === newIdxItem.seriesIndex && lastIdxItem.dataIndex === newIdxItem.dataIndex;
|
||||
});
|
||||
// check is cbParams data value changed
|
||||
lastCbParamsList && each(lastItem.seriesDataIndices, function (idxItem) {
|
||||
var seriesIdx = idxItem.seriesIndex;
|
||||
var cbParams = cbParamsList[seriesIdx];
|
||||
var lastCbParams = lastCbParamsList[seriesIdx];
|
||||
if (cbParams && lastCbParams && lastCbParams.data !== cbParams.data) {
|
||||
contentNotChanged = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
this._lastDataByCoordSys = dataByCoordSys;
|
||||
this._cbParamsList = cbParamsList;
|
||||
return !!contentNotChanged;
|
||||
};
|
||||
TooltipView.prototype._hide = function (dispatchAction) {
|
||||
// Do not directly hideLater here, because this behavior may be prevented
|
||||
// in dispatchAction when showTip is dispatched.
|
||||
// FIXME
|
||||
// duplicated hideTip if manuallyHideTip is called from dispatchAction.
|
||||
this._lastDataByCoordSys = null;
|
||||
dispatchAction({
|
||||
type: 'hideTip',
|
||||
from: this.uid
|
||||
});
|
||||
};
|
||||
TooltipView.prototype.dispose = function (ecModel, api) {
|
||||
if (env.node || !api.getDom()) {
|
||||
return;
|
||||
}
|
||||
clear(this, '_updatePosition');
|
||||
this._tooltipContent.dispose();
|
||||
globalListener.unregister('itemTooltip', api);
|
||||
};
|
||||
TooltipView.type = 'tooltip';
|
||||
return TooltipView;
|
||||
}(ComponentView);
|
||||
/**
|
||||
* From top to bottom. (the last one should be globalTooltipModel);
|
||||
*/
|
||||
function buildTooltipModel(modelCascade, globalTooltipModel, defaultTooltipOption) {
|
||||
// Last is always tooltip model.
|
||||
var ecModel = globalTooltipModel.ecModel;
|
||||
var resultModel;
|
||||
if (defaultTooltipOption) {
|
||||
resultModel = new Model(defaultTooltipOption, ecModel, ecModel);
|
||||
resultModel = new Model(globalTooltipModel.option, resultModel, ecModel);
|
||||
} else {
|
||||
resultModel = globalTooltipModel;
|
||||
}
|
||||
for (var i = modelCascade.length - 1; i >= 0; i--) {
|
||||
var tooltipOpt = modelCascade[i];
|
||||
if (tooltipOpt) {
|
||||
if (tooltipOpt instanceof Model) {
|
||||
tooltipOpt = tooltipOpt.get('tooltip', true);
|
||||
}
|
||||
// In each data item tooltip can be simply write:
|
||||
// {
|
||||
// value: 10,
|
||||
// tooltip: 'Something you need to know'
|
||||
// }
|
||||
if (isString(tooltipOpt)) {
|
||||
tooltipOpt = {
|
||||
formatter: tooltipOpt
|
||||
};
|
||||
}
|
||||
if (tooltipOpt) {
|
||||
resultModel = new Model(tooltipOpt, resultModel, ecModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
return resultModel;
|
||||
}
|
||||
function makeDispatchAction(payload, api) {
|
||||
return payload.dispatchAction || bind(api.dispatchAction, api);
|
||||
}
|
||||
function refixTooltipPosition(x, y, content, viewWidth, viewHeight, gapH, gapV) {
|
||||
var size = content.getSize();
|
||||
var width = size[0];
|
||||
var height = size[1];
|
||||
if (gapH != null) {
|
||||
// Add extra 2 pixels for this case:
|
||||
// At present the "values" in default tooltip are using CSS `float: right`.
|
||||
// When the right edge of the tooltip box is on the right side of the
|
||||
// viewport, the `float` layout might push the "values" to the second line.
|
||||
if (x + width + gapH + 2 > viewWidth) {
|
||||
x -= width + gapH;
|
||||
} else {
|
||||
x += gapH;
|
||||
}
|
||||
}
|
||||
if (gapV != null) {
|
||||
if (y + height + gapV > viewHeight) {
|
||||
y -= height + gapV;
|
||||
} else {
|
||||
y += gapV;
|
||||
}
|
||||
}
|
||||
return [x, y];
|
||||
}
|
||||
function confineTooltipPosition(x, y, content, viewWidth, viewHeight) {
|
||||
var size = content.getSize();
|
||||
var width = size[0];
|
||||
var height = size[1];
|
||||
x = Math.min(x + width, viewWidth) - width;
|
||||
y = Math.min(y + height, viewHeight) - height;
|
||||
x = Math.max(x, 0);
|
||||
y = Math.max(y, 0);
|
||||
return [x, y];
|
||||
}
|
||||
function calcTooltipPosition(position, rect, contentSize, borderWidth) {
|
||||
var domWidth = contentSize[0];
|
||||
var domHeight = contentSize[1];
|
||||
var offset = Math.ceil(Math.SQRT2 * borderWidth) + 8;
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var rectWidth = rect.width;
|
||||
var rectHeight = rect.height;
|
||||
switch (position) {
|
||||
case 'inside':
|
||||
x = rect.x + rectWidth / 2 - domWidth / 2;
|
||||
y = rect.y + rectHeight / 2 - domHeight / 2;
|
||||
break;
|
||||
case 'top':
|
||||
x = rect.x + rectWidth / 2 - domWidth / 2;
|
||||
y = rect.y - domHeight - offset;
|
||||
break;
|
||||
case 'bottom':
|
||||
x = rect.x + rectWidth / 2 - domWidth / 2;
|
||||
y = rect.y + rectHeight + offset;
|
||||
break;
|
||||
case 'left':
|
||||
x = rect.x - domWidth - offset;
|
||||
y = rect.y + rectHeight / 2 - domHeight / 2;
|
||||
break;
|
||||
case 'right':
|
||||
x = rect.x + rectWidth + offset;
|
||||
y = rect.y + rectHeight / 2 - domHeight / 2;
|
||||
}
|
||||
return [x, y];
|
||||
}
|
||||
function isCenterAlign(align) {
|
||||
return align === 'center' || align === 'middle';
|
||||
}
|
||||
/**
|
||||
* Find target component by payload like:
|
||||
* ```js
|
||||
* { legendId: 'some_id', name: 'xxx' }
|
||||
* { toolboxIndex: 1, name: 'xxx' }
|
||||
* { geoName: 'some_name', name: 'xxx' }
|
||||
* ```
|
||||
* PENDING: at present only
|
||||
*
|
||||
* If not found, return null/undefined.
|
||||
*/
|
||||
function findComponentReference(payload, ecModel, api) {
|
||||
var queryOptionMap = preParseFinder(payload).queryOptionMap;
|
||||
var componentMainType = queryOptionMap.keys()[0];
|
||||
if (!componentMainType || componentMainType === 'series') {
|
||||
return;
|
||||
}
|
||||
var queryResult = queryReferringComponents(ecModel, componentMainType, queryOptionMap.get(componentMainType), {
|
||||
useDefault: false,
|
||||
enableAll: false,
|
||||
enableNone: false
|
||||
});
|
||||
var model = queryResult.models[0];
|
||||
if (!model) {
|
||||
return;
|
||||
}
|
||||
var view = api.getViewOfComponentModel(model);
|
||||
var el;
|
||||
view.group.traverse(function (subEl) {
|
||||
var tooltipConfig = getECData(subEl).tooltipConfig;
|
||||
if (tooltipConfig && tooltipConfig.name === payload.name) {
|
||||
el = subEl;
|
||||
return true; // stop
|
||||
}
|
||||
});
|
||||
if (el) {
|
||||
return {
|
||||
componentMainType: componentMainType,
|
||||
componentIndex: model.componentIndex,
|
||||
el: el
|
||||
};
|
||||
}
|
||||
}
|
||||
export default TooltipView;
|
78
frontend/node_modules/echarts/lib/component/tooltip/helper.js
generated
vendored
Normal file
78
frontend/node_modules/echarts/lib/component/tooltip/helper.js
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { toCamelCase } from '../../util/format.js';
|
||||
import env from 'zrender/lib/core/env.js';
|
||||
/* global document */
|
||||
export function shouldTooltipConfine(tooltipModel) {
|
||||
var confineOption = tooltipModel.get('confine');
|
||||
return confineOption != null ? !!confineOption
|
||||
// In richText mode, the outside part can not be visible.
|
||||
: tooltipModel.get('renderMode') === 'richText';
|
||||
}
|
||||
function testStyle(styleProps) {
|
||||
if (!env.domSupported) {
|
||||
return;
|
||||
}
|
||||
var style = document.documentElement.style;
|
||||
for (var i = 0, len = styleProps.length; i < len; i++) {
|
||||
if (styleProps[i] in style) {
|
||||
return styleProps[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
export var TRANSFORM_VENDOR = testStyle(['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform']);
|
||||
export var TRANSITION_VENDOR = testStyle(['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']);
|
||||
export function toCSSVendorPrefix(styleVendor, styleProp) {
|
||||
if (!styleVendor) {
|
||||
return styleProp;
|
||||
}
|
||||
styleProp = toCamelCase(styleProp, true);
|
||||
var idx = styleVendor.indexOf(styleProp);
|
||||
styleVendor = idx === -1 ? styleProp : "-" + styleVendor.slice(0, idx) + "-" + styleProp;
|
||||
return styleVendor.toLowerCase();
|
||||
}
|
||||
export function getComputedStyle(el, style) {
|
||||
var stl = el.currentStyle || document.defaultView && document.defaultView.getComputedStyle(el);
|
||||
return stl ? style ? stl[style] : stl : null;
|
||||
}
|
71
frontend/node_modules/echarts/lib/component/tooltip/install.js
generated
vendored
Normal file
71
frontend/node_modules/echarts/lib/component/tooltip/install.js
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { install as installAxisPointer } from '../axisPointer/install.js';
|
||||
import { use } from '../../extension.js';
|
||||
import TooltipModel from './TooltipModel.js';
|
||||
import TooltipView from './TooltipView.js';
|
||||
import { noop } from 'zrender/lib/core/util.js';
|
||||
export function install(registers) {
|
||||
use(installAxisPointer);
|
||||
registers.registerComponentModel(TooltipModel);
|
||||
registers.registerComponentView(TooltipView);
|
||||
/**
|
||||
* @action
|
||||
* @property {string} type
|
||||
* @property {number} seriesIndex
|
||||
* @property {number} dataIndex
|
||||
* @property {number} [x]
|
||||
* @property {number} [y]
|
||||
*/
|
||||
registers.registerAction({
|
||||
type: 'showTip',
|
||||
event: 'showTip',
|
||||
update: 'tooltip:manuallyShowTip'
|
||||
}, noop);
|
||||
registers.registerAction({
|
||||
type: 'hideTip',
|
||||
event: 'hideTip',
|
||||
update: 'tooltip:manuallyHideTip'
|
||||
}, noop);
|
||||
}
|
142
frontend/node_modules/echarts/lib/component/tooltip/seriesFormatTooltip.js
generated
vendored
Normal file
142
frontend/node_modules/echarts/lib/component/tooltip/seriesFormatTooltip.js
generated
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { trim, isArray, each, reduce } from 'zrender/lib/core/util.js';
|
||||
import { retrieveVisualColorForTooltipMarker, createTooltipMarkup } from './tooltipMarkup.js';
|
||||
import { retrieveRawValue } from '../../data/helper/dataProvider.js';
|
||||
import { isNameSpecified } from '../../util/model.js';
|
||||
export function defaultSeriesFormatTooltip(opt) {
|
||||
var series = opt.series;
|
||||
var dataIndex = opt.dataIndex;
|
||||
var multipleSeries = opt.multipleSeries;
|
||||
var data = series.getData();
|
||||
var tooltipDims = data.mapDimensionsAll('defaultedTooltip');
|
||||
var tooltipDimLen = tooltipDims.length;
|
||||
var value = series.getRawValue(dataIndex);
|
||||
var isValueArr = isArray(value);
|
||||
var markerColor = retrieveVisualColorForTooltipMarker(series, dataIndex);
|
||||
// Complicated rule for pretty tooltip.
|
||||
var inlineValue;
|
||||
var inlineValueType;
|
||||
var subBlocks;
|
||||
var sortParam;
|
||||
if (tooltipDimLen > 1 || isValueArr && !tooltipDimLen) {
|
||||
var formatArrResult = formatTooltipArrayValue(value, series, dataIndex, tooltipDims, markerColor);
|
||||
inlineValue = formatArrResult.inlineValues;
|
||||
inlineValueType = formatArrResult.inlineValueTypes;
|
||||
subBlocks = formatArrResult.blocks;
|
||||
// Only support tooltip sort by the first inline value. It's enough in most cases.
|
||||
sortParam = formatArrResult.inlineValues[0];
|
||||
} else if (tooltipDimLen) {
|
||||
var dimInfo = data.getDimensionInfo(tooltipDims[0]);
|
||||
sortParam = inlineValue = retrieveRawValue(data, dataIndex, tooltipDims[0]);
|
||||
inlineValueType = dimInfo.type;
|
||||
} else {
|
||||
sortParam = inlineValue = isValueArr ? value[0] : value;
|
||||
}
|
||||
// Do not show generated series name. It might not be readable.
|
||||
var seriesNameSpecified = isNameSpecified(series);
|
||||
var seriesName = seriesNameSpecified && series.name || '';
|
||||
var itemName = data.getName(dataIndex);
|
||||
var inlineName = multipleSeries ? seriesName : itemName;
|
||||
return createTooltipMarkup('section', {
|
||||
header: seriesName,
|
||||
// When series name is not specified, do not show a header line with only '-'.
|
||||
// This case always happens in tooltip.trigger: 'item'.
|
||||
noHeader: multipleSeries || !seriesNameSpecified,
|
||||
sortParam: sortParam,
|
||||
blocks: [createTooltipMarkup('nameValue', {
|
||||
markerType: 'item',
|
||||
markerColor: markerColor,
|
||||
// Do not mix display seriesName and itemName in one tooltip,
|
||||
// which might confuses users.
|
||||
name: inlineName,
|
||||
// name dimension might be auto assigned, where the name might
|
||||
// be not readable. So we check trim here.
|
||||
noName: !trim(inlineName),
|
||||
value: inlineValue,
|
||||
valueType: inlineValueType,
|
||||
dataIndex: dataIndex
|
||||
})].concat(subBlocks || [])
|
||||
});
|
||||
}
|
||||
function formatTooltipArrayValue(value, series, dataIndex, tooltipDims, colorStr) {
|
||||
// check: category-no-encode-has-axis-data in dataset.html
|
||||
var data = series.getData();
|
||||
var isValueMultipleLine = reduce(value, function (isValueMultipleLine, val, idx) {
|
||||
var dimItem = data.getDimensionInfo(idx);
|
||||
return isValueMultipleLine = isValueMultipleLine || dimItem && dimItem.tooltip !== false && dimItem.displayName != null;
|
||||
}, false);
|
||||
var inlineValues = [];
|
||||
var inlineValueTypes = [];
|
||||
var blocks = [];
|
||||
tooltipDims.length ? each(tooltipDims, function (dim) {
|
||||
setEachItem(retrieveRawValue(data, dataIndex, dim), dim);
|
||||
})
|
||||
// By default, all dims is used on tooltip.
|
||||
: each(value, setEachItem);
|
||||
function setEachItem(val, dim) {
|
||||
var dimInfo = data.getDimensionInfo(dim);
|
||||
// If `dimInfo.tooltip` is not set, show tooltip.
|
||||
if (!dimInfo || dimInfo.otherDims.tooltip === false) {
|
||||
return;
|
||||
}
|
||||
if (isValueMultipleLine) {
|
||||
blocks.push(createTooltipMarkup('nameValue', {
|
||||
markerType: 'subItem',
|
||||
markerColor: colorStr,
|
||||
name: dimInfo.displayName,
|
||||
value: val,
|
||||
valueType: dimInfo.type
|
||||
}));
|
||||
} else {
|
||||
inlineValues.push(val);
|
||||
inlineValueTypes.push(dimInfo.type);
|
||||
}
|
||||
}
|
||||
return {
|
||||
inlineValues: inlineValues,
|
||||
inlineValueTypes: inlineValueTypes,
|
||||
blocks: blocks
|
||||
};
|
||||
}
|
334
frontend/node_modules/echarts/lib/component/tooltip/tooltipMarkup.js
generated
vendored
Normal file
334
frontend/node_modules/echarts/lib/component/tooltip/tooltipMarkup.js
generated
vendored
Normal file
@ -0,0 +1,334 @@
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { getTooltipMarker, encodeHTML, makeValueReadable, convertToColorString } from '../../util/format.js';
|
||||
import { isString, each, hasOwn, isArray, map, assert, extend } from 'zrender/lib/core/util.js';
|
||||
import { SortOrderComparator } from '../../data/helper/dataValueHelper.js';
|
||||
import { getRandomIdBase } from '../../util/number.js';
|
||||
var TOOLTIP_LINE_HEIGHT_CSS = 'line-height:1';
|
||||
function getTooltipLineHeight(textStyle) {
|
||||
var lineHeight = textStyle.lineHeight;
|
||||
if (lineHeight == null) {
|
||||
return TOOLTIP_LINE_HEIGHT_CSS;
|
||||
} else {
|
||||
return "line-height:" + encodeHTML(lineHeight + '') + "px";
|
||||
}
|
||||
}
|
||||
// TODO: more textStyle option
|
||||
function getTooltipTextStyle(textStyle, renderMode) {
|
||||
var nameFontColor = textStyle.color || '#6e7079';
|
||||
var nameFontSize = textStyle.fontSize || 12;
|
||||
var nameFontWeight = textStyle.fontWeight || '400';
|
||||
var valueFontColor = textStyle.color || '#464646';
|
||||
var valueFontSize = textStyle.fontSize || 14;
|
||||
var valueFontWeight = textStyle.fontWeight || '900';
|
||||
if (renderMode === 'html') {
|
||||
// `textStyle` is probably from user input, should be encoded to reduce security risk.
|
||||
return {
|
||||
// eslint-disable-next-line max-len
|
||||
nameStyle: "font-size:" + encodeHTML(nameFontSize + '') + "px;color:" + encodeHTML(nameFontColor) + ";font-weight:" + encodeHTML(nameFontWeight + ''),
|
||||
// eslint-disable-next-line max-len
|
||||
valueStyle: "font-size:" + encodeHTML(valueFontSize + '') + "px;color:" + encodeHTML(valueFontColor) + ";font-weight:" + encodeHTML(valueFontWeight + '')
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
nameStyle: {
|
||||
fontSize: nameFontSize,
|
||||
fill: nameFontColor,
|
||||
fontWeight: nameFontWeight
|
||||
},
|
||||
valueStyle: {
|
||||
fontSize: valueFontSize,
|
||||
fill: valueFontColor,
|
||||
fontWeight: valueFontWeight
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
// See `TooltipMarkupLayoutIntent['innerGapLevel']`.
|
||||
// (value from UI design)
|
||||
var HTML_GAPS = [0, 10, 20, 30];
|
||||
var RICH_TEXT_GAPS = ['', '\n', '\n\n', '\n\n\n'];
|
||||
// eslint-disable-next-line max-len
|
||||
export function createTooltipMarkup(type, option) {
|
||||
option.type = type;
|
||||
return option;
|
||||
}
|
||||
function isSectionFragment(frag) {
|
||||
return frag.type === 'section';
|
||||
}
|
||||
function getBuilder(frag) {
|
||||
return isSectionFragment(frag) ? buildSection : buildNameValue;
|
||||
}
|
||||
function getBlockGapLevel(frag) {
|
||||
if (isSectionFragment(frag)) {
|
||||
var gapLevel_1 = 0;
|
||||
var subBlockLen = frag.blocks.length;
|
||||
var hasInnerGap_1 = subBlockLen > 1 || subBlockLen > 0 && !frag.noHeader;
|
||||
each(frag.blocks, function (subBlock) {
|
||||
var subGapLevel = getBlockGapLevel(subBlock);
|
||||
// If the some of the sub-blocks have some gaps (like 10px) inside, this block
|
||||
// should use a larger gap (like 20px) to distinguish those sub-blocks.
|
||||
if (subGapLevel >= gapLevel_1) {
|
||||
gapLevel_1 = subGapLevel + +(hasInnerGap_1 && (
|
||||
// 0 always can not be readable gap level.
|
||||
!subGapLevel
|
||||
// If no header, always keep the sub gap level. Otherwise
|
||||
// look weird in case `multipleSeries`.
|
||||
|| isSectionFragment(subBlock) && !subBlock.noHeader));
|
||||
}
|
||||
});
|
||||
return gapLevel_1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
function buildSection(ctx, fragment, topMarginForOuterGap, toolTipTextStyle) {
|
||||
var noHeader = fragment.noHeader;
|
||||
var gaps = getGap(getBlockGapLevel(fragment));
|
||||
var subMarkupTextList = [];
|
||||
var subBlocks = fragment.blocks || [];
|
||||
assert(!subBlocks || isArray(subBlocks));
|
||||
subBlocks = subBlocks || [];
|
||||
var orderMode = ctx.orderMode;
|
||||
if (fragment.sortBlocks && orderMode) {
|
||||
subBlocks = subBlocks.slice();
|
||||
var orderMap = {
|
||||
valueAsc: 'asc',
|
||||
valueDesc: 'desc'
|
||||
};
|
||||
if (hasOwn(orderMap, orderMode)) {
|
||||
var comparator_1 = new SortOrderComparator(orderMap[orderMode], null);
|
||||
subBlocks.sort(function (a, b) {
|
||||
return comparator_1.evaluate(a.sortParam, b.sortParam);
|
||||
});
|
||||
}
|
||||
// FIXME 'seriesDesc' necessary?
|
||||
else if (orderMode === 'seriesDesc') {
|
||||
subBlocks.reverse();
|
||||
}
|
||||
}
|
||||
each(subBlocks, function (subBlock, idx) {
|
||||
var valueFormatter = fragment.valueFormatter;
|
||||
var subMarkupText = getBuilder(subBlock)(
|
||||
// Inherit valueFormatter
|
||||
valueFormatter ? extend(extend({}, ctx), {
|
||||
valueFormatter: valueFormatter
|
||||
}) : ctx, subBlock, idx > 0 ? gaps.html : 0, toolTipTextStyle);
|
||||
subMarkupText != null && subMarkupTextList.push(subMarkupText);
|
||||
});
|
||||
var subMarkupText = ctx.renderMode === 'richText' ? subMarkupTextList.join(gaps.richText) : wrapBlockHTML(toolTipTextStyle, subMarkupTextList.join(''), noHeader ? topMarginForOuterGap : gaps.html);
|
||||
if (noHeader) {
|
||||
return subMarkupText;
|
||||
}
|
||||
var displayableHeader = makeValueReadable(fragment.header, 'ordinal', ctx.useUTC);
|
||||
var nameStyle = getTooltipTextStyle(toolTipTextStyle, ctx.renderMode).nameStyle;
|
||||
var tooltipLineHeight = getTooltipLineHeight(toolTipTextStyle);
|
||||
if (ctx.renderMode === 'richText') {
|
||||
return wrapInlineNameRichText(ctx, displayableHeader, nameStyle) + gaps.richText + subMarkupText;
|
||||
} else {
|
||||
return wrapBlockHTML(toolTipTextStyle, "<div style=\"" + nameStyle + ";" + tooltipLineHeight + ";\">" + encodeHTML(displayableHeader) + '</div>' + subMarkupText, topMarginForOuterGap);
|
||||
}
|
||||
}
|
||||
function buildNameValue(ctx, fragment, topMarginForOuterGap, toolTipTextStyle) {
|
||||
var renderMode = ctx.renderMode;
|
||||
var noName = fragment.noName;
|
||||
var noValue = fragment.noValue;
|
||||
var noMarker = !fragment.markerType;
|
||||
var name = fragment.name;
|
||||
var useUTC = ctx.useUTC;
|
||||
var valueFormatter = fragment.valueFormatter || ctx.valueFormatter || function (value) {
|
||||
value = isArray(value) ? value : [value];
|
||||
return map(value, function (val, idx) {
|
||||
return makeValueReadable(val, isArray(valueTypeOption) ? valueTypeOption[idx] : valueTypeOption, useUTC);
|
||||
});
|
||||
};
|
||||
if (noName && noValue) {
|
||||
return;
|
||||
}
|
||||
var markerStr = noMarker ? '' : ctx.markupStyleCreator.makeTooltipMarker(fragment.markerType, fragment.markerColor || '#333', renderMode);
|
||||
var readableName = noName ? '' : makeValueReadable(name, 'ordinal', useUTC);
|
||||
var valueTypeOption = fragment.valueType;
|
||||
var readableValueList = noValue ? [] : valueFormatter(fragment.value, fragment.dataIndex);
|
||||
var valueAlignRight = !noMarker || !noName;
|
||||
// It little weird if only value next to marker but far from marker.
|
||||
var valueCloseToMarker = !noMarker && noName;
|
||||
var _a = getTooltipTextStyle(toolTipTextStyle, renderMode),
|
||||
nameStyle = _a.nameStyle,
|
||||
valueStyle = _a.valueStyle;
|
||||
return renderMode === 'richText' ? (noMarker ? '' : markerStr) + (noName ? '' : wrapInlineNameRichText(ctx, readableName, nameStyle))
|
||||
// Value has commas inside, so use ' ' as delimiter for multiple values.
|
||||
+ (noValue ? '' : wrapInlineValueRichText(ctx, readableValueList, valueAlignRight, valueCloseToMarker, valueStyle)) : wrapBlockHTML(toolTipTextStyle, (noMarker ? '' : markerStr) + (noName ? '' : wrapInlineNameHTML(readableName, !noMarker, nameStyle)) + (noValue ? '' : wrapInlineValueHTML(readableValueList, valueAlignRight, valueCloseToMarker, valueStyle)), topMarginForOuterGap);
|
||||
}
|
||||
/**
|
||||
* @return markupText. null/undefined means no content.
|
||||
*/
|
||||
export function buildTooltipMarkup(fragment, markupStyleCreator, renderMode, orderMode, useUTC, toolTipTextStyle) {
|
||||
if (!fragment) {
|
||||
return;
|
||||
}
|
||||
var builder = getBuilder(fragment);
|
||||
var ctx = {
|
||||
useUTC: useUTC,
|
||||
renderMode: renderMode,
|
||||
orderMode: orderMode,
|
||||
markupStyleCreator: markupStyleCreator,
|
||||
valueFormatter: fragment.valueFormatter
|
||||
};
|
||||
return builder(ctx, fragment, 0, toolTipTextStyle);
|
||||
}
|
||||
function getGap(gapLevel) {
|
||||
return {
|
||||
html: HTML_GAPS[gapLevel],
|
||||
richText: RICH_TEXT_GAPS[gapLevel]
|
||||
};
|
||||
}
|
||||
function wrapBlockHTML(textStyle, encodedContent, topGap) {
|
||||
var clearfix = '<div style="clear:both"></div>';
|
||||
var marginCSS = "margin: " + topGap + "px 0 0";
|
||||
var tooltipLineHeight = getTooltipLineHeight(textStyle);
|
||||
return "<div style=\"" + marginCSS + ";" + tooltipLineHeight + ";\">" + encodedContent + clearfix + '</div>';
|
||||
}
|
||||
function wrapInlineNameHTML(name, leftHasMarker, style) {
|
||||
var marginCss = leftHasMarker ? 'margin-left:2px' : '';
|
||||
return "<span style=\"" + style + ";" + marginCss + "\">" + encodeHTML(name) + '</span>';
|
||||
}
|
||||
function wrapInlineValueHTML(valueList, alignRight, valueCloseToMarker, style) {
|
||||
// Do not too close to marker, considering there are multiple values separated by spaces.
|
||||
var paddingStr = valueCloseToMarker ? '10px' : '20px';
|
||||
var alignCSS = alignRight ? "float:right;margin-left:" + paddingStr : '';
|
||||
valueList = isArray(valueList) ? valueList : [valueList];
|
||||
return "<span style=\"" + alignCSS + ";" + style + "\">"
|
||||
// Value has commas inside, so use ' ' as delimiter for multiple values.
|
||||
+ map(valueList, function (value) {
|
||||
return encodeHTML(value);
|
||||
}).join(' ') + '</span>';
|
||||
}
|
||||
function wrapInlineNameRichText(ctx, name, style) {
|
||||
return ctx.markupStyleCreator.wrapRichTextStyle(name, style);
|
||||
}
|
||||
function wrapInlineValueRichText(ctx, values, alignRight, valueCloseToMarker, style) {
|
||||
var styles = [style];
|
||||
var paddingLeft = valueCloseToMarker ? 10 : 20;
|
||||
alignRight && styles.push({
|
||||
padding: [0, 0, 0, paddingLeft],
|
||||
align: 'right'
|
||||
});
|
||||
// Value has commas inside, so use ' ' as delimiter for multiple values.
|
||||
return ctx.markupStyleCreator.wrapRichTextStyle(isArray(values) ? values.join(' ') : values, styles);
|
||||
}
|
||||
export function retrieveVisualColorForTooltipMarker(series, dataIndex) {
|
||||
var style = series.getData().getItemVisual(dataIndex, 'style');
|
||||
var color = style[series.visualDrawType];
|
||||
return convertToColorString(color);
|
||||
}
|
||||
export function getPaddingFromTooltipModel(model, renderMode) {
|
||||
var padding = model.get('padding');
|
||||
return padding != null ? padding
|
||||
// We give slightly different to look pretty.
|
||||
: renderMode === 'richText' ? [8, 10] : 10;
|
||||
}
|
||||
/**
|
||||
* The major feature is generate styles for `renderMode: 'richText'`.
|
||||
* But it also serves `renderMode: 'html'` to provide
|
||||
* "renderMode-independent" API.
|
||||
*/
|
||||
var TooltipMarkupStyleCreator = /** @class */function () {
|
||||
function TooltipMarkupStyleCreator() {
|
||||
this.richTextStyles = {};
|
||||
// Notice that "generate a style name" usually happens repeatedly when mouse is moving and
|
||||
// a tooltip is displayed. So we put the `_nextStyleNameId` as a member of each creator
|
||||
// rather than static shared by all creators (which will cause it increase to fast).
|
||||
this._nextStyleNameId = getRandomIdBase();
|
||||
}
|
||||
TooltipMarkupStyleCreator.prototype._generateStyleName = function () {
|
||||
return '__EC_aUTo_' + this._nextStyleNameId++;
|
||||
};
|
||||
TooltipMarkupStyleCreator.prototype.makeTooltipMarker = function (markerType, colorStr, renderMode) {
|
||||
var markerId = renderMode === 'richText' ? this._generateStyleName() : null;
|
||||
var marker = getTooltipMarker({
|
||||
color: colorStr,
|
||||
type: markerType,
|
||||
renderMode: renderMode,
|
||||
markerId: markerId
|
||||
});
|
||||
if (isString(marker)) {
|
||||
return marker;
|
||||
} else {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
assert(markerId);
|
||||
}
|
||||
this.richTextStyles[markerId] = marker.style;
|
||||
return marker.content;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @usage
|
||||
* ```ts
|
||||
* const styledText = markupStyleCreator.wrapRichTextStyle([
|
||||
* // The styles will be auto merged.
|
||||
* {
|
||||
* fontSize: 12,
|
||||
* color: 'blue'
|
||||
* },
|
||||
* {
|
||||
* padding: 20
|
||||
* }
|
||||
* ]);
|
||||
* ```
|
||||
*/
|
||||
TooltipMarkupStyleCreator.prototype.wrapRichTextStyle = function (text, styles) {
|
||||
var finalStl = {};
|
||||
if (isArray(styles)) {
|
||||
each(styles, function (stl) {
|
||||
return extend(finalStl, stl);
|
||||
});
|
||||
} else {
|
||||
extend(finalStl, styles);
|
||||
}
|
||||
var styleName = this._generateStyleName();
|
||||
this.richTextStyles[styleName] = finalStl;
|
||||
return "{" + styleName + "|" + text + "}";
|
||||
};
|
||||
return TooltipMarkupStyleCreator;
|
||||
}();
|
||||
export { TooltipMarkupStyleCreator };
|
Reference in New Issue
Block a user