echarts封装hooks
目录
- 处理props参数:
- convertSeries: 允许用户通过
props.convertSeries
自定义series
配置。 - convertXAxis: 允许用户通过
props.convertXAxis
自定义xAxis
配置。 - convertYxis: 允许用户通过
props.convertYxis
自定义yAxis
配置。 - convertData: 允许用户通过
props.convertData
自定义series
中data
数据。 - convertlegend: 允许用户通过
props.convertlegend
自定义legend
配置。
- convertSeries: 允许用户通过
- 宽高适配: 使用
countChartSize
函数根据窗口尺寸调整图表的宽高。
基础配置
- getBaseLegend: 返回图例的基本样式。
const getBaseLegend = () => { return { bottom: 0, left: 0, orient: "vertical", itemWidth: 8, itemHeight: 8, textStyle: { color: "white", }, }; };
- getBaseSeries: 返回基础的饼图配置。
export const getBaseSeries = () => { return { type: "pie", radius: ["50%", "70%"], width: 140, height: 140, label: { show: false, position: "bottom", }, labelLine: { show: false, }, data: [ { value: 1048, name: "大型及以上餐饮>500m²" }, { value: 735, name: "中型餐饮150m²<面积≤500m²" }, { value: 580, name: "小微型餐饮≤150m²" }, ], }; };
useChart Hook
- useChart: 接受一个
props
参数,根据props
动态生成ECharts的配置对象options
。export const useChart = (props: any) => { const options = { tooltip: { trigger: "item", position: ["50%", "50%"], borderColor: "#9DC3EF", borderWidth: 1, backgroundColor: "rgba(16,21,35,0.8)", textStyle: { color: "white", }, }, color: ["#83BAFA", "#3768D8", "#15DED7", "#F1E49D", "#668DE3"], legend: getBaseLegend(), series: [getBaseSeries()], grid: { bottom: "20%", height: 90, }, } as any;
自定义配置处理
- 重写Series配置: 根据
props.convertSeries
,可以自定义图表的 series 配置。if (props.convertSeries) { if (props.multiple) { options.series = props.convertSeries(); } else { options.series[0] = { ...getBaseSeries(), ...props.convertSeries(), }; } }
- 重写x轴: 如果存在
props.convertXAxis
,则使用该函数来生成 xAxis 配置。if (props.convertXAxis) { options.xAxis = props.convertXAxis(); }
- 重写Y轴: 同样地,若存在
props.convertYxis
,则生成 yAxis 配置。if (props.convertYxis) { options.yAxis = props.convertYxis(); }
- 重写数据: 使用
props.convertData
函数来生成 series 的数据。if (props.convertData) { options.series[0].data = props.convertData(); }
- 重写图例: 通过
props.convertlegend
可以自定义图例配置。if (props.convertlegend) { options.legend = { ...getBaseLegend(), ...props.convertlegend(), }; }
宽高适配
- 适配宽高: 对于series中的每个图表项,通过
countChartSize
函数根据窗口尺寸进行宽高适配。if (options.series) { options.series.forEach((item: { width: number; height: number }) => { if (item.width && item.height) { const currentItem = cloneDeep(item); const { width, height } = countChartSize( currentItem.width, currentItem.height ); item.width = width; item.height = height; } }); }
计算图表宽高
- countChartSize: 计算图表在不同屏幕尺寸下的宽高。
const countChartSize = (width: number, height: number) => { return { width: (window.innerWidth / 1920) * width, height: (window.innerHeight / 1080) * height, }; };
返回最终配置
- 返回 ****
options
: 返回生成的图表配置对象。return options; };
通过 useChart
hook,用户可以根据需求自定义图表的各个部分配置,并且可以适配不同的屏幕尺寸,使得图表配置变得更加灵活和易用。
完整代码:
import { cloneDeep } from "lodash";
/**
* 获取默认的图例样式
*/
const getBaseLegend = () => {
return {
bottom: 0,
left: 0,
orient: "vertical",
itemWidth: 8,
itemHeight: 8,
textStyle: {
color: "white",
},
};
};
export const getBaseSeries = () => {
return {
type: "pie",
radius: ["50%", "70%"],
width: 140,
height: 140,
label: {
show: false,
position: "bottom",
},
labelLine: {
show: false,
},
data: [
{ value: 1048, name: "大型及以上餐饮>500m²" },
{ value: 735, name: "中型餐饮150m²<面积≤500m²" },
{ value: 580, name: "小微型餐饮≤150m²" },
],
};
};
export const useChart = (props: any) => {
const options = {
tooltip: {
trigger: "item",
position: ["50%", "50%"],
borderColor: "#9DC3EF",
borderWidth: 1,
backgroundColor: "rgba(16,21,35,0.8)",
textStyle: {
color: "white",
},
},
color: ["#83BAFA", "#3768D8", "#15DED7", "#F1E49D", "#668DE3"],
legend: getBaseLegend(),
series: [getBaseSeries()],
grid: {
bottom: "20%",
height: 90,
},
} as any;
/** 抽象出每个选项的实现操作 */
// 重写Series配置
if (props.convertSeries) {
// 图表里存在多个图
if (props.multiple) {
options.series = props.convertSeries();
} else {
// 只第一个图
options.series[0] = {
...getBaseSeries(),
...props.convertSeries(),
};
}
}
// 重写x轴
if (props.convertXAxis) {
options.xAxis = props.convertXAxis();
}
// 重写Y轴
if (props.convertYxis) {
options.yAxis = props.convertYxis();
}
// 注意要先修改series 在修改数据 否则会被覆盖
// 重写数据层
if (props.convertData) {
options.series[0].data = props.convertData();
}
// 重写图例
if (props.convertlegend) {
options.legend = {
...getBaseLegend(),
...props.convertlegend(),
};
}
// 统一对宽高做适配
if (options.series) {
options.series.forEach((item: { width: number; height: number }) => {
if (item.width && item.height) {
const currentItem = cloneDeep(item);
const { width, height } = countChartSize(
currentItem.width,
currentItem.height
);
item.width = width;
item.height = height;
}
});
}
return options;
};
// 计算图表宽高
const countChartSize = (width: number, height: number) => {
return {
width: (window.innerWidth / 1920) * width,
height: (window.innerHeight / 1080) * height,
};
};
对封装echarts的使用
示例:社会餐饮图表配置
const societyChartOption = useChart({
convertData: () => {
return [
{ value: 1048, name: "大型及以上餐饮>500m²" },
{ value: 735, name: "中型餐饮150m²<面积≤500m²" },
{ value: 580, name: "小微型餐饮≤150m²" },
];
},
});
这里调用 useChart
并传入一个对象,包含 convertData
方法。convertData
方法返回社会餐饮图表的数据。
示例:集体食堂图表配置
const groupChartOption = useChart({
convertData: () => {
return [
{ value: 1048, name: "学校食堂" },
{ value: 1048, name: "医疗机构食堂" },
{ value: 1048, name: "其他食堂" },
{ value: 1048, name: "养老机构食堂" },
];
},
});
类似地,useChart
被调用并传入 convertData
方法来生成集体食堂图表的数据。
示例:认证企业数图表配置
const foodChartOptionA = useChart({
convertData: () => {
return [
{ value: 1048, name: "大型及以上餐饮>500m²" },
{ value: 735, name: "中型餐饮150m²<面积≤500m²" },
{ value: 580, name: "小微型餐饮≤150m²" },
{ value: 1048, name: "学校食堂" },
{ value: 1048, name: "医疗机构食堂" },
{ value: 1048, name: "其他食堂" },
{ value: 1048, name: "养老机构食堂" },
];
},
convertSeries: () => {
return {
with: 157,
height: 157,
};
},
convertlegend: () => {
return {
right: 0,
left: null,
itemGap: 25,
top: "center",
};
},
});
这里 useChart
被调用时传入了三个方法:convertData
、convertSeries
和 convertlegend
。这些方法分别用来生成图表的数据、系列的宽高和图例的位置。