提交 c667be87 编写于 作者: P pah100

tweak axispointer and tooltip

上级 fb31e6d6
......@@ -45,7 +45,7 @@ define(function(require) {
animationDurationUpdate: 200,
lineStyle: {
color: '#555',
color: '#aaa',
width: 1,
type: 'solid'
},
......@@ -69,9 +69,11 @@ define(function(require) {
borderColor: null,
borderWidth: 0,
shadowBlur: 3,
shadowColor: '#aaa',
shadowOffsetX: 0,
shadowOffsetY: 2
shadowColor: '#aaa'
// Considering applicability, common style should
// better not have shadowOffset.
// shadowOffsetX: 0,
// shadowOffsetY: 2
},
handle: {
......
......@@ -9,8 +9,8 @@ define(function(require) {
var eventTool = require('zrender/core/event');
var throttle = require('../../util/throttle');
var extend = zrUtil.extend;
var clone = zrUtil.clone;
var bind = zrUtil.bind;
/**
* Base axis pointer class in 2D.
......@@ -70,6 +70,12 @@ define(function(require) {
var value = axisPointerModel.get('value');
var status = axisPointerModel.get('status');
// Bind them to `this`, not in closure, otherwise they will not
// be replaced when user calling setOption in not merge mode.
this._axisModel = axisModel;
this._axisPointerModel = axisPointerModel;
this._api = api;
// Optimize: `render` will be called repeatly during mouse move.
// So it is power consuming if performing `render` each time,
// especially on mobile device.
......@@ -105,18 +111,24 @@ define(function(require) {
}
this._lastGraphicKey = graphicKey;
var moveAnimation = this.determineAnimation(axisModel, axisPointerModel);
var moveAnimation = this._moveAnimation =
this.determineAnimation(axisModel, axisPointerModel);
if (!group) {
group = this._group = new graphic.Group();
this.createEl(group, elOption, axisModel, axisPointerModel);
this.createPointerEl(group, elOption, axisModel, axisPointerModel);
this.createLabelEl(group, elOption, axisModel, axisPointerModel);
api.getZr().add(group);
}
else {
this.updateEl(group, moveAnimation, elOption, axisModel, axisPointerModel);
var doUpdateProps = zrUtil.curry(updateProps, axisPointerModel, moveAnimation);
this.updatePointerEl(group, elOption, doUpdateProps, axisPointerModel);
this.updateLabelEl(group, elOption, doUpdateProps, axisPointerModel);
}
this._renderHandle(value, moveAnimation, axisModel, axisPointerModel, api);
updateMandatoryProps(group, axisPointerModel, true);
this._renderHandle(value);
},
/**
......@@ -180,24 +192,10 @@ define(function(require) {
/**
* @protected
*/
createEl: function (group, elOption, axisModel, axisPointerModel) {
var basicOpt = {
z: axisPointerModel.get('z'),
zlevel: axisPointerModel.get('zlevel'),
silent: true
};
this.createPointerEl(group, elOption, basicOpt, axisModel, axisPointerModel);
this.createLabelEl(group, elOption, basicOpt, axisModel, axisPointerModel);
},
/**
* @protected
*/
createPointerEl: function (group, elOption, basicOpt, axisModel, axisPointerModel) {
createPointerEl: function (group, elOption, axisModel, axisPointerModel) {
var pointerOption = elOption.pointer;
var pointerEl = get(group).pointerEl = new graphic[pointerOption.type](
extend(clone(basicOpt), elOption.pointer)
clone(elOption.pointer)
);
group.add(pointerEl);
},
......@@ -205,28 +203,15 @@ define(function(require) {
/**
* @protected
*/
createLabelEl: function (group, elOption, basicOpt, axisModel, axisPointerModel) {
createLabelEl: function (group, elOption, axisModel, axisPointerModel) {
var labelEl = get(group).labelEl = new graphic.Rect(
extend(clone(basicOpt), elOption.label)
clone(elOption.label)
);
group.add(labelEl);
updateLabelShowHide(labelEl, axisPointerModel);
},
/**
* @protected
*/
updateEl: function (group, moveAnimation, elOption, axisModel, axisPointerModel) {
if (!group) {
return;
}
var doUpdateProps = zrUtil.curry(updateProps, axisPointerModel, moveAnimation);
this.updatePointerEl(group, elOption, doUpdateProps, axisPointerModel);
this.updateLabelEl(group, elOption, doUpdateProps, axisPointerModel);
},
/**
* @protected
*/
......@@ -245,8 +230,10 @@ define(function(require) {
var labelEl = get(group).labelEl;
if (labelEl) {
labelEl.setStyle(elOption.label.style);
labelEl.attr('shape', elOption.label.shape);
updateProps(labelEl, {
// Consider text length change in vertical axis, animation should
// be used on shape, otherwise the effect will be weird.
shape: elOption.label.shape,
position: elOption.label.position
});
......@@ -257,12 +244,13 @@ define(function(require) {
/**
* @private
*/
_renderHandle: function (value, moveAnimation, axisModel, axisPointerModel, api) {
_renderHandle: function (value) {
if (this._dragging || !this.updateHandleTransform) {
return;
}
var zr = api.getZr();
var axisPointerModel = this._axisPointerModel;
var zr = this._api.getZr();
var handle = this._handle;
var handleModel = axisPointerModel.getModel('handle');
......@@ -281,19 +269,15 @@ define(function(require) {
// Fot mobile devicem, prevent screen slider on the button.
eventTool.stop(e.event);
},
onmousedown: zrUtil.bind(
this._onHandleDragMove, this, axisModel, axisPointerModel, api, 0, 0
),
drift: zrUtil.bind(
this._onHandleDragMove, this, axisModel, axisPointerModel, api
),
ondragend: zrUtil.bind(
this._onHandleDragEnd, this, axisModel, axisPointerModel, api, moveAnimation
)
onmousedown: bind(this._onHandleDragMove, this, 0, 0),
drift: bind(this._onHandleDragMove, this),
ondragend: bind(this._onHandleDragEnd, this)
});
zr.add(handle);
}
updateMandatoryProps(handle, axisPointerModel, false);
// update style
var includeStyles = [
'color', 'borderColor', 'borderWidth', 'opacity',
......@@ -315,21 +299,27 @@ define(function(require) {
'fixRate'
);
this._moveHandleToValue(handle, value, moveAnimation, axisModel, axisPointerModel, isInit);
this._moveHandleToValue(value, isInit);
},
/**
* @private
*/
_moveHandleToValue: function (handle, value, moveAnimation, axisModel, axisPointerModel, isInit) {
var trans = this.getHandleTransform(value, axisModel, axisPointerModel);
updateProps(axisPointerModel, !isInit && moveAnimation, handle, getHandleTransProps(trans));
_moveHandleToValue: function (value, isInit) {
updateProps(
this._axisPointerModel,
!isInit && this._moveAnimation,
this._handle,
getHandleTransProps(this.getHandleTransform(
value, this._axisModel, this._axisPointerModel
))
);
},
/**
* @private
*/
_onHandleDragMove: function (axisModel, axisPointerModel, api, dx, dy) {
_onHandleDragMove: function (dx, dy) {
var handle = this._handle;
if (!handle) {
return;
......@@ -341,8 +331,8 @@ define(function(require) {
var trans = this.updateHandleTransform(
getHandleTransProps(handle),
[dx, dy],
axisModel,
axisPointerModel
this._axisModel,
this._axisPointerModel
);
this._payloadInfo = trans;
......@@ -350,14 +340,14 @@ define(function(require) {
handle.attr(getHandleTransProps(trans));
get(handle).lastProp = null;
this._doDispatchAxisPointer(axisModel, api);
this._doDispatchAxisPointer();
},
/**
* Throttled method.
* @private
*/
_doDispatchAxisPointer: function (axisModel, api) {
_doDispatchAxisPointer: function () {
var handle = this._handle;
if (!handle) {
return;
......@@ -371,28 +361,28 @@ define(function(require) {
tooltipOption: payloadInfo.tooltipOption,
highDownKey: 'axisPointerHandle'
};
var axis = axisModel.axis;
payload[axis.dim + 'AxisId'] = axisModel.id;
api.dispatchAction(payload);
var axis = this._axisModel.axis;
payload[axis.dim + 'AxisId'] = this._axisModel.id;
this._api.dispatchAction(payload);
},
/**
* @private
*/
_onHandleDragEnd: function (axisModel, axisPointerModel, api, moveAnimation) {
_onHandleDragEnd: function (moveAnimation) {
this._dragging = false;
var handle = this._handle;
if (!handle) {
return;
}
var value = axisPointerModel.get('value');
var value = this._axisPointerModel.get('value');
// Consider snap or categroy axis, handle may be not consistent with
// axisPointer. So move handle to align the exact value position when
// drag ended.
this._moveHandleToValue(handle, value, moveAnimation, axisModel, axisPointerModel);
this._moveHandleToValue(value);
api.dispatchAction({
this._api.dispatchAction({
type: 'hideTip'
});
},
......@@ -527,6 +517,19 @@ define(function(require) {
);
}
function updateMandatoryProps(group, axisPointerModel, silent) {
var z = axisPointerModel.get('z');
var zlevel = axisPointerModel.get('zlevel');
group && group.traverse(function (el) {
if (el.type !== 'group') {
z != null && (el.z = z);
zlevel != null && (el.zlevel = zlevel);
el.silent = silent;
}
});
}
clazzUtil.enableClassExtend(BaseAxisPointer);
return BaseAxisPointer;
......
......@@ -145,7 +145,6 @@ define(function(require) {
});
}
function makeAxisPointerModel(
axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip
) {
......@@ -155,7 +154,7 @@ define(function(require) {
each(
[
'type', 'precision', 'snap', 'lineStyle', 'shadowStyle', 'label',
'animation', 'animationDurationUpdate', 'animationEasingUpdate'
'animation', 'animationDurationUpdate', 'animationEasingUpdate', 'z'
],
function (field) {
volatileOption[field] = zrUtil.clone(tooltipAxisPointerModel.get(field));
......@@ -173,7 +172,8 @@ define(function(require) {
volatileOption.type = 'line';
}
var labelOption = volatileOption.label || (volatileOption.label = {});
labelOption.show = false;
// Follow the convention, do not show label when triggered by tooltip by default.
labelOption.show == null && (labelOption.show = false);
if (fromTooltip === 'cross') {
// When 'cross', both axes show labels.
......@@ -182,7 +182,10 @@ define(function(require) {
// (cross style is dashed by default)
if (!triggerTooltip) {
var crossStyle = volatileOption.lineStyle = tooltipAxisPointerModel.get('crossStyle');
volatileOption.label.textStyle = crossStyle && crossStyle.textStyle;
crossStyle && zrUtil.defaults(
labelOption.textStyle || (labelOption.textStyle = {}),
crossStyle.textStyle
);
}
}
......
......@@ -69,7 +69,7 @@ define(function (require) {
var textStyleModel = tooltipModel.getModel('textStyle');
var padding = tooltipModel.get('padding');
// Animation transition
// Animation transition. Do not animate when transitionDuration is 0.
transitionDuration &&
cssText.push(assembleTransition(transitionDuration));
......@@ -112,7 +112,7 @@ define(function (require) {
*/
function TooltipContent(container, api) {
var el = document.createElement('div');
var zr = api.getZr();
var zr = this._zr = api.getZr();
this.el = el;
......@@ -173,6 +173,8 @@ define(function (require) {
* Update when tooltip is rendered
*/
update: function () {
// FIXME
// Move this logic to ec main?
var container = this._container;
var stl = container.currentStyle
|| document.defaultView.getComputedStyle(container);
......@@ -213,6 +215,16 @@ define(function (require) {
},
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 viewportRoot;
if (zr && zr.painter && (viewportRoot = zr.painter.getViewportRoot())) {
x += viewportRoot.offsetLeft || 0;
y += viewportRoot.offsetTop || 0;
}
var style = this.el.style;
style.left = x + 'px';
style.top = y + 'px';
......@@ -226,8 +238,6 @@ define(function (require) {
this._show = false;
},
// showLater: function ()
hideLater: function (time) {
if (this._show && !(this._inContent && this._enterable)) {
if (time) {
......
......@@ -85,7 +85,7 @@ define(function (require) {
animationEasingUpdate: 'exponentialOut',
crossStyle: {
color: '#555',
color: '#999',
width: 1,
type: 'dashed',
......
......@@ -5,7 +5,7 @@ define(function (require) {
var formatUtil = require('../../util/format');
var numberUtil = require('../../util/number');
var findPointFromSeries = require('../axisPointer/findPointFromSeries');
var parsePercent = numberUtil.parsePercent;
var layoutUtil = require('../../util/layout');
var env = require('zrender/core/env');
var Model = require('../../model/Model');
var globalListener = require('../axisPointer/globalListener');
......@@ -13,6 +13,7 @@ define(function (require) {
var bind = zrUtil.bind;
var each = zrUtil.each;
var parsePercent = numberUtil.parsePercent;
require('../../echarts').extendComponentView({
......@@ -469,21 +470,34 @@ define(function (require) {
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 (typeof positionExpr === 'function') {
// Callback of position can be an array or a string specify the position
positionExpr = positionExpr([x, y], params, content.el, rect);
positionExpr = positionExpr([x, y], params, content.el, rect, {
viewSize: [viewWidth, viewHeight],
contentSize: contentSize.slice()
});
}
var contentSize = content.getSize();
var align = tooltipModel.get('align');
var vAlign = tooltipModel.get('verticalAlign');
if (zrUtil.isArray(positionExpr)) {
x = parsePercent(positionExpr[0], viewWidth);
y = parsePercent(positionExpr[1], viewHeight);
}
// When positionExpr is left/top/right/bottom, align and verticalAlign will not work.
else if (zrUtil.isObject(positionExpr)) {
positionExpr.width = contentSize[0];
positionExpr.height = contentSize[1];
var layoutRect = layoutUtil.getLayoutRect(
positionExpr, {width: viewWidth, height: viewHeight}
);
x = layoutRect.x;
y = layoutRect.y;
}
// Specify tooltip position by string 'top' 'bottom' 'left' 'right' around graphic element
else if (typeof positionExpr === 'string' && el) {
var pos = calcTooltipPosition(
......@@ -500,8 +514,8 @@ define(function (require) {
y = pos[1];
}
align && (x -= align === 'center' ? contentSize[0] / 2 : align === 'right' ? contentSize[0] : 0);
vAlign && (y -= vAlign === 'middle' ? contentSize[1] / 2 : vAlign === 'bottom' ? contentSize[1] : 0);
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 (tooltipModel.get('confine')) {
var pos = confineTooltipPosition(
......@@ -668,4 +682,8 @@ define(function (require) {
return [x, y];
}
function isCenterAlign(align) {
return align === 'center' || align === 'middle';
}
});
\ No newline at end of file
......@@ -370,7 +370,7 @@ define(function(require) {
? opt.name + ''
: existCpt
? existCpt.name
: '\0##';
: '\0-'; // name may be displayed on screen, so use '-'.
if (existCpt) {
keyInfo.id = existCpt.id;
......
......@@ -34,6 +34,8 @@
<div class="chart" id="handle-value-init"></div>
<h1>single coordinate system handle | tooltip time label should be consistent with axisPinter.label.formatter</h1>
<div class="chart" id="themeRiver"></div>
<h1>setOption in not merge mode: (1) drag handle (2) click the eye. Check: handle should be normal</h1>
<div class="chart" id="setOption-merge"></div>
......@@ -339,5 +341,139 @@
<script>
require([
'echarts',
'echarts/chart/line',
'echarts/component/legend',
'echarts/component/grid',
'echarts/component/tooltip',
'echarts/component/dataZoom',
'echarts/component/toolbox',
'zrender/vml/vml'
], function (echarts) {
var base = +new Date(1968, 9, 3);
var oneDay = 24 * 3600 * 1000;
var date = [];
var data = [Math.random() * 300];
for (var i = 1; i < 200; i++) {
var now = new Date(base += oneDay);
date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));
data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));
}
option = {
animation: false,
title: {
left: 'center',
text: '触屏 tooltip 和 dataZoom 示例',
subtext: '"tootip" and "dataZoom" on mobile device',
},
legend: {
top: 'bottom',
data:['意向']
},
tooltip: {
triggerOn: 'none',
position: function (pt) {
return [pt[0], 100];
}
},
toolbox: {
left: 'center',
top: 10,
itemSize: 40,
feature: {
myMerge: {
show: true,
title: 'setOption in NOT merge mode',
icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
onclick: function () {
chart.setOption(option, true);
}
}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
axisPointer: {
lineStyle: {
color: '#215F5A',
width: 2
},
label: {
show: true
},
handle: {
show: true
}
},
data: date
},
yAxis: {
type: 'value',
boundaryGap: [0, '100%']
},
grid: {
top: 70,
left: 20,
right: 30,
containLabel: true,
height: 150
},
dataZoom: [{
type: 'inside',
start: 0,
end: 10
}],
series: [
{
name:'模拟数据',
type:'line',
smooth:true,
symbol: 'none',
sampling: 'average',
itemStyle: {
normal: {
color: '#8ec6ad'
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: '#8ec6ad'
}, {
offset: 1,
color: '#ffe'
}])
}
},
data: data
}
]
};
var chart = createChart('setOption-merge', echarts, option, 400);
});
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册