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