提交 045369d3 编写于 作者: S sushuang

Fix hoverStyle on zr hoverLayer.

上级 0ae97035
......@@ -345,7 +345,7 @@ symbolProto._updateCommon = function (data, idx, symbolSize, seriesScope) {
function onEmphasis() {
// Do not support this hover animation util some scenario required.
// Animation can only be supported in hover layer when using `el.incremetal`.
if (this.incremental || graphic.isInEmphasis(this)) {
if (this.incremental || this.useHoverLayer || graphic.isInEmphasis(this)) {
return;
}
var scale = this.__symbolOriginalScale;
......@@ -359,7 +359,7 @@ function onEmphasis() {
}
function onNormal() {
if (this.incremental || graphic.isInEmphasis(this)) {
if (this.incremental || this.useHoverLayer || graphic.isInEmphasis(this)) {
return;
}
this.animateTo({
......
......@@ -241,8 +241,23 @@ function hasFillOrStroke(fillOrStroke) {
return fillOrStroke != null && fillOrStroke != 'none';
}
// Most lifted color are duplicated.
var liftedColorMap = zrUtil.createHashMap();
var liftedColorCount = 0;
function liftColor(color) {
return typeof color === 'string' ? colorTool.lift(color, -0.1) : color;
if (typeof color !== 'string') {
return color;
}
var liftedColor = liftedColorMap.get(color);
if (!liftedColor) {
liftedColor = colorTool.lift(color, -0.1);
if (liftedColorCount < 10000) {
liftedColorMap.set(color, liftedColor);
liftedColorCount++;
}
}
return liftedColor;
}
function cacheElementStl(el) {
......@@ -258,54 +273,51 @@ function cacheElementStl(el) {
}
var normalStyle = el.__normalStl = {};
// Create default hoverStyle on mouseover
var stroke = el.style.stroke;
var fill = el.style.fill;
hoverStyle.fill = hoverStyle.fill
|| (hasFillOrStroke(fill) ? liftColor(fill) : null);
hoverStyle.stroke = hoverStyle.stroke
|| (hasFillOrStroke(stroke) ? liftColor(stroke) : null);
var elStyle = el.style;
for (var name in hoverStyle) {
// See comment in `doSingleEnterHover`.
if (hoverStyle[name] != null) {
normalStyle[name] = el.style[name];
normalStyle[name] = elStyle[name];
}
}
// Always cache fill and stroke to normalStyle for lifting color.
normalStyle.fill = elStyle.fill;
normalStyle.stroke = elStyle.stroke;
}
function doSingleEnterHover(el) {
var hoverStl = el.__hoverStl;
if (!hoverStl || el.__isHover) {
if (!hoverStl || el.__highlighted) {
return;
}
if (el.useHoverLayer) {
el.__zr && el.__zr.addHover(el, hoverStl);
}
else {
doSingleApplyHoverStyle(el);
}
var useHoverLayer = el.useHoverLayer;
el.__highlighted = useHoverLayer ? 'layer' : 'plain';
el.__isHover = true;
}
var zr = el.__zr;
if (!zr && useHoverLayer) {
return;
}
function doSingleApplyHoverStyle(el) {
var style = el.style;
var hoverStl = el.__hoverStl;
var elTarget = el;
var targetStyle = el.style;
if (!hoverStl) {
return;
if (useHoverLayer) {
elTarget = zr.addHover(el);
targetStyle = elTarget.style;
}
// Consider case: only `position: 'top'` is set on emphasis, then text
// color should be returned to `autoColor`, rather than remain '#fff'.
// So we should rollback then apply again after style merging.
rollbackDefaultTextStyle(style);
rollbackDefaultTextStyle(targetStyle);
cacheElementStl(el);
if (!useHoverLayer) {
cacheElementStl(elTarget);
}
// styles can be:
// {
......@@ -326,30 +338,39 @@ function doSingleApplyHoverStyle(el) {
// all properties in merge. So we use merge mode when setting style here, where
// only properties that is not `null/undefined` can be set. The disadventage:
// null/undefined can not be used to remove style any more in `emphasis`.
style.extendFrom(hoverStl);
targetStyle.extendFrom(hoverStl);
applyDefaultTextStyle(style);
setDefaultHoverFillStroke(targetStyle, hoverStl, 'fill');
setDefaultHoverFillStroke(targetStyle, hoverStl, 'stroke');
applyDefaultTextStyle(targetStyle);
if (!useHoverLayer) {
el.dirty(false);
el.z2 += 1;
}
}
function doSingleLeaveHover(el) {
if (!el.__isHover) {
return;
function setDefaultHoverFillStroke(targetStyle, hoverStyle, prop) {
if (!hasFillOrStroke(hoverStyle[prop]) && hasFillOrStroke(targetStyle[prop])) {
targetStyle[prop] = liftColor(targetStyle[prop]);
}
}
if (el.useHoverLayer) {
el.__zr && el.__zr.removeHover(el);
}
else {
function doSingleLeaveHover(el) {
if (el.__highlighted) {
doSingleRestoreHoverStyle(el);
el.__highlighted = false;
}
el.__isHover = false;
}
function doSingleRestoreHoverStyle(el) {
var highlighted = el.__highlighted;
if (highlighted === 'layer') {
el.__zr && el.__zr.removeHover(el);
}
else if (highlighted) {
var style = el.style;
var normalStl = el.__normalStl;
......@@ -364,6 +385,7 @@ function doSingleRestoreHoverStyle(el) {
el.z2 -= 1;
}
}
}
function traverseCall(el, method) {
......@@ -390,15 +412,9 @@ export function setElementHoverStyle(el, hoverStl) {
hoverStl = el.__hoverStl = hoverStl !== false && (hoverStl || {});
el.__hoverStlDirty = true;
if (el.__isHover) {
if (el.useHoverLayer) {
// Update hover style on hover layer.
el.__zr && el.__zr.addHover(el, hoverStl);
}
else {
doSingleRestoreHoverStyle(el);
doSingleApplyHoverStyle(el);
}
if (el.__highlighted) {
doSingleLeaveHover(el);
doSingleEnterHover(el);
}
}
......
......@@ -36,19 +36,88 @@ under the License.
background: #146402;
color: #fff;
}
#info {
position: fixed;
left: 0;
top: 0;
background: #fff;
padding: 2px 5px;
z-index: 9999;
box-shadow: 0 0 2px #333;
}
</style>
<div id="info"></div>
<div id="main0"></div>
<div id="main1"></div>
<div id="main2"></div>
<div id="main3"></div>
<div id="main4"></div>
<script>
var useHoverLayer = location.search.indexOf('?useHoverLayer&') >= 0;
var hoverLayerThreshold = useHoverLayer ? 0 : null;
var infoEl = document.getElementById('info');
genInfo();
function genInfo(zrRefreshTimestamp) {
infoEl.innerHTML = [
'hoverLayerThreshold: ' + hoverLayerThreshold,
'zr refresh base layer at: <span style="color:red">' + (zrRefreshTimestamp || null) + '</span>'
].join('<br>');
}
function genHoverLayerBtns() {
return [{
text: 'useHoverLayer',
onclick: function () {
var url = location.href;
if (url.indexOf('?') < 0) {
url += '?';
}
location.href = url.replace('?', '?useHoverLayer&');
}
}, {
text: 'notUseHoverLayer',
onclick: function () {
location.href = location.href.replace(/\?useHoverLayer&/, '\?');
}
}]
}
var originalCreate = testHelper.create;
testHelper.create = function (echarts, dom, opt) {
var buttons = opt.buttons || [];
opt.buttons = buttons = genHoverLayerBtns().concat(buttons);
var chart = originalCreate.call(this, echarts, dom, opt);
var zr = chart.getZr();
var originalRefreshImmediately = zr.refreshImmediately;
zr.refreshImmediately = function () {
var result = originalRefreshImmediately.apply(this, arguments);
// Make sure refreshImmediately is not called when `useHoverLayer`.
genInfo(+new Date());
return result;
};
return chart;
}
</script>
<script>
require(['echarts'], function (echarts) {
var option = {
hoverLayerThreshold: hoverLayerThreshold,
tooltip: {},
xAxis: {
},
......@@ -71,7 +140,8 @@ under the License.
testHelper.create(echarts, 'main0', {
title: [
'normal no label, hover show label inside',
'TEST: hover twice, should be normal'
'TEST: hover twice, should be normal',
'zrBaseLayer should not be refreshed'
],
option: option,
height: 200
......@@ -86,6 +156,7 @@ under the License.
<script>
require(['echarts'], function (echarts) {
var option = {
hoverLayerThreshold: hoverLayerThreshold,
tooltip: {},
xAxis: {
},
......@@ -108,13 +179,14 @@ under the License.
position: 'top'
}
},
data: [[12, 331221], [55, 331221]]
data: [[12, 331221], [20, 331221], [55, 331221]]
}]
};
testHelper.create(echarts, 'main1', {
title: [
'normal label inside, hover label outside top.'
'normal label inside, hover label outside top.',
'lifted color should be able to restore after hover twice.'
],
option: option,
height: 200
......@@ -131,6 +203,7 @@ under the License.
<script>
require(['echarts'], function (echarts) {
var option = {
hoverLayerThreshold: hoverLayerThreshold,
tooltip: {},
xAxis: {
},
......@@ -202,6 +275,7 @@ under the License.
<script>
require(['echarts'], function (echarts) {
var option = {
hoverLayerThreshold: hoverLayerThreshold,
tooltip: {},
xAxis: {
},
......@@ -249,7 +323,7 @@ under the License.
});
}
}, {
text: 'setOption to modify hoverStyle',
text: 'setOption to modify hoverStyle yellow',
onclick: function () {
chart.setOption({
series: [{
......@@ -265,6 +339,23 @@ under the License.
}]
});
}
}, {
text: 'setOption to modify hoverStyle blue',
onclick: function () {
chart.setOption({
series: [{
id: 's',
emphasis: {
itemStyle: {
color: 'blue'
},
label: {
fontSize: 50
}
}
}]
});
}
}, {
text: 'downplay dataIndex 0',
onclick: function () {
......@@ -282,5 +373,57 @@ under the License.
<script>
require(['echarts'], function (echarts) {
var option = {
hoverLayerThreshold: hoverLayerThreshold,
tooltip: {},
xAxis: {
},
yAxis: {
splitNumber: 2,
scale: true
},
series: [{
type: 'custom',
renderItem: function (params, api) {
return {
type: 'group',
children: [{
type: 'rect',
shape: {x: 100, y: 30, width: 100, height: 50},
style: {fill: '#333'}
}, {
type: 'rect',
shape: {x: 130, y: 50, width: 100, height: 50},
style: {fill: '#555'}
}, {
type: 'rect',
shape: {x: 160, y: 70, width: 100, height: 50},
style: {fill: '#777'}
}]
};
},
data: [[12, 331221], [55, 331221]]
}]
};
testHelper.create(echarts, 'main4', {
title: [
'custom series: all highlighted when hover, keep z correct'
],
option: option,
height: 200
});
});
</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.
先完成此消息的编辑!
想要评论请 注册