fix(data-vi): charts flickers (#3836)
This commit is contained in:
parent
e95f4ab123
commit
996e89fb14
@ -11,38 +11,38 @@ describe('api', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('setGroup', () => {
|
test('setGroup', () => {
|
||||||
const charts1 = [new Chart({ name: 'test1', title: 'Test1', component: null })];
|
const charts1 = [new Chart({ name: 'test1', title: 'Test1', Component: null })];
|
||||||
plugin.charts.setGroup('group', charts1);
|
plugin.charts.setGroup('group', charts1);
|
||||||
expect(plugin.charts.charts.get('group')).toEqual(charts1);
|
expect(plugin.charts.charts.get('group')).toEqual(charts1);
|
||||||
|
|
||||||
const charts2 = [new Chart({ name: 'test2', title: 'Test2', component: null })];
|
const charts2 = [new Chart({ name: 'test2', title: 'Test2', Component: null })];
|
||||||
plugin.charts.setGroup('group', charts2);
|
plugin.charts.setGroup('group', charts2);
|
||||||
expect(plugin.charts.charts.get('group')).toEqual(charts2);
|
expect(plugin.charts.charts.get('group')).toEqual(charts2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('addGroup', () => {
|
test('addGroup', () => {
|
||||||
const charts1 = [new Chart({ name: 'test1', title: 'Test1', component: null })];
|
const charts1 = [new Chart({ name: 'test1', title: 'Test1', Component: null })];
|
||||||
plugin.charts.setGroup('group1', charts1);
|
plugin.charts.setGroup('group1', charts1);
|
||||||
const charts2 = [new Chart({ name: 'test2', title: 'Test2', component: null })];
|
const charts2 = [new Chart({ name: 'test2', title: 'Test2', Component: null })];
|
||||||
plugin.charts.addGroup('group2', charts2);
|
plugin.charts.addGroup('group2', charts2);
|
||||||
expect(plugin.charts.charts.get('group1')).toEqual(charts1);
|
expect(plugin.charts.charts.get('group1')).toEqual(charts1);
|
||||||
expect(plugin.charts.charts.get('group2')).toEqual(charts2);
|
expect(plugin.charts.charts.get('group2')).toEqual(charts2);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('add', () => {
|
test('add', () => {
|
||||||
const charts1 = [new Chart({ name: 'test1', title: 'Test1', component: null })];
|
const charts1 = [new Chart({ name: 'test1', title: 'Test1', Component: null })];
|
||||||
plugin.charts.setGroup('group', charts1);
|
plugin.charts.setGroup('group', charts1);
|
||||||
|
|
||||||
const chart = new Chart({ name: 'test2', title: 'Test2', component: null });
|
const chart = new Chart({ name: 'test2', title: 'Test2', Component: null });
|
||||||
plugin.charts.add('group', chart);
|
plugin.charts.add('group', chart);
|
||||||
expect(plugin.charts.charts.get('group').length).toEqual(2);
|
expect(plugin.charts.charts.get('group').length).toEqual(2);
|
||||||
expect(plugin.charts.charts.get('group')[1].name).toEqual('test2');
|
expect(plugin.charts.charts.get('group')[1].name).toEqual('test2');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getChartTypes', () => {
|
test('getChartTypes', () => {
|
||||||
const charts1 = [new Chart({ name: 'test1', title: 'Test1', component: null })];
|
const charts1 = [new Chart({ name: 'test1', title: 'Test1', Component: null })];
|
||||||
plugin.charts.setGroup('group1', charts1);
|
plugin.charts.setGroup('group1', charts1);
|
||||||
const charts2 = [new Chart({ name: 'test2', title: 'Test2', component: null })];
|
const charts2 = [new Chart({ name: 'test2', title: 'Test2', Component: null })];
|
||||||
plugin.charts.setGroup('group2', charts2);
|
plugin.charts.setGroup('group2', charts2);
|
||||||
expect(plugin.charts.getChartTypes()).toEqual([
|
expect(plugin.charts.getChartTypes()).toEqual([
|
||||||
{
|
{
|
||||||
@ -69,9 +69,9 @@ describe('api', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('getCharts', () => {
|
test('getCharts', () => {
|
||||||
const charts1 = [new Chart({ name: 'test1', title: 'Test1', component: null })];
|
const charts1 = [new Chart({ name: 'test1', title: 'Test1', Component: null })];
|
||||||
plugin.charts.setGroup('group1', charts1);
|
plugin.charts.setGroup('group1', charts1);
|
||||||
const charts2 = [new Chart({ name: 'test2', title: 'Test2', component: null })];
|
const charts2 = [new Chart({ name: 'test2', title: 'Test2', Component: null })];
|
||||||
plugin.charts.setGroup('group2', charts2);
|
plugin.charts.setGroup('group2', charts2);
|
||||||
expect(plugin.charts.getCharts()).toEqual({
|
expect(plugin.charts.getCharts()).toEqual({
|
||||||
'group1.test1': charts1[0],
|
'group1.test1': charts1[0],
|
||||||
@ -80,9 +80,9 @@ describe('api', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('getChart', () => {
|
test('getChart', () => {
|
||||||
const charts1 = [new Chart({ name: 'test1', title: 'Test1', component: null })];
|
const charts1 = [new Chart({ name: 'test1', title: 'Test1', Component: null })];
|
||||||
plugin.charts.setGroup('group1', charts1);
|
plugin.charts.setGroup('group1', charts1);
|
||||||
const charts2 = [new Chart({ name: 'test2', title: 'Test2', component: null })];
|
const charts2 = [new Chart({ name: 'test2', title: 'Test2', Component: null })];
|
||||||
plugin.charts.setGroup('group2', charts2);
|
plugin.charts.setGroup('group2', charts2);
|
||||||
expect(plugin.charts.getChart('group1.test1')).toEqual(charts1[0]);
|
expect(plugin.charts.getChart('group1.test1')).toEqual(charts1[0]);
|
||||||
expect(plugin.charts.getChart('group2.test2')).toEqual(charts2[0]);
|
expect(plugin.charts.getChart('group2.test2')).toEqual(charts2[0]);
|
||||||
@ -90,7 +90,7 @@ describe('api', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('auto infer', () => {
|
describe('auto infer', () => {
|
||||||
const chart = new Chart({ name: 'test', title: 'Test', component: null });
|
const chart = new Chart({ name: 'test', title: 'Test', Component: null });
|
||||||
const fields = [
|
const fields = [
|
||||||
{
|
{
|
||||||
name: 'price',
|
name: 'price',
|
||||||
|
@ -8,7 +8,7 @@ export class Statistic extends AntdChart {
|
|||||||
super({
|
super({
|
||||||
name: 'statistic',
|
name: 'statistic',
|
||||||
title: 'Statistic',
|
title: 'Statistic',
|
||||||
component: AntdStatistic,
|
Component: AntdStatistic,
|
||||||
config: [
|
config: [
|
||||||
{
|
{
|
||||||
property: 'field',
|
property: 'field',
|
||||||
|
@ -4,7 +4,7 @@ import { Table as AntdTable } from 'antd';
|
|||||||
|
|
||||||
export class Table extends AntdChart {
|
export class Table extends AntdChart {
|
||||||
constructor() {
|
constructor() {
|
||||||
super({ name: 'table', title: 'Table', component: AntdTable });
|
super({ name: 'table', title: 'Table', Component: AntdTable });
|
||||||
}
|
}
|
||||||
|
|
||||||
getProps({ data, fieldProps, general, advanced }: RenderProps) {
|
getProps({ data, fieldProps, general, advanced }: RenderProps) {
|
||||||
|
@ -22,7 +22,7 @@ export type RenderProps = {
|
|||||||
export interface ChartType {
|
export interface ChartType {
|
||||||
name: string;
|
name: string;
|
||||||
title: string;
|
title: string;
|
||||||
component: React.FC<any>;
|
Component: React.FC<any>;
|
||||||
schema: ISchema;
|
schema: ISchema;
|
||||||
init?: (
|
init?: (
|
||||||
fields: FieldOption[],
|
fields: FieldOption[],
|
||||||
@ -34,7 +34,7 @@ export interface ChartType {
|
|||||||
general?: any;
|
general?: any;
|
||||||
advanced?: any;
|
advanced?: any;
|
||||||
};
|
};
|
||||||
render: (props: RenderProps) => React.FC<any>;
|
getProps(props: RenderProps): any;
|
||||||
getReference?: () => {
|
getReference?: () => {
|
||||||
title: string;
|
title: string;
|
||||||
link: string;
|
link: string;
|
||||||
@ -44,21 +44,21 @@ export interface ChartType {
|
|||||||
export type ChartProps = {
|
export type ChartProps = {
|
||||||
name: string;
|
name: string;
|
||||||
title: string;
|
title: string;
|
||||||
component: React.FC<any>;
|
Component: React.FC<any>;
|
||||||
config?: Config[];
|
config?: Config[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Chart implements ChartType {
|
export class Chart implements ChartType {
|
||||||
name: string;
|
name: string;
|
||||||
title: string;
|
title: string;
|
||||||
component: React.FC<any>;
|
Component: React.FC<any>;
|
||||||
config: Config[];
|
config: Config[];
|
||||||
configs = new Map<string, Function>();
|
configs = new Map<string, Function>();
|
||||||
|
|
||||||
constructor({ name, title, component, config }: ChartProps) {
|
constructor({ name, title, Component, config }: ChartProps) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.component = component;
|
this.Component = Component;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.addConfigs(configs);
|
this.addConfigs(configs);
|
||||||
}
|
}
|
||||||
@ -170,11 +170,4 @@ export class Chart implements ChartType {
|
|||||||
getProps(props: RenderProps): any {
|
getProps(props: RenderProps): any {
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
render({ data, general, advanced, fieldProps }: RenderProps) {
|
|
||||||
return () =>
|
|
||||||
React.createElement(this.component, {
|
|
||||||
...this.getProps({ data, general, advanced, fieldProps }),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { ChartType } from '../chart';
|
|||||||
|
|
||||||
export class Bar extends G2PlotChart {
|
export class Bar extends G2PlotChart {
|
||||||
constructor() {
|
constructor() {
|
||||||
super({ name: 'bar', title: 'Bar Chart', component: G2PlotBar, config: ['isGroup', 'isStack', 'isPercent'] });
|
super({ name: 'bar', title: 'Bar Chart', Component: G2PlotBar, config: ['isGroup', 'isStack', 'isPercent'] });
|
||||||
}
|
}
|
||||||
|
|
||||||
init: ChartType['init'] = (fields, { measures, dimensions }) => {
|
init: ChartType['init'] = (fields, { measures, dimensions }) => {
|
||||||
|
@ -6,7 +6,7 @@ import lodash from 'lodash';
|
|||||||
|
|
||||||
export class DualAxes extends G2PlotChart {
|
export class DualAxes extends G2PlotChart {
|
||||||
constructor() {
|
constructor() {
|
||||||
super({ name: 'dualAxes', title: 'Dual Axes Chart', component: G2DualAxes });
|
super({ name: 'dualAxes', title: 'Dual Axes Chart', Component: G2DualAxes });
|
||||||
this.config = [
|
this.config = [
|
||||||
'xField',
|
'xField',
|
||||||
{
|
{
|
||||||
|
@ -2,11 +2,11 @@ import { Chart, ChartProps, ChartType, RenderProps } from '../chart';
|
|||||||
import configs from './configs';
|
import configs from './configs';
|
||||||
|
|
||||||
export class G2PlotChart extends Chart {
|
export class G2PlotChart extends Chart {
|
||||||
constructor({ name, title, component, config }: ChartProps) {
|
constructor({ name, title, Component, config }: ChartProps) {
|
||||||
super({
|
super({
|
||||||
name,
|
name,
|
||||||
title,
|
title,
|
||||||
component,
|
Component,
|
||||||
config: ['xField', 'yField', 'seriesField', ...(config || [])],
|
config: ['xField', 'yField', 'seriesField', ...(config || [])],
|
||||||
});
|
});
|
||||||
this.addConfigs(configs);
|
this.addConfigs(configs);
|
||||||
|
@ -7,13 +7,13 @@ export default [
|
|||||||
new G2PlotChart({
|
new G2PlotChart({
|
||||||
name: 'line',
|
name: 'line',
|
||||||
title: 'Line Chart',
|
title: 'Line Chart',
|
||||||
component: Line,
|
Component: Line,
|
||||||
config: ['smooth', 'isStack'],
|
config: ['smooth', 'isStack'],
|
||||||
}),
|
}),
|
||||||
new G2PlotChart({
|
new G2PlotChart({
|
||||||
name: 'area',
|
name: 'area',
|
||||||
title: 'Area Chart',
|
title: 'Area Chart',
|
||||||
component: Area,
|
Component: Area,
|
||||||
config: [
|
config: [
|
||||||
'smooth',
|
'smooth',
|
||||||
{
|
{
|
||||||
@ -26,16 +26,16 @@ export default [
|
|||||||
new G2PlotChart({
|
new G2PlotChart({
|
||||||
name: 'column',
|
name: 'column',
|
||||||
title: 'Column Chart',
|
title: 'Column Chart',
|
||||||
component: Column,
|
Component: Column,
|
||||||
config: ['isGroup', 'isStack', 'isPercent'],
|
config: ['isGroup', 'isStack', 'isPercent'],
|
||||||
}),
|
}),
|
||||||
new G2PlotChart({
|
new G2PlotChart({
|
||||||
name: 'bar',
|
name: 'bar',
|
||||||
title: 'Bar Chart',
|
title: 'Bar Chart',
|
||||||
component: Bar,
|
Component: Bar,
|
||||||
config: ['isGroup', 'isStack', 'isPercent'],
|
config: ['isGroup', 'isStack', 'isPercent'],
|
||||||
}),
|
}),
|
||||||
new Pie(),
|
new Pie(),
|
||||||
new DualAxes(),
|
new DualAxes(),
|
||||||
new G2PlotChart({ name: 'scatter', title: 'Scatter Chart', component: Scatter }),
|
new G2PlotChart({ name: 'scatter', title: 'Scatter Chart', Component: Scatter }),
|
||||||
];
|
];
|
||||||
|
@ -4,7 +4,7 @@ import { ChartType, RenderProps } from '../chart';
|
|||||||
|
|
||||||
export class Pie extends G2PlotChart {
|
export class Pie extends G2PlotChart {
|
||||||
constructor() {
|
constructor() {
|
||||||
super({ name: 'pie', title: 'Pie Chart', component: G2Pie });
|
super({ name: 'pie', title: 'Pie Chart', Component: G2Pie });
|
||||||
this.config = [
|
this.config = [
|
||||||
{
|
{
|
||||||
property: 'field',
|
property: 'field',
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
useDesignable,
|
useDesignable,
|
||||||
} from '@nocobase/client';
|
} from '@nocobase/client';
|
||||||
import { Empty, Result, Spin, Typography } from 'antd';
|
import { Empty, Result, Spin, Typography } from 'antd';
|
||||||
import React, { useContext } from 'react';
|
import React, { memo, useContext } from 'react';
|
||||||
import { ErrorBoundary } from 'react-error-boundary';
|
import { ErrorBoundary } from 'react-error-boundary';
|
||||||
import { ChartConfigContext } from '../configure';
|
import { ChartConfigContext } from '../configure';
|
||||||
import { useData, useFieldTransformer, useFieldsWithAssociation } from '../hooks';
|
import { useData, useFieldTransformer, useFieldsWithAssociation } from '../hooks';
|
||||||
@ -22,6 +22,8 @@ import { ChartRendererContext } from './ChartRendererProvider';
|
|||||||
import { useChart } from '../chart/group';
|
import { useChart } from '../chart/group';
|
||||||
import { ChartDataContext } from '../block/ChartDataProvider';
|
import { ChartDataContext } from '../block/ChartDataProvider';
|
||||||
const { Paragraph, Text } = Typography;
|
const { Paragraph, Text } = Typography;
|
||||||
|
import lodash from 'lodash';
|
||||||
|
import { Line } from '@ant-design/plots';
|
||||||
|
|
||||||
export const ChartRenderer: React.FC & {
|
export const ChartRenderer: React.FC & {
|
||||||
Designer: React.FC;
|
Designer: React.FC;
|
||||||
@ -38,7 +40,7 @@ export const ChartRenderer: React.FC & {
|
|||||||
const chart = useChart(config?.chartType);
|
const chart = useChart(config?.chartType);
|
||||||
const locale = api.auth.getLocale();
|
const locale = api.auth.getLocale();
|
||||||
const transformers = useFieldTransformer(transform, locale);
|
const transformers = useFieldTransformer(transform, locale);
|
||||||
const Component = chart?.render({
|
const chartProps = chart?.getProps({
|
||||||
data,
|
data,
|
||||||
general,
|
general,
|
||||||
advanced,
|
advanced,
|
||||||
@ -51,30 +53,27 @@ export const ChartRenderer: React.FC & {
|
|||||||
return props;
|
return props;
|
||||||
}, {}),
|
}, {}),
|
||||||
});
|
});
|
||||||
|
const C = chart?.Component;
|
||||||
|
|
||||||
const C = () =>
|
if (!chart) {
|
||||||
chart ? (
|
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={t('Please configure chart')} />;
|
||||||
|
}
|
||||||
|
if (!(data && data.length) && !service.loading) {
|
||||||
|
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={t('No data')} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Spin spinning={service.loading}>
|
||||||
<ErrorBoundary
|
<ErrorBoundary
|
||||||
onError={(error) => {
|
onError={(error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}}
|
}}
|
||||||
FallbackComponent={ErrorFallback}
|
FallbackComponent={ErrorFallback}
|
||||||
>
|
>
|
||||||
<Component />
|
<C {...chartProps} />
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
) : (
|
</Spin>
|
||||||
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={t('Please configure chart')} />
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if (service.loading) {
|
|
||||||
return <Spin />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(data && data.length)) {
|
|
||||||
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={t('No data')} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <C />;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ChartRenderer.Designer = function Designer() {
|
ChartRenderer.Designer = function Designer() {
|
||||||
|
Loading…
Reference in New Issue
Block a user