You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
826 lines
26 KiB
826 lines
26 KiB
|
|
/* |
|
* Licensed to the Apache Software Foundation (ASF) under one |
|
* or more contributor license agreements. See the NOTICE file |
|
* distributed with this work for additional information |
|
* regarding copyright ownership. The ASF licenses this file |
|
* to you under the Apache License, Version 2.0 (the |
|
* "License"); you may not use this file except in compliance |
|
* with the License. You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, |
|
* software distributed under the License is distributed on an |
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|
* KIND, either express or implied. See the License for the |
|
* specific language governing permissions and limitations |
|
* under the License. |
|
*/ |
|
|
|
|
|
/** |
|
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|
*/ |
|
|
|
/* |
|
* Licensed to the Apache Software Foundation (ASF) under one |
|
* or more contributor license agreements. See the NOTICE file |
|
* distributed with this work for additional information |
|
* regarding copyright ownership. The ASF licenses this file |
|
* to you under the Apache License, Version 2.0 (the |
|
* "License"); you may not use this file except in compliance |
|
* with the License. You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, |
|
* software distributed under the License is distributed on an |
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|
* KIND, either express or implied. See the License for the |
|
* specific language governing permissions and limitations |
|
* under the License. |
|
*/ |
|
import LRU from 'zrender/lib/core/LRU.js'; |
|
import { extend, indexOf, isArrayLike, isObject, keys, isArray, each, isString, isGradientObject, map } from 'zrender/lib/core/util.js'; |
|
import { getECData } from './innerStore.js'; |
|
import * as colorTool from 'zrender/lib/tool/color.js'; |
|
import { queryDataIndex, makeInner } from './model.js'; |
|
import Path from 'zrender/lib/graphic/Path.js'; |
|
import { error } from './log.js'; // Reserve 0 as default. |
|
|
|
var _highlightNextDigit = 1; |
|
var _highlightKeyMap = {}; |
|
var getSavedStates = makeInner(); |
|
var getComponentStates = makeInner(); |
|
export var HOVER_STATE_NORMAL = 0; |
|
export var HOVER_STATE_BLUR = 1; |
|
export var HOVER_STATE_EMPHASIS = 2; |
|
export var SPECIAL_STATES = ['emphasis', 'blur', 'select']; |
|
export var DISPLAY_STATES = ['normal', 'emphasis', 'blur', 'select']; |
|
export var Z2_EMPHASIS_LIFT = 10; |
|
export var Z2_SELECT_LIFT = 9; |
|
export var HIGHLIGHT_ACTION_TYPE = 'highlight'; |
|
export var DOWNPLAY_ACTION_TYPE = 'downplay'; |
|
export var SELECT_ACTION_TYPE = 'select'; |
|
export var UNSELECT_ACTION_TYPE = 'unselect'; |
|
export var TOGGLE_SELECT_ACTION_TYPE = 'toggleSelect'; |
|
|
|
function hasFillOrStroke(fillOrStroke) { |
|
return fillOrStroke != null && fillOrStroke !== 'none'; |
|
} // Most lifted color are duplicated. |
|
|
|
|
|
var liftedColorCache = new LRU(100); |
|
|
|
function liftColor(color) { |
|
if (isString(color)) { |
|
var liftedColor = liftedColorCache.get(color); |
|
|
|
if (!liftedColor) { |
|
liftedColor = colorTool.lift(color, -0.1); |
|
liftedColorCache.put(color, liftedColor); |
|
} |
|
|
|
return liftedColor; |
|
} else if (isGradientObject(color)) { |
|
var ret = extend({}, color); |
|
ret.colorStops = map(color.colorStops, function (stop) { |
|
return { |
|
offset: stop.offset, |
|
color: colorTool.lift(stop.color, -0.1) |
|
}; |
|
}); |
|
return ret; |
|
} // Change nothing. |
|
|
|
|
|
return color; |
|
} |
|
|
|
function doChangeHoverState(el, stateName, hoverStateEnum) { |
|
if (el.onHoverStateChange && (el.hoverState || 0) !== hoverStateEnum) { |
|
el.onHoverStateChange(stateName); |
|
} |
|
|
|
el.hoverState = hoverStateEnum; |
|
} |
|
|
|
function singleEnterEmphasis(el) { |
|
// Only mark the flag. |
|
// States will be applied in the echarts.ts in next frame. |
|
doChangeHoverState(el, 'emphasis', HOVER_STATE_EMPHASIS); |
|
} |
|
|
|
function singleLeaveEmphasis(el) { |
|
// Only mark the flag. |
|
// States will be applied in the echarts.ts in next frame. |
|
if (el.hoverState === HOVER_STATE_EMPHASIS) { |
|
doChangeHoverState(el, 'normal', HOVER_STATE_NORMAL); |
|
} |
|
} |
|
|
|
function singleEnterBlur(el) { |
|
doChangeHoverState(el, 'blur', HOVER_STATE_BLUR); |
|
} |
|
|
|
function singleLeaveBlur(el) { |
|
if (el.hoverState === HOVER_STATE_BLUR) { |
|
doChangeHoverState(el, 'normal', HOVER_STATE_NORMAL); |
|
} |
|
} |
|
|
|
function singleEnterSelect(el) { |
|
el.selected = true; |
|
} |
|
|
|
function singleLeaveSelect(el) { |
|
el.selected = false; |
|
} |
|
|
|
function updateElementState(el, updater, commonParam) { |
|
updater(el, commonParam); |
|
} |
|
|
|
function traverseUpdateState(el, updater, commonParam) { |
|
updateElementState(el, updater, commonParam); |
|
el.isGroup && el.traverse(function (child) { |
|
updateElementState(child, updater, commonParam); |
|
}); |
|
} |
|
|
|
export function setStatesFlag(el, stateName) { |
|
switch (stateName) { |
|
case 'emphasis': |
|
el.hoverState = HOVER_STATE_EMPHASIS; |
|
break; |
|
|
|
case 'normal': |
|
el.hoverState = HOVER_STATE_NORMAL; |
|
break; |
|
|
|
case 'blur': |
|
el.hoverState = HOVER_STATE_BLUR; |
|
break; |
|
|
|
case 'select': |
|
el.selected = true; |
|
} |
|
} |
|
/** |
|
* If we reuse elements when rerender. |
|
* DON'T forget to clearStates before we update the style and shape. |
|
* Or we may update on the wrong state instead of normal state. |
|
*/ |
|
|
|
export function clearStates(el) { |
|
if (el.isGroup) { |
|
el.traverse(function (child) { |
|
child.clearStates(); |
|
}); |
|
} else { |
|
el.clearStates(); |
|
} |
|
} |
|
|
|
function getFromStateStyle(el, props, toStateName, defaultValue) { |
|
var style = el.style; |
|
var fromState = {}; |
|
|
|
for (var i = 0; i < props.length; i++) { |
|
var propName = props[i]; |
|
var val = style[propName]; |
|
fromState[propName] = val == null ? defaultValue && defaultValue[propName] : val; |
|
} |
|
|
|
for (var i = 0; i < el.animators.length; i++) { |
|
var animator = el.animators[i]; |
|
|
|
if (animator.__fromStateTransition // Don't consider the animation to emphasis state. |
|
&& animator.__fromStateTransition.indexOf(toStateName) < 0 && animator.targetName === 'style') { |
|
animator.saveTo(fromState, props); |
|
} |
|
} |
|
|
|
return fromState; |
|
} |
|
|
|
function createEmphasisDefaultState(el, stateName, targetStates, state) { |
|
var hasSelect = targetStates && indexOf(targetStates, 'select') >= 0; |
|
var cloned = false; |
|
|
|
if (el instanceof Path) { |
|
var store = getSavedStates(el); |
|
var fromFill = hasSelect ? store.selectFill || store.normalFill : store.normalFill; |
|
var fromStroke = hasSelect ? store.selectStroke || store.normalStroke : store.normalStroke; |
|
|
|
if (hasFillOrStroke(fromFill) || hasFillOrStroke(fromStroke)) { |
|
state = state || {}; |
|
var emphasisStyle = state.style || {}; // inherit case |
|
|
|
if (emphasisStyle.fill === 'inherit') { |
|
cloned = true; |
|
state = extend({}, state); |
|
emphasisStyle = extend({}, emphasisStyle); |
|
emphasisStyle.fill = fromFill; |
|
} // Apply default color lift |
|
else if (!hasFillOrStroke(emphasisStyle.fill) && hasFillOrStroke(fromFill)) { |
|
cloned = true; // Not modify the original value. |
|
|
|
state = extend({}, state); |
|
emphasisStyle = extend({}, emphasisStyle); // Already being applied 'emphasis'. DON'T lift color multiple times. |
|
|
|
emphasisStyle.fill = liftColor(fromFill); |
|
} // Not highlight stroke if fill has been highlighted. |
|
else if (!hasFillOrStroke(emphasisStyle.stroke) && hasFillOrStroke(fromStroke)) { |
|
if (!cloned) { |
|
state = extend({}, state); |
|
emphasisStyle = extend({}, emphasisStyle); |
|
} |
|
|
|
emphasisStyle.stroke = liftColor(fromStroke); |
|
} |
|
|
|
state.style = emphasisStyle; |
|
} |
|
} |
|
|
|
if (state) { |
|
// TODO Share with textContent? |
|
if (state.z2 == null) { |
|
if (!cloned) { |
|
state = extend({}, state); |
|
} |
|
|
|
var z2EmphasisLift = el.z2EmphasisLift; |
|
state.z2 = el.z2 + (z2EmphasisLift != null ? z2EmphasisLift : Z2_EMPHASIS_LIFT); |
|
} |
|
} |
|
|
|
return state; |
|
} |
|
|
|
function createSelectDefaultState(el, stateName, state) { |
|
// const hasSelect = indexOf(el.currentStates, stateName) >= 0; |
|
if (state) { |
|
// TODO Share with textContent? |
|
if (state.z2 == null) { |
|
state = extend({}, state); |
|
var z2SelectLift = el.z2SelectLift; |
|
state.z2 = el.z2 + (z2SelectLift != null ? z2SelectLift : Z2_SELECT_LIFT); |
|
} |
|
} |
|
|
|
return state; |
|
} |
|
|
|
function createBlurDefaultState(el, stateName, state) { |
|
var hasBlur = indexOf(el.currentStates, stateName) >= 0; |
|
var currentOpacity = el.style.opacity; |
|
var fromState = !hasBlur ? getFromStateStyle(el, ['opacity'], stateName, { |
|
opacity: 1 |
|
}) : null; |
|
state = state || {}; |
|
var blurStyle = state.style || {}; |
|
|
|
if (blurStyle.opacity == null) { |
|
// clone state |
|
state = extend({}, state); |
|
blurStyle = extend({ |
|
// Already being applied 'emphasis'. DON'T mul opacity multiple times. |
|
opacity: hasBlur ? currentOpacity : fromState.opacity * 0.1 |
|
}, blurStyle); |
|
state.style = blurStyle; |
|
} |
|
|
|
return state; |
|
} |
|
|
|
function elementStateProxy(stateName, targetStates) { |
|
var state = this.states[stateName]; |
|
|
|
if (this.style) { |
|
if (stateName === 'emphasis') { |
|
return createEmphasisDefaultState(this, stateName, targetStates, state); |
|
} else if (stateName === 'blur') { |
|
return createBlurDefaultState(this, stateName, state); |
|
} else if (stateName === 'select') { |
|
return createSelectDefaultState(this, stateName, state); |
|
} |
|
} |
|
|
|
return state; |
|
} |
|
/** |
|
* Set hover style (namely "emphasis style") of element. |
|
* @param el Should not be `zrender/graphic/Group`. |
|
* @param focus 'self' | 'selfInSeries' | 'series' |
|
*/ |
|
|
|
|
|
export function setDefaultStateProxy(el) { |
|
el.stateProxy = elementStateProxy; |
|
var textContent = el.getTextContent(); |
|
var textGuide = el.getTextGuideLine(); |
|
|
|
if (textContent) { |
|
textContent.stateProxy = elementStateProxy; |
|
} |
|
|
|
if (textGuide) { |
|
textGuide.stateProxy = elementStateProxy; |
|
} |
|
} |
|
export function enterEmphasisWhenMouseOver(el, e) { |
|
!shouldSilent(el, e) // "emphasis" event highlight has higher priority than mouse highlight. |
|
&& !el.__highByOuter && traverseUpdateState(el, singleEnterEmphasis); |
|
} |
|
export function leaveEmphasisWhenMouseOut(el, e) { |
|
!shouldSilent(el, e) // "emphasis" event highlight has higher priority than mouse highlight. |
|
&& !el.__highByOuter && traverseUpdateState(el, singleLeaveEmphasis); |
|
} |
|
export function enterEmphasis(el, highlightDigit) { |
|
el.__highByOuter |= 1 << (highlightDigit || 0); |
|
traverseUpdateState(el, singleEnterEmphasis); |
|
} |
|
export function leaveEmphasis(el, highlightDigit) { |
|
!(el.__highByOuter &= ~(1 << (highlightDigit || 0))) && traverseUpdateState(el, singleLeaveEmphasis); |
|
} |
|
export function enterBlur(el) { |
|
traverseUpdateState(el, singleEnterBlur); |
|
} |
|
export function leaveBlur(el) { |
|
traverseUpdateState(el, singleLeaveBlur); |
|
} |
|
export function enterSelect(el) { |
|
traverseUpdateState(el, singleEnterSelect); |
|
} |
|
export function leaveSelect(el) { |
|
traverseUpdateState(el, singleLeaveSelect); |
|
} |
|
|
|
function shouldSilent(el, e) { |
|
return el.__highDownSilentOnTouch && e.zrByTouch; |
|
} |
|
|
|
export function allLeaveBlur(api) { |
|
var model = api.getModel(); |
|
var leaveBlurredSeries = []; |
|
var allComponentViews = []; |
|
model.eachComponent(function (componentType, componentModel) { |
|
var componentStates = getComponentStates(componentModel); |
|
var isSeries = componentType === 'series'; |
|
var view = isSeries ? api.getViewOfSeriesModel(componentModel) : api.getViewOfComponentModel(componentModel); |
|
!isSeries && allComponentViews.push(view); |
|
|
|
if (componentStates.isBlured) { |
|
// Leave blur anyway |
|
view.group.traverse(function (child) { |
|
singleLeaveBlur(child); |
|
}); |
|
isSeries && leaveBlurredSeries.push(componentModel); |
|
} |
|
|
|
componentStates.isBlured = false; |
|
}); |
|
each(allComponentViews, function (view) { |
|
if (view && view.toggleBlurSeries) { |
|
view.toggleBlurSeries(leaveBlurredSeries, false, model); |
|
} |
|
}); |
|
} |
|
export function blurSeries(targetSeriesIndex, focus, blurScope, api) { |
|
var ecModel = api.getModel(); |
|
blurScope = blurScope || 'coordinateSystem'; |
|
|
|
function leaveBlurOfIndices(data, dataIndices) { |
|
for (var i = 0; i < dataIndices.length; i++) { |
|
var itemEl = data.getItemGraphicEl(dataIndices[i]); |
|
itemEl && leaveBlur(itemEl); |
|
} |
|
} |
|
|
|
if (targetSeriesIndex == null) { |
|
return; |
|
} |
|
|
|
if (!focus || focus === 'none') { |
|
return; |
|
} |
|
|
|
var targetSeriesModel = ecModel.getSeriesByIndex(targetSeriesIndex); |
|
var targetCoordSys = targetSeriesModel.coordinateSystem; |
|
|
|
if (targetCoordSys && targetCoordSys.master) { |
|
targetCoordSys = targetCoordSys.master; |
|
} |
|
|
|
var blurredSeries = []; |
|
ecModel.eachSeries(function (seriesModel) { |
|
var sameSeries = targetSeriesModel === seriesModel; |
|
var coordSys = seriesModel.coordinateSystem; |
|
|
|
if (coordSys && coordSys.master) { |
|
coordSys = coordSys.master; |
|
} |
|
|
|
var sameCoordSys = coordSys && targetCoordSys ? coordSys === targetCoordSys : sameSeries; // If there is no coordinate system. use sameSeries instead. |
|
|
|
if (!( // Not blur other series if blurScope series |
|
blurScope === 'series' && !sameSeries // Not blur other coordinate system if blurScope is coordinateSystem |
|
|| blurScope === 'coordinateSystem' && !sameCoordSys // Not blur self series if focus is series. |
|
|| focus === 'series' && sameSeries // TODO blurScope: coordinate system |
|
)) { |
|
var view = api.getViewOfSeriesModel(seriesModel); |
|
view.group.traverse(function (child) { |
|
// For the elements that have been triggered by other components, |
|
// and are still required to be highlighted, |
|
// because the current is directly forced to blur the element, |
|
// it will cause the focus self to be unable to highlight, so skip the blur of this element. |
|
if (child.__highByOuter && sameSeries && focus === 'self') { |
|
return; |
|
} |
|
|
|
singleEnterBlur(child); |
|
}); |
|
|
|
if (isArrayLike(focus)) { |
|
leaveBlurOfIndices(seriesModel.getData(), focus); |
|
} else if (isObject(focus)) { |
|
var dataTypes = keys(focus); |
|
|
|
for (var d = 0; d < dataTypes.length; d++) { |
|
leaveBlurOfIndices(seriesModel.getData(dataTypes[d]), focus[dataTypes[d]]); |
|
} |
|
} |
|
|
|
blurredSeries.push(seriesModel); |
|
getComponentStates(seriesModel).isBlured = true; |
|
} |
|
}); |
|
ecModel.eachComponent(function (componentType, componentModel) { |
|
if (componentType === 'series') { |
|
return; |
|
} |
|
|
|
var view = api.getViewOfComponentModel(componentModel); |
|
|
|
if (view && view.toggleBlurSeries) { |
|
view.toggleBlurSeries(blurredSeries, true, ecModel); |
|
} |
|
}); |
|
} |
|
export function blurComponent(componentMainType, componentIndex, api) { |
|
if (componentMainType == null || componentIndex == null) { |
|
return; |
|
} |
|
|
|
var componentModel = api.getModel().getComponent(componentMainType, componentIndex); |
|
|
|
if (!componentModel) { |
|
return; |
|
} |
|
|
|
getComponentStates(componentModel).isBlured = true; |
|
var view = api.getViewOfComponentModel(componentModel); |
|
|
|
if (!view || !view.focusBlurEnabled) { |
|
return; |
|
} |
|
|
|
view.group.traverse(function (child) { |
|
singleEnterBlur(child); |
|
}); |
|
} |
|
export function blurSeriesFromHighlightPayload(seriesModel, payload, api) { |
|
var seriesIndex = seriesModel.seriesIndex; |
|
var data = seriesModel.getData(payload.dataType); |
|
|
|
if (!data) { |
|
if (process.env.NODE_ENV !== 'production') { |
|
error("Unknown dataType " + payload.dataType); |
|
} |
|
|
|
return; |
|
} |
|
|
|
var dataIndex = queryDataIndex(data, payload); // Pick the first one if there is multiple/none exists. |
|
|
|
dataIndex = (isArray(dataIndex) ? dataIndex[0] : dataIndex) || 0; |
|
var el = data.getItemGraphicEl(dataIndex); |
|
|
|
if (!el) { |
|
var count = data.count(); |
|
var current = 0; // If data on dataIndex is NaN. |
|
|
|
while (!el && current < count) { |
|
el = data.getItemGraphicEl(current++); |
|
} |
|
} |
|
|
|
if (el) { |
|
var ecData = getECData(el); |
|
blurSeries(seriesIndex, ecData.focus, ecData.blurScope, api); |
|
} else { |
|
// If there is no element put on the data. Try getting it from raw option |
|
// TODO Should put it on seriesModel? |
|
var focus_1 = seriesModel.get(['emphasis', 'focus']); |
|
var blurScope = seriesModel.get(['emphasis', 'blurScope']); |
|
|
|
if (focus_1 != null) { |
|
blurSeries(seriesIndex, focus_1, blurScope, api); |
|
} |
|
} |
|
} |
|
export function findComponentHighDownDispatchers(componentMainType, componentIndex, name, api) { |
|
var ret = { |
|
focusSelf: false, |
|
dispatchers: null |
|
}; |
|
|
|
if (componentMainType == null || componentMainType === 'series' || componentIndex == null || name == null) { |
|
return ret; |
|
} |
|
|
|
var componentModel = api.getModel().getComponent(componentMainType, componentIndex); |
|
|
|
if (!componentModel) { |
|
return ret; |
|
} |
|
|
|
var view = api.getViewOfComponentModel(componentModel); |
|
|
|
if (!view || !view.findHighDownDispatchers) { |
|
return ret; |
|
} |
|
|
|
var dispatchers = view.findHighDownDispatchers(name); // At presnet, the component (like Geo) only blur inside itself. |
|
// So we do not use `blurScope` in component. |
|
|
|
var focusSelf; |
|
|
|
for (var i = 0; i < dispatchers.length; i++) { |
|
if (process.env.NODE_ENV !== 'production' && !isHighDownDispatcher(dispatchers[i])) { |
|
error('param should be highDownDispatcher'); |
|
} |
|
|
|
if (getECData(dispatchers[i]).focus === 'self') { |
|
focusSelf = true; |
|
break; |
|
} |
|
} |
|
|
|
return { |
|
focusSelf: focusSelf, |
|
dispatchers: dispatchers |
|
}; |
|
} |
|
export function handleGlobalMouseOverForHighDown(dispatcher, e, api) { |
|
if (process.env.NODE_ENV !== 'production' && !isHighDownDispatcher(dispatcher)) { |
|
error('param should be highDownDispatcher'); |
|
} |
|
|
|
var ecData = getECData(dispatcher); |
|
|
|
var _a = findComponentHighDownDispatchers(ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api), |
|
dispatchers = _a.dispatchers, |
|
focusSelf = _a.focusSelf; // If `findHighDownDispatchers` is supported on the component, |
|
// highlight/downplay elements with the same name. |
|
|
|
|
|
if (dispatchers) { |
|
if (focusSelf) { |
|
blurComponent(ecData.componentMainType, ecData.componentIndex, api); |
|
} |
|
|
|
each(dispatchers, function (dispatcher) { |
|
return enterEmphasisWhenMouseOver(dispatcher, e); |
|
}); |
|
} else { |
|
// Try blur all in the related series. Then emphasis the hoverred. |
|
// TODO. progressive mode. |
|
blurSeries(ecData.seriesIndex, ecData.focus, ecData.blurScope, api); |
|
|
|
if (ecData.focus === 'self') { |
|
blurComponent(ecData.componentMainType, ecData.componentIndex, api); |
|
} // Other than series, component that not support `findHighDownDispatcher` will |
|
// also use it. But in this case, highlight/downplay are only supported in |
|
// mouse hover but not in dispatchAction. |
|
|
|
|
|
enterEmphasisWhenMouseOver(dispatcher, e); |
|
} |
|
} |
|
export function handleGlobalMouseOutForHighDown(dispatcher, e, api) { |
|
if (process.env.NODE_ENV !== 'production' && !isHighDownDispatcher(dispatcher)) { |
|
error('param should be highDownDispatcher'); |
|
} |
|
|
|
allLeaveBlur(api); |
|
var ecData = getECData(dispatcher); |
|
var dispatchers = findComponentHighDownDispatchers(ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api).dispatchers; |
|
|
|
if (dispatchers) { |
|
each(dispatchers, function (dispatcher) { |
|
return leaveEmphasisWhenMouseOut(dispatcher, e); |
|
}); |
|
} else { |
|
leaveEmphasisWhenMouseOut(dispatcher, e); |
|
} |
|
} |
|
export function toggleSelectionFromPayload(seriesModel, payload, api) { |
|
if (!isSelectChangePayload(payload)) { |
|
return; |
|
} |
|
|
|
var dataType = payload.dataType; |
|
var data = seriesModel.getData(dataType); |
|
var dataIndex = queryDataIndex(data, payload); |
|
|
|
if (!isArray(dataIndex)) { |
|
dataIndex = [dataIndex]; |
|
} |
|
|
|
seriesModel[payload.type === TOGGLE_SELECT_ACTION_TYPE ? 'toggleSelect' : payload.type === SELECT_ACTION_TYPE ? 'select' : 'unselect'](dataIndex, dataType); |
|
} |
|
export function updateSeriesElementSelection(seriesModel) { |
|
var allData = seriesModel.getAllData(); |
|
each(allData, function (_a) { |
|
var data = _a.data, |
|
type = _a.type; |
|
data.eachItemGraphicEl(function (el, idx) { |
|
seriesModel.isSelected(idx, type) ? enterSelect(el) : leaveSelect(el); |
|
}); |
|
}); |
|
} |
|
export function getAllSelectedIndices(ecModel) { |
|
var ret = []; |
|
ecModel.eachSeries(function (seriesModel) { |
|
var allData = seriesModel.getAllData(); |
|
each(allData, function (_a) { |
|
var data = _a.data, |
|
type = _a.type; |
|
var dataIndices = seriesModel.getSelectedDataIndices(); |
|
|
|
if (dataIndices.length > 0) { |
|
var item = { |
|
dataIndex: dataIndices, |
|
seriesIndex: seriesModel.seriesIndex |
|
}; |
|
|
|
if (type != null) { |
|
item.dataType = type; |
|
} |
|
|
|
ret.push(item); |
|
} |
|
}); |
|
}); |
|
return ret; |
|
} |
|
/** |
|
* Enable the function that mouseover will trigger the emphasis state. |
|
* |
|
* NOTE: |
|
* This function should be used on the element with dataIndex, seriesIndex. |
|
* |
|
*/ |
|
|
|
export function enableHoverEmphasis(el, focus, blurScope) { |
|
setAsHighDownDispatcher(el, true); |
|
traverseUpdateState(el, setDefaultStateProxy); |
|
enableHoverFocus(el, focus, blurScope); |
|
} |
|
export function disableHoverEmphasis(el) { |
|
setAsHighDownDispatcher(el, false); |
|
} |
|
export function toggleHoverEmphasis(el, focus, blurScope, isDisabled) { |
|
isDisabled ? disableHoverEmphasis(el) : enableHoverEmphasis(el, focus, blurScope); |
|
} |
|
export function enableHoverFocus(el, focus, blurScope) { |
|
var ecData = getECData(el); |
|
|
|
if (focus != null) { |
|
// TODO dataIndex may be set after this function. This check is not useful. |
|
// if (ecData.dataIndex == null) { |
|
// if (__DEV__) { |
|
// console.warn('focus can only been set on element with dataIndex'); |
|
// } |
|
// } |
|
// else { |
|
ecData.focus = focus; |
|
ecData.blurScope = blurScope; // } |
|
} else if (ecData.focus) { |
|
ecData.focus = null; |
|
} |
|
} |
|
var OTHER_STATES = ['emphasis', 'blur', 'select']; |
|
var defaultStyleGetterMap = { |
|
itemStyle: 'getItemStyle', |
|
lineStyle: 'getLineStyle', |
|
areaStyle: 'getAreaStyle' |
|
}; |
|
/** |
|
* Set emphasis/blur/selected states of element. |
|
*/ |
|
|
|
export function setStatesStylesFromModel(el, itemModel, styleType, // default itemStyle |
|
getter) { |
|
styleType = styleType || 'itemStyle'; |
|
|
|
for (var i = 0; i < OTHER_STATES.length; i++) { |
|
var stateName = OTHER_STATES[i]; |
|
var model = itemModel.getModel([stateName, styleType]); |
|
var state = el.ensureState(stateName); // Let it throw error if getterType is not found. |
|
|
|
state.style = getter ? getter(model) : model[defaultStyleGetterMap[styleType]](); |
|
} |
|
} |
|
/** |
|
* |
|
* Set element as highlight / downplay dispatcher. |
|
* It will be checked when element received mouseover event or from highlight action. |
|
* It's in change of all highlight/downplay behavior of it's children. |
|
* |
|
* @param el |
|
* @param el.highDownSilentOnTouch |
|
* In touch device, mouseover event will be trigger on touchstart event |
|
* (see module:zrender/dom/HandlerProxy). By this mechanism, we can |
|
* conveniently use hoverStyle when tap on touch screen without additional |
|
* code for compatibility. |
|
* But if the chart/component has select feature, which usually also use |
|
* hoverStyle, there might be conflict between 'select-highlight' and |
|
* 'hover-highlight' especially when roam is enabled (see geo for example). |
|
* In this case, `highDownSilentOnTouch` should be used to disable |
|
* hover-highlight on touch device. |
|
* @param asDispatcher If `false`, do not set as "highDownDispatcher". |
|
*/ |
|
|
|
export function setAsHighDownDispatcher(el, asDispatcher) { |
|
var disable = asDispatcher === false; |
|
var extendedEl = el; // Make `highDownSilentOnTouch` and `onStateChange` only work after |
|
// `setAsHighDownDispatcher` called. Avoid it is modified by user unexpectedly. |
|
|
|
if (el.highDownSilentOnTouch) { |
|
extendedEl.__highDownSilentOnTouch = el.highDownSilentOnTouch; |
|
} // Simple optimize, since this method might be |
|
// called for each elements of a group in some cases. |
|
|
|
|
|
if (!disable || extendedEl.__highDownDispatcher) { |
|
// Emphasis, normal can be triggered manually by API or other components like hover link. |
|
// el[method]('emphasis', onElementEmphasisEvent)[method]('normal', onElementNormalEvent); |
|
// Also keep previous record. |
|
extendedEl.__highByOuter = extendedEl.__highByOuter || 0; |
|
extendedEl.__highDownDispatcher = !disable; |
|
} |
|
} |
|
export function isHighDownDispatcher(el) { |
|
return !!(el && el.__highDownDispatcher); |
|
} |
|
/** |
|
* Enable component highlight/downplay features: |
|
* + hover link (within the same name) |
|
* + focus blur in component |
|
*/ |
|
|
|
export function enableComponentHighDownFeatures(el, componentModel, componentHighDownName) { |
|
var ecData = getECData(el); |
|
ecData.componentMainType = componentModel.mainType; |
|
ecData.componentIndex = componentModel.componentIndex; |
|
ecData.componentHighDownName = componentHighDownName; |
|
} |
|
/** |
|
* Support highlight/downplay record on each elements. |
|
* For the case: hover highlight/downplay (legend, visualMap, ...) and |
|
* user triggered highlight/downplay should not conflict. |
|
* Only all of the highlightDigit cleared, return to normal. |
|
* @param {string} highlightKey |
|
* @return {number} highlightDigit |
|
*/ |
|
|
|
export function getHighlightDigit(highlightKey) { |
|
var highlightDigit = _highlightKeyMap[highlightKey]; |
|
|
|
if (highlightDigit == null && _highlightNextDigit <= 32) { |
|
highlightDigit = _highlightKeyMap[highlightKey] = _highlightNextDigit++; |
|
} |
|
|
|
return highlightDigit; |
|
} |
|
export function isSelectChangePayload(payload) { |
|
var payloadType = payload.type; |
|
return payloadType === SELECT_ACTION_TYPE || payloadType === UNSELECT_ACTION_TYPE || payloadType === TOGGLE_SELECT_ACTION_TYPE; |
|
} |
|
export function isHighDownPayload(payload) { |
|
var payloadType = payload.type; |
|
return payloadType === HIGHLIGHT_ACTION_TYPE || payloadType === DOWNPLAY_ACTION_TYPE; |
|
} |
|
export function savePathStates(el) { |
|
var store = getSavedStates(el); |
|
store.normalFill = el.style.fill; |
|
store.normalStroke = el.style.stroke; |
|
var selectState = el.states.select || {}; |
|
store.selectFill = selectState.style && selectState.style.fill || null; |
|
store.selectStroke = selectState.style && selectState.style.stroke || null; |
|
} |