Skip to content

Commit

Permalink
Merge pull request #678 from VisActor/fix/legendItemHove-trigger
Browse files Browse the repository at this point in the history
Fix/legend item hove trigger
  • Loading branch information
kkxxkk2019 authored Nov 15, 2023
2 parents 04006b6 + 6199657 commit 57a4a28
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vrender-components",
"comment": "fix: legendItemHover and legendItemUnHover should trigger once",
"type": "none"
}
],
"packageName": "@visactor/vrender-components"
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,25 +127,25 @@ const vLegend = new DiscreteLegend({
}
}
},
background: {
style: {
stroke: '#000',
lineWidth: 1
// cornerRadius: 5
},
state: {
selectedHover: {
fill: 'rgba(0,0,0,.3)'
},
selected: {
fill: 'pink',
fillOpacity: 0.5
},
unSelected: {
fill: 'blue'
}
}
},
// background: {
// style: {
// stroke: '#000',
// lineWidth: 1
// // cornerRadius: 5
// },
// state: {
// selectedHover: {
// fill: 'rgba(0,0,0,.3)'
// },
// selected: {
// fill: 'pink',
// fillOpacity: 0.5
// },
// unSelected: {
// fill: 'blue'
// }
// }
// },
focus: true
},
items: [
Expand Down Expand Up @@ -398,6 +398,12 @@ vLegend.addEventListener('legendItemClick', e => {
console.log(e, e.detail.currentSelected);
});

hLegend.addEventListener('legendItemClick', e => {
console.log(e, e.detail.currentSelected);
vLegend.addEventListener('legendItemHover', e => {
console.log('legendItemHover');
});

vLegend.addEventListener('legendItemUnHover', e => {
console.log('legendItemUnHover');
});

window.vLegend = vLegend;
132 changes: 74 additions & 58 deletions packages/vrender-components/src/legend/discrete/discrete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export class DiscreteLegend extends LegendBase<DiscreteLegendAttrs> {
private _itemHeight = 0; // 存储每一个图例项的高度
private _itemMaxWidth = 0; // 存储图例项的最大的宽度
private _pager!: Pager;
private _lastActiveItem: IGroup;

static defaultAttributes: Partial<DiscreteLegendAttrs> = {
layout: 'horizontal',
Expand Down Expand Up @@ -307,7 +308,7 @@ export class DiscreteLegend extends LegendBase<DiscreteLegendAttrs> {
const { hover = true, select = true } = this.attribute;
if (hover) {
this._itemsContainer.addEventListener('pointermove', this._onHover as EventListenerOrEventListenerObject);
this._itemsContainer.addEventListener('pointerout', this._onUnHover as EventListenerOrEventListenerObject);
this._itemsContainer.addEventListener('pointerleave', this._onUnHover as EventListenerOrEventListenerObject);
}

if (select) {
Expand Down Expand Up @@ -349,6 +350,7 @@ export class DiscreteLegend extends LegendBase<DiscreteLegendAttrs> {
});
this._appendDataToShape(itemGroup, LEGEND_ELEMENT_NAME.item, item, itemGroup, background?.state);
}
itemGroup.id = `${id ?? label}-${index}`;

itemGroup.addState(isSelected ? LegendStateValue.selected : LegendStateValue.unSelected);

Expand Down Expand Up @@ -675,69 +677,25 @@ export class DiscreteLegend extends LegendBase<DiscreteLegendAttrs> {
if (target?.name?.startsWith(LEGEND_ELEMENT_NAME.item)) {
// @ts-ignore
const legendItem = target.delegate;
const selected = legendItem.hasState(LegendStateValue.selected);

if (selected) {
// use selectedHover state
this._setLegendItemState(legendItem, LegendStateValue.selectedHover, e);
} else {
// use unSelectedHover state
this._setLegendItemState(legendItem, LegendStateValue.unSelectedHover, e);
}

const focusButton = (legendItem.getChildren()[0] as unknown as IGroup).find(
node => node.name === LEGEND_ELEMENT_NAME.focus,
false
) as IGraphic;
if (focusButton) {
focusButton.setAttribute('visible', true);
// 如果上个激活元素存在,则判断当前元素是否和上个激活元素相同,相同则不做处理,不相同则触发 unhover
if (this._lastActiveItem) {
if (this._lastActiveItem.id === legendItem.id) {
return;
}
this._unHover(this._lastActiveItem, e);
}

this._dispatchEvent(LegendEvent.legendItemHover, legendItem, e);
this._hover(legendItem, e);
} else if (this._lastActiveItem) {
this._unHover(this._lastActiveItem, e);
this._lastActiveItem = null;
}
};

private _onUnHover = (e: FederatedPointerEvent) => {
const target = e.target as unknown as IGroup;
if (target?.name?.startsWith(LEGEND_ELEMENT_NAME.item)) {
// @ts-ignore
const legendItem = target.delegate;

let attributeUpdate = false;
if (
legendItem.hasState(LegendStateValue.unSelectedHover) ||
legendItem.hasState(LegendStateValue.selectedHover)
) {
attributeUpdate = true;
}
legendItem.removeState(LegendStateValue.unSelectedHover);
legendItem.removeState(LegendStateValue.selectedHover);
legendItem
.getChildren()[0]
.getChildren()
.forEach((child: any) => {
if (
!attributeUpdate &&
(child.hasState(LegendStateValue.unSelectedHover) || child.hasState(LegendStateValue.selectedHover))
) {
attributeUpdate = true;
}
(child as unknown as IGraphic).removeState(LegendStateValue.unSelectedHover);
(child as unknown as IGraphic).removeState(LegendStateValue.selectedHover);
});

const focusButton = (legendItem.getChildren()[0] as unknown as IGroup).find(
node => node.name === LEGEND_ELEMENT_NAME.focus,
false
) as IGraphic;
if (focusButton) {
focusButton.setAttribute('visible', false);
}

if (attributeUpdate) {
this._dispatchEvent(LegendEvent.legendItemAttributeUpdate, legendItem, e);
}
this._dispatchEvent(LegendEvent.legendItemUnHover, legendItem, e);
if (this._lastActiveItem) {
this._unHover(this._lastActiveItem, e);
this._lastActiveItem = null;
}
};

Expand Down Expand Up @@ -822,6 +780,64 @@ export class DiscreteLegend extends LegendBase<DiscreteLegendAttrs> {
}
};

private _hover(legendItem: IGroup, e: FederatedPointerEvent) {
this._lastActiveItem = legendItem;
const selected = legendItem.hasState(LegendStateValue.selected);

if (selected) {
// use selectedHover state
this._setLegendItemState(legendItem, LegendStateValue.selectedHover, e);
} else {
// use unSelectedHover state
this._setLegendItemState(legendItem, LegendStateValue.unSelectedHover, e);
}

const focusButton = (legendItem.getChildren()[0] as unknown as IGroup).find(
node => node.name === LEGEND_ELEMENT_NAME.focus,
false
) as IGraphic;
if (focusButton) {
focusButton.setAttribute('visible', true);
}

this._dispatchEvent(LegendEvent.legendItemHover, legendItem, e);
}

private _unHover(legendItem: IGroup, e: FederatedPointerEvent) {
let attributeUpdate = false;
if (legendItem.hasState(LegendStateValue.unSelectedHover) || legendItem.hasState(LegendStateValue.selectedHover)) {
attributeUpdate = true;
}
legendItem.removeState(LegendStateValue.unSelectedHover);
legendItem.removeState(LegendStateValue.selectedHover);
legendItem
.getChildren()[0]
.getChildren()
.forEach((child: any) => {
if (
!attributeUpdate &&
(child.hasState(LegendStateValue.unSelectedHover) || child.hasState(LegendStateValue.selectedHover))
) {
attributeUpdate = true;
}
(child as unknown as IGraphic).removeState(LegendStateValue.unSelectedHover);
(child as unknown as IGraphic).removeState(LegendStateValue.selectedHover);
});

const focusButton = (legendItem.getChildren()[0] as unknown as IGroup).find(
node => node.name === LEGEND_ELEMENT_NAME.focus,
false
) as IGraphic;
if (focusButton) {
focusButton.setAttribute('visible', false);
}

if (attributeUpdate) {
this._dispatchEvent(LegendEvent.legendItemAttributeUpdate, legendItem, e);
}
this._dispatchEvent(LegendEvent.legendItemUnHover, legendItem, e);
}

private _setLegendItemState(legendItem: IGroup, stateName: string, e?: FederatedPointerEvent) {
const keepCurrentStates = true;
let attributeUpdate = false;
Expand Down

0 comments on commit 57a4a28

Please sign in to comment.