You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by ov...@apache.org on 2018/07/03 07:08:59 UTC
[incubator-echarts] branch master updated: feat(tooltip): improve
tooltip interface, implement other functions
This is an automated email from the ASF dual-hosted git repository.
ovilia pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
The following commit(s) were added to refs/heads/master by this push:
new c631068 feat(tooltip): improve tooltip interface, implement other functions
c631068 is described below
commit c631068aa4ec3458ba04b9f3842f106759405460
Author: Ovilia <zw...@gmail.com>
AuthorDate: Tue Jul 3 15:08:34 2018 +0800
feat(tooltip): improve tooltip interface, implement other functions
---
src/component/tooltip/TooltipModel.js | 6 ++--
src/component/tooltip/TooltipRichContent.js | 53 +++++++++++++++++++++++++++--
src/component/tooltip/TooltipView.js | 34 ++++++++++--------
src/model/Series.js | 42 +++++++++++++++++------
src/model/mixin/dataFormat.js | 7 +++-
src/util/format.js | 23 +++++++++----
6 files changed, 125 insertions(+), 40 deletions(-)
diff --git a/src/component/tooltip/TooltipModel.js b/src/component/tooltip/TooltipModel.js
index 5fe862b..b115871 100644
--- a/src/component/tooltip/TooltipModel.js
+++ b/src/component/tooltip/TooltipModel.js
@@ -46,10 +46,10 @@ export default echarts.extendComponentModel({
displayMode: 'single', // 'single' | 'multipleByCoordSys'
- useHtml: 'auto', // 'auto', true, or false
+ renderMode: 'auto', // 'auto' | 'html' | 'richtext'
// 'auto': use html by default, and use non-html if `document` is not defined
- // true: use html for tooltip
- // false: use canvas, svg, and etc. for tooltip
+ // 'html': use html for tooltip
+ // 'richtext': use canvas, svg, and etc. for tooltip
// 位置 {Array} | {Function}
// position: null
diff --git a/src/component/tooltip/TooltipRichContent.js b/src/component/tooltip/TooltipRichContent.js
index b5f8078..d7df394 100644
--- a/src/component/tooltip/TooltipRichContent.js
+++ b/src/component/tooltip/TooltipRichContent.js
@@ -17,6 +17,7 @@
* under the License.
*/
+import * as zrUtil from 'zrender/src/core/util';
import Group from 'zrender/src/container/Group';
import Text from 'zrender/src/graphic/Text';
@@ -30,9 +31,6 @@ function TooltipRichContent(api) {
var zr = this._zr = api.getZr();
// zr.add(this.el);
- this._x = api.getWidth() / 2;
- this._y = api.getHeight() / 2;
-
this._show = false;
/**
@@ -55,6 +53,7 @@ TooltipRichContent.prototype = {
* Update when tooltip is rendered
*/
update: function () {
+ // noop
},
show: function (tooltipModel) {
@@ -66,6 +65,13 @@ TooltipRichContent.prototype = {
this._show = true;
},
+ /**
+ * Set tooltip content
+ *
+ * @param {string} content rich text string of content
+ * @param {Object} markerRich rich text style
+ * @param {Object} tooltipModel tooltip model
+ */
setContent: function (content, markerRich, tooltipModel) {
if (this.el) {
this._zr.remove(this.el);
@@ -103,6 +109,34 @@ TooltipRichContent.prototype = {
z: tooltipModel.get('z')
});
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('mousemove', function (e) {
+ e = e || window.event;
+ if (!self._enterable) {
+ // Try trigger zrender event to avoid mouse
+ // in and out shape too frequently
+ var handler = zr.handler;
+ eventUtil.normalizeEvent(container, e, true);
+ handler.dispatch('mousemove', e);
+ }
+ });
+ this.el.on('mouseout', function () {
+ if (self._enterable) {
+ if (self._show) {
+ self.hideLater(self._hideDelay);
+ }
+ }
+ self._inContent = false;
+ });
},
setEnterable: function (enterable) {
@@ -121,9 +155,22 @@ TooltipRichContent.prototype = {
},
hide: function () {
+ this.el.hide();
+ this._show = false;
},
hideLater: function (time) {
+ if (this._show && !(this._inContent && this._enterable)) {
+ if (time) {
+ this._hideDelay = time;
+ // Set show false to avoid invoke hideLater mutiple times
+ this._show = false;
+ this._hideTimeout = setTimeout(zrUtil.bind(this.hide, this), time);
+ }
+ else {
+ this.hide();
+ }
+ }
},
isShow: function () {
diff --git a/src/component/tooltip/TooltipView.js b/src/component/tooltip/TooltipView.js
index 0427904..4ce0d30 100644
--- a/src/component/tooltip/TooltipView.js
+++ b/src/component/tooltip/TooltipView.js
@@ -50,23 +50,27 @@ export default echarts.extendComponentView({
}
var tooltip = ecModel.get('tooltip');
- this._isRich = false;
- if (tooltip.length && (tooltip[0].useHtml === false // force using non-html
- || tooltip[0].useHtml === 'auto' && !document)) // auto using non-html when no `document`
- {
- this._isRich = true;
+ this._renderMode = 'html';
+ if (tooltip.length) {
+ if (tooltip[0].renderMode === 'auto') {
+ // using html when `document` exists, use richtext otherwise
+ this._renderMode = document ? 'html' : 'richtext';
+ }
+ else {
+ this._renderMode = tooltip[0].renderMode || this._renderMode;
+ }
}
- var tooltipContent
- if (this._isRich) {
- tooltipContent = new TooltipRichContent(api);
+ var tooltipContent;
+ if (this._renderMode === 'html') {
+ tooltipContent = new TooltipContent(api.getDom(), api);
+ this._newLine = '<br/>';
}
else {
- tooltipContent = new TooltipContent(api.getDom(), api);
+ tooltipContent = new TooltipRichContent(api);
+ this._newLine = '\n';
}
- this._newLine = this._isRich ? '\n' : '<br/>';
-
this._tooltipContent = tooltipContent;
},
@@ -364,7 +368,7 @@ export default echarts.extendComponentView({
globalTooltipModel
]);
- var isRich = this._isRich;
+ var renderMode = this._renderMode;
var newLine = this._newLine;
var markers = {};
@@ -409,7 +413,7 @@ export default echarts.extendComponentView({
if (dataParams) {
singleParamsList.push(dataParams);
- var seriesTooltip = series.formatTooltip(dataIndex, true, null, isRich);
+ var seriesTooltip = series.formatTooltip(dataIndex, true, null, renderMode);
var html;
if (zrUtil.isObject(seriesTooltip)) {
@@ -429,7 +433,7 @@ export default echarts.extendComponentView({
// (1) shold be the first data which has name?
// (2) themeRiver, firstDataIndex is array, and first line is unnecessary.
var firstLine = valueLabel;
- if (isRich) {
+ if (renderMode !== 'html') {
singleDefaultHTML.push(seriesDefaultHTML.join(newLine))
}
else {
@@ -495,7 +499,7 @@ export default echarts.extendComponentView({
}
var params = dataModel.getDataParams(dataIndex, dataType);
- var seriesTooltip = dataModel.formatTooltip(dataIndex, false, dataType, this._isRich);
+ var seriesTooltip = dataModel.formatTooltip(dataIndex, false, dataType, this._renderMode);
var defaultHtml, markers;
if (zrUtil.isObject(seriesTooltip)) {
defaultHtml = seriesTooltip.html;
diff --git a/src/model/Series.js b/src/model/Series.js
index 32db075..af39fc4 100644
--- a/src/model/Series.js
+++ b/src/model/Series.js
@@ -303,13 +303,19 @@ var SeriesModel = ComponentModel.extend({
* @param {number} dataIndex
* @param {boolean} [multipleSeries=false]
* @param {number} [dataType]
- * @param {boolean} [isRich=false]
+ * @param {string} [renderMode='html'] valid values: 'html' and 'richtext'.
+ * 'html' is used for rendering tooltip in extra DOM form, and the result
+ * string is used as DOM HTML content.
+ * 'richtext' is used for rendering tooltip in rich text form, for those where
+ * DOM operation is not supported.
* @return {Object} formatted tooltip with `html` and `markers`
*/
- formatTooltip: function (dataIndex, multipleSeries, dataType, isRich) {
+ formatTooltip: function (dataIndex, multipleSeries, dataType, renderMode) {
var series = this;
- var newLine = isRich ? '\n' : '<br/>';
+ renderMode = renderMode || 'html';
+ var newLine = renderMode === 'html' ? '<br/>' : '\n';
+ var isRichText = renderMode === 'richtext';
var markers = {};
var markerId = 0;
@@ -338,9 +344,16 @@ var SeriesModel = ComponentModel.extend({
}
var dimType = dimInfo.type;
var markName = series.seriesIndex + 'at' + markerId;
- var dimHead = getTooltipMarker({color: color, type: 'subItem', isRich: isRich, markerId: markName});
+ var dimHead = getTooltipMarker({
+ color: color,
+ type: 'subItem',
+ renderMode: renderMode,
+ markerId: markName
+ });
+
+ var dimHeadStr = typeof dimHead === 'string' ? dimHead : dimHead.content;
var valStr = (vertially
- ? dimHead + encodeHTML(dimInfo.displayName || '-') + ': '
+ ? dimHeadStr + encodeHTML(dimInfo.displayName || '-') + ': '
: ''
)
// FIXME should not format time for raw data?
@@ -352,15 +365,16 @@ var SeriesModel = ComponentModel.extend({
);
valStr && result.push(valStr);
- if (isRich) {
+ if (isRichText) {
markers[markName] = color;
++markerId;
}
}
return {
- html: (vertially ? isRich : '') + result.join(vertially ? isRich : ', '),
- markers: markers
+ renderMode: renderMode,
+ content: (vertially ? isRichText : '') + result.join(vertially ? isRichText : ', '),
+ style: markers
};
}
@@ -388,7 +402,12 @@ var SeriesModel = ComponentModel.extend({
: formatSingleValue(isValueArr ? value[0] : value);
var markName = series.seriesIndex + 'at' + markerId;
- var colorEl = getTooltipMarker({ color: color, type: 'item', isRich: isRich, markerId: markName });
+ var colorEl = getTooltipMarker({
+ color: color,
+ type: 'item',
+ renderMode: renderMode,
+ markerId: markName
+ });
markers[markName] = color;
++markerId;
@@ -402,13 +421,14 @@ var SeriesModel = ComponentModel.extend({
? encodeHTML(seriesName) + (!multipleSeries ? newLine : ': ')
: '';
+ var colorStr = typeof colorEl === 'string' ? colorEl : colorEl.content;
var html = !multipleSeries
- ? seriesName + colorEl
+ ? seriesName + colorStr
+ (name
? encodeHTML(name) + ': ' + formattedValue
: formattedValue
)
- : colorEl + seriesName + formattedValue;
+ : colorStr + seriesName + formattedValue;
return {
html: html,
diff --git a/src/model/mixin/dataFormat.js b/src/model/mixin/dataFormat.js
index 5b6087c..11fd5e1 100644
--- a/src/model/mixin/dataFormat.js
+++ b/src/model/mixin/dataFormat.js
@@ -37,6 +37,8 @@ export default {
var name = data.getName(dataIndex);
var itemOpt = data.getRawDataItem(dataIndex);
var color = data.getItemVisual(dataIndex, 'color');
+ var tooltip = this.ecModel.get('tooltip');
+ var renderMode = tooltip && tooltip.length ? tooltip[0].renderMode : 'auto';
return {
componentType: this.mainType,
@@ -51,7 +53,10 @@ export default {
dataType: dataType,
value: rawValue,
color: color,
- marker: getTooltipMarker(color),
+ marker: getTooltipMarker({
+ color: color,
+ renderMode: renderMode
+ }),
// Param name list for mapping `a`, `b`, `c`, `d`, `e`
$vars: ['seriesName', 'name', 'value']
diff --git a/src/util/format.js b/src/util/format.js
index 119756b..0f0581b 100644
--- a/src/util/format.js
+++ b/src/util/format.js
@@ -20,6 +20,7 @@
import * as zrUtil from 'zrender/src/core/util';
import * as textContain from 'zrender/src/contain/text';
import * as numberUtil from './number';
+import Text from 'zrender/src/graphic/Text';
/**
* 每三位默认加,格式化
@@ -135,7 +136,8 @@ export function formatTplSimple(tpl, param, encode) {
* @param {string} [opt.color]
* @param {string} [opt.extraCssText]
* @param {string} [opt.type='item'] 'item' or 'subItem'
- * @param {boolean} [opt.isRich=false] if renders with rich text
+ * @param {string} [opt.renderMode='html'] render mode of tooltip, 'html' or 'richtext'
+ * @param {string} [opt.markerId='X'] id name for marker. If only one marker is in a rich text, this can be omitted.
* @return {string}
*/
export function getTooltipMarker(opt, extraCssText) {
@@ -143,17 +145,14 @@ export function getTooltipMarker(opt, extraCssText) {
var color = opt.color;
var type = opt.type;
var extraCssText = opt.extraCssText;
- var isRich = opt.isRich == null ? false : opt.isRich;
+ var renderMode = opt.renderMode || 'html';
+ var markerId = opt.markerId || 'X';
if (!color) {
return '';
}
- if (isRich) {
- // Space for rich element marker
- return '{marker' + opt.markerId + '|} ';
- }
- else {
+ if (renderMode === 'html') {
return type === 'subItem'
? '<span style="display:inline-block;vertical-align:middle;margin-right:8px;margin-left:3px;'
+ 'border-radius:4px;width:4px;height:4px;background-color:'
@@ -162,6 +161,16 @@ export function getTooltipMarker(opt, extraCssText) {
+ 'border-radius:10px;width:10px;height:10px;background-color:'
+ encodeHTML(color) + ';' + (extraCssText || '') + '"></span>';
}
+ else {
+ // Space for rich element marker
+ return {
+ renderMode: renderMode,
+ content: '{marker' + markerId + '|} ',
+ style: {
+ color: color
+ }
+ };
+ }
}
function pad(str, len) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org