产出品管理 - 产出品概览页面饼图展示开发

This commit is contained in:
郭永超 2025-07-10 16:41:20 +08:00
parent b741c624f2
commit a32894789c
4 changed files with 178 additions and 7 deletions

View File

@ -10,6 +10,7 @@ declare module 'vue' {
AreaCascader: typeof import('./src/components/AreaCascader/index.vue')['default']
AreaSelect: typeof import('./src/components/AreaSelect/index.vue')['default']
CodeDialog: typeof import('./src/components/code-dialog/index.vue')['default']
CustomEchartBar: typeof import('./src/components/custom-echart-bar/index.vue')['default']
CustomEchartPie: typeof import('./src/components/custom-echart-pie/index.vue')['default']
FileUploader: typeof import('./src/components/FileUploader/index.vue')['default']
LandSelect: typeof import('./src/components/LandSelect.vue')['default']

View File

@ -0,0 +1,125 @@
<template>
<div ref="chartRef" :style="{ height, width }"></div>
</template>
<script>
import { ref, reactive, watchEffect } from 'vue';
import { cloneDeep } from 'lodash';
import { useEcharts } from '../../hooks/useEcharts';
export default {
name: 'CustomEchartBar',
props: {
chartData: {
type: Array,
default: () => [],
required: true,
},
option: {
type: Object,
default: () => ({}),
},
type: {
type: String,
default: 'bar',
},
width: {
type: String,
default: '100%',
},
height: {
type: String,
default: 'calc(100vh - 78px)',
},
isSeries: {
type: Boolean,
default: false,
},
},
emits: ['click'],
setup(props, { emit }) {
const chartRef = ref(null);
const { setOptions, getInstance, startAutoPlay } = useEcharts(chartRef);
const option = reactive({
tooltip: {
trigger: 'axis',
tooltip: {
backgroundColor: 'rgba(12, 36, 56, 0.9)', // (RGBA)
borderColor: '#2cf4fd', //
borderWidth: 1, //
textStyle: {
color: '#fff', //
fontSize: 12,
},
formatter: '{b}{c}',
},
axisPointer: {
type: 'shadow',
label: {
show: true,
backgroundColor: '#333',
},
},
},
legend: {
top: 30,
},
grid: {
top: 60,
},
xAxis: {
type: 'category',
data: [],
},
yAxis: {
type: 'value',
},
series: [],
});
watchEffect(() => {
props.chartData && initCharts();
});
function initCharts() {
if (props.option) {
Object.assign(option, cloneDeep(props.option));
}
let typeArr = Array.from(new Set(props.chartData.map((item) => item.type)));
let xAxisData = Array.from(new Set(props.chartData.map((item) => item.name)));
let seriesData = [];
typeArr.forEach((type, index) => {
const barStyle = props.option?.barStyle ?? {};
let obj = { name: type, type: props.type, ...barStyle };
let data = [];
xAxisData.forEach((x) => {
let dataArr = props.chartData.filter((item) => type === item.type && item.name == x);
if (dataArr && dataArr.length > 0) {
data.push(dataArr[0].value);
} else {
data.push(null);
}
});
obj['data'] = data;
if (props.option?.color) {
obj.color = props.option?.color[index];
}
seriesData.push(obj);
});
option.series = props.isSeries && option.series.length > 0 ? option.series : seriesData;
option.xAxis.data = xAxisData;
setOptions(option);
startAutoPlay({
interval: 2000,
seriesIndex: 0,
showTooltip: true,
});
getInstance()?.off('click', onClick);
getInstance()?.on('click', onClick);
}
function onClick(params) {
emit('click', params);
}
return { chartRef };
},
};
</script>

View File

@ -376,8 +376,6 @@
padding: 10px 20px;
.statistics-echart-box {
height: 400px;
padding-bottom: 50px;
box-sizing: content-box;
background-color: #fff;
}
.statistics-echart-title {

View File

@ -1,4 +1,4 @@
<template>
<!-- <template>
<div class="custom-page" :style="`background-image: url(${getAssetsFile('images/output/output.png')})`"></div>
</template>
@ -13,9 +13,9 @@ import { getAssetsFile } from '@/utils';
background-size: cover;
background-repeat: no-repeat;
}
</style>
</style> -->
<!-- <template>
<template>
<div class="app-container">
<div class="container-custom">
<h2 class="custom-h2">产出品概览</h2>
@ -37,7 +37,11 @@ import { getAssetsFile } from '@/utils';
<el-row :gutter="20">
<el-col :span="12" class="statistics-echart-box">
<p class="statistics-echart-title">产出品产量数据</p>
<customEchartPie ref="pie1" :chart-data="chartData1" :option="option" :width="'100%'" :height="'100%'"></customEchartPie>
<customEchartPie ref="pie1" :chart-data="chartData1" :option="option" :width="'100%'" :height="'90%'"></customEchartPie>
</el-col>
<el-col :span="12" class="statistics-echart-box">
<p class="statistics-echart-title">产出品产量排行</p>
<customEchartBar ref="pie1" :chart-data="chartData2" :option="option2" :width="'100%'" :height="'100%'"></customEchartBar>
</el-col>
</el-row>
</div>
@ -48,6 +52,7 @@ import { getAssetsFile } from '@/utils';
<script setup>
import { ref, reactive, computed, onMounted } from 'vue';
import customEchartPie from '@/components/custom-echart-pie';
import customEchartBar from '@/components/custom-echart-bar';
import { ElMessage } from 'element-plus';
//
@ -64,11 +69,53 @@ const chartData1 = ref([
{ value: 735, name: '水果类' },
{ value: 484, name: '药材类' },
]);
//
const chartData2 = ref([
{ value: 30.57, name: '凤梨' },
{ value: 44.43, name: '铁皮石斛' },
{ value: 52.87, name: '芒果' },
{ value: 65.43, name: '榴莲' },
{ value: 74.54, name: '香蕉' },
{ value: 85.88, name: '苦瓜' },
{ value: 93.669, name: '丝瓜' },
{ value: 103.67, name: '小米椒' },
{ value: 118.98, name: '圆茄' },
{ value: 127.65, name: '黄皮甘蔗' },
]);
const option = reactive({
tooltip: {
formatter: '{b} ({c} 吨)',
},
});
const option2 = reactive({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow', //
},
formatter: '{b}: {c} 吨', //
},
grid: {
left: '3%',
right: '4%',
bottom: '10%',
containLabel: true, //
},
xAxis: {
type: 'value',
name: '吨',
axisLabel: {
formatter: '{value} 吨',
},
},
yAxis: {
type: 'category',
data: ['凤梨', '铁皮石斛', '芒果', '榴莲', '香蕉', '苦瓜', '丝瓜', '小米椒', '圆茄', '黄皮甘蔗'],
axisLabel: {
interval: 0,
},
},
});
const onSubmit = () => {
console.log(formInline);
};
@ -77,4 +124,4 @@ onMounted(() => {
// onSubmit();
});
</script>
<style lang="scss" scoped></style> -->
<style lang="scss" scoped></style>