说了这么多废话,开始贴代码了⬇️⬇️⬇️
先说说这次二次封装暴露出的功能
- 柱状图负值可以自定义颜色
- 多柱子多折线设置
- 三个好看立体柱子
- 折线的symbol
- MarkLine标记线是柱子的还是折线的
- MarkPoint标记点展示最大最小值
示例图
上代码
第一个(参数都有写,见封装的类型属性说明)
使用
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: {