先说说这个对ECharts让我们总结一封装的东西,感觉这是重点!
二次封装及使用的矛盾痛点:
- 一般包装只会暴露一些常见的属性,如图表的颜色和数据;
- 封装人员不会考虑包装所有情况,因为它毫无意义,比如图表上的文本大小。如果面具被考虑,最好不要包装,直接使用Echarts获得属性;
- 但在使用过程中,除了对颜色数据的不同要求外,确实会根据实际情况和设计草案进行调整,如图表的具体位置、图例的位置、文本的风格等
解决思路及方法:
以图表的位置为例Echarts中的属性为gird
1.在包装过程中,我们是对的grid设置默认值,如:
let gridDefault: EChartOption.Grid = {
left: 88, right: 196, bottom: 50, top: 110, };
同时暴露一个grid属性,属性继承Echarts的grid属性
const Component = ({
gird}:{
grid?: EChartOption.Grid;})=>{
return () }
3、合并属性
使用时,若有,则用传递的值替换。 但
简单的属性还可以,可以直接覆盖替换,比如gird的left、right等等
但Echarts属性往往是,使用时间传参如果没有写,如果没有写,使用Object.assign()会导致深度默认属性
由于组件的二次开发,用户肯定不希望每个属性都传播,
针对这种情况,我发现了,他不像assign一样,,merge他会,相同的属性会被覆盖,
这样,在包装组件时,抛出的继承就是这样的Echarts组件的属性和默认属性一次merge。合并后即可。grid = merge(gridDefault, grid);
结论:
为了实现更高的组件自由度,抛出更多的继承Echarts代码中的属性merge默认值可以。这样,开发人员就不需要考虑组件需要什么属性,只需要考虑他们需要什么属性
说了这么多废话,开始贴代码。
先说说这次二次封装暴露出的功能
示例图
上代码
第一个(所有参数了,见封装类型属性说明)
import React from "react"; import {
MultiBarAndLineCharts } from "组件路径的封装"; const Index: React.FC<{
}> = () => {
let xAxisData = ["name1", "name2", "name3", "name4", "name5"];
let barDataS = [
[100, 200, 320.48, 200, -100],
[50, -50, 50, -50, 100],
];
let lineDataS = [[58, 81, 42, 98, 35]];
let nameS = ["柱状图1", "柱状图2", "折线图1"];
let yAxisNames = ["单位/亿元", ""];
let color = ["rgb(254,163,61)", "rgb(17,145,222)", "rgb(54,68,192)"];
let barNegativeNumberColor = ["rgb(254,163,61)", "rgb(196,76,78)"];
return (
<div
style={
{
width: "100%", height: "600px", background: "rgba(13,19,41)" }}
>
<MultiBarAndLineCharts
xAxisData={
xAxisData}
barDataS={
barDataS}
lineDataS={
lineDataS}
nameS={
nameS}
color={
color}
barWidth={
40}
barNegativeNumberColor={
barNegativeNumberColor}
yAxisNames={
yAxisNames}
/>
</div>
);
};
export default Index;
import React from "react"; import ReactEcharts from "echarts-for-react"; import { EChartOption } from "echarts"; import { merge } from "lodash"; const MultiBarAndLineCharts = ({ grid, legend, tooltip, xAxis, yAxisNames = ["", ""], yAxis, xAxisData, barDataS, lineDataS, nameS, lineSymbol, barWidth = "auto", barNegativeNumberColor, borderWidth = 5, color, showLabel = [true, true], barLabel, lineLabel, customMarkLine = { show: true, type: "line", title: "标记线", width: 2, color: "yellow", value: 50, }, markLine, smooth = false, }: { /** * @description 直角坐标系内绘图网格,继承EChart.Grid */ grid?: EChartOption.Grid; /** * @description 图例组件,继承EChart.Legend */ legend?: EChartOption.Legend; /** * @description 提示框组件,继承EChart.Tooltip */ tooltip?: EChartOption.Tooltip; /** * @description 直角坐标系 grid 中的 x 轴,继承EChart.XAxis */ xAxis?: EChartOption.XAxis; /** * @description 两个y轴的名字 */ yAxisNames?: string[]; /** * @description 直角坐标系 grid 中的 y 轴,继承EChart.YAxis。 */ yAxis?: EChartOption.YAxis[]; /** * @description x轴数据 */ xAxisData: string[]; /** * @description 柱状图数据,二维数组,每个item是一组柱状图数据 */ barDataS: number[][]; /** * @description 折线图数据,二维数组,每个item是一组折线图数据 */ lineDataS: number[][]; /** * @description 柱状图和折线图的名字,这个参数是为了和legend对应起来 */ nameS: string[]; /** * @description 折线图的Symbol,需要是图片时使用,url为图片地址、size为大小 */ lineSymbol?: { url: string; size: number }[]; /** * @description 柱状图每个柱子宽度 */ barWidth?: number | string; /** * @description 当柱状图有负数,且需要单独设置颜色时使用。注意:若要使用,则每个柱子都要设置,即该属性长度等于barDataS属性长度 */ barNegativeNumberColor?: string[]; /** * @description 折线图item点的边框宽度 */ borderWidth?: number; /** * @description 该图表的系列颜色 */ color: string[]; /** * @description 是否显示Label,是个数组,第一个参数控制柱状图label,第二个控制折线图label */ showLabel?: boolean[]; /** * @description 柱状图label,继承EChart.SeriesBar的Label,若有额外需求,参考EChart文档进行设置。因为没有对应的EChart的Label类型,所以给个any,自定义的时候要参考文档哦 */ barLabel?: any; /** * @description 折线图label,继承EChart.SeriesLine的Label,若有额外需求,参考EChart文档进行设置。因为没有对应的EChart的Label类型,所以给个any,自定义的时候要参考文档哦 */ lineLabel?: any; /** * @description 自定义MarkLine样式,包括:是否显示、属于bar还是line、文本、宽度、颜色、值 */ customMarkLine?: { show: boolean; type: "bar" | "line"; title: string; width: number; color: string; value: number; }; /** * @description MarkLine,因为没有对应的EChart的MarkLine类型,所以给个any,自定义的时候要参考文档哦 */ markLine?: any; /** * @description 折线图是否是平滑曲线 */ smooth?: boolean; }) => { let allSeries: EChartOption.Series[] = []; // 各种参数判断,有问题缺失抛出错误信息 (function logErr() { // 判断参数必填项 if (!(xAxisData && barDataS && lineDataS && nameS && color)) throw new SyntaxError("缺少必填的参数"); // 判断每个系列的bar是不是都传进来一个负值的颜色,如果不是,抛出个错误 if ( barNegativeNumberColor && barNegativeNumberColor.length !== barDataS.length ) throw new SyntaxError( "barNegativeNumberColor属性的长度必须和barDataS的长度一致" ); // 如果color长度不等于bar和line的长度和,抛出个警告 if (color.length !== barDataS.length + lineDataS.length) console.warn("属性color的长度建议等于bar+line的长度"); // name和数据的长度得一样,要不然没legend if (nameS.length !== barDataS.length + lineDataS.length) console.warn("属性nameS长度需要等于bar+line的长度"); })(); // merge默认参数和传递的参数 (function mergeParams() { let gridDefault: EChartOption.Grid = { left: 88, right: 200, bottom: 50, top: 120, }; let legendDefault: EChartOption.Legend = { show: true, textStyle: { color: "rgba(255, 255, 255, 1)", fontSize: 20, fontFamily: "pingFangMedium", }, right: 0, }; let tooltipDefault: EChartOption.Tooltip = { show: true, trigger: "axis", }; let xAxisDefault: EChartOption.XAxis = { show: true, type: "category", axisLabel: { fontSize: 30, color: "rgba(255, 255, 255, 0.65)", fontFamily: "pingFangMedium", padding: 0, interval: 0, }, axisLine: { show: true, lineStyle: { type: "dashed", color: "rgba(208, 225, 245, 0.3)", }, }, axisTick: { show: false, }, }; let yAxisDefault: EChartOption.YAxis[] = [ { show: true, type: "value", splitNumber: 5, name: yAxisNames[0], nameTextStyle: { color: "rgba(133, 133, 133, 1)", fontSize: 18, fontFamily: "pingFangMedium", padding: [0, 0, 15, 0], }, axisLabel: { show: true, fontSize: 18, color: "rgba(133, 133, 133, 1)", formatter: (value: any) => { return Math.ceil(value).toLocaleString("en-us"); }, }, axisLine: { show: false, }, splitLine: { lineStyle: { type: "dashed", color: "rgba(208, 225, 245, 0.3)", }, }, axisTick: { show: false, }, max: (value: any) => { return value.max + value.max / 10; }, min: (value: any) => { if (value.min < 0) return value.min + value.min / 4; else return 0; }, }, { type: "value", name: yAxisNames[1], show: true, splitLine: { show: false }, axisLine: { show: false }, axisTick: { show: false }, axisLabel: { show: true, fontSize: 18, color: "rgba(133, 133, 133, 1)", formatter: (params: any) => { return `${ params}%`; }, }, }, ]; let barLabelDefault = { show: showLabel[0], color: "rgba(255, 255, 255, 1)", fontSize: 20, position: "top", }; let lineLabelDefault = { show: showLabel[1], color: "rgba(255, 255, 255, 1)", fontSize: 25, formatter: function (params: any) { return params.value + "%"; }, }; let markLineDefault = { symbol: ["none", "none"], silent: true, lineStyle: { type: "dashed", width: customMarkLine.width, color: customMarkLine.color, }, label: { show: true, fontSize: 22, position: "right", padding: [0, 0, 0, 18], formatter: function (params: any) { return `${ customMarkLine.title} (${ params.value}${ customMarkLine.type === "line" ? "%" : "" })`; }, }, data: [ { yAxis: customMarkLine.value, }, ], }; grid = merge(gridDefault, grid); tooltip = merge(tooltipDefault, tooltip); legend = merge(legendDefault, legend); xAxis = merge(xAxisDefault, xAxis); yAxis = merge(yAxisDefault, yAxis); barLabel = merge(barLabelDefault, barLabel); lineLabel = merge(lineLabelDefault, lineLabel); markLine = merge(markLineDefault, markLine); })(); // 柱状图基本配置 let barSeriesBasicConfig: EChartOption.SeriesBar = { type: "bar", barWidth: barWidth, label: barLabel, }; // 折线图图基本配置 let lineSeriesBasicConfig: EChartOption.SeriesLine = { type: "line", yAxisIndex: 1, lineStyle: { width: 5, }, symbolSize: 15, label: lineLabel, smooth, }; // 处理柱状图数据 barDataS.forEach((item, index) => { let data: { value: number; itemStyle?: { color: string }; label?: { position: string }; }[] 标签:
m18圆柱型激光对射型传感器7klb动态轴重秤传感器