123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630 |
- "use strict";
- var Util = require('../util/common');
- var Global = require('../global');
- var Tooltip = require('../component/tooltip');
- var Helper = require('../util/helper'); // Register the default configuration for Tooltip
- Global.tooltip = Util.deepMix({
- triggerOn: 'press',
- triggerOff: 'pressend',
- alwaysShow: false,
- showTitle: false,
- showCrosshairs: false,
- crosshairsStyle: {
- stroke: 'rgba(0, 0, 0, 0.25)',
- lineWidth: 1
- },
- showTooltipMarker: true,
- background: {
- radius: 1,
- fill: 'rgba(0, 0, 0, 0.65)',
- padding: [3, 5]
- },
- titleStyle: {
- fontSize: 12,
- fill: '#fff',
- textAlign: 'start',
- textBaseline: 'top'
- },
- nameStyle: {
- fontSize: 12,
- fill: 'rgba(255, 255, 255, 0.65)',
- textAlign: 'start',
- textBaseline: 'middle'
- },
- valueStyle: {
- fontSize: 12,
- fill: '#fff',
- textAlign: 'start',
- textBaseline: 'middle'
- },
- showItemMarker: true,
- itemMarkerStyle: {
- radius: 3,
- symbol: 'circle',
- lineWidth: 1,
- stroke: '#fff'
- },
- layout: 'horizontal',
- snap: false
- }, Global.tooltip || {});
- function _getTooltipValueScale(geom) {
- var colorAttr = geom.getAttr('color');
- if (colorAttr) {
- var colorScale = colorAttr.getScale(colorAttr.type);
- if (colorScale.isLinear) {
- return colorScale;
- }
- }
- var xScale = geom.getXScale();
- var yScale = geom.getYScale();
- if (yScale) {
- return yScale;
- }
- return xScale;
- }
- function getTooltipName(geom, origin) {
- var name;
- var nameScale;
- var groupScales = geom._getGroupScales();
- if (groupScales.length) {
- Util.each(groupScales, function (scale) {
- nameScale = scale;
- return false;
- });
- }
- if (nameScale) {
- var field = nameScale.field;
- name = nameScale.getText(origin[field]);
- } else {
- var valueScale = _getTooltipValueScale(geom);
- name = valueScale.alias || valueScale.field;
- }
- return name;
- }
- function getTooltipValue(geom, origin) {
- var scale = _getTooltipValueScale(geom);
- return scale.getText(origin[scale.field]);
- }
- function getTooltipTitle(geom, origin) {
- var position = geom.getAttr('position');
- var field = position.getFields()[0];
- var scale = geom.get('scales')[field];
- return scale.getText(origin[scale.field]);
- }
- function _indexOfArray(items, item) {
- var rst = -1;
- Util.each(items, function (sub, index) {
- if (sub.title === item.title && sub.name === item.name && sub.value === item.value && sub.color === item.color) {
- rst = index;
- return false;
- }
- });
- return rst;
- }
- function _uniqItems(items) {
- var tmp = [];
- Util.each(items, function (item) {
- var index = _indexOfArray(tmp, item);
- if (index === -1) {
- tmp.push(item);
- } else {
- tmp[index] = item;
- }
- });
- return tmp;
- }
- function isEqual(arr1, arr2) {
- return JSON.stringify(arr1) === JSON.stringify(arr2);
- }
- var TooltipController = /*#__PURE__*/function () {
- function TooltipController(cfg) {
- var _this = this;
- this.handleShowEvent = function (ev) {
- var chart = _this.chart;
- if (!_this.enable) return;
- var plot = chart.get('plotRange');
- var point = Util.createEvent(ev, chart);
- if (!Helper.isPointInPlot(point, plot) && !_this._tooltipCfg.alwaysShow) {
- // not in chart plot
- _this.hideTooltip();
- return;
- }
- var lastTimeStamp = _this.timeStamp;
- var timeStamp = +new Date();
- if (timeStamp - lastTimeStamp > 16) {
- _this.showTooltip(point);
- _this.timeStamp = timeStamp;
- }
- };
- this.handleHideEvent = function () {
- if (!_this.enable) return;
- _this.hideTooltip();
- };
- this.enable = true;
- this.cfg = {};
- this.tooltip = null;
- this.chart = null;
- this.timeStamp = 0;
- Util.mix(this, cfg);
- var _chart = this.chart;
- var canvas = _chart.get('canvas');
- this.canvas = canvas;
- this.canvasDom = canvas.get('el');
- }
- var _proto = TooltipController.prototype;
- _proto._setCrosshairsCfg = function _setCrosshairsCfg() {
- var self = this;
- var chart = self.chart;
- var defaultCfg = Util.mix({}, Global.tooltip);
- var geoms = chart.get('geoms');
- var shapes = [];
- Util.each(geoms, function (geom) {
- var type = geom.get('type');
- if (shapes.indexOf(type) === -1) {
- shapes.push(type);
- }
- });
- var coordType = chart.get('coord').type;
- if (geoms.length && (coordType === 'cartesian' || coordType === 'rect')) {
- if (shapes.length === 1 && ['line', 'area', 'path', 'point'].indexOf(shapes[0]) !== -1) {
- Util.mix(defaultCfg, {
- showCrosshairs: true
- });
- }
- }
- return defaultCfg;
- };
- _proto._getMaxLength = function _getMaxLength(cfg) {
- if (cfg === void 0) {
- cfg = {};
- }
- var _cfg = cfg,
- layout = _cfg.layout,
- plotRange = _cfg.plotRange;
- return layout === 'horizontal' ? plotRange.br.x - plotRange.bl.x : plotRange.bl.y - plotRange.tr.y;
- };
- _proto.render = function render() {
- var self = this;
- if (self.tooltip) {
- return;
- }
- var chart = self.chart;
- var canvas = chart.get('canvas');
- var frontPlot = chart.get('frontPlot').addGroup({
- className: 'tooltipContainer',
- zIndex: 10
- });
- var backPlot = chart.get('backPlot').addGroup({
- className: 'tooltipContainer'
- });
- var plotRange = chart.get('plotRange');
- var coord = chart.get('coord');
- var defaultCfg = self._setCrosshairsCfg();
- var cfg = self.cfg; // 通过 chart.tooltip() 接口传入的 tooltip 配置项
- var tooltipCfg = Util.deepMix({
- plotRange: plotRange,
- frontPlot: frontPlot,
- backPlot: backPlot,
- canvas: canvas,
- fixed: coord.transposed || coord.isPolar
- }, defaultCfg, cfg); // 创建 tooltip 实例需要的配置,不应该修改 this.cfg,即用户传入的配置
- tooltipCfg.maxLength = self._getMaxLength(tooltipCfg);
- this._tooltipCfg = tooltipCfg;
- var tooltip = new Tooltip(tooltipCfg);
- self.tooltip = tooltip;
- self.bindEvents();
- };
- _proto.clear = function clear() {
- var tooltip = this.tooltip;
- if (tooltip) {
- tooltip.destroy();
- this.unBindEvents();
- }
- this.tooltip = null;
- this.prePoint = null;
- this._lastActive = null;
- };
- _proto._getTooltipMarkerStyle = function _getTooltipMarkerStyle(cfg) {
- if (cfg === void 0) {
- cfg = {};
- }
- var _cfg2 = cfg,
- type = _cfg2.type,
- items = _cfg2.items;
- var tooltipCfg = this._tooltipCfg;
- if (type === 'rect') {
- var x;
- var y;
- var width;
- var height;
- var chart = this.chart;
- var _chart$get = chart.get('plotRange'),
- tl = _chart$get.tl,
- br = _chart$get.br;
- var coord = chart.get('coord');
- var firstItem = items[0];
- var lastItem = items[items.length - 1];
- var intervalWidth = firstItem.width;
- if (coord.transposed) {
- x = tl.x;
- y = lastItem.y - intervalWidth * 0.75;
- width = br.x - tl.x;
- height = firstItem.y - lastItem.y + 1.5 * intervalWidth;
- } else {
- x = firstItem.x - intervalWidth * 0.75;
- y = tl.y;
- width = lastItem.x - firstItem.x + 1.5 * intervalWidth;
- height = br.y - tl.y;
- }
- cfg.style = Util.mix({
- x: x,
- y: y,
- width: width,
- height: height,
- fill: '#CCD6EC',
- opacity: 0.3
- }, tooltipCfg.tooltipMarkerStyle);
- } else {
- cfg.style = Util.mix({
- radius: 4,
- fill: '#fff',
- lineWidth: 2
- }, tooltipCfg.tooltipMarkerStyle);
- }
- return cfg;
- };
- _proto._setTooltip = function _setTooltip(point, items, tooltipMarkerCfg) {
- if (tooltipMarkerCfg === void 0) {
- tooltipMarkerCfg = {};
- }
- var lastActive = this._lastActive;
- var tooltip = this.tooltip;
- var cfg = this._tooltipCfg;
- items = _uniqItems(items);
- var chart = this.chart;
- var coord = chart.get('coord');
- var yScale = chart.getYScales()[0];
- var snap = cfg.snap;
- if (snap === false && yScale.isLinear) {
- var invertPoint = coord.invertPoint(point);
- var plot = chart.get('plotRange');
- var tip;
- var pos;
- if (Helper.isPointInPlot(point, plot)) {
- if (coord.transposed) {
- tip = yScale.invert(invertPoint.x);
- pos = point.x;
- tooltip.setXTipContent(tip);
- tooltip.setXTipPosition(pos);
- tooltip.setYCrosshairPosition(pos);
- } else {
- tip = yScale.invert(invertPoint.y);
- pos = point.y;
- tooltip.setYTipContent(tip);
- tooltip.setYTipPosition(pos);
- tooltip.setXCrosshairPosition(pos);
- }
- }
- }
- if (cfg.onShow) {
- cfg.onShow({
- x: point.x,
- y: point.y,
- tooltip: tooltip,
- items: items,
- tooltipMarkerCfg: tooltipMarkerCfg
- });
- }
- if (isEqual(lastActive, items)) {
- if (snap === false && (Util.directionEnabled(cfg.crosshairsType, 'y') || cfg.showYTip)) {
- var canvas = this.chart.get('canvas');
- canvas.draw();
- }
- return;
- }
- this._lastActive = items;
- var onChange = cfg.onChange;
- if (onChange) {
- onChange({
- x: point.x,
- y: point.y,
- tooltip: tooltip,
- items: items,
- tooltipMarkerCfg: tooltipMarkerCfg
- });
- }
- var first = items[0];
- var title = first.title || first.name;
- var xTipPosX = first.x;
- if (items.length > 1) {
- xTipPosX = (items[0].x + items[items.length - 1].x) / 2;
- }
- tooltip.setContent(title, items, coord.transposed);
- tooltip.setPosition(items, point);
- if (coord.transposed) {
- var yTipPosY = first.y;
- if (items.length > 1) {
- yTipPosY = (items[0].y + items[items.length - 1].y) / 2;
- }
- tooltip.setYTipContent(title);
- tooltip.setYTipPosition(yTipPosY);
- tooltip.setXCrosshairPosition(yTipPosY);
- if (snap) {
- tooltip.setXTipContent(first.value);
- tooltip.setXTipPosition(xTipPosX);
- tooltip.setYCrosshairPosition(xTipPosX);
- }
- } else {
- tooltip.setXTipContent(title);
- tooltip.setXTipPosition(xTipPosX);
- tooltip.setYCrosshairPosition(xTipPosX);
- if (snap) {
- tooltip.setYTipContent(first.value);
- tooltip.setYTipPosition(first.y);
- tooltip.setXCrosshairPosition(first.y);
- }
- }
- var markerItems = tooltipMarkerCfg.items;
- if (cfg.showTooltipMarker && markerItems.length) {
- tooltipMarkerCfg = this._getTooltipMarkerStyle(tooltipMarkerCfg);
- tooltip.setMarkers(tooltipMarkerCfg);
- } else {
- tooltip.clearMarkers();
- }
- tooltip.show();
- };
- _proto.showTooltip = function showTooltip(point) {
- var self = this;
- var chart = self.chart;
- var tooltipMarkerType;
- var tooltipMarkerItems = [];
- var items = [];
- var cfg = self._tooltipCfg;
- var marker;
- if (cfg.showItemMarker) {
- marker = cfg.itemMarkerStyle;
- }
- var geoms = chart.get('geoms');
- var coord = chart.get('coord');
- Util.each(geoms, function (geom) {
- if (geom.get('visible')) {
- var type = geom.get('type');
- var records = geom.getSnapRecords(point);
- var adjust = geom.get('adjust'); // 漏斗图和金子塔图tooltip位置有问题,暂时不开放显示
- if (type === 'interval' && adjust && adjust.type === 'symmetric') {
- return;
- }
- Util.each(records, function (record) {
- if (record.x && record.y) {
- var x = record.x,
- y = record.y,
- _origin = record._origin,
- color = record.color;
- var tooltipItem = {
- x: x,
- y: Util.isArray(y) ? y[1] : y,
- color: color || Global.defaultColor,
- origin: _origin,
- name: getTooltipName(geom, _origin),
- value: getTooltipValue(geom, _origin),
- title: getTooltipTitle(geom, _origin)
- };
- if (marker) {
- tooltipItem.marker = Util.mix({
- fill: color || Global.defaultColor
- }, marker);
- }
- items.push(tooltipItem);
- if (['line', 'area', 'path'].indexOf(type) !== -1) {
- tooltipMarkerType = 'circle';
- tooltipMarkerItems.push(tooltipItem);
- } else if (type === 'interval' && (coord.type === 'cartesian' || coord.type === 'rect')) {
- tooltipMarkerType = 'rect';
- tooltipItem.width = geom.getSize(record._origin);
- tooltipMarkerItems.push(tooltipItem);
- }
- }
- });
- }
- });
- if (items.length) {
- var tooltipMarkerCfg = {
- items: tooltipMarkerItems,
- type: tooltipMarkerType
- };
- self._setTooltip(point, items, tooltipMarkerCfg);
- } else {
- self.hideTooltip();
- }
- };
- _proto.hideTooltip = function hideTooltip() {
- var cfg = this._tooltipCfg;
- this._lastActive = null;
- var tooltip = this.tooltip;
- if (tooltip) {
- tooltip.hide();
- if (cfg.onHide) {
- cfg.onHide({
- tooltip: tooltip
- });
- }
- var canvas = this.chart.get('canvas');
- canvas.draw();
- }
- };
- _proto._handleEvent = function _handleEvent(methodName, method, action) {
- var canvas = this.canvas;
- Util.each([].concat(methodName), function (aMethod) {
- if (action === 'bind') {
- canvas.on(aMethod, method);
- } else {
- canvas.off(aMethod, method);
- }
- });
- };
- _proto.bindEvents = function bindEvents() {
- var cfg = this._tooltipCfg;
- var triggerOn = cfg.triggerOn,
- triggerOff = cfg.triggerOff,
- alwaysShow = cfg.alwaysShow;
- triggerOn && this._handleEvent(triggerOn, this.handleShowEvent, 'bind'); // 如果 !alwaysShow, 则在手势离开后就隐藏
- if (!alwaysShow) {
- this._handleEvent(triggerOff, this.handleHideEvent, 'bind');
- }
- };
- _proto.unBindEvents = function unBindEvents() {
- var cfg = this._tooltipCfg;
- var triggerOn = cfg.triggerOn,
- triggerOff = cfg.triggerOff,
- alwaysShow = cfg.alwaysShow;
- triggerOn && this._handleEvent(triggerOn, this.handleShowEvent, 'unBind');
- if (!alwaysShow) {
- this._handleEvent(triggerOff, this.handleHideEvent, 'unBind');
- }
- };
- return TooltipController;
- }();
- module.exports = {
- init: function init(chart) {
- var tooltipController = new TooltipController({
- chart: chart
- });
- chart.set('tooltipController', tooltipController);
- chart.tooltip = function (enable, cfg) {
- if (Util.isObject(enable)) {
- cfg = enable;
- enable = true;
- }
- tooltipController.enable = enable;
- if (cfg) {
- tooltipController.cfg = cfg;
- }
- return this;
- };
- },
- afterGeomDraw: function afterGeomDraw(chart) {
- var tooltipController = chart.get('tooltipController');
- tooltipController.render();
- chart.showTooltip = function (point) {
- tooltipController.showTooltip(point);
- return this;
- };
- chart.hideTooltip = function () {
- tooltipController.hideTooltip();
- return this;
- };
- },
- clearInner: function clearInner(chart) {
- var tooltipController = chart.get('tooltipController');
- tooltipController.clear();
- }
- };
|