fix: ui issues
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import Chart from '@/components/echarts/chart';
|
||||
import {
|
||||
barItemConfig,
|
||||
grid,
|
||||
legend,
|
||||
tooltip,
|
||||
xAxis,
|
||||
yAxis
|
||||
} from '@/components/echarts/config';
|
||||
import _ from 'lodash';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { ChartProps } from './types';
|
||||
|
||||
const BarChart: React.FC<ChartProps> = (props) => {
|
||||
const {
|
||||
seriesData,
|
||||
xAxisData,
|
||||
height,
|
||||
width,
|
||||
labelFormatter,
|
||||
legendData,
|
||||
title
|
||||
} = props;
|
||||
const [dataOptions, setDataOptions] = useState({});
|
||||
|
||||
const options = {
|
||||
title: {
|
||||
text: ''
|
||||
},
|
||||
grid,
|
||||
tooltip: {
|
||||
...tooltip
|
||||
// axisPointer: {
|
||||
// type: 'shadow'
|
||||
// }
|
||||
},
|
||||
xAxis: {
|
||||
...xAxis,
|
||||
axisLabel: {
|
||||
...xAxis.axisLabel,
|
||||
formatter: labelFormatter
|
||||
},
|
||||
data: []
|
||||
},
|
||||
yAxis,
|
||||
legend: {
|
||||
...legend,
|
||||
data: []
|
||||
},
|
||||
|
||||
series: []
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const data = _.map(seriesData, (item: any) => {
|
||||
return {
|
||||
...item,
|
||||
...barItemConfig,
|
||||
stack: 'total',
|
||||
itemStyle: {
|
||||
color: item.color
|
||||
}
|
||||
};
|
||||
});
|
||||
const optionsConfig = {
|
||||
...options,
|
||||
title: {
|
||||
show: true,
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
fontSize: 14
|
||||
},
|
||||
text: title
|
||||
},
|
||||
yAxis: {
|
||||
...options.yAxis
|
||||
},
|
||||
xAxis: {
|
||||
...options.xAxis,
|
||||
data: xAxisData
|
||||
},
|
||||
series: data
|
||||
};
|
||||
console.log('optionsConfig=========', optionsConfig);
|
||||
setDataOptions(optionsConfig);
|
||||
}, [seriesData, xAxisData, title]);
|
||||
return (
|
||||
<Chart
|
||||
height={height}
|
||||
options={dataOptions}
|
||||
width={width || '100%'}
|
||||
></Chart>
|
||||
);
|
||||
};
|
||||
|
||||
export default BarChart;
|
||||
@@ -0,0 +1,58 @@
|
||||
import { throttle } from 'echarts/core';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import echarts, { ECOption } from '.';
|
||||
|
||||
const Chart: React.FC<{
|
||||
options: ECOption;
|
||||
height: number | string;
|
||||
width: number | string;
|
||||
}> = ({ options, width, height }) => {
|
||||
const container = useRef<HTMLDivElement>(null);
|
||||
const chart = useRef<echarts.EChartsType>();
|
||||
|
||||
const init = useCallback(() => {
|
||||
if (container.current) {
|
||||
chart.current?.clear();
|
||||
chart.current = echarts.init(container.current);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const resize = useCallback(() => {
|
||||
chart.current?.resize();
|
||||
}, []);
|
||||
|
||||
const setOption = useCallback((options: ECOption) => {
|
||||
chart.current?.clear();
|
||||
chart.current?.setOption(options, {
|
||||
notMerge: true,
|
||||
lazyUpdate: true
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
init();
|
||||
return () => {
|
||||
chart.current?.dispose();
|
||||
};
|
||||
}, [init]);
|
||||
|
||||
useEffect(() => {
|
||||
resize();
|
||||
setOption(options);
|
||||
}, [options]);
|
||||
|
||||
// resize on window resize
|
||||
useEffect(() => {
|
||||
const handleResize = throttle(() => {
|
||||
resize();
|
||||
}, 100);
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
};
|
||||
}, [resize, chart]);
|
||||
|
||||
return <div ref={container} style={{ width: width, height }}></div>;
|
||||
};
|
||||
|
||||
export default Chart;
|
||||
@@ -0,0 +1,102 @@
|
||||
const chartColorMap = {
|
||||
tickLineColor: 'rgba(217,217,217,0.5)',
|
||||
axislabelColor: 'rgba(0, 0, 0, 0.4)'
|
||||
};
|
||||
|
||||
export const tooltip = {
|
||||
trigger: 'axis',
|
||||
// axisPointer: {
|
||||
// type: 'shadow'
|
||||
// }
|
||||
formatter(params: any) {
|
||||
let result = `<span class="tooltip-x-name">${params[0].axisValue}</span>`;
|
||||
params.forEach((item: any) => {
|
||||
result += `<span class="tooltip-item">
|
||||
<span class="tooltip-item-name">
|
||||
<span style="display:inline-block;margin-right:5px;border-radius:8px;width:8px;height:8px;background-color:${item.color};"></span>
|
||||
<span class="tooltip-title">${item.seriesName}</span>:
|
||||
</span>
|
||||
<span class="tooltip-value">${item.data.value}</span>
|
||||
</span>`;
|
||||
});
|
||||
return `<div class="tooltip-wrapper">${result}</div>`;
|
||||
}
|
||||
};
|
||||
|
||||
export const grid = {
|
||||
left: 0,
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
containLabel: true
|
||||
};
|
||||
|
||||
export const legend = {
|
||||
itemWidth: 8,
|
||||
itemHeight: 8
|
||||
};
|
||||
|
||||
export const xAxis = {
|
||||
type: 'category',
|
||||
boundaryGap: true,
|
||||
axisTick: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: chartColorMap.tickLineColor
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: chartColorMap.axislabelColor,
|
||||
fontSize: 12
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
}
|
||||
};
|
||||
|
||||
export const yAxis = {
|
||||
// max: 100,
|
||||
// min: 0,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'dashed'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: chartColorMap.axislabelColor,
|
||||
fontSize: 12
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
type: 'value'
|
||||
};
|
||||
|
||||
export const title = {
|
||||
show: true,
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
fontSize: 14
|
||||
},
|
||||
text: ''
|
||||
};
|
||||
|
||||
export const barItemConfig = {
|
||||
type: 'bar',
|
||||
barMaxWidth: 20,
|
||||
barMinWidth: 8,
|
||||
// stack: 'total',
|
||||
barGap: '30%',
|
||||
barCategoryGap: '50%'
|
||||
};
|
||||
|
||||
export const lineItemConfig = {
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
itemStyle: {},
|
||||
lineStyle: {
|
||||
width: 1.5,
|
||||
opacity: 0.7
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,116 @@
|
||||
import Chart from '@/components/echarts/chart';
|
||||
import {
|
||||
grid,
|
||||
legend,
|
||||
title as titleConfig,
|
||||
tooltip,
|
||||
xAxis,
|
||||
yAxis
|
||||
} from '@/components/echarts/config';
|
||||
import _ from 'lodash';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { ChartProps } from './types';
|
||||
|
||||
const BarChart: React.FC<ChartProps> = (props) => {
|
||||
const {
|
||||
seriesData,
|
||||
xAxisData,
|
||||
height,
|
||||
width,
|
||||
labelFormatter,
|
||||
legendData,
|
||||
title
|
||||
} = props;
|
||||
const [dataOptions, setDataOptions] = useState({});
|
||||
|
||||
const options = {
|
||||
title: titleConfig,
|
||||
grid,
|
||||
tooltip: {
|
||||
...tooltip
|
||||
},
|
||||
xAxis: {
|
||||
...xAxis,
|
||||
axisLabel: {
|
||||
...xAxis.axisLabel,
|
||||
formatter: labelFormatter
|
||||
}
|
||||
},
|
||||
yAxis,
|
||||
legend: {
|
||||
...legend,
|
||||
data: []
|
||||
},
|
||||
|
||||
series: []
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const data = _.map(seriesData, (item: any) => {
|
||||
return {
|
||||
...item,
|
||||
type: 'bar',
|
||||
barWidth: 20,
|
||||
stack: 'Ad',
|
||||
barGap: '30%',
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
itemStyle: {
|
||||
color: item.color
|
||||
}
|
||||
};
|
||||
return item;
|
||||
});
|
||||
const optionsConfig = {
|
||||
...options,
|
||||
title: {
|
||||
...options.title,
|
||||
left: 'start',
|
||||
text: title
|
||||
},
|
||||
yAxis: {
|
||||
...options.yAxis,
|
||||
inverse: true,
|
||||
type: 'category',
|
||||
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
data: xAxisData,
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
...options.xAxis,
|
||||
boundaryGap: true,
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: data
|
||||
};
|
||||
console.log('optionsConfig========h=', optionsConfig);
|
||||
setDataOptions(optionsConfig);
|
||||
}, [seriesData, xAxisData, title]);
|
||||
return (
|
||||
<Chart
|
||||
height={height}
|
||||
options={dataOptions}
|
||||
width={width || '100%'}
|
||||
></Chart>
|
||||
);
|
||||
};
|
||||
|
||||
export default BarChart;
|
||||
@@ -0,0 +1,56 @@
|
||||
import type {
|
||||
// 系列类型的定义后缀都为 SeriesOption
|
||||
BarSeriesOption,
|
||||
LineSeriesOption
|
||||
} from 'echarts/charts';
|
||||
import { BarChart, LineChart } from 'echarts/charts';
|
||||
import type {
|
||||
DatasetComponentOption,
|
||||
GridComponentOption,
|
||||
// 组件类型的定义后缀都为 ComponentOption
|
||||
TitleComponentOption,
|
||||
TooltipComponentOption
|
||||
} from 'echarts/components';
|
||||
import {
|
||||
// 数据集组件
|
||||
DatasetComponent,
|
||||
GridComponent,
|
||||
LegendComponent,
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
// 内置数据转换器组件 (filter, sort)
|
||||
TransformComponent
|
||||
} from 'echarts/components';
|
||||
import type { ComposeOption } from 'echarts/core';
|
||||
import * as echarts from 'echarts/core';
|
||||
import { LabelLayout, UniversalTransition } from 'echarts/features';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
|
||||
// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
|
||||
type ECOption = ComposeOption<
|
||||
| BarSeriesOption
|
||||
| LineSeriesOption
|
||||
| TitleComponentOption
|
||||
| TooltipComponentOption
|
||||
| GridComponentOption
|
||||
| DatasetComponentOption
|
||||
>;
|
||||
|
||||
// 注册必须的组件
|
||||
echarts.use([
|
||||
LegendComponent,
|
||||
TitleComponent,
|
||||
TooltipComponent,
|
||||
GridComponent,
|
||||
DatasetComponent,
|
||||
TransformComponent,
|
||||
BarChart,
|
||||
LineChart,
|
||||
LabelLayout,
|
||||
UniversalTransition,
|
||||
CanvasRenderer
|
||||
]);
|
||||
|
||||
export type { ECOption };
|
||||
|
||||
export default echarts;
|
||||
@@ -0,0 +1,98 @@
|
||||
import Chart from '@/components/echarts/chart';
|
||||
import {
|
||||
grid,
|
||||
legend,
|
||||
lineItemConfig,
|
||||
tooltip,
|
||||
xAxis,
|
||||
yAxis
|
||||
} from '@/components/echarts/config';
|
||||
import _ from 'lodash';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { ChartProps } from './types';
|
||||
|
||||
const LineChart: React.FC<ChartProps> = (props) => {
|
||||
const {
|
||||
seriesData,
|
||||
xAxisData,
|
||||
height,
|
||||
width,
|
||||
labelFormatter,
|
||||
legendData,
|
||||
smooth,
|
||||
title
|
||||
} = props;
|
||||
const [dataOptions, setDataOptions] = useState({});
|
||||
|
||||
const options = {
|
||||
title: {
|
||||
text: ''
|
||||
},
|
||||
grid,
|
||||
tooltip: {
|
||||
...tooltip
|
||||
},
|
||||
xAxis: {
|
||||
...xAxis,
|
||||
axisLabel: {
|
||||
...xAxis.axisLabel,
|
||||
formatter: labelFormatter
|
||||
}
|
||||
},
|
||||
yAxis,
|
||||
legend: {
|
||||
...legend,
|
||||
data: []
|
||||
},
|
||||
|
||||
series: []
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const data = _.map(seriesData, (item: any) => {
|
||||
return {
|
||||
...item,
|
||||
...lineItemConfig,
|
||||
smooth: smooth,
|
||||
itemStyle: {
|
||||
...lineItemConfig.itemStyle,
|
||||
color: item.color
|
||||
},
|
||||
lineStyle: {
|
||||
...lineItemConfig.lineStyle,
|
||||
color: item.color
|
||||
}
|
||||
};
|
||||
});
|
||||
const optionsConfig = {
|
||||
...options,
|
||||
title: {
|
||||
show: true,
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
fontSize: 14
|
||||
},
|
||||
text: title
|
||||
},
|
||||
yAxis: {
|
||||
...options.yAxis
|
||||
},
|
||||
xAxis: {
|
||||
...options.xAxis,
|
||||
data: xAxisData
|
||||
},
|
||||
series: data
|
||||
};
|
||||
console.log('optionsConfig========line=', optionsConfig);
|
||||
setDataOptions(optionsConfig);
|
||||
}, [seriesData, xAxisData, title]);
|
||||
return (
|
||||
<Chart
|
||||
height={height}
|
||||
options={dataOptions}
|
||||
width={width || '100%'}
|
||||
></Chart>
|
||||
);
|
||||
};
|
||||
|
||||
export default LineChart;
|
||||
@@ -0,0 +1,17 @@
|
||||
export interface ChartProps {
|
||||
seriesData: any[];
|
||||
xAxisData: string[];
|
||||
legendData?: string[];
|
||||
labelFormatter?: (val?: any) => string;
|
||||
height: string | number;
|
||||
width?: string | number;
|
||||
title?: string;
|
||||
smooth?: boolean;
|
||||
}
|
||||
|
||||
export interface AreaChartItemProps {
|
||||
name: string;
|
||||
color: string;
|
||||
areaStyle: any;
|
||||
data: { time: string; value: number }[];
|
||||
}
|
||||
Reference in New Issue
Block a user