feat:折柱图

This commit is contained in:
wangzenghua 2025-03-05 08:41:12 +00:00
parent 2c93b36eb4
commit 4c780a22ab
5 changed files with 138 additions and 36 deletions

View File

@ -5,18 +5,22 @@
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%',
@ -25,14 +29,11 @@ export default {
type: String,
default: 'calc(100vh - 78px)',
},
seriesColor: {
type: String,
default: '#1890ff',
},
},
setup(props) {
emits: ['click'],
setup(props, { emit }) {
const chartRef = ref(null);
const { setOptions } = useEcharts(chartRef);
const { setOptions, getInstance } = useEcharts(chartRef);
const option = reactive({
tooltip: {
trigger: 'axis',
@ -44,6 +45,12 @@ export default {
},
},
},
legend: {
top: 30,
},
grid: {
top: 60,
},
xAxis: {
type: 'category',
data: [],
@ -51,14 +58,7 @@ export default {
yAxis: {
type: 'value',
},
series: [
{
name: 'bar',
type: 'bar',
data: [],
color: props.seriesColor,
},
],
series: [],
});
watchEffect(() => {
@ -69,16 +69,36 @@ export default {
if (props.option) {
Object.assign(option, cloneDeep(props.option));
}
let seriesData = props.chartData.map((item) => {
return item.value;
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);
}
});
let xAxisData = props.chartData.map((item) => {
return item.name;
obj['data'] = data;
if (props.option?.color) {
obj.color = props.option?.color[index];
}
seriesData.push(obj);
});
option.series[0].data = seriesData;
option.series[0].color = props.seriesColor;
option.series = seriesData;
option.xAxis.data = xAxisData;
setOptions(option);
getInstance()?.off('click', onClick);
getInstance()?.on('click', onClick);
}
function onClick(params) {
emit('click', params);
}
return { chartRef };
},

View File

@ -7,7 +7,7 @@ import { cloneDeep } from 'lodash';
import { useEcharts } from '../../hooks/useEcharts';
export default {
name: 'CustomEchartMultiLine',
name: 'CustomEchartLine',
props: {
chartData: {
type: Array,

View File

@ -0,0 +1,85 @@
<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: 'CustomEchartMixin',
props: {
chartData: {
type: Array,
default: () => [],
},
option: {
type: Object,
default: () => ({}),
},
width: {
type: String,
default: '100%',
},
height: {
type: String,
default: 'calc(100vh - 78px)',
},
},
setup(props) {
const chartRef = ref(null);
const { setOptions } = useEcharts(chartRef);
const option = reactive({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true,
backgroundColor: '#333',
},
},
},
xAxis: {
type: 'category',
data: [],
},
yAxis: {
type: 'value',
},
series: [
{
name: 'bar',
type: 'bar',
data: [],
},
],
});
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) => {
let obj = { name: type };
let chartArr = props.chartData.filter((item) => type === item.type);
obj['data'] = chartArr.map((item) => item.value);
obj['type'] = chartArr[0].seriesType;
seriesData.push(obj);
});
option.series = seriesData;
option.xAxis.data = xAxisData;
setOptions(option);
}
return { chartRef };
},
};
</script>

View File

@ -4,6 +4,7 @@ import CustomImportExcel from './custom-import-excel';
import CustomRichEditor from './custom-rich-editor';
import CustomEchartBar from './custom-echart-bar';
import CustomEchartPie from './custom-echart-pie';
import CustomEchartMultiLine from './custom-echart-multi-line';
import CustomEchartLine from './custom-echart-line';
import CustomEchartMixin from './custom-echart-mixin';
export { SvgIcon, CustomTableOperate, CustomImportExcel, CustomRichEditor, CustomEchartBar, CustomEchartPie, CustomEchartMultiLine };
export { SvgIcon, CustomTableOperate, CustomImportExcel, CustomRichEditor, CustomEchartBar, CustomEchartPie, CustomEchartLine, CustomEchartMixin };

View File

@ -16,7 +16,7 @@
<el-row :gutter="16">
<el-col :span="24">
<el-card shadow="hover">
<custom-echart-multi-line :chart-data="state.landTrendData" height="500px" :option="state.landTrendOption" type="line" />
<custom-echart-line :chart-data="state.landTrendData" height="500px" :option="state.landTrendOption" type="line" />
</el-card>
</el-col>
</el-row>
@ -75,17 +75,13 @@ const state = reactive({
// show: false,
// },
},
series: [
{
name: 'bar',
type: 'bar',
barWidth: 50,
data: [],
barStyle: {
// barWidth: 50,
showBackground: true,
itemStyle: {
borderRadius: 25,
borderRadius: 10,
},
},
],
},
cropData: [
{ value: 230, name: '土豆' },