提交 480dbb8f 编写于 作者: P pissang

refact(states): focusNodeAdjacency changed to focus: 'adjacency' in graph/sankey

上级 c3cc56d0
......@@ -138,7 +138,7 @@ interface CustomBaseElementOption extends Partial<Pick<
// updateDuringAnimation
during?(params: typeof customDuringAPI): void;
focus?: 'none' | 'self' | 'series'
focus?: 'none' | 'self' | 'series' | ArrayLike<number>
blurScope?: BlurScope
};
interface CustomDisplayableOption extends CustomBaseElementOption, Partial<Pick<
......
......@@ -62,7 +62,7 @@ export interface GraphNodeStateOption {
}
export interface GraphNodeItemOption extends SymbolOptionMixin, GraphNodeStateOption,
GraphNodeStateOption, StatesOptionMixin<GraphNodeStateOption> {
GraphNodeStateOption, StatesOptionMixin<GraphNodeStateOption, 'adjacency'> {
id?: string
name?: string
value?: GraphDataValue
......@@ -87,15 +87,14 @@ export interface GraphNodeItemOption extends SymbolOptionMixin, GraphNodeStateOp
category?: number | string
draggable?: boolean
focusNodeAdjacency?: boolean
}
export interface GraphEdgeStateOption {
lineStyle?: GraphEdgeLineStyleOption
label?: LineLabelOption
}
export interface GraphEdgeItemOption extends GraphEdgeStateOption, StatesOptionMixin<GraphEdgeStateOption> {
export interface GraphEdgeItemOption
extends GraphEdgeStateOption, StatesOptionMixin<GraphEdgeStateOption, 'adjacency'> {
/**
* Name or index of source node.
*/
......@@ -115,8 +114,6 @@ export interface GraphEdgeItemOption extends GraphEdgeStateOption, StatesOptionM
symbolSize?: number | number[]
ignoreForceLayout?: boolean
focusNodeAdjacency?: boolean
}
export interface GraphCategoryItemOption extends SymbolOptionMixin,
......@@ -173,6 +170,7 @@ export interface GraphSeriesOption extends SeriesOption,
lineStyle?: GraphEdgeLineStyleOption
emphasis?: {
focus?: StatesOptionMixin<unknown, 'adjacency'>['emphasis']['focus']
label?: LabelOption
edgeLabel?: LabelOption
itemStyle?: ItemStyleOption
......
......@@ -33,49 +33,13 @@ import GraphSeriesModel, { GraphNodeItemOption, GraphEdgeItemOption } from './Gr
import { CoordinateSystem } from '../../coord/CoordinateSystem';
import View from '../../coord/View';
import Symbol from '../helper/Symbol';
import Model from '../../model/Model';
import { Payload } from '../../util/types';
import List from '../../data/List';
import Line from '../helper/Line';
import { GraphNode, GraphEdge } from '../../data/Graph';
const FOCUS_ADJACENCY = '__focusNodeAdjacency';
const UNFOCUS_ADJACENCY = '__unfocusNodeAdjacency';
interface FocusNodePayload extends Payload {
dataIndex: number
edgeDataIndex: number
}
function isViewCoordSys(coordSys: CoordinateSystem): coordSys is View {
return coordSys.type === 'view';
}
function fadeInItem(nodeOrEdge: GraphNode | GraphEdge) {
const el = nodeOrEdge.getGraphicEl() as Symbol | Line;
if (el) {
if ((el as Symbol).getSymbolPath) {
(el as Symbol).getSymbolPath().removeState('blur');
}
else {
(el as Line).getLinePath().removeState('blur');
}
}
}
function fadeOutItem(nodeOrEdge: GraphNode | GraphEdge) {
const el = nodeOrEdge.getGraphicEl() as Symbol | Line;
if (el) {
if ((el as Symbol).getSymbolPath) {
(el as Symbol).getSymbolPath().useState('blur');
}
else {
(el as Line).getLinePath().useState('blur');
}
}
}
class GraphView extends ChartView {
static readonly type = 'graph';
......@@ -115,7 +79,6 @@ class GraphView extends ChartView {
}
render(seriesModel: GraphSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
const graphView = this;
const coordSys = seriesModel.coordinateSystem;
this._model = seriesModel;
......@@ -158,8 +121,10 @@ class GraphView extends ChartView {
this._startForceLayoutIteration(forceLayout, layoutAnimation);
}
data.eachItemGraphicEl((el: Symbol, idx) => {
const itemModel = data.getItemModel(idx) as Model<GraphNodeItemOption>;
data.graph.eachNode((node) => {
const idx = node.dataIndex;
const el = node.getGraphicEl() as Symbol;
const itemModel = node.getModel<GraphNodeItemOption>();
// Update draggable
el.off('drag').off('dragend');
const draggable = itemModel.get('draggable');
......@@ -181,41 +146,22 @@ class GraphView extends ChartView {
}
el.setDraggable(draggable && !!forceLayout);
(el as any)[FOCUS_ADJACENCY] && el.off('mouseover', (el as any)[FOCUS_ADJACENCY]);
(el as any)[UNFOCUS_ADJACENCY] && el.off('mouseout', (el as any)[UNFOCUS_ADJACENCY]);
const focus = itemModel.get(['emphasis', 'focus']);
if (itemModel.get('focusNodeAdjacency')) {
el.on('mouseover', (el as any)[FOCUS_ADJACENCY] = function () {
api.dispatchAction({
type: 'focusNodeAdjacency',
seriesId: seriesModel.id,
dataIndex: graphic.getECData(el).dataIndex
});
});
el.on('mouseout', (el as any)[UNFOCUS_ADJACENCY] = function () {
graphView._dispatchUnfocus(api);
});
if (focus === 'adjacency') {
graphic.getECData(el).focus = node.getAdjacentDataIndices();
}
});
data.graph.eachEdge(function (edge) {
const el = edge.getGraphicEl() as Line;
const focus = edge.getModel<GraphEdgeItemOption>().get(['emphasis', 'focus']);
(el as any)[FOCUS_ADJACENCY] && el.off('mouseover', (el as any)[FOCUS_ADJACENCY]);
(el as any)[UNFOCUS_ADJACENCY] && el.off('mouseout', (el as any)[UNFOCUS_ADJACENCY]);
if (edge.getModel<GraphEdgeItemOption>().get('focusNodeAdjacency')) {
el.on('mouseover', (el as any)[FOCUS_ADJACENCY] = function () {
api.dispatchAction({
type: 'focusNodeAdjacency',
seriesId: seriesModel.id,
edgeDataIndex: edge.dataIndex
});
});
el.on('mouseout', (el as any)[UNFOCUS_ADJACENCY] = function () {
graphView._dispatchUnfocus(api);
});
if (focus === 'adjacency') {
graphic.getECData(el).focus = {
edge: [edge.dataIndex],
node: [edge.node1.dataIndex, edge.node2.dataIndex]
};
}
});
......@@ -264,71 +210,6 @@ class GraphView extends ChartView {
this._controllerHost = null;
}
_dispatchUnfocus(api: ExtensionAPI) {
const self = this;
api.dispatchAction({
type: 'unfocusNodeAdjacency',
seriesId: self._model.id
});
}
focusNodeAdjacency(
seriesModel: GraphSeriesModel,
ecModel: GlobalModel,
api: ExtensionAPI,
payload: FocusNodePayload
) {
const data = seriesModel.getData();
const graph = data.graph;
const dataIndex = payload.dataIndex;
const edgeDataIndex = payload.edgeDataIndex;
const node = graph.getNodeByIndex(dataIndex);
const edge = graph.getEdgeByIndex(edgeDataIndex);
if (!node && !edge) {
return;
}
graph.eachNode(function (node) {
fadeOutItem(node);
});
graph.eachEdge(function (edge) {
fadeOutItem(edge);
});
if (node) {
fadeInItem(node);
zrUtil.each(node.edges, function (adjacentEdge) {
if (adjacentEdge.dataIndex < 0) {
return;
}
fadeInItem(adjacentEdge);
fadeInItem(adjacentEdge.node1);
fadeInItem(adjacentEdge.node2);
});
}
if (edge) {
fadeInItem(edge);
fadeInItem(edge.node1);
fadeInItem(edge.node2);
}
}
unfocusNodeAdjacency(
seriesModel: GraphSeriesModel
) {
const graph = seriesModel.getData().graph;
graph.eachNode(function (node) {
fadeInItem(node);
});
graph.eachEdge(function (edge) {
fadeInItem(edge);
});
}
_startForceLayoutIteration(
forceLayout: GraphSeriesModel['forceLayout'],
layoutAnimation?: boolean
......
......@@ -88,7 +88,7 @@ interface SymbolDrawStateOption {
// TODO Separate series and item?
export interface SymbolDrawItemModelOption extends SymbolOptionMixin<object>,
StatesOptionMixin<SymbolDrawStateOption>,
StatesOptionMixin<SymbolDrawStateOption, string>,
SymbolDrawStateOption {
hoverAnimation?: boolean
......
......@@ -57,7 +57,7 @@ interface SankeyEdgeStyleOption extends LineStyleOption {
}
export interface SankeyNodeItemOption extends SankeyNodeStateOption,
StatesOptionMixin<SankeyNodeStateOption>,
StatesOptionMixin<SankeyNodeStateOption, 'adjacency'>,
OptionDataItemObject<OptionDataValue> {
id?: string
......@@ -71,7 +71,8 @@ export interface SankeyNodeItemOption extends SankeyNodeStateOption,
focusNodeAdjacency?: FocusNodeAdjacency
}
export interface SankeyEdgeItemOption extends SankeyEdgeStateOption, StatesOptionMixin<SankeyEdgeStateOption> {
export interface SankeyEdgeItemOption
extends SankeyEdgeStateOption, StatesOptionMixin<SankeyEdgeStateOption, 'adjacency'> {
/**
* Name or index of source node.
*/
......@@ -88,7 +89,7 @@ export interface SankeyLevelOption {
depth: number
}
export interface SankeySeriesOption extends SeriesOption<SankeyBothStateOption>, SankeyBothStateOption,
export interface SankeySeriesOption extends SeriesOption<SankeyBothStateOption, 'adjacency'>, SankeyBothStateOption,
BoxLayoutOptionMixin {
type?: 'sankey'
......
......@@ -19,46 +19,22 @@
import * as graphic from '../../util/graphic';
import { enterEmphasis, leaveEmphasis, enableHoverEmphasis, setStatesStylesFromModel } from '../../util/states';
import * as zrUtil from 'zrender/src/core/util';
import { LayoutOrient, Payload, ECElement } from '../../util/types';
import { PathProps } from 'zrender/src/graphic/Path';
import SankeySeriesModel, { SankeyEdgeItemOption, SankeyNodeItemOption } from './SankeySeries';
import ChartView from '../../view/Chart';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
import { GraphNode, GraphEdge } from '../../data/Graph';
import { GraphEdgeItemOption } from '../graph/GraphSeries';
import List from '../../data/List';
import { RectLike } from 'zrender/src/core/BoundingRect';
import { setLabelStyle } from '../../label/labelStyle';
import { setItemVisualFromData } from '../../visual/helper';
interface FocusNodeAdjacencyPayload extends Payload {
dataIndex?: number
edgeDataIndex?: number
}
interface SankeyEl extends graphic.Path {
downplay(): void
highlight(): void
focusNodeAdjHandler(): void
unfocusNodeAdjHandler(): void
}
function fadeInItem(nodeOrEdge: GraphNode | GraphEdge) {
const el = nodeOrEdge.getGraphicEl();
if (el) {
el.removeState('blur');
}
}
function fadeOutItem(nodeOrEdge: GraphNode | GraphEdge) {
const el = nodeOrEdge.getGraphicEl();
if (el) {
el.useState('blur');
}
}
class SankeyPathShape {
x1 = 0;
y1 = 0;
......@@ -236,11 +212,18 @@ class SankeyView extends ChartView {
setStatesStylesFromModel(curve, edgeModel, 'lineStyle', 'getItemStyle');
enableHoverEmphasis(curve, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
group.add(curve);
edgeData.setItemGraphicEl(edge.dataIndex, curve);
const focus = emphasisModel.get('focus');
enableHoverEmphasis(
curve,
focus === 'adjacency' ? edge.getAdjacentDataIndices() : focus,
emphasisModel.get('blurScope')
);
graphic.getECData(curve).dataType = 'edge';
});
// Generate a rect for each node
......@@ -278,16 +261,21 @@ class SankeyView extends ChartView {
setStatesStylesFromModel(rect, itemModel);
enableHoverEmphasis(rect, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
group.add(rect);
nodeData.setItemGraphicEl(node.dataIndex, rect);
graphic.getECData(rect).dataType = 'node';
const focus = emphasisModel.get('focus');
enableHoverEmphasis(
rect,
focus === 'adjacency' ? node.getAdjacentDataIndices() : focus,
emphasisModel.get('blurScope')
);
});
nodeData.eachItemGraphicEl(function (el: graphic.Rect & SankeyEl, dataIndex: number) {
nodeData.eachItemGraphicEl(function (el: graphic.Rect, dataIndex: number) {
const itemModel = nodeData.getItemModel<SankeyNodeItemOption>(dataIndex);
if (itemModel.get('draggable')) {
el.drift = function (this: typeof el, dx, dy) {
......@@ -309,60 +297,6 @@ class SankeyView extends ChartView {
el.draggable = true;
el.cursor = 'move';
}
el.highlight = function () {
enterEmphasis(this);
};
el.downplay = function () {
leaveEmphasis(this);
};
el.focusNodeAdjHandler && el.off('mouseover', el.focusNodeAdjHandler);
el.unfocusNodeAdjHandler && el.off('mouseout', el.unfocusNodeAdjHandler);
if (itemModel.get('focusNodeAdjacency')) {
el.on('mouseover', el.focusNodeAdjHandler = function () {
if (!sankeyView._focusAdjacencyDisabled) {
api.dispatchAction({
type: 'focusNodeAdjacency',
seriesId: seriesModel.id,
dataIndex: graphic.getECData(el).dataIndex
});
}
});
el.on('mouseout', el.unfocusNodeAdjHandler = function () {
if (!sankeyView._focusAdjacencyDisabled) {
sankeyView._dispatchUnfocus(api);
}
});
}
});
edgeData.eachItemGraphicEl(function (el: SankeyPath & SankeyEl, dataIndex) {
const edgeModel = edgeData.getItemModel<GraphEdgeItemOption>(dataIndex);
el.focusNodeAdjHandler && el.off('mouseover', el.focusNodeAdjHandler);
el.unfocusNodeAdjHandler && el.off('mouseout', el.unfocusNodeAdjHandler);
if (edgeModel.get('focusNodeAdjacency')) {
el.on('mouseover', el.focusNodeAdjHandler = function () {
if (!sankeyView._focusAdjacencyDisabled) {
api.dispatchAction({
type: 'focusNodeAdjacency',
seriesId: seriesModel.id,
edgeDataIndex: graphic.getECData(el).dataIndex
});
}
});
el.on('mouseout', el.unfocusNodeAdjHandler = function () {
if (!sankeyView._focusAdjacencyDisabled) {
sankeyView._dispatchUnfocus(api);
}
});
}
});
if (!this._data && seriesModel.isAnimationEnabled()) {
......@@ -376,91 +310,6 @@ class SankeyView extends ChartView {
dispose() {
}
_dispatchUnfocus(api: ExtensionAPI) {
const self = this;
api.dispatchAction({
type: 'unfocusNodeAdjacency',
seriesId: self._model.id
});
}
focusNodeAdjacency(
seriesModel: SankeySeriesModel,
ecModel: GlobalModel,
api: ExtensionAPI,
payload: FocusNodeAdjacencyPayload
) {
const data = seriesModel.getData();
const graph = data.graph;
const dataIndex = payload.dataIndex;
const edgeDataIndex = payload.edgeDataIndex;
if (dataIndex == null && edgeDataIndex == null) {
return;
}
const node = graph.getNodeByIndex(dataIndex);
const edge = graph.getEdgeByIndex(edgeDataIndex);
graph.eachNode(function (node) {
fadeOutItem(node);
});
graph.eachEdge(function (edge) {
fadeOutItem(edge);
});
if (node) {
const itemModel = data.getItemModel<SankeyNodeItemOption>(dataIndex);
fadeInItem(node);
const focusNodeAdj = itemModel.get('focusNodeAdjacency');
if (focusNodeAdj === 'outEdges') {
zrUtil.each(node.outEdges, function (edge) {
if (edge.dataIndex < 0) {
return;
}
fadeInItem(edge);
fadeInItem(edge.node2);
});
}
else if (focusNodeAdj === 'inEdges') {
zrUtil.each(node.inEdges, function (edge) {
if (edge.dataIndex < 0) {
return;
}
fadeInItem(edge);
fadeInItem(edge.node1);
});
}
else if (focusNodeAdj === 'allEdges') {
zrUtil.each(node.edges, function (edge) {
if (edge.dataIndex < 0) {
return;
}
fadeInItem(edge);
(edge.node1 !== node) && fadeInItem(edge.node1);
(edge.node2 !== node) && fadeInItem(edge.node2);
});
}
}
if (edge) {
fadeInItem(edge);
fadeInItem(edge.node1);
fadeInItem(edge.node2);
}
}
unfocusNodeAdjacency(
seriesModel: SankeySeriesModel
) {
const graph = seriesModel.getGraph();
graph.eachNode(function (node) {
fadeInItem(node);
});
graph.eachEdge(function (edge) {
fadeInItem(edge);
});
}
}
// Add animation to the view
......
......@@ -376,6 +376,22 @@ class GraphNode {
return itemModel.getModel(path as any);
}
getAdjacentDataIndices(): {node: number[], edge: number[]} {
const dataIndices = {
edge: [] as number[],
node: [] as number[]
};
for (let i = 0; i < this.edges.length; i++) {
const adjacentEdge = this.edges[i];
if (adjacentEdge.dataIndex < 0) {
continue;
}
dataIndices.edge.push(adjacentEdge.dataIndex);
dataIndices.node.push(adjacentEdge.node1.dataIndex, adjacentEdge.node2.dataIndex);
}
return dataIndices;
}
}
......@@ -410,6 +426,13 @@ class GraphEdge {
return itemModel.getModel(path as any);
}
getAdjacentDataIndices(): {node: number[], edge: number[]} {
return {
edge: [this.dataIndex],
node: [this.node1.dataIndex, this.node2.dataIndex]
};
}
}
type GetDataName<Host> = Host extends GraphEdge ? 'edgeData' : 'data';
......
......@@ -1312,8 +1312,7 @@ class ECharts extends Eventful {
if (isHighlight || isDownplay) {
if (model instanceof SeriesModel) {
const seriesIndex = model.seriesIndex;
const dataType = payload.dataType;
const data = model.getData(dataType);
const data = model.getData(payload.dataType);
let dataIndex = modelUtil.queryDataIndex(data, payload);
// Pick the first one if there is multiple/none exists.
dataIndex = (zrUtil.isArray(dataIndex) ? dataIndex[0] : dataIndex) || 0;
......@@ -1329,7 +1328,7 @@ class ECharts extends Eventful {
if (el) {
const ecData = graphic.getECData(el);
toggleSeriesBlurStates(
seriesIndex, ecData.focus, ecData.blurScope, ecIns, dataType, isHighlight
seriesIndex, ecData.focus, ecData.blurScope, ecIns, isHighlight
);
}
else {
......@@ -1338,7 +1337,7 @@ class ECharts extends Eventful {
const focus = model.get(['emphasis', 'focus']);
const blurScope = model.get(['emphasis', 'blurScope']);
if (focus != null) {
toggleSeriesBlurStates(seriesIndex, focus, blurScope, ecIns, dataType, isHighlight);
toggleSeriesBlurStates(seriesIndex, focus, blurScope, ecIns, isHighlight);
}
}
}
......@@ -1735,7 +1734,7 @@ class ECharts extends Eventful {
const ecData = graphic.getECData(dispatcher);
// Try blur all in the related series. Then emphasis the hoverred.
toggleSeriesBlurStates(
ecData.seriesIndex, ecData.focus, ecData.blurScope, ecIns, ecData.dataType, true
ecData.seriesIndex, ecData.focus, ecData.blurScope, ecIns, true
);
enterEmphasisWhenMouseOver(dispatcher, e);
......@@ -1747,7 +1746,7 @@ class ECharts extends Eventful {
if (dispatcher) {
const ecData = graphic.getECData(dispatcher);
toggleSeriesBlurStates(
ecData.seriesIndex, ecData.focus, ecData.blurScope, ecIns, ecData.dataType, false
ecData.seriesIndex, ecData.focus, ecData.blurScope, ecIns, false
);
leaveEmphasisWhenMouseOut(dispatcher, e);
......
......@@ -115,6 +115,19 @@ function compatSunburstState(option: Dictionary<any>) {
}
}
function compatGraphFocus(option: Dictionary<any>) {
if (!option) {
return;
}
if (option.focusNodeAdjacency != null) {
option.emphasis = option.emphasis || {};
if (option.emphasis.focus == null) {
deprecateLog('`focusNodeAdjacency` in graph/sankey has been changed to `emphasis: { focus: \'adjacency\'}`');
option.emphasis.focus = 'adjacency';
}
}
}
function traverseTree(data: any[], cb: Function) {
if (data) {
for (let i = 0; i < data.length; i++) {
......@@ -194,6 +207,10 @@ export default function (option: ECUnitOption, isTheme?: boolean) {
traverseTree(seriesOpt.data, compatSunburstState);
}
else if (seriesType === 'graph' || seriesType === 'sankey') {
compatGraphFocus(seriesOpt);
// TODO nodes, edges?
}
else if (seriesType === 'map') {
if ((seriesOpt as any).mapType && !(seriesOpt as any).map) {
deprecateLog('`mapType` in map has been changed to `map`');
......
......@@ -58,7 +58,7 @@ import {
ZRStyleProps,
ParsedValue,
BlurScope,
GeneralFocus} from './types';
InnerFocus} from './types';
import { makeInner } from './model';
import {
extend,
......@@ -900,7 +900,7 @@ export interface ECData {
seriesIndex?: number;
dataType?: string;
focus?: GeneralFocus
focus?: InnerFocus
blurScope?: BlurScope
}
......
......@@ -6,8 +6,8 @@ import { PatternObject } from 'zrender/src/graphic/Pattern';
import { GradientObject } from 'zrender/src/graphic/Gradient';
import Element, { ElementEvent } from 'zrender/src/Element';
import Model from '../model/Model';
import { DisplayState, ECElement, ColorString, BlurScope, GeneralFocus } from './types';
import { extend, indexOf, isArrayLike } from 'zrender/src/core/util';
import { DisplayState, ECElement, ColorString, BlurScope, InnerFocus } from './types';
import { extend, indexOf, isArrayLike, isObject, keys } from 'zrender/src/core/util';
import {
Z2_EMPHASIS_LIFT,
getECData,
......@@ -15,6 +15,7 @@ import {
} from './graphic';
import * as colorTool from 'zrender/src/tool/color';
import { EChartsType } from '../echarts';
import List from '../data/List';
// Reserve 0 as default.
export let _highlightNextDigit = 1;
......@@ -288,10 +289,9 @@ function shouldSilent(el: Element, e: ElementEvent) {
export function toggleSeriesBlurStates(
targetSeriesIndex: number,
focus: GeneralFocus,
focus: InnerFocus,
blurScope: BlurScope,
ecIns: EChartsType,
dataType: string,
isBlur: boolean
) {
if (targetSeriesIndex == null) {
......@@ -305,6 +305,13 @@ export function toggleSeriesBlurStates(
return;
}
function leaveBlur(data: List, dataIndices: ArrayLike<number>) {
for (let i = 0; i < dataIndices.length; i++) {
const itemEl = data.getItemGraphicEl(dataIndices[i]);
itemEl && traverseUpdateState(itemEl as ExtendedElement, singleLeaveBlur);
}
}
model.eachSeries(function (seriesModel) {
const sameSeries = targetSeriesIndex === seriesModel.seriesIndex;
if (!(
......@@ -317,11 +324,15 @@ export function toggleSeriesBlurStates(
isBlur ? singleEnterBlur(child) : singleLeaveBlur(child);
});
if (isBlur && isArrayLike(focus)) {
const data = seriesModel.getData(dataType);
for (let i = 0; i < focus.length; i++) {
const itemEl = data.getItemGraphicEl((focus as number[])[i]);
itemEl && traverseUpdateState(itemEl as ExtendedElement, singleLeaveBlur);
if (isBlur) {
if (isArrayLike(focus)) {
leaveBlur(seriesModel.getData(), focus as ArrayLike<number>);
}
else if (isObject(focus)) {
const dataTypes = keys(focus);
for (let d = 0; d < dataTypes.length; d++) {
leaveBlur(seriesModel.getData(dataTypes[d]), focus[dataTypes[d]]);
}
}
}
}
......@@ -335,14 +346,14 @@ export function toggleSeriesBlurStates(
* This function should be used on the element with dataIndex, seriesIndex.
*
*/
export function enableHoverEmphasis(el: Element, focus?: GeneralFocus, blurScope?: BlurScope) {
export function enableHoverEmphasis(el: Element, focus?: InnerFocus, blurScope?: BlurScope) {
setAsHighDownDispatcher(el, true);
traverseUpdateState(el as ExtendedElement, setDefaultStateProxy);
enableHoverFocus(el, focus, blurScope);
}
export function enableHoverFocus(el: Element, focus: GeneralFocus, blurScope: BlurScope) {
export function enableHoverFocus(el: Element, focus: InnerFocus, blurScope: BlurScope) {
if (focus != null) {
const ecData = getECData(el);
// TODO dataIndex may be set after this function. This check is not useful.
......
......@@ -1136,8 +1136,9 @@ export type BlurScope = 'coordinateSystem' | 'series' | 'global';
/**
* can be array of data indices.
* Or may be an dictionary if have different types of data like in graph.
*/
export type GeneralFocus = string | ArrayLike<number>;
export type InnerFocus = string | ArrayLike<number> | Dictionary<ArrayLike<number>>;
export interface StatesOptionMixin<StateOption, ExtraFocusOptions = never> {
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册