未验证 提交 25ceb56c 编写于 作者: Y Yi Shen 提交者: GitHub

Merge pull request #13383 from plainheart/feat/tooltip-class

feat(tooltip): allow adding classes to tooltip DOM and migrate changes to next branch in #12834.
...@@ -198,6 +198,9 @@ function makeStyleCoord(out: number[], zr: ZRenderType, appendToBody: boolean, z ...@@ -198,6 +198,9 @@ function makeStyleCoord(out: number[], zr: ZRenderType, appendToBody: boolean, z
out[1] += viewportRootOffset.offsetTop; out[1] += viewportRootOffset.offsetTop;
} }
} }
out[2] = out[0] / zr.getWidth();
out[3] = out[1] / zr.getHeight();
} }
interface TooltipContentOption { interface TooltipContentOption {
...@@ -217,7 +220,7 @@ class TooltipHTMLContent { ...@@ -217,7 +220,7 @@ class TooltipHTMLContent {
private _show: boolean = false; private _show: boolean = false;
private _styleCoord: [number, number] = [0, 0]; private _styleCoord: [number, number, number, number] = [0, 0, 0, 0];
private _appendToBody: boolean; private _appendToBody: boolean;
private _enterable = true; private _enterable = true;
...@@ -301,7 +304,7 @@ class TooltipHTMLContent { ...@@ -301,7 +304,7 @@ class TooltipHTMLContent {
/** /**
* Update when tooltip is rendered * Update when tooltip is rendered
*/ */
update() { update(tooltipModel: Model<TooltipOption>) {
// FIXME // FIXME
// Move this logic to ec main? // Move this logic to ec main?
const container = this._container; const container = this._container;
...@@ -311,6 +314,14 @@ class TooltipHTMLContent { ...@@ -311,6 +314,14 @@ class TooltipHTMLContent {
if (domStyle.position !== 'absolute' && stl.position !== 'absolute') { if (domStyle.position !== 'absolute' && stl.position !== 'absolute') {
domStyle.position = 'relative'; domStyle.position = 'relative';
} }
// move tooltip if chart resized
const alwaysShowContent = tooltipModel.get('alwaysShowContent');
alwaysShowContent && this._moveIfResized();
// update className
this.el.className = tooltipModel.get('className') || '';
// Hide the tooltip // Hide the tooltip
// PENDING // PENDING
// this.hide(); // this.hide();
...@@ -332,10 +343,10 @@ class TooltipHTMLContent { ...@@ -332,10 +343,10 @@ class TooltipHTMLContent {
el.style.display = el.innerHTML ? 'block' : 'none'; el.style.display = el.innerHTML ? 'block' : 'none';
// If mouse occsionally move over the tooltip, a mouseout event will be // If mouse occasionally move over the tooltip, a mouseout event will be
// triggered by canvas, and cuase some unexpectable result like dragging // triggered by canvas, and cause some unexpectable result like dragging
// stop, "unfocusAdjacency". Here `pointer-events: none` is used to solve // stop, "unfocusAdjacency". Here `pointer-events: none` is used to solve
// it. Although it is not suppored by IE8~IE10, fortunately it is a rare // it. Although it is not supported by IE8~IE10, fortunately it is a rare
// scenario. // scenario.
el.style.pointerEvents = this._enterable ? 'auto' : 'none'; el.style.pointerEvents = this._enterable ? 'auto' : 'none';
...@@ -385,6 +396,21 @@ class TooltipHTMLContent { ...@@ -385,6 +396,21 @@ class TooltipHTMLContent {
} }
} }
/**
* when `alwaysShowContent` is true,
* move the tooltip after chart resized
*/
_moveIfResized() {
// The ratio of left to width
const ratioX = this._styleCoord[2];
// The ratio of top to height
const ratioY = this._styleCoord[3];
this.moveTo(
ratioX * this._zr.getWidth(),
ratioY * this._zr.getHeight()
);
}
hide() { hide() {
this.el.style.display = 'none'; this.el.style.display = 'none';
this._show = false; this._show = false;
...@@ -394,7 +420,7 @@ class TooltipHTMLContent { ...@@ -394,7 +420,7 @@ class TooltipHTMLContent {
if (this._show && !(this._inContent && this._enterable)) { if (this._show && !(this._inContent && this._enterable)) {
if (time) { if (time) {
this._hideDelay = time; this._hideDelay = time;
// Set show false to avoid invoke hideLater mutiple times // Set show false to avoid invoke hideLater multiple times
this._show = false; this._show = false;
this._hideTimeout = setTimeout(zrUtil.bind(this.hide, this), time) as any; this._hideTimeout = setTimeout(zrUtil.bind(this.hide, this), time) as any;
} }
......
...@@ -65,6 +65,12 @@ export interface TooltipOption extends CommonTooltipOption<TopLevelFormatterPara ...@@ -65,6 +65,12 @@ export interface TooltipOption extends CommonTooltipOption<TopLevelFormatterPara
*/ */
appendToBody?: boolean appendToBody?: boolean
/**
* specified class name of tooltip dom
* Only available when renderMode is html
*/
className?: string
order?: TooltipOrderMode order?: TooltipOrderMode
} }
...@@ -173,4 +179,4 @@ class TooltipModel extends ComponentModel<TooltipOption> { ...@@ -173,4 +179,4 @@ class TooltipModel extends ComponentModel<TooltipOption> {
ComponentModel.registerClass(TooltipModel); ComponentModel.registerClass(TooltipModel);
export default TooltipModel; export default TooltipModel;
\ No newline at end of file
...@@ -32,6 +32,8 @@ class TooltipRichContent { ...@@ -32,6 +32,8 @@ class TooltipRichContent {
private _show = false; private _show = false;
private _styleCoord: [number, number, number, number] = [0, 0, 0, 0];
private _hideTimeout: number; private _hideTimeout: number;
private _enterable = true; private _enterable = true;
...@@ -44,13 +46,15 @@ class TooltipRichContent { ...@@ -44,13 +46,15 @@ class TooltipRichContent {
constructor(api: ExtensionAPI) { constructor(api: ExtensionAPI) {
this._zr = api.getZr(); this._zr = api.getZr();
makeStyleCoord(this._styleCoord, this._zr, api.getWidth() / 2, api.getHeight() / 2);
} }
/** /**
* Update when tooltip is rendered * Update when tooltip is rendered
*/ */
update() { update(tooltipModel: Model<TooltipOption>) {
// noop const alwaysShowContent = tooltipModel.get('alwaysShowContent');
alwaysShowContent && this._moveIfResized();
} }
show() { show() {
...@@ -136,6 +140,10 @@ class TooltipRichContent { ...@@ -136,6 +140,10 @@ class TooltipRichContent {
moveTo(x: number, y: number) { moveTo(x: number, y: number) {
const el = this.el; const el = this.el;
if (el) { if (el) {
const styleCoord = this._styleCoord;
makeStyleCoord(styleCoord, this._zr, x, y);
x = styleCoord[0];
y = styleCoord[1];
const style = el.style; const style = el.style;
const borderWidth = mathMaxWith0(style.borderWidth || 0); const borderWidth = mathMaxWith0(style.borderWidth || 0);
const shadowOuterSize = calcShadowOuterSize(style); const shadowOuterSize = calcShadowOuterSize(style);
...@@ -146,6 +154,22 @@ class TooltipRichContent { ...@@ -146,6 +154,22 @@ class TooltipRichContent {
} }
} }
/**
* when `alwaysShowContent` is true,
* move the tooltip after chart resized
*/
_moveIfResized() {
// The ratio of left to width
const ratioX = this._styleCoord[2];
// The ratio of top to height
const ratioY = this._styleCoord[3];
this.moveTo(
ratioX * this._zr.getWidth(),
ratioY * this._zr.getHeight()
);
}
hide() { hide() {
if (this.el) { if (this.el) {
this.el.hide(); this.el.hide();
...@@ -157,7 +181,7 @@ class TooltipRichContent { ...@@ -157,7 +181,7 @@ class TooltipRichContent {
if (this._show && !(this._inContent && this._enterable)) { if (this._show && !(this._inContent && this._enterable)) {
if (time) { if (time) {
this._hideDelay = time; this._hideDelay = time;
// Set show false to avoid invoke hideLater mutiple times // Set show false to avoid invoke hideLater multiple times
this._show = false; this._show = false;
this._hideTimeout = setTimeout(zrUtil.bind(this.hide, this), time) as any; this._hideTimeout = setTimeout(zrUtil.bind(this.hide, this), time) as any;
} }
...@@ -200,4 +224,11 @@ function calcShadowOuterSize(style: TextStyleProps) { ...@@ -200,4 +224,11 @@ function calcShadowOuterSize(style: TextStyleProps) {
}; };
} }
function makeStyleCoord(out: number[], zr: ZRenderType, zrX: number, zrY: number) {
out[0] = zrX;
out[1] = zrY;
out[2] = out[0] / zr.getWidth();
out[3] = out[1] / zr.getHeight();
}
export default TooltipRichContent; export default TooltipRichContent;
...@@ -196,7 +196,7 @@ class TooltipView extends ComponentView { ...@@ -196,7 +196,7 @@ class TooltipView extends ComponentView {
this._alwaysShowContent = tooltipModel.get('alwaysShowContent'); this._alwaysShowContent = tooltipModel.get('alwaysShowContent');
const tooltipContent = this._tooltipContent; const tooltipContent = this._tooltipContent;
tooltipContent.update(); tooltipContent.update(tooltipModel);
tooltipContent.setEnterable(tooltipModel.get('enterable')); tooltipContent.setEnterable(tooltipModel.get('enterable'));
this._initGlobalListener(); this._initGlobalListener();
...@@ -450,7 +450,7 @@ class TooltipView extends ComponentView { ...@@ -450,7 +450,7 @@ class TooltipView extends ComponentView {
) { ) {
// showDelay is used in this case: tooltip.enterable is set // showDelay is used in this case: tooltip.enterable is set
// as true. User intent to move mouse into tooltip and click // as true. User intent to move mouse into tooltip and click
// something. `showDelay` makes it easyer to enter the content // something. `showDelay` makes it easier to enter the content
// but tooltip do not move immediately. // but tooltip do not move immediately.
const delay = tooltipModel.get('showDelay'); const delay = tooltipModel.get('showDelay');
cb = zrUtil.bind(cb, this); cb = zrUtil.bind(cb, this);
...@@ -666,7 +666,7 @@ class TooltipView extends ComponentView { ...@@ -666,7 +666,7 @@ class TooltipView extends ComponentView {
const markupStyleCreator = new TooltipMarkupStyleCreator(); const markupStyleCreator = new TooltipMarkupStyleCreator();
// Do not check whether `trigger` is 'none' here, because `trigger` // Do not check whether `trigger` is 'none' here, because `trigger`
// only works on cooridinate system. In fact, we have not found case // only works on coordinate system. In fact, we have not found case
// that requires setting `trigger` nothing on component yet. // that requires setting `trigger` nothing on component yet.
this._showOrMove(subTooltipModel, function (this: TooltipView) { this._showOrMove(subTooltipModel, function (this: TooltipView) {
......
...@@ -40,6 +40,18 @@ under the License. ...@@ -40,6 +40,18 @@ under the License.
margin: 0 auto; margin: 0 auto;
} }
.custoized-tooltip-class {
background-color: cyan!important;
text-shadow: 0 0 5px red;
}
.custoized-tooltip-class::after {
content: 'pseudo after';
display: inline-block;
position: absolute;
left: 110%;
top: 50%;
transform: translateY(-50%);
}
</style> </style>
...@@ -203,12 +215,34 @@ under the License. ...@@ -203,12 +215,34 @@ under the License.
}; };
var chart = testHelper.create(echarts, 'main0', { var chart = testHelper.create(echarts, 'main0', {
option: option option: option,
buttons: [
{
text: 'add class',
onclick: function () {
chart.setOption({
tooltip: {
className: 'custoized-tooltip-class'
}
})
}
},
{
text: 'recovery class',
onclick: function () {
chart.setOption({
tooltip: {
className: ''
}
})
}
}
]
}); });
chart.setOption(option, true); chart.setOption(option, true);
window.addEventListener('resize',function () { window.addEventListener('resize', function () {
chart.resize(); chart.resize();
}) });
}); });
</script> </script>
...@@ -372,9 +406,9 @@ under the License. ...@@ -372,9 +406,9 @@ under the License.
option: option option: option
}); });
chart.setOption(option, true); chart.setOption(option, true);
window.addEventListener('resize',function () { window.addEventListener('resize', function () {
chart.resize(); chart.resize();
}) });
}); });
</script> </script>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册