在初始化的时候有一点不同,使用svg方式渲染更清晰
echarts.init(dom, undefined, { renderer: "svg" });
期望结果:
- 鼠标滚轮缩放,图表字体自适应,图形自适应
本次封装比较草率,实在看不下去就自己修改一下
先说使用方式
useSelfAdaptionEcharts(option, myChart);//option图表配置,myChart图表实例
注意needDefaultFields这个变量上面的注释说明
import * as echarts from "echarts";
import { ECharts } from "echarts";
type EChartsOption = echarts.EChartsOption;
// 需要转为自适应的字段
const fields = [
"borderDashOffset",
"fontSize",
"width",
"height",
"left",
"right",
"top",
"bottom",
"distance",
"padding",
"nameGap",
"borderWidth",
"borderRadius",
"shadowOffsetX",
"shadowOffsetY",
"itemWidth",
"itemHeight",
"radius"
];
/*
需要设置默认值的字段🤪
{
key:字段名
pathList:[
[该字段所涉及的层级关系]
]
}
在传入的option中需要把需要设置默认值的字段层级写到上一层
例如:需要将tooltip中的textStyle的fontSize设置默认值
option中只需要写 tooltip:{textStyle:{}}
*/
const needDefaultFields = [
{
key: "fontSize",
defaultVal: 10,
pathList: [
["legend", "textStyle"],
["xAxis", "axisLabel"],
["yAxis", "axisLabel"],
["series","label"],
["yAxis", "nameTextStyle"]
]
},
{
key: "fontSize",
defaultVal: 14,
pathList: [["tooltip", "textStyle"]]
}
];
const standWidth = window.innerWidth;
const standFontSize = 1920 / 16; //定义标准 1rem ===16px
const countSize = (currentSize: number) => {
// 计算字体大小对应的rem数值
const transformRemVal = currentSize / 16;
const curWidth = window.innerWidth;
const fontSize = curWidth / standFontSize;
return transformRemVal * fontSize;
};
let curVal = null; //当前取值
let tempKey = null; //存储数组所在的key
let findResKey = null; //key查找结果
let newOptions = null;
const isComplexType = obj => (typeof obj === 'object' || typeof obj === 'function')&&(obj !==null)
const deepCopy = obj =>{
if (typeof obj !== "object" || obj == null) {
return obj
}
//定义返回值result
// 判断传进来的数据类型 是数组/对象 就给result一个数组/对象
let result = Array.isArray(obj) ? [] : {};
//循环遍历方便拷贝
for (let key in obj) {
//判读自有属性
if (obj.hasOwnProperty(key)) {
//函数递归实现深层拷贝
result[key] = deepCopy(obj[key])
}
}
//返回出去
return result
}
const isInFields = (key: string) => fields.find(item => item === key);
const isObject = (val: any) => val instanceof Object;
const isArray = (val: any) => val instanceof Array;
/**
* [hanldeOptions 将配置中所涉及到的字段使用计算函数进行尺寸计算]
* @optionObj 图表配置
* @arrKey 数组项所属的key名
*/
function hanldeOptions<T>(optionObj: any, arrKey = null): T {
// debugger
for (let key in optionObj) {
// 如果还是对象继续递归,函数不作处理
curVal = optionObj[key];
if (typeof curVal === "object" && typeof curVal !== "function") {
tempKey = null;
isArray(curVal) && (tempKey = key);
hanldeOptions(curVal, tempKey);
} else {
if (arrKey) findResKey = isInFields(arrKey);
else findResKey = isInFields(key);
if (findResKey && typeof optionObj[findResKey] === "number") {
optionObj[findResKey] = countSize(optionObj[findResKey]);
}
}
}
return optionObj;
}
/**
* [useSelfAdaptionEcharts 将需要设置默认值的配置信息赋值]
* @optionObj 图表配置
* @keyArr 目标key的层级关系数组
* @tarVal 目标key需要的值
* @tarKey 目标key名称
*/
const setDefaultSize = (optionObj: any, keyArr: any, tarVal: number, tarKey: string) => {
if (keyArr.length === 0) {
// 保留原始值,如果配置中有值就不再设置
if (!optionObj[tarKey]) optionObj[tarKey] = tarVal;
return optionObj;
}
let currentKey = keyArr.shift();
/*
首先捕捉到 外层都没有这个属性就没必要递归下去了
例如:legend这个属性都没有,没必要设置它里面的fontSize了
因为可能不想展示图例,如果optionObj[currentKey] = {};就违背了最初的设定😎
*/
if (!optionObj[currentKey]) return optionObj// optionObj[currentKey] = {};
if (isArray(optionObj[currentKey])) {
optionObj[currentKey].forEach(item => (item = setDefaultSize(item, keyArr, tarVal, tarKey)));
} else optionObj[currentKey] = setDefaultSize(optionObj[currentKey], keyArr, tarVal, tarKey);
return optionObj;
};
/**
* [handleDefaultOptionsSize 将已有的option中指定配置使用自适应计算]
* @options 图表配置
*/
const handleDefaultOptionsSize = (options: EChartsOption) => {
let newOption = deepCopy(options);
needDefaultFields.forEach(defaultItem => {
defaultItem.pathList.forEach(pathItem => {
setDefaultSize(newOption, deepCopy(pathItem), defaultItem.defaultVal, defaultItem.key);
});
});
return newOption;
};
/**
* [useSelfAdaptionEcharts 将已有的option中指定配置使用自适应计算]
* @options 图表配置
* @echartsInstance 图表实例
* @needDefault 是否需要设置常用字段的默认值
*/
export const useSelfAdaptionEcharts = (options: EChartsOption, echartsInstance: ECharts, needDefault = true) => {
let newOptions = null;
curVal = null; //当前取值
tempKey = null; //存储数组所在的key
findResKey = null; //key查找结果
if (needDefault) newOptions = handleDefaultOptionsSize(options);
const resOptions = hanldeOptions(deepCopy(newOptions ?? options));
echartsInstance.setOption(resOptions);
window.addEventListener("resize", () => {
const resOptions = hanldeOptions(deepCopy(newOptions ?? options));
echartsInstance.setOption(resOptions);
echartsInstance.resize();
});
};