Skip to content

Commit

Permalink
feature: support tooltip.appendToBody. Fix #8049. Based on the PR e…
Browse files Browse the repository at this point in the history
  • Loading branch information
100pah committed Jan 13, 2020
1 parent 4023cfa commit c201b68
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 43 deletions.
77 changes: 54 additions & 23 deletions src/component/tooltip/TooltipContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import * as zrUtil from 'zrender/src/core/util';
import * as zrColor from 'zrender/src/tool/color';
import * as eventUtil from 'zrender/src/core/event';
import * as domUtil from 'zrender/src/core/dom';
import env from 'zrender/src/core/env';
import * as formatUtil from '../../util/format';

Expand Down Expand Up @@ -121,24 +122,63 @@ function assembleCssText(tooltipModel) {
return cssText.join(';') + ';';
}

// If not able to make, do not modify the input `out`.
function makeStyleCoord(out, zr, appendToBody, zrX, zrY) {
var zrPainter = zr && zr.painter;

if (appendToBody) {
var zrViewportRoot = zrPainter && zrPainter.getViewportRoot();
if (zrViewportRoot) {
// Some APPs might use scale on body, so we support CSS transform here.
domUtil.transformLocalCoord(out, zrViewportRoot, document.body, 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;
}
}
}

/**
* @alias module:echarts/component/tooltip/TooltipContent
* @param {HTMLElement} container
* @param {ExtensionAPI} api
* @param {Object} [opt]
* @param {boolean} [opt.appendToBody]
* `false`: the DOM element will be inside the container. Default value.
* `true`: the DOM element will be appended to HTML body, which avoid
* some overflow clip but intrude outside of the container.
* @constructor
*/
function TooltipContent(container, api) {
function TooltipContent(container, api, opt) {
if (env.wxa) {
return null;
}

var el = document.createElement('div');
el.domBelongToZr = true;
this.el = el;
var zr = this._zr = api.getZr();
var appendToBody = this._appendToBody = opt && opt.appendToBody;

this.el = el;
this._styleCoord = [0, 0];

this._x = api.getWidth() / 2;
this._y = api.getHeight() / 2;
makeStyleCoord(this._styleCoord, zr, appendToBody, api.getWidth() / 2, api.getHeight() / 2);

document.body.appendChild(el);
if (appendToBody) {
document.body.appendChild(el);
}
else {
container.appendChild(el);
}

this._container = container;

Expand Down Expand Up @@ -172,7 +212,8 @@ function TooltipContent(container, api) {
// Try trigger zrender event to avoid mouse
// in and out shape too frequently
var handler = zr.handler;
eventUtil.normalizeEvent(container, e, true);
var zrViewportRoot = zr.painter.getViewportRoot();
eventUtil.normalizeEvent(zrViewportRoot, e, true);
handler.dispatch('mousemove', e);
}
};
Expand Down Expand Up @@ -217,12 +258,13 @@ TooltipContent.prototype = {
show: function (tooltipModel) {
clearTimeout(this._hideTimeout);
var el = this.el;
var styleCoord = this._styleCoord;

el.style.cssText = gCssText + assembleCssText(tooltipModel)
// Because of the reason described in:
// http://stackoverflow.com/questions/21125587/css3-transition-not-working-in-chrome-anymore
// we should set initial value to `left` and `top`.
+ ';left:' + this._x + 'px;top:' + this._y + 'px;'
+ ';left:' + styleCoord[0] + 'px;top:' + styleCoord[1] + 'px;'
+ (tooltipModel.get('extraCssText') || '');

el.style.display = el.innerHTML ? 'block' : 'none';
Expand Down Expand Up @@ -250,23 +292,13 @@ TooltipContent.prototype = {
return [el.clientWidth, el.clientHeight];
},

moveTo: function (x, y) {
// 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 zr = this._zr;
var viewportRootOffset;
if (zr && zr.painter && (viewportRootOffset = zr.painter.getViewportRootOffset())) {
x += viewportRootOffset.offsetLeft;
y += viewportRootOffset.offsetTop;
}
moveTo: function (zrX, zrY) {
var styleCoord = this._styleCoord;
makeStyleCoord(styleCoord, this._zr, this._appendToBody, zrX, zrY);

var style = this.el.style;
style.left = x + 'px';
style.top = y + 'px';

this._x = x;
this._y = y;
style.left = styleCoord[0] + 'px';
style.top = styleCoord[1] + 'px';
},

hide: function () {
Expand All @@ -292,7 +324,6 @@ TooltipContent.prototype = {
return this._show;
},


dispose: function () {
this.el.parentNode.removeChild(this.el);
},
Expand Down
36 changes: 16 additions & 20 deletions src/component/tooltip/TooltipView.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ export default echarts.extendComponentView({

var tooltipContent;
if (this._renderMode === 'html') {
tooltipContent = new TooltipContent(api.getDom(), api);
tooltipContent = new TooltipContent(api.getDom(), api, {
appendToBody: tooltipModel.get('appendToBody', true)
});
this._newLine = '<br/>';
}
else {
Expand All @@ -65,10 +67,6 @@ export default echarts.extendComponentView({
}

this._tooltipContent = tooltipContent;

this._event = {};
this._viewWidth = document.body.clientWidth;
this._viewHeight = document.body.clientHeight;
},

render: function (tooltipModel, ecModel, api) {
Expand Down Expand Up @@ -130,7 +128,6 @@ export default echarts.extendComponentView({
// If 'none', it is not controlled by mouse totally.
if (triggerOn !== 'none') {
if (triggerOn.indexOf(currTrigger) >= 0) {
this._event = e.event;
this._tryShow(e, dispatchAction);
}
else if (currTrigger === 'leave') {
Expand Down Expand Up @@ -206,16 +203,14 @@ export default echarts.extendComponentView({
this._tryShow({
offsetX: payload.x,
offsetY: payload.y,
target: el,
event: this._event
target: el
}, dispatchAction);
}
else if (dataByCoordSys) {
this._tryShow({
offsetX: payload.x,
offsetY: payload.y,
position: payload.position,
event: this._event,
dataByCoordSys: payload.dataByCoordSys,
tooltipOption: payload.tooltipOption
}, dispatchAction);
Expand All @@ -234,8 +229,7 @@ export default echarts.extendComponentView({
offsetX: cx,
offsetY: cy,
position: payload.position,
target: pointInfo.el,
event: this._event
target: pointInfo.el
}, dispatchAction);
}
}
Expand All @@ -252,8 +246,7 @@ export default echarts.extendComponentView({
offsetX: payload.x,
offsetY: payload.y,
position: payload.position,
target: api.getZr().findHover(payload.x, payload.y).target,
event: this._event
target: api.getZr().findHover(payload.x, payload.y).target
}, dispatchAction);
}
},
Expand Down Expand Up @@ -320,8 +313,8 @@ export default echarts.extendComponentView({
}

// Save mouse x, mouse y. So we can try to keep showing the tip if chart is refreshed
this._lastX = e.event.pageX;
this._lastY = e.event.pageY;
this._lastX = e.offsetX;
this._lastY = e.offsetY;

var dataByCoordSys = e.dataByCoordSys;
if (dataByCoordSys && dataByCoordSys.length) {
Expand Down Expand Up @@ -359,7 +352,9 @@ export default echarts.extendComponentView({
_showAxisTooltip: function (dataByCoordSys, e) {
var ecModel = this._ecModel;
var globalTooltipModel = this._tooltipModel;
var point = [e.event.pageX, e.event.pageY];

var point = [e.offsetX, e.offsetY];

var singleDefaultHTML = [];
var singleParamsList = [];
var singleTooltipModel = buildTooltipModel([
Expand Down Expand Up @@ -515,7 +510,7 @@ export default echarts.extendComponentView({
this._showOrMove(tooltipModel, function () {
this._showTooltipContent(
tooltipModel, defaultHtml, params, asyncTicket,
e.event.pageX, e.event.pageY, e.position, e.target, markers
e.offsetX, e.offsetY, e.position, e.target, markers
);
});

Expand Down Expand Up @@ -551,7 +546,7 @@ export default echarts.extendComponentView({
this._showOrMove(subTooltipModel, function () {
this._showTooltipContent(
subTooltipModel, defaultHtml, subTooltipModel.get('formatterParams') || {},
asyncTicket, e.event.pageX, e.event.pageY, e.position, el
asyncTicket, e.offsetX, e.offsetY, e.position, el
);
});

Expand Down Expand Up @@ -613,8 +608,9 @@ export default echarts.extendComponentView({
* @return {Array.<number>}
*/
_updatePosition: function (tooltipModel, positionExpr, x, y, content, params, el) {
var viewWidth = this._viewWidth;
var viewHeight = this._viewHeight;
var viewWidth = this._api.getWidth();
var viewHeight = this._api.getHeight();

positionExpr = positionExpr || tooltipModel.get('position');

var contentSize = content.getSize();
Expand Down
1 change: 1 addition & 0 deletions test/runTest/actions/__meta__.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
"toolbox-title": 4,
"toolbox-tooltip": 1,
"tooltip": 10,
"tooltip-appendToBody": 4,
"tooltip-axisPointer": 20,
"tooltip-axisPointer2": 1,
"tooltip-cascade": 4,
Expand Down
1 change: 1 addition & 0 deletions test/runTest/actions/tooltip-appendToBody.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"name":"Action 1","ops":[{"type":"mousemove","time":877,"x":731,"y":147},{"type":"mousemove","time":1084,"x":563,"y":160},{"type":"mousemove","time":1309,"x":562,"y":160},{"type":"mousemove","time":1510,"x":364,"y":193},{"type":"mousemove","time":1719,"x":320,"y":194},{"type":"mousemove","time":1926,"x":316,"y":208},{"type":"mousemove","time":2126,"x":316,"y":211},{"type":"mousemove","time":2826,"x":316,"y":212},{"type":"mousemove","time":3026,"x":314,"y":234},{"type":"mousemove","time":3226,"x":315,"y":242},{"type":"mousemove","time":3435,"x":315,"y":242},{"type":"mousemove","time":3493,"x":315,"y":242},{"type":"mousemove","time":3693,"x":315,"y":262},{"type":"mousemove","time":3893,"x":316,"y":273},{"type":"mousemove","time":4093,"x":319,"y":290},{"type":"mousemove","time":4393,"x":319,"y":291},{"type":"mousemove","time":4593,"x":342,"y":290},{"type":"mousemove","time":4797,"x":604,"y":269},{"type":"mousemove","time":4998,"x":612,"y":262},{"type":"mousemove","time":5209,"x":625,"y":249},{"type":"mousemove","time":5415,"x":607,"y":249},{"type":"mousemove","time":5627,"x":505,"y":248},{"type":"mousewheel","time":5764,"x":505,"y":248,"deltaY":1},{"type":"mousewheel","time":5815,"x":505,"y":248,"deltaY":4},{"type":"mousewheel","time":5847,"x":505,"y":248,"deltaY":7},{"type":"mousewheel","time":5873,"x":505,"y":248,"deltaY":4},{"type":"mousewheel","time":5907,"x":505,"y":248,"deltaY":5},{"type":"mousewheel","time":5930,"x":505,"y":248,"deltaY":1},{"type":"mousemove","time":6497,"x":501,"y":251},{"type":"mousemove","time":6697,"x":407,"y":330},{"type":"mousemove","time":6906,"x":405,"y":333},{"type":"mousedown","time":7161,"x":405,"y":333},{"type":"mousemove","time":7199,"x":388,"y":345},{"type":"mousemove","time":7409,"x":368,"y":363},{"type":"mousemove","time":7615,"x":368,"y":363},{"type":"mousemove","time":7828,"x":388,"y":369},{"type":"mousemove","time":8045,"x":389,"y":369},{"type":"mousemove","time":8251,"x":364,"y":359},{"type":"mousemove","time":8460,"x":358,"y":336},{"type":"mouseup","time":8811,"x":358,"y":336},{"time":8812,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":8823,"x":349,"y":333},{"type":"mousemove","time":9029,"x":292,"y":282},{"type":"mousemove","time":9231,"x":286,"y":272},{"type":"mousemove","time":9447,"x":283,"y":248},{"type":"mousemove","time":9647,"x":283,"y":251},{"type":"mousemove","time":9847,"x":283,"y":253}],"scrollY":0,"scrollX":0,"timestamp":1578864522547},{"name":"Action 2","ops":[{"type":"mousemove","time":1064,"x":179,"y":319},{"type":"mousemove","time":1264,"x":208,"y":323},{"type":"mousemove","time":1473,"x":239,"y":323},{"type":"mousemove","time":1681,"x":242,"y":323},{"type":"mousemove","time":1881,"x":274,"y":335},{"type":"mousemove","time":2083,"x":302,"y":343},{"type":"mousemove","time":2283,"x":324,"y":346},{"type":"mousemove","time":2483,"x":331,"y":348},{"type":"mousemove","time":2917,"x":331,"y":348},{"type":"mousemove","time":3117,"x":331,"y":336},{"type":"mousemove","time":3327,"x":333,"y":331},{"type":"mousemove","time":3543,"x":337,"y":346},{"type":"mousemove","time":3767,"x":336,"y":354},{"type":"mousemove","time":3975,"x":336,"y":356},{"type":"mousemove","time":4184,"x":336,"y":354},{"type":"mousemove","time":4384,"x":356,"y":323},{"type":"mousemove","time":4594,"x":357,"y":322},{"type":"mousemove","time":4883,"x":358,"y":322},{"type":"mousemove","time":5083,"x":362,"y":325},{"type":"mousemove","time":5283,"x":352,"y":331},{"type":"mousemove","time":5484,"x":344,"y":338},{"type":"mousemove","time":5699,"x":338,"y":343},{"type":"mousemove","time":5907,"x":337,"y":344},{"type":"mousemove","time":6119,"x":352,"y":342},{"type":"mousemove","time":6324,"x":344,"y":346},{"type":"mousemove","time":6532,"x":338,"y":350},{"type":"mousemove","time":6743,"x":334,"y":350},{"type":"mousemove","time":6959,"x":334,"y":350}],"scrollY":157,"scrollX":0,"timestamp":1578864545306},{"name":"Action 3","ops":[{"type":"mousemove","time":880,"x":188,"y":96},{"type":"mousemove","time":1080,"x":218,"y":58},{"type":"mousemove","time":1280,"x":233,"y":35},{"type":"mousemove","time":1487,"x":244,"y":26},{"type":"mousemove","time":1704,"x":247,"y":22},{"type":"mousedown","time":2221,"x":247,"y":22},{"type":"mouseup","time":2537,"x":247,"y":22},{"time":2538,"delay":400,"type":"screenshot-auto"},{"type":"mousedown","time":3186,"x":247,"y":22},{"type":"mouseup","time":3772,"x":247,"y":22},{"time":3773,"delay":400,"type":"screenshot-auto"}],"scrollY":579,"scrollX":0,"timestamp":1578864579827},{"name":"Action 4","ops":[{"type":"mousemove","time":949,"x":276,"y":348},{"type":"mousemove","time":1156,"x":294,"y":338},{"type":"mousemove","time":1365,"x":314,"y":325},{"type":"mousemove","time":1574,"x":334,"y":319},{"type":"mousemove","time":1780,"x":337,"y":316},{"type":"mousemove","time":1989,"x":330,"y":317},{"type":"mousemove","time":2198,"x":331,"y":317},{"type":"mousemove","time":2409,"x":353,"y":311},{"type":"mousemove","time":2626,"x":356,"y":310},{"type":"mousemove","time":3164,"x":361,"y":307},{"type":"mousemove","time":3364,"x":390,"y":293},{"type":"mousemove","time":3575,"x":343,"y":324},{"type":"mousemove","time":3797,"x":348,"y":321},{"type":"mousemove","time":4040,"x":361,"y":305},{"type":"mousemove","time":4265,"x":357,"y":306},{"type":"mousemove","time":4474,"x":356,"y":308},{"type":"mousemove","time":4781,"x":359,"y":306},{"type":"mousemove","time":4990,"x":390,"y":289},{"type":"mousemove","time":5547,"x":390,"y":289},{"type":"mousemove","time":5747,"x":395,"y":291},{"type":"mousemove","time":5958,"x":392,"y":287},{"type":"mousemove","time":6164,"x":391,"y":290},{"type":"mousemove","time":6364,"x":394,"y":289},{"type":"mousemove","time":6567,"x":385,"y":277},{"type":"mousemove","time":6773,"x":385,"y":277},{"type":"mousemove","time":6970,"x":378,"y":281},{"type":"mousemove","time":7170,"x":345,"y":303},{"type":"mousemove","time":7372,"x":338,"y":306},{"type":"mousemove","time":7582,"x":324,"y":306},{"type":"mousemove","time":7797,"x":307,"y":307},{"type":"mousemove","time":7970,"x":307,"y":307},{"type":"mousemove","time":8171,"x":223,"y":294}],"scrollY":579,"scrollX":0,"timestamp":1578864604914}]

0 comments on commit c201b68

Please sign in to comment.