lcw
This commit is contained in:
78
src/views/backOfficeSystem/AnalysisReport/components/a.js
Normal file
78
src/views/backOfficeSystem/AnalysisReport/components/a.js
Normal file
@ -0,0 +1,78 @@
|
||||
// import jsPDF from 'jspdf';
|
||||
// import html2canvas from 'html2canvas';
|
||||
|
||||
|
||||
// export function useExportToPDF() {
|
||||
// const exportToImage = async (element, filename = 'screenshot.png') => {
|
||||
// const canvas = await html2canvas(element, {
|
||||
// scale: 2,
|
||||
// useCORS: true,
|
||||
// });
|
||||
|
||||
// // 转换为图片并下载
|
||||
// const link = document.createElement('a');
|
||||
// link.download = filename;
|
||||
// link.href = canvas.toDataURL('image/png');
|
||||
// link.click();
|
||||
// };
|
||||
|
||||
// // 将div导出为PDF的方法
|
||||
// const exportDivToPDF = async (element, filename = 'document.pdf') => {
|
||||
// try {
|
||||
// // 使用html2canvas将div转换为canvas
|
||||
// const canvas = await html2canvas(element, {
|
||||
// scale: 2, // 提高清晰度
|
||||
// useCORS: true, // 允许跨域图片
|
||||
// logging: false, // 关闭日志
|
||||
// width: element.offsetWidth,
|
||||
// height: element.offsetHeight,
|
||||
// windowWidth: element.scrollWidth,
|
||||
// windowHeight: element.scrollHeight,
|
||||
// backgroundColor: '#ffffff' // 设置背景色为白色
|
||||
// });
|
||||
|
||||
// // 获取canvas的宽高
|
||||
// const imgWidth = 210; // A4纸宽度(mm)
|
||||
// const pageHeight = 297; // A4纸高度(mm)
|
||||
// const imgHeight = canvas.height * imgWidth / canvas.width;
|
||||
// let heightLeft = imgHeight;
|
||||
// let position = 0;
|
||||
|
||||
// // 创建PDF文档
|
||||
// const pdf = new jsPDF({
|
||||
// orientation: 'portrait',
|
||||
// unit: 'mm',
|
||||
// format: 'a4'
|
||||
// });
|
||||
|
||||
// // 将canvas转换为图片并添加到PDF
|
||||
// const imgData = canvas.toDataURL('image/png');
|
||||
// pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
|
||||
// heightLeft -= pageHeight;
|
||||
|
||||
// // 如果内容超出一页,添加新页面
|
||||
// while (heightLeft > 0) {
|
||||
// position = heightLeft - imgHeight;
|
||||
// pdf.addPage();
|
||||
// pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
|
||||
// heightLeft -= pageHeight;
|
||||
// }
|
||||
|
||||
// // 下载PDF
|
||||
// pdf.save(filename);
|
||||
// } catch (error) {
|
||||
// console.error('导出PDF失败:', error);
|
||||
// alert('导出PDF失败,请稍后重试');
|
||||
// }
|
||||
// };
|
||||
|
||||
// return {
|
||||
// exportToImage,
|
||||
// exportDivToPDF
|
||||
// };
|
||||
// }
|
||||
// exportToImage
|
||||
// };
|
||||
// }
|
||||
export function exportDivToPDF(divId, filename) {
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div class="box" ref="chartDom"></div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, onMounted,watch } from "vue";
|
||||
import * as echarts from "echarts";
|
||||
let chartDom = ref(null); //注意变量名 和 ref名字要对应
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: '2023年1月1日至2023年12月31日'
|
||||
},
|
||||
xAxisData: {
|
||||
type: Array,
|
||||
default: () => ['A', 'B', 'C', 'D', 'E', 'F']
|
||||
},
|
||||
seriesData: {
|
||||
type: Array,
|
||||
default: () => [[2549], [12421], [2637],[ 3146],[ 15189], [9562]]
|
||||
},
|
||||
// yAxisData: {
|
||||
// type: Array,
|
||||
// default: () => [2549, 12421, 2637, 3146, 15189, 9562]
|
||||
// },
|
||||
})
|
||||
const chartInstance = ref(null);
|
||||
onMounted(() => {
|
||||
|
||||
initChart();
|
||||
});
|
||||
watch([
|
||||
() => props.seriesData,
|
||||
() => props.xAxisData,
|
||||
], () => {
|
||||
initChart();
|
||||
});
|
||||
const initChart = () => {
|
||||
chartInstance.value = props.seriesData.map((item, index) => {
|
||||
console.log(item,"xxxxxxxx");
|
||||
|
||||
return {
|
||||
name: props.xAxisData[index],
|
||||
data: item,
|
||||
type: "bar",
|
||||
barWidth: "20",
|
||||
// barGap: 20, // 系列之间的间距
|
||||
barCategoryGap: 100, // 类别之间的间距
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: function (params) {
|
||||
// 值为0或null时不显示
|
||||
if (params.value === 0 || params.value === null) {
|
||||
return '';
|
||||
}
|
||||
// 格式化数值显示
|
||||
return params.value.toLocaleString();
|
||||
},
|
||||
color: '#2c3e50',
|
||||
fontSize: 12,
|
||||
fontWeight: 'bold',
|
||||
distance: 10 // 标签与柱子的距离
|
||||
},
|
||||
}
|
||||
})
|
||||
console.log(chartInstance.value);
|
||||
|
||||
var myChart = echarts.init(chartDom.value);
|
||||
var option = {
|
||||
title: {
|
||||
text: props.title,
|
||||
left: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
// 鼠标悬浮提示数据
|
||||
trigger: "axis",
|
||||
backgroundColor: "rgba(32, 33, 36,.7)",
|
||||
borderColor: "rgba(32, 33, 36,0.20)",
|
||||
borderWidth: 15,
|
||||
textStyle: {
|
||||
// 文字提示样式
|
||||
color: "#fff",
|
||||
fontSize: "12",
|
||||
},
|
||||
axisPointer: {
|
||||
// 坐标轴虚线
|
||||
type: "cross",
|
||||
label: {
|
||||
backgroundColor: "#6a7985",
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
right: 0
|
||||
},
|
||||
// },
|
||||
grid: {
|
||||
// 控制图表的位置
|
||||
left: "5%",
|
||||
right: "5%",
|
||||
top: "18%",
|
||||
bottom: "5%",
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
data: props.xAxisData,
|
||||
},
|
||||
yAxis: {
|
||||
// axisLabel: {
|
||||
// // y轴线 标签修改
|
||||
// textStyle: {
|
||||
// color: "white", //坐标值得具体的颜色
|
||||
// },
|
||||
// },
|
||||
// data: props.xAxisData,
|
||||
},
|
||||
series: chartInstance.value
|
||||
};
|
||||
option && myChart.setOption(option);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
height: 60vh;
|
||||
/* background-color: #031a67; */
|
||||
}
|
||||
</style>
|
@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<!-- 将固定id改为ref引用 -->
|
||||
<div ref="chartContainer" style="height: 100%;"></div>
|
||||
</template>
|
||||
<script setup>
|
||||
import * as echarts from 'echarts';
|
||||
import { onMounted, onUnmounted, ref, watch, defineProps } from 'vue';
|
||||
|
||||
// 定义组件的属性,使其可复用
|
||||
const props = defineProps({
|
||||
// 图表数据
|
||||
chartData: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
{ value: 40, name: 'rose 1' },
|
||||
{ value: 38, name: 'rose 2' },
|
||||
{ value: 32, name: 'rose 3' },
|
||||
{ value: 30, name: 'rose 4' },
|
||||
{ value: 28, name: 'rose 5' },
|
||||
{ value: 26, name: 'rose 6' },
|
||||
{ value: 22, name: 'rose 7' },
|
||||
{ value: 18, name: 'rose 8' }
|
||||
]
|
||||
},
|
||||
// 图表标题
|
||||
chartName: {
|
||||
type: String,
|
||||
default: 'Nightingale Chart'
|
||||
},
|
||||
// 是否显示工具箱
|
||||
showToolbox: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否显示图例
|
||||
showLegend: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 内半径
|
||||
innerRadius: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
// 外半径
|
||||
outerRadius: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
// 扇形间距
|
||||
padAngle: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
title: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
text: 'Nightingale Chart',
|
||||
left: 'center'
|
||||
})
|
||||
},
|
||||
roseType: {
|
||||
type: String,
|
||||
default: 'radius'
|
||||
}
|
||||
});
|
||||
|
||||
// 图表容器引用
|
||||
const chartContainer = ref(null);
|
||||
// 图表实例引用
|
||||
const chartInstance = ref(null);
|
||||
|
||||
// 初始化图表
|
||||
const initChart = () => {
|
||||
const chartDom = chartContainer.value;
|
||||
if (!chartDom) return;
|
||||
|
||||
// 如果已经存在实例,先销毁
|
||||
if (chartInstance.value) {
|
||||
chartInstance.value.dispose();
|
||||
}
|
||||
|
||||
// 创建新实例
|
||||
chartInstance.value = echarts.init(chartDom);
|
||||
|
||||
// 设置图表选项
|
||||
const option = {
|
||||
title: props.title,
|
||||
legend: props.showLegend ? {
|
||||
top: 'bottom'
|
||||
} : false,
|
||||
toolbox: props.showToolbox ? {
|
||||
show: true,
|
||||
feature: {
|
||||
mark: { show: true },
|
||||
dataView: { show: true, readOnly: false },
|
||||
restore: { show: true },
|
||||
saveAsImage: { show: true }
|
||||
}
|
||||
} : false,
|
||||
series: [
|
||||
{
|
||||
name: props.chartName,
|
||||
type: 'pie',
|
||||
radius: [props.innerRadius, props.outerRadius],
|
||||
center: ['50%', '50%'],
|
||||
roseType: props.roseType,
|
||||
// 在 ECharts 5.3.3 中,当 roseType 为 'area' 时,padAngle 需要特殊处理
|
||||
// 为了确保间距生效,我们需要添加一个小的非零值来替代0
|
||||
// padAngle: props.padAngle === 0 ? 0.1 : props.padAngle,
|
||||
itemStyle: {
|
||||
borderColor: '#fff',
|
||||
borderWidth:props.padAngle
|
||||
},
|
||||
// 显示百分比
|
||||
label: {
|
||||
show: true,
|
||||
formatter: function(params) {
|
||||
// 对于值为0的项,显示0%而不是极小值计算出的百分比
|
||||
if (props.chartData.find(d => d.name === params.name && d.value === 0)) {
|
||||
return params.name + ': 0%';
|
||||
}
|
||||
return params.name + ': ' + params.percent + '%';
|
||||
}
|
||||
},
|
||||
// 鼠标悬停时的样式
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: '16',
|
||||
fontWeight: 'bold',
|
||||
formatter: function(params) {
|
||||
// 对于值为0的项,显示0%而不是极小值计算出的百分比
|
||||
if (props.chartData.find(d => d.name === params.name && d.value === 0)) {
|
||||
return params.name + ': 0%';
|
||||
}
|
||||
return params.name + ': ' + params.percent + '%';
|
||||
}
|
||||
}
|
||||
},
|
||||
// 处理数据,确保值为0的项也能显示
|
||||
data: props.chartData.map(item => ({
|
||||
...item,
|
||||
// 对于值为0的数据,设置一个极小值来确保它在饼图中显示
|
||||
value: item.value === 0 ? 0.0000001 : item.value
|
||||
}))
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// 应用选项
|
||||
chartInstance.value.setOption(option);
|
||||
};
|
||||
|
||||
// 处理窗口大小变化,自动调整图表大小
|
||||
const handleResize = () => {
|
||||
if (chartInstance.value) {
|
||||
chartInstance.value.resize();
|
||||
}
|
||||
};
|
||||
|
||||
// 组件挂载时初始化图表
|
||||
onMounted(() => {
|
||||
initChart();
|
||||
window.addEventListener('resize', handleResize);
|
||||
});
|
||||
|
||||
// 组件卸载时销毁图表实例并移除事件监听
|
||||
onUnmounted(() => {
|
||||
if (chartInstance.value) {
|
||||
chartInstance.value.dispose();
|
||||
}
|
||||
window.removeEventListener('resize', handleResize);
|
||||
});
|
||||
|
||||
// 监听数据变化,更新图表
|
||||
watch(() => props.chartData, () => {
|
||||
initChart();
|
||||
}, { deep: true });
|
||||
|
||||
// 监听其他配置变化,更新图表
|
||||
watch([
|
||||
() => props.chartName,
|
||||
() => props.showToolbox,
|
||||
() => props.showLegend,
|
||||
() => props.innerRadius,
|
||||
() => props.outerRadius,
|
||||
() => props.padAngle,
|
||||
()=> props.roseType,
|
||||
], () => {
|
||||
initChart();
|
||||
});
|
||||
</script>
|
||||
<style scoped>
|
||||
:deep(div) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* min-height: 400px; */
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user