diff --git a/src/component/legend/LegendView.ts b/src/component/legend/LegendView.ts index 35b0779f2b..9016468240 100644 --- a/src/component/legend/LegendView.ts +++ b/src/component/legend/LegendView.ts @@ -329,7 +329,8 @@ class LegendView extends ComponentView { }, onclick() { api.dispatchAction({ - type: type === 'all' ? 'legendAllSelect' : 'legendInverseSelect' + type: type === 'all' ? 'legendAllSelect' : 'legendInverseSelect', + legendId: legendModel.id }); } }); diff --git a/src/component/legend/legendAction.ts b/src/component/legend/legendAction.ts index 04ed3723a8..d0771e79aa 100644 --- a/src/component/legend/legendAction.ts +++ b/src/component/legend/legendAction.ts @@ -17,59 +17,81 @@ * under the License. */ -// @ts-nocheck +import {curry, each, hasOwn} from 'zrender/src/core/util'; +import { EChartsExtensionInstallRegisters } from '../../extension'; +import { Payload } from '../../util/types'; +import type GlobalModel from '../../model/Global'; +import type LegendModel from './LegendModel'; -import {curry, each} from 'zrender/src/core/util'; +type LegendSelectMethodNames = 'select' | 'unSelect' | 'toggleSelected' | 'allSelect' | 'inverseSelect'; -function legendSelectActionHandler(methodName, payload, ecModel) { - const selectedMap = {}; - const isToggleSelect = methodName === 'toggleSelected'; - let isSelected; - // Update all legend components - ecModel.eachComponent('legend', function (legendModel) { - if (isToggleSelect && isSelected != null) { - // Force other legend has same selected status - // Or the first is toggled to true and other are toggled to false - // In the case one legend has some item unSelected in option. And if other legend - // doesn't has the item, they will assume it is selected. - legendModel[isSelected ? 'select' : 'unSelect'](payload.name); - } - else if (methodName === 'allSelect' || methodName === 'inverseSelect') { +function legendSelectActionHandler(methodName: LegendSelectMethodNames, payload: Payload, ecModel: GlobalModel) { + const isAllSelect = methodName === 'allSelect' || methodName === 'inverseSelect'; + const selectedMap: Record = {}; + + const actionLegendIndices: number[] = []; + ecModel.eachComponent({ mainType: 'legend', query: payload }, function (legendModel: LegendModel) { + if (isAllSelect) { legendModel[methodName](); } else { legendModel[methodName](payload.name); - isSelected = legendModel.isSelected(payload.name); } - const legendData = legendModel.getData(); - each(legendData, function (model) { - const name = model.get('name'); - // Wrap element - if (name === '\n' || name === '') { - return; - } - const isItemSelected = legendModel.isSelected(name); - if (selectedMap.hasOwnProperty(name)) { - // Unselected if any legend is unselected - selectedMap[name] = selectedMap[name] && isItemSelected; - } - else { - selectedMap[name] = isItemSelected; - } + + makeSelectedMap(legendModel, selectedMap); + + actionLegendIndices.push(legendModel.componentIndex); + }); + + const allSelectedMap: Record = {}; + + // make selectedMap from all legend components + ecModel.eachComponent('legend', function (legendModel: LegendModel) { + each(selectedMap, function (isSelected, name) { + // Force other legend has same selected status + // Or the first is toggled to true and other are toggled to false + // In the case one legend has some item unSelected in option. And if other legend + // doesn't has the item, they will assume it is selected. + legendModel[isSelected ? 'select' : 'unSelect'](name); }); + + makeSelectedMap(legendModel, allSelectedMap); }); + // Return the event explicitly - return (methodName === 'allSelect' || methodName === 'inverseSelect') + return isAllSelect ? { - selected: selectedMap + selected: allSelectedMap, + // return legendIndex array to tell the developers which legends are allSelect / inverseSelect + legendIndex: actionLegendIndices } : { name: payload.name, - selected: selectedMap + selected: allSelectedMap }; } -export function installLegendAction(registers) { +function makeSelectedMap(legendModel: LegendModel, out?: Record) { + const selectedMap: Record = out || {}; + each(legendModel.getData(), function (model) { + const name = model.get('name'); + // Wrap element + if (name === '\n' || name === '') { + return; + } + const isItemSelected = legendModel.isSelected(name); + if (hasOwn(selectedMap, name)) { + // Unselected if any legend is unselected + selectedMap[name] = selectedMap[name] && isItemSelected; + } + else { + selectedMap[name] = isItemSelected; + } + }); + return selectedMap; +} + +export function installLegendAction(registers: EChartsExtensionInstallRegisters) { /** * @event legendToggleSelect * @type {Object} @@ -113,4 +135,4 @@ export function installLegendAction(registers) { 'legendUnSelect', 'legendunselected', curry(legendSelectActionHandler, 'unSelect') ); -} \ No newline at end of file +} diff --git a/test/legend-action.html b/test/legend-action.html new file mode 100644 index 0000000000..90dda2e3f2 --- /dev/null +++ b/test/legend-action.html @@ -0,0 +1,136 @@ + + + + + + + + + + + + +
+ + + + diff --git a/test/runTest/actions/__meta__.json b/test/runTest/actions/__meta__.json index 26eac6dd21..54a683e54f 100644 --- a/test/runTest/actions/__meta__.json +++ b/test/runTest/actions/__meta__.json @@ -122,6 +122,7 @@ "label-position": 1, "largeLine-tooltip": 1, "legend": 11, + "legend-action": 1, "legend-visualMapColor": 2, "line": 1, "line-animation": 1, diff --git a/test/runTest/actions/legend-action.json b/test/runTest/actions/legend-action.json new file mode 100644 index 0000000000..bd0b61577f --- /dev/null +++ b/test/runTest/actions/legend-action.json @@ -0,0 +1 @@ +[{"name":"Action 1","ops":[{"type":"mousemove","time":301,"x":470,"y":19},{"type":"mousemove","time":500,"x":289,"y":47},{"type":"mousemove","time":700,"x":197,"y":115},{"type":"mousemove","time":903,"x":188,"y":132},{"type":"mousedown","time":1024,"x":188,"y":132},{"type":"mouseup","time":1169,"x":188,"y":132},{"time":1170,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":1483,"x":201,"y":132},{"type":"mousemove","time":1689,"x":273,"y":120},{"type":"mousemove","time":1900,"x":325,"y":117},{"type":"mousemove","time":2103,"x":242,"y":126},{"type":"mousemove","time":2266,"x":242,"y":127},{"type":"mousedown","time":2408,"x":257,"y":133},{"type":"mousemove","time":2469,"x":257,"y":133},{"type":"mouseup","time":2552,"x":257,"y":133},{"time":2553,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":2899,"x":261,"y":133},{"type":"mousemove","time":3099,"x":268,"y":132},{"type":"mousemove","time":3299,"x":297,"y":129},{"type":"mousedown","time":3472,"x":299,"y":129},{"type":"mousemove","time":3503,"x":299,"y":129},{"type":"mouseup","time":3646,"x":299,"y":129},{"time":3647,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":4016,"x":304,"y":129},{"type":"mousemove","time":4216,"x":474,"y":132},{"type":"mousemove","time":4421,"x":548,"y":141},{"type":"mousemove","time":4669,"x":525,"y":131},{"type":"mousedown","time":4681,"x":525,"y":131},{"type":"mouseup","time":4816,"x":525,"y":131},{"time":4817,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":4999,"x":526,"y":130},{"type":"mousemove","time":5199,"x":622,"y":130},{"type":"mousemove","time":5399,"x":646,"y":131},{"type":"mousedown","time":5521,"x":651,"y":132},{"type":"mousemove","time":5604,"x":651,"y":133},{"type":"mouseup","time":5655,"x":651,"y":133},{"time":5656,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":5886,"x":651,"y":133},{"type":"mousemove","time":6050,"x":651,"y":134},{"type":"mousemove","time":6333,"x":661,"y":135},{"type":"mousemove","time":6533,"x":689,"y":134},{"type":"mousedown","time":6648,"x":690,"y":134},{"type":"mousemove","time":6736,"x":690,"y":134},{"type":"mouseup","time":6759,"x":690,"y":134},{"time":6760,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":6983,"x":688,"y":134},{"type":"mousemove","time":7187,"x":659,"y":133},{"type":"mousedown","time":7304,"x":659,"y":133},{"type":"mouseup","time":7438,"x":659,"y":133},{"time":7439,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":7699,"x":651,"y":133},{"type":"mousemove","time":7899,"x":583,"y":135},{"type":"mousemove","time":8105,"x":521,"y":135},{"type":"mousedown","time":8203,"x":521,"y":135},{"type":"mouseup","time":8310,"x":521,"y":135},{"time":8311,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":8432,"x":542,"y":135},{"type":"mousemove","time":8636,"x":640,"y":135},{"type":"mousemove","time":8870,"x":656,"y":134},{"type":"mousedown","time":8896,"x":656,"y":134},{"type":"mouseup","time":9038,"x":656,"y":134},{"time":9039,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":9184,"x":654,"y":130},{"type":"mousemove","time":9387,"x":613,"y":109},{"type":"mousemove","time":9599,"x":582,"y":96},{"type":"mousemove","time":9803,"x":577,"y":94},{"type":"mousedown","time":9927,"x":577,"y":94},{"type":"mouseup","time":10136,"x":577,"y":94},{"time":10137,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":10401,"x":574,"y":93},{"type":"mousemove","time":10603,"x":407,"y":94},{"type":"mousemove","time":10820,"x":304,"y":94},{"type":"mousemove","time":11116,"x":301,"y":94},{"type":"mousedown","time":11319,"x":296,"y":97},{"type":"mousemove","time":11323,"x":296,"y":97},{"type":"mouseup","time":11430,"x":296,"y":97},{"time":11431,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":11616,"x":296,"y":98},{"type":"mousemove","time":11817,"x":246,"y":118},{"type":"mousemove","time":12021,"x":218,"y":135},{"type":"mousedown","time":12137,"x":218,"y":135},{"type":"mouseup","time":12230,"x":218,"y":135},{"time":12231,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":12382,"x":293,"y":133},{"type":"mousemove","time":12583,"x":397,"y":129},{"type":"mousemove","time":12786,"x":441,"y":129},{"type":"mousedown","time":12804,"x":441,"y":129},{"type":"mouseup","time":12886,"x":441,"y":129},{"time":12887,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":12950,"x":419,"y":128},{"type":"mousemove","time":13154,"x":244,"y":79},{"type":"mousemove","time":13366,"x":244,"y":91},{"type":"mousedown","time":13431,"x":245,"y":92},{"type":"mousemove","time":13569,"x":245,"y":92},{"type":"mouseup","time":13574,"x":245,"y":92},{"time":13575,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":13749,"x":256,"y":94},{"type":"mousemove","time":13949,"x":451,"y":91},{"type":"mousemove","time":14153,"x":473,"y":88},{"type":"mousedown","time":14353,"x":473,"y":87},{"type":"mousemove","time":14371,"x":473,"y":87},{"type":"mouseup","time":14520,"x":473,"y":87},{"time":14521,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":15049,"x":474,"y":87},{"type":"mousemove","time":15252,"x":516,"y":83},{"type":"mousemove","time":15487,"x":519,"y":92},{"type":"mousemove","time":15736,"x":514,"y":97},{"type":"mousedown","time":15920,"x":514,"y":97},{"type":"mouseup","time":16054,"x":514,"y":97},{"time":16055,"delay":400,"type":"screenshot-auto"},{"type":"mousemove","time":16666,"x":531,"y":94},{"type":"mousemove","time":16870,"x":612,"y":81}],"scrollY":0,"scrollX":0,"timestamp":1720675612620}] \ No newline at end of file