<template>
<div ref="barChart" :style="{ width: '100%', height: height + 'px' }"></div>
</template>
<script lang="ts">
import { defineComponent, ref, onMounted, onUnmounted, watch, PropType } from 'vue';
import * as echarts from 'echarts';
export default defineComponent({
name: 'HorizontalBarChart',
props: {
data: {
type: Array as PropType<{ name: string; value: number }[]>,
required: true,
},
height: {
type: Number,
default: 300,
},
// 可自定义柱形颜色
barColor: {
type: String,
default: '#409EFF',
},
// 可自定义X轴分割线颜色
xSplitLineColor: {
type: String,
default: '#F0F2F5',
},
},
setup(props) {
const barChart = ref<HTMLDivElement | null>(null);
let chartInstance: echarts.ECharts | null = null;
const initChart = () => {
if (barChart.value && !chartInstance) {
chartInstance = echarts.init(barChart.value);
}
if (chartInstance) {
const option = {
// 悬浮提示框配置
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(255, 255, 255, 0.9)',
borderColor: '#EEEEEE',
borderWidth: 1,
padding: 10,
textStyle: {
color: '#333333',
fontSize: 14,
},
formatter: function (params: any) {
return `
<div style="font-weight: 500;">${params.name}</div>
<div>数据:${params.value}</div>
`;
},
position: function (point: number[], params: any, dom: any, rect: any, size: any) {
let x = point[0];
let y = point[1];
const viewWidth = size.viewSize[0];
const viewHeight = size.viewSize[1];
const domWidth = dom.offsetWidth;
const domHeight = dom.offsetHeight;
if (x + domWidth > viewWidth) {
x = x - domWidth - 10;
}
if (y + domHeight > viewHeight) {
y = y - domHeight - 10;
}
return [x, y];
},
},
grid: {
left: '1%',
right: '4%',
bottom: '2%',
top: '10%',
containLabel: true,
},
xAxis: {
type: 'value',
// 添加X轴分割线(横向分割线)
splitLine: {
show: true,
lineStyle: {
color: props.xSplitLineColor,
width: 1,
type: 'solid', // 实线分割
},
},
axisLabel: {
formatter: '{value}',
margin: 15,
},
},
yAxis: {
type: 'category',
data: props.data.map((item) => item.name),
inverse: true,
axisLine: {
show: false,
},
axisTick: {
show: false,
},
textStyle: {
fontSize: 12,
color: '#606266',
},
// 去掉Y轴分割线
splitLine: {
show: false,
},
axisLabel: {
margin: 15,
},
},
series: [
{
type: 'bar',
data: props.data.map((item) => item.value),
itemStyle: {
color: props.barColor,
borderRadius: [0, 4, 4, 0],
},
barWidth: 15,
emphasis: {
itemStyle: {
color: `${props.barColor}CC`,
},
},
},
{
type: 'bar',
data: props.data.map((item) => item.value),
barWidth: 0,
label: {
show: true,
position: 'right',
formatter: '{c}',
color: '#606266',
fontSize: 12,
distance: 5,
},
},
],
};
chartInstance.setOption(option);
}
};
const handleResize = () => {
if (chartInstance) {
chartInstance.resize();
}
};
onMounted(() => {
setTimeout(initChart, 0);
window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
if (chartInstance) {
chartInstance.dispose();
chartInstance = null;
}
});
watch(
() => props.data,
() => {
initChart();
},
{ deep: true },
);
watch(
() => [props.barColor, props.xSplitLineColor, props.height],
() => {
initChart();
},
);
return {
barChart,
};
},
});
</script>
页面引入
<HorizontalBar :data="chartData" :height="260" />
import HorizontalBar from '@/components/Echatrs/HorizontalBar.vue';
const chartData = ref([
{ name: '企业名E', value: 180 },
{ name: '企业名D', value: 70 },
{ name: '企业名C', value: 230 },
{ name: '企业名B', value: 170 },
{ name: '企业名A', value: 195 },
]);
647

被折叠的 条评论
为什么被折叠?



