diff --git a/src/geometry/base.ts b/src/geometry/base.ts index 9384f75ca1..008781f420 100644 --- a/src/geometry/base.ts +++ b/src/geometry/base.ts @@ -819,11 +819,12 @@ export default class Geometry extends Base { const dataArray = this.beforeMapping(beforeMappingData); const mappingArray = []; - for (const eachGroup of dataArray) { + + dataArray.forEach((eachGroup, index) => { const mappingData = this.mapping(eachGroup); mappingArray.push(mappingData); - this.createElements(mappingData, isUpdate); - } + this.createElements(mappingData, index, isUpdate); + }); if (this.canDoGroupAnimation(isUpdate)) { // 如果用户没有配置 appear.animation,就默认走整体动画 @@ -1271,11 +1272,16 @@ export default class Geometry extends Base { * @param [isUpdate] * @returns elements */ - protected createElements(mappingData: MappingDatum[], isUpdate: boolean = false): Element[] { + protected createElements(mappingData: MappingDatum[], index: number, isUpdate: boolean = false): Element[] { const { lastElementsMap, elementsMap, elements } = this; - each(mappingData, (mappingDatum) => { - const id = this.getElementId(mappingDatum); - let result = lastElementsMap[id] || elementsMap[id]; + each(mappingData, (mappingDatum, subIndex) => { + let id = this.getElementId(mappingDatum); + if (elementsMap[id]) { + // 存在重复数据,则根据再根据 index 进行区分 + id = `${id}-${index}-${subIndex}`; + } + + let result = lastElementsMap[id]; if (!result) { // 创建新的 element result = this.createElement(mappingDatum, isUpdate); @@ -1291,11 +1297,8 @@ export default class Geometry extends Base { delete lastElementsMap[id]; } - if (!elementsMap[id]) { - // 保证唯一性 - elements.push(result); - elementsMap[id] = result; - } + elements.push(result); + elementsMap[id] = result; }); return elements; } diff --git a/src/geometry/heatmap.ts b/src/geometry/heatmap.ts index cb50c5af79..76502ac4d5 100644 --- a/src/geometry/heatmap.ts +++ b/src/geometry/heatmap.ts @@ -16,7 +16,7 @@ export default class Heatmap extends Geometry { private shadowCanvas: HTMLCanvasElement; private imageShape: IShape; - protected createElements(mappingData: MappingDatum[], isUpdate: boolean = false) { + protected createElements(mappingData: MappingDatum[], index: number, isUpdate: boolean = false) { const range = this.prepareRange(mappingData); const radius = this.prepareSize(); diff --git a/src/geometry/path.ts b/src/geometry/path.ts index 836f472751..96a872a965 100644 --- a/src/geometry/path.ts +++ b/src/geometry/path.ts @@ -36,13 +36,13 @@ export default class Path extends Geometry { * @param [isUpdate] * @returns elements */ - protected createElements(mappingData: MappingDatum[], isUpdate: boolean = false): Element[] { + protected createElements(mappingData: MappingDatum[], index: number, isUpdate: boolean = false): Element[] { // Path 的每个 element 对应一组数据 const { lastElementsMap, elementsMap, elements, theme, container } = this; const elementId = this.getElementId(mappingData); const shapeCfg = this.getShapeInfo(mappingData); - let result = lastElementsMap[elementId] || elementsMap[elementId]; + let result = lastElementsMap[elementId]; if (!result) { const shapeFactory = this.getShapeFactory(); @@ -64,10 +64,8 @@ export default class Path extends Geometry { delete lastElementsMap[elementId]; } - if (!elementsMap[elementId]) { - elements.push(result); - elementsMap[elementId] = result; - } + elements.push(result); + elementsMap[elementId] = result; return elements; } diff --git a/tests/bugs/2016-spec.ts b/tests/bugs/2016-spec.ts index 99bca69134..2832aa996a 100644 --- a/tests/bugs/2016-spec.ts +++ b/tests/bugs/2016-spec.ts @@ -28,10 +28,10 @@ describe('#2016', () => { .shape('circle'); chart.render(); - expect(point.elements.length).toBe(2); + expect(point.elements.length).toBe(4); chart.render(true); - expect(point.elements.length).toBe(2); + expect(point.elements.length).toBe(4); }); afterAll(() => { diff --git a/tests/bugs/2141-spec.ts b/tests/bugs/2141-spec.ts new file mode 100644 index 0000000000..82fde94a98 --- /dev/null +++ b/tests/bugs/2141-spec.ts @@ -0,0 +1,58 @@ +import { Chart } from '../../src'; +import { createDiv } from '../util/dom'; + +import 'jest-extended'; + +describe('#2141', () => { + const data = [ + { item: '事例一', count: 40, percent: 0.4 }, + { item: '事例二', count: 21, percent: 0.21 }, + { item: '事例三', count: 17, percent: 0.17 }, + { item: '事例四', count: 13, percent: 0.13 }, + { item: '事例五', count: 9, percent: 0.09 }, + ]; + + const chart = new Chart({ + container: createDiv(), + width: 400, + height: 300, + }); + + chart.coordinate('theta', { + radius: 0.75, + }); + + chart.data(data); + chart.animate(false); + const interval = chart + .interval() + .position('percent') + .adjust('stack') + .style({ + lineWidth: 1, + stroke: '#fff' + }); + chart.render(); + + it('render, id uniq', () => { + // 保证数据同 element 的条数对应 + expect(interval.elements.length).toBe(data.length); + expect(interval.elementsMap).toContainAllKeys(['1', '1-0-1', '1-0-2', '1-0-3', '1-0-4']); + }); + + it('update', () => { + const newData = [ + { item: '事例一', count: 40, percent: 0.2 }, + { item: '事例二', count: 21, percent: 0.11 }, + { item: '事例三', count: 17, percent: 0.27 }, + { item: '事例四', count: 13, percent: 0.13 }, + { item: '事例五', count: 9, percent: 0.09 }, + { item: '事例五', count: 9, percent: 0.1 }, + ]; + chart.changeData(newData); + + expect(interval.elements.length).toBe(newData.length); + expect(interval.elements[1].getData()).toEqual({ item: '事例二', count: 21, percent: 0.11 }); + expect(interval.elementsMap).toContainAllKeys(['1', '1-0-1', '1-0-2', '1-0-3', '1-0-4', '1-0-5']); + }); +});