diff --git a/CHANGELOG.md b/CHANGELOG.md index 80e09e132..ff2a64a64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,15 @@ -### v: 1.1.1 +## 1.1.2 + +`2021-04-12` + +- 🐞 修复更新逻辑,config immutable 避免底层修改 config 后出现重复更新。 + +## 1.1.1 - remname: history -> CHANGELOG - fix: graph layout and changeData error -### v: 1.1.0 +## 1.1.0 - 文档更新 [#545](https://github.com/ant-design/ant-design-charts/pull/545) - feat: 新增弦图(Chord) [#545](https://github.com/ant-design/ant-design-charts/pull/545) @@ -14,27 +20,27 @@ - measureTextWidth - adaptors -### v: 1.0.1 +## 1.0.1 - 新增瀑布图 -### v: 1.0.0 +## 1.0.0 - 底层依赖架构全新升级 - 新增全量 API - 持续迭代 -### v: 0.9.6 +## 0.9.6 - 新增 onlyChangeData props 用于控制 changeData 。 -### v: 0.9.5 +## 0.9.5 - tooltip 添加 ReactNode 支持。 - 提供额外 API : downloadImage()、toDataURL() 。 - 新增 memoData props 用于控制 rerender 。 -### v: 0.9.4 +## 0.9.4 新增图表 @@ -47,6 +53,6 @@ - OverlappedComboPlot -### v: 0.9.2 +## 0.9.2 修改 props 属性名,chartStyle => style。 diff --git a/package.json b/package.json index 079a00421..245bb8ddf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@ant-design/charts", - "version": "1.1.1", + "version": "1.1.2", "description": "React translate g2plot", "bugs": { "url": "https://github.com/ant-design/ant-design-charts/issues" diff --git a/src/hooks/useChart.ts b/src/hooks/useChart.ts index b70c3ff06..bf0d3312d 100644 --- a/src/hooks/useChart.ts +++ b/src/hooks/useChart.ts @@ -143,7 +143,7 @@ export default function useInit(ChartClass: a processConfig(); chart.current.update(config); } - chartOptions.current = config; + chartOptions.current = { ...config }; } }, [config]); @@ -168,7 +168,7 @@ export default function useInit(ChartClass: a }; chartInstance.render(); if (!chartOptions.current) { - chartOptions.current = config; + chartOptions.current = { ...config }; } chart.current = utils.clone(chartInstance) as T; if (onReady) { diff --git a/tests/plots/chord.test.js b/tests/plots/chord.test.js new file mode 100644 index 000000000..9599b279b --- /dev/null +++ b/tests/plots/chord.test.js @@ -0,0 +1,162 @@ +import React, { useRef, createRef } from 'react'; +import { create } from 'react-test-renderer'; +import { renderHook } from '@testing-library/react-hooks'; +import ReactDOM from 'react-dom'; +import { act } from 'react-dom/test-utils'; +import Chord from '../../src/chord'; +import ChartLoading from '../../src/util/createLoading'; +import { ErrorBoundary } from '../../src/base'; + +const refs = renderHook(() => useRef()); + +describe('Chord render', () => { + let container; + const data = [ + { source: '北京', target: '天津', value: 30 }, + { source: '北京', target: '上海', value: 80 }, + { source: '北京', target: '河北', value: 46 }, + { source: '北京', target: '辽宁', value: 49 }, + { source: '北京', target: '黑龙江', value: 69 }, + { source: '北京', target: '吉林', value: 19 }, + { source: '天津', target: '河北', value: 62 }, + { source: '天津', target: '辽宁', value: 82 }, + { source: '天津', target: '上海', value: 16 }, + { source: '上海', target: '黑龙江', value: 16 }, + { source: '河北', target: '黑龙江', value: 76 }, + { source: '河北', target: '内蒙古', value: 24 }, + { source: '内蒙古', target: '北京', value: 32 }, + ]; + beforeEach(() => { + container = document.createElement('div'); + document.body.appendChild(container); + }); + afterEach(() => { + document.body.removeChild(container); + container = null; + }); + + it('classname * loading * style', () => { + const props = { + style: { + height: '80%', + }, + className: 'container', + loading: true, + }; + const testRenderer = create(); + const testInstance = testRenderer.root; + const renderTree = testRenderer.toTree(); + expect(renderTree.rendered[0].nodeType).toBe('component'); + expect(renderTree.rendered[1].props.className).toBe('container'); + expect(renderTree.rendered[1].props.style).toEqual({ + height: '80%', + }); + expect(renderTree.rendered[1].nodeType).toBe('host'); + expect(renderTree.rendered[1].type).toBe('div'); + expect(testInstance.findAllByType(ChartLoading).length).toBe(1); + }); + + it('classname * loading * style with default', () => { + const props = {}; + const testRenderer = create(); + const testInstance = testRenderer.root; + const renderTree = testRenderer.toTree(); + expect(renderTree.rendered.nodeType).toBe('host'); + expect(renderTree.rendered.type).toBe('div'); + expect(renderTree.rendered.props.className).toBeUndefined(); + expect(testInstance.findAllByType(ChartLoading).length).toBe(0); + expect(renderTree.rendered.props.style).toEqual({ + height: 'inherit', + }); + }); + + it('error template', () => { + const props = { + loading: true, + // An object of type loadingTemplate is only used to trigger a boundary error + loadingTemplate: { + triggleError: true, + }, + errorTemplate: () => custom error, + }; + const chartProps = { + data: [], + sourceField: 'source', + targetField: 'target', + weightField: 'value', + autoFit: false, + width: '200', + height: '160', + }; + const testRenderer = create(); + const testInstance = testRenderer.root; + expect(testInstance.findByType(ErrorBoundary).children[0].children).toEqual(['custom error']); + }); + + it('chart render * chartRef with callback', () => { + let chartRef = undefined; + const props = { + className: 'container', + chartRef: (ref) => { + chartRef = ref; + }, + }; + const chartProps = { + data, + sourceField: 'source', + targetField: 'target', + weightField: 'value', + autoFit: false, + width: 200, + height: 160, + }; + act(() => { + ReactDOM.render(, container); + }); + expect(chartRef).not.toBeUndefined(); + const canvas = container.querySelector('canvas'); + expect(canvas.width).toBe(200); + expect(canvas.height).toBe(160); + expect(chartRef.chart.views[0].getData().length).toBe(data.length); + }); + + it('chartRef with createRef', () => { + const chartRef = createRef(); + const props = { + className: 'container', + chartRef, + }; + const chartProps = { + data, + sourceField: 'source', + targetField: 'target', + weightField: 'value', + autoFit: false, + width: 200, + height: 160, + }; + act(() => { + ReactDOM.render(, container); + }); + expect(chartRef.current.chart.views[0].getData().length).toBe(data.length); + }); + + it('chartRef with useRef', () => { + const props = { + className: 'container', + }; + const chartProps = { + data, + sourceField: 'source', + targetField: 'target', + weightField: 'value', + autoFit: false, + width: 200, + height: 160, + }; + act(() => { + ReactDOM.render(, container); + }); + expect(refs.current.getChart().chart.views[0].getData().length).toBe(data.length); + }); +}); diff --git a/tests/utils/use-chart.test.js b/tests/utils/use-chart.test.js index 7e3efd322..7a91f96d9 100644 --- a/tests/utils/use-chart.test.js +++ b/tests/utils/use-chart.test.js @@ -1,6 +1,5 @@ import React from 'react'; -import ReactDOM from 'react-dom'; -import { create } from 'react-test-renderer'; +import ReactDOM, { unmountComponentAtNode } from 'react-dom'; import { isFunction } from 'lodash'; import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; @@ -35,6 +34,7 @@ describe('use chart', () => { document.body.appendChild(container); }); afterEach(() => { + unmountComponentAtNode(container); document.body.removeChild(container); container = null; }); @@ -107,7 +107,7 @@ describe('use chart', () => { }); it('chart change data with normal chart', () => { - let chartRef = undefined; + let chartRef; const props = { data: [], xField: 'date', @@ -117,24 +117,16 @@ describe('use chart', () => { }, }; const wrapper = mount(); - const updateData = [ - { - date: '2010-01', - scales: 1998, - }, - { - date: '2010-02', - scales: 1850, - }, - ]; + chartRef.update = jest.fn(); wrapper.setProps({ data: areaData, }); + expect(chartRef.update).not.toHaveBeenCalled(); expect(chartRef.chart.getData()).toEqual(areaData); }); it('update config with normal chart', () => { - let chartRef = undefined; + let chartRef; const props = { data: areaData, xField: 'date', @@ -144,16 +136,18 @@ describe('use chart', () => { }, }; const wrapper = mount(); + chartRef.changeData = jest.fn(); wrapper.setProps({ point: { size: 5, }, }); + expect(chartRef.changeData).not.toHaveBeenCalled(); expect(chartRef.options.point).toEqual({ size: 5 }); }); it('change data with special chart', () => { - let chartRef = undefined; + let chartRef; const props = { percent: 0.2, xField: 'date', @@ -163,6 +157,7 @@ describe('use chart', () => { }, }; const wrapper = mount(); + chartRef.update = jest.fn(); wrapper.setProps({ percent: 0.5, });