1.常用-引用ts文件方式
1.1 导出ts文件-一个简单的柱状图
export const baseBarChart = (xdata: string[], data: number[][], legendData: string[]) => {
if (data.length === 0) {
return noData;
}
// 定义颜色数组
const color = [
'#00CCCC',
'#FF9900',
'#1677DC',
'#FF6666',
'#B366FF',
'#6666FF',
'#3366CC',
'#0099CC',
'#00CC66',
'#98CB19',
'#FFCC00',
'#666699',
];
const maxDataValue = Math.max(...data.flat()); // 计算数据中的最大值
const yAxisMax = Math.ceil(maxDataValue / 5) * 5; // 将最大值向上取整到最接近的5的倍数
// 使用循环动态添加series,根据数组数目自动生成柱状图数量
const seriseData = data.map((item, index) => {
return {
name: legendData[index],
data: item,
type: 'bar',
// barWidth: 30,
barMaxWidth: 30,
xAxisIndex: 0,
color: color[index], // 循环使用颜色数组
label: {
show: true, // 显示数值
position: 'top', // 数值显示在柱子的顶部
fontSize: 14, // 字体大小
color: '#333333', // 字体颜色
fontWeight: 'bold', // 字体加粗
},
};
});
// 完整的配置项
let option: any = {
tooltip: {
trigger: 'axis',
textStyle: {
fontSize: 14,
color: '#9A9A9A',
},
},
grid: {
containLabel: true,
bottom: '15%',
top: '10%',
left: '2%',
right: '2%',
},
xAxis: {
type: 'category',
data: xdata,
axisLabel: {
color: '#9a9a9a',
fontSize: 12,
interval: 'auto', // 自动隐藏部分标签(可根据需要调整为具体值)
formatter: function (value: any) {
// 截断过长的标签,并添加省略号
return value.length > 2 ? value.slice(0, 2) + '...' : value;
},
},
},
yAxis: {
type: 'value',
min: 0,
max: yAxisMax, // 动态设置最大值
interval: yAxisMax / 5, // 根据最大值动态设置刻度间隔
axisLabel: {
color: '#9a9a9a',
fontSize: 14,
},
},
legend: {
left: 'center',
type: 'scroll',
bottom: '2%',
textStyle: {
fontSize: 14,
color: '#9A9A9A',
},
itemWidth: 16,
itemHeight: 10,
},
series: seriseData,
};
return option;
};
1.2 vue文件-部分
<div id="chartContainerBarTwo" ref="chartContainerBarTwo" class="chartContainerBarTwo">
</div>
import { baseBarChart, baseLineChart, baseCircleChart } from '../../../echarts';
import { onMounted, ref, Ref, computed } from 'vue';
import { useECharts } from '@/hooks/web/useECharts';
import * as echarts from 'echarts';
onMounted(() => {
init();
});
function init() {
initDeviceCountChartTwo();
}
const chartContainerBarTwo = ref<HTMLDivElement | null>(null);
第一种
const initDeviceCountChartTwo = async () => {
// 初始化图表并获取实例
const { setOptions, getInstance } = useECharts(chartContainerBarTwo as Ref<HTMLDivElement>);
try {
let legend: any = ['智能仪表'];
let xdata: any = ['天津分公司', '深圳分公司', '海南分公司', '湛江分公司', '上海分公司'];
let data: any = [[46224, 13021, 3791, 9072, 4557]];
setOptions(baseBarChart(xdata, data, legend));
// 获取图表实例并保存(如果需要)
const currentChartInstance = getInstance();
console.log('当前图表实例已保存:', currentChartInstance);
loading1.value = false;
} catch (error) {
setOptions(baseBarChart([], [], []));
loading1.value = false;
}
};
第二种
const initDeviceCountChartTwo = async () => {
const chart = echarts.init(chartContainerBarTwo.value);
try {
let legend: any = ['智能仪表'];
let xdata: any = ['天津分公司', '深圳分公司', '海南分公司', '湛江分公司', '上海分公司'];
let data: any = [[46224, 13021, 3791, 9072, 4557]];
chart.setOption(baseBarChart(xdata, data, legend));
loading1.value = false;
} catch (error) {
setOptions(baseBarChart([], [], []));
loading1.value = false;
}
};
PS:与之对应的还有图表resize函数,详情见博客解决 ECharts 切换图表时的 Resize 问题-CSDN博客
2.封装-ref作为传参
这是一个环形图ts文件,效果如下,中间可放图片,内外圈颜色不一样,可设置题目
import * as echarts from 'echarts';
import { type ECharts, init } from 'echarts';
import type { Ref } from 'vue';
import imagePath from '../views/index/instrumentDevice/img/circle-center.png';
/**
* 初始化 ECharts 图表的通用函数
* @param chartRef - Vue 的 ref,指向 DOM 元素
* @param data - 图表数据
* @param colors - 渐变颜色外圈数组
* @param colorse - 渐变颜色内圈数组
* @param title - 图表标题(可选)
* @returns ECharts 实例
*/
function initEcharts(
chartRef: Ref<HTMLDivElement | null>,
data: any[],
colors: string[][],
colorse: string[][],
title?: string,
): ECharts | null {
// 检查 ref 是否有效
if (!chartRef.value) {
console.error('ECharts ref is not valid');
return null;
}
// 创建 ECharts 实例
const myChart = init(chartRef.value);
// 计算总计
const total = data.reduce((acc, item) => acc + Number(item.value), 0);
// 图表配置
const chartData = {
title: {
text: title,
left: 'left',
top: '5%',
textStyle: {
fontSize: 18,
fontWeight: 'bold',
color: '#ffffff',
},
},
legend: {
top: '90%',
left: 'center',
itemWidth: 16,
itemHeight: 10,
textStyle: {
color: '#ffffff',
},
},
tooltip: {
show: false,
formatter: (params: any) => {
const percent = ((params.value / total) * 100).toFixed(1);
return `总计: ${params.value} (${percent}%)`;
},
trigger: 'item',
confine: true,
backgroundColor: '#1E2857',
borderColor: '#1E2857',
color: '#fff',
textStyle: {
color: '#fff',
},
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985',
},
},
},
grid: {
top: '0%',
left: '0%',
right: '0%',
bottom: '0%',
},
graphic: [
{
type: 'image',
style: {
image: imagePath,
width: 150,
height: 150,
},
left: 'center',
top: 'center',
},
{
type: 'text', // 添加文本元素
style: {
text: `总计: ${total}`, // 显示总计信息
fontSize: 16,
fontWeight: 'bold',
fill: '#ffffff', // 文本颜色
},
left: 'center', // 水平居中
top: '85%', // 距离底部 5%
},
],
series: [
// 外圈
{
type: 'pie',
radius: ['50%', '60%'],
avoidLabelOverlap: true,
z: 11,
label: {
show: true, // 外圈显示标签
position: 'outside',
formatter: (params: any) => {
const percent = ((params.value / total) * 100).toFixed(1);
return `${params.name} ${percent}%`;
},
fontSize: 14,
color: '#ffffff',
},
labelLine: {
show: true,
length: 10,
length2: 20,
position: 'outside',
lineStyle: {
color: '#ffffff',
},
},
data: data.map((item, index) => ({
...item,
itemStyle: {
color: new echarts.graphic.RadialGradient(0, 0, 1, [
{ offset: 0, color: colors[index][0] },
{ offset: 1, color: colors[index][1] },
]),
},
label: {
show: item.value > 0, // 当值大于 0 时显示标签
},
labelLine: {
show: item.value > 0, // 当值大于 0 时显示引导线
},
})),
},
// 内圈阴影
{
type: 'pie',
radius: ['40%', '60%'],
avoidLabelOverlap: true,
z: 10,
itemStyle: {
borderRadius: 2,
borderWidth: 1,
shadowBlur: 20,
shadowColor: '#1569ff',
shadowOffsetX: 0,
shadowOffsetY: 0,
},
label: {
show: false, // 内圈不显示标签
},
labelLine: {
show: false, // 内圈不显示引导线
},
data: data.map((item, index) => ({
...item,
itemStyle: {
color: new echarts.graphic.RadialGradient(0, 0, 1, [
{ offset: 0, color: `${colors[index][0]}4D` }, //渐变色透明度
{ offset: 1, color: `${colors[index][0]}4D` },
]),
},
})),
},
],
animation: false,
};
// 设置图表配置
myChart.setOption(chartData, true);
return myChart;
}
export default initEcharts;
vue文件-部分
<div v-if="currentChart === 'SIS'" ref="echartsRefSIS" class="content_echarts"></div>
const echartsRefSIS = ref<HTMLDivElement | null>(null);
let ref: Ref<HTMLDivElement | null> | null = null;
ref = echartsRefSIS;
// 初始化 ECharts 实例
const myChart = initEcharts(ref, annularList, gradientColors, gradientColorse, title);
currentChartInstance = myChart; // 保存当前图表实例