You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

441 lines
13 KiB

<template>
<a-row type="flex" style="height: 92%">
<a-col :span="8">
<div
style="
box-shadow: 0 0 0 2px rgba(218, 218, 218, 0.5); /* 灰色阴影 */
width: 98%;
height: 96%;
margin: 2%;
">
<a-radio-group
v-model:value="mode"
@change="changeMode"
style="
padding-bottom: 10px;
width: 40%;
height: 4%;
padding-left: 30px;
padding-top: 10px;
">
<a-radio-button value="1" style="width: 50%; text-align: center"> 同比 </a-radio-button>
<a-radio-button value="2" style="width: 50%; text-align: center"> 环比 </a-radio-button>
</a-radio-group>
<div ref="analysisGraphchart" style="width: 100%; height: 95%"></div>
</div>
</a-col>
<a-col :span="16">
<div
ref="analysisGraphRingchart"
style="
width: 98%;
height: 38%;
box-shadow: 0 0 0 2px rgba(218, 218, 218, 0.5);
margin: 1%;
"></div>
<div
ref="analysisGraphBarchart"
style="
width: 98%;
height: 58%;
box-shadow: 0 0 0 2px rgba(218, 218, 218, 0.5);
margin: 1%;
"></div>
</a-col>
</a-row>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref, inject, watch } from 'vue';
import * as echarts from 'echarts';
export default defineComponent({
name: 'AnalysisGraph',
setup() {
const mode = ref<String>('1');
let data = ref<any[]>([]);
interface PageData {
// 图表 表格数据
graphTableList: any[];
// 图表 表格表头
graphTableColumns: any[];
// 图表 图表数据
graphGraphList: any[];
// 分析 表格数据
analysisTableList: any[];
// 分析 图表数据
analysisGraphList: any[];
}
const pageData = inject<PageData>('pageData');
if (!pageData) {
throw new Error('pageData is not provided');
}
// 监听 pageData 的变化
watch(
() => pageData as PageData,
(_newValue, _oldValue) => {
// 执行你的逻辑代码
draw();
},
{ deep: true },
);
const changeMode = () => {};
const analysisGraphchart = ref(null);
const analysisGraphRingchart = ref(null);
const analysisGraphBarchart = ref(null);
// 左侧柱状图
let chartInstance: echarts.ECharts | null = null;
// 圆环图
let chartRight1: echarts.ECharts | null = null;
// 右下角柱状图
let chartRight2: echarts.ECharts | null = null;
const draw = () => {
data.value = pageData.analysisGraphList;
// 绘制左侧图
drawLeft();
drawRight1();
};
const drawLeft = () => {
if (data.value && data.value.length > 0) {
if (chartInstance) {
chartInstance.dispose();
}
chartInstance = echarts.init(analysisGraphchart.value);
var seriesdata = [];
var dateX = [];
for (let i = 0; i < data.value.length; i++) {
dateX.push(data.value[i].name);
seriesdata.push({ value: data.value[i].value, label: data.value[i].labelRight });
}
var seriesList = [
{
name: data.value[0].energyType,
data: seriesdata,
type: 'bar',
label: {
show: true,
formatter: '{b}',
},
barWidth: '25%',
},
];
const option = {
grid: {
top: 60,
bottom: 20,
},
dataZoom: [
{
show: true,
type: 'slider',
zoomLock: true,
startValue: 0, // 从头开始。
endValue: 4,
showDetail: false,
width: 5,
yAxisIndex: [0, 1], // 控制y轴滚动对象
},
{
show: true,
type: 'inside',
// width: 0,
startValue: 0,
endValue: 10,
minValueSpan: 10,
yAxisIndex: [0],
zoomOnMouseWheel: false, // 关闭滚轮缩放
moveOnMouseWheel: true, // 开启滚轮平移
moveOnMouseMove: true, // 鼠标移动能触发数据窗口平移
},
],
yAxis: {
type: 'category',
axisLine: { show: false },
axisLabel: { show: false },
axisTick: { show: false },
splitLine: { show: false },
data: dateX,
},
xAxis: {
type: 'value',
position: 'top',
splitLine: {
lineStyle: {
type: 'dashed',
},
},
},
series: seriesList,
};
chartInstance = echarts.init(analysisGraphchart.value);
chartInstance.setOption(option);
}
};
const drawRight1 = () => {
if (data.value && data.value.length > 0) {
if (chartRight1) {
chartRight1.dispose();
}
chartRight1 = echarts.init(analysisGraphRingchart.value);
var seriesdata = [];
var dateX = [];
// var legendList: string | any[] = [];
for (let i = 0; i < data.value.length; i++) {
dateX.push(data.value[i].name);
seriesdata.push({ value: data.value[i].ringValue, name: data.value[i].name });
}
var seriesList = [
{
// name: data.value[0].energyType,
data: seriesdata,
type: 'pie',
// 圆环内径和外径
radius: ['70%', '90%'],
center: ['30%', '50%'], // 调整环形图的位置,百分比表示相对于容器的宽高
// 显示折线
labelLine: {
show: true,
length: 10, // 调整第一个折线段的长度
length2: 30, // 调整第二个折线段的长度
},
label: {
show: true,
// formatter: '{b}',
position: 'outside', // 确保标签在环形图外部
// alignTo: 'edge',
formatter: '{c}' + data.value[0].energyUnit + '\n{d}%',
alignTo: 'labelLine',
distanceToLabelLine: 5, // 调整标签和引导线之间的距离
distance: 10, // 调整标签距离图形的距离
},
itemStyle: {
normal: {
// 白色间距
borderWidth: 2,
borderColor: '#ffffff',
},
},
},
];
const option = {
tooltip: {
trigger: 'item',
},
// 图例
legend: {
top: 'center',
left: '60%',
// 排列方式 垂直
orient: 'vertical',
},
yAxis: {
type: 'category',
axisLine: { show: false },
axisLabel: { show: false },
axisTick: { show: false },
splitLine: { show: false },
data: dateX,
},
xAxis: {
type: 'value',
position: 'top',
splitLine: {
lineStyle: {
type: 'dashed',
},
},
},
series: seriesList,
};
chartRight1 = echarts.init(analysisGraphRingchart.value);
chartRight1.setOption(option);
// 默认点击第一个
if (seriesdata.length > 0) {
drawRight2(seriesdata[0]);
}
chartRight1.on('click', function (params) {
// 控制台输出数据的名称
console.log(params.name + ' 被点击了');
drawRight2(params);
});
}
};
// 右下角柱状图
// chartRight2
// analysisGraphBarchart
const drawRight2 = (auxiliary: any) => {
if (chartRight2) {
chartRight2.dispose();
}
// 辅助线
var compareData: any[] = [];
// 展示数据
var showData: any[] = [];
// X轴
var dateX: any[] = [];
data.value.forEach((item) => {
if (item.name !== auxiliary.name) {
dateX.push(item.name);
showData.push(item.ringValue);
compareData.push(auxiliary.value);
}
});
const option = {
// 图例
legend: {
data: [
{ name: '对比值', icon: 'rect' }, // 对比值使用矩形图标
{
name: '参考线',
icon: 'path://M234.666667 490.666667h-153.6a25.6 25.6 0 1 0 0 51.2h153.6a25.6 25.6 0 1 0 0-51.2zM473.6 490.666667h-153.6a25.6 25.6 0 1 0 0 51.2h153.6a25.6 25.6 0 1 0 0-51.2zM934.4 490.666667h-136.533333a25.6 25.6 0 1 0 0 51.2h136.533333a25.6 25.6 0 1 0 0-51.2zM712.533333 490.666667h-153.6a25.6 25.6 0 1 0 0 51.2h153.6a25.6 25.6 0 1 0 0-51.2z',
}, // 参考线使用自定义路径图标,只显示线条
],
orient: 'horizontal',
bottom: 10,
left: 60,
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
lineStyle: {
color: 'red', // 设置 tooltip 的线颜色
},
},
},
grid: {
top: 20,
bottom: 60,
},
xAxis: {
type: 'category',
axisLine: { show: false },
axisLabel: { show: true },
axisTick: { show: false },
splitLine: { show: false },
data: dateX,
},
yAxis: {
type: 'value',
position: 'top',
splitLine: {
lineStyle: {
type: 'dashed',
},
},
},
dataZoom: [
{
show: true,
type: 'slider',
zoomLock: true,
startValue: 0, // 从头开始。
endValue: 5,
bottom: '0%',
height: 10,
showDetail: false,
},
{
show: true,
type: 'inside',
xAxisIndex: 0,
zoomOnMouseWheel: false, // 滚轮是否触发缩放
moveOnMouseMove: true, // 鼠标滚轮触发滚动
moveOnMouseWheel: true,
},
],
series: [
{
name: '对比值',
type: 'bar',
stack: 'Total',
label: {
// show: true,
position: 'right',
formatter: '{b}',
},
data: showData,
barWidth: 30, // 设置柱状图的宽度
},
{
name: '参考线',
type: 'line',
data: compareData,
markLine: {
symbol: 'none',
label: {
show: false,
},
lineStyle: {
type: 'dashed',
color: 'red',
},
},
itemStyle: {
color: 'red', // 设置参考线的小圆点颜色
},
emphasis: {
itemStyle: {
opacity: 0, // 隐藏鼠标悬停时的节点
},
},
showSymbol: false, // 隐藏数据点
lineStyle: {
type: 'dashed', // 虚线样式
color: 'red',
},
},
],
};
chartRight2 = echarts.init(analysisGraphBarchart.value);
chartRight2.setOption(option);
};
onMounted(() => {
draw();
});
// 下载图表
const downloadChart = () => {
if (chartInstance) {
const base64 = chartInstance.getDataURL({
type: 'png',
backgroundColor: '#fff',
});
const link = document.createElement('a');
link.href = base64;
link.download = 'chart.png';
link.click();
}
};
return {
analysisGraphchart,
analysisGraphRingchart,
analysisGraphBarchart,
downloadChart,
mode,
changeMode,
};
},
});
</script>
<style lang="less" scoped></style>