<script lang="ts" setup name="BarChartVertical"> /** * 垂直条形图,支持渐变,支持增加背景颜色 */ import * as echarts from 'echarts/core' import type { ECharts } from 'echarts' import { init } from 'echarts' import type { Ref } from 'vue' import type { ECBasicOption } from 'echarts/types/dist/shared' import type { barOption, barSeriesOption, lineDataI } from '@/components/Echart/echart-interface' import tdTheme from '@/components/Echart/theme.json' // 引入默认主题 const props = defineProps({ id: { type: String, default: 'chart', }, unit: { // 单位 type: String, default: '', }, width: { type: String, default: '100%', }, /** * 图表高 */ height: { type: String, default: '100%', }, colors: { // 颜色 type: Array, default: () => { return ['#2D8CF0', '#0337ff'] }, }, axisLineColor: { // 轴线颜色 type: String, default: '#101d5d', }, fontColor: { // 轴线上文字颜色 type: String, default: '#000fff', }, labelColor: { // 图形上文本标签颜色 type: String, default: '#47c8b2', }, seriesData: { // 数据 type: Array, default: () => { return [] }, }, yAxisData: { // X轴数据 type: Array, default: () => { return [] }, }, }) // 图表对象 let chart: ECharts const chartRef: Ref<HTMLElement | null> = ref(null) const timer = ref() // 监听数据变化 watch(() => props.seriesData, () => { refreshChart() }, { immediate: true, deep: true, }) // 构建option function buildOption() { const option = { dataZoom: [ { yAxisIndex: 0, // 这里是从X轴的0刻度开始 show: false, // 是否显示滑动条,不影响使用 type: 'slider', // 这个 dataZoom 组件是 slider 型 dataZoom 组件 startValue: 0, // 从头开始。 endValue: 5, // 一次性展示多少个。 }, ], grid: { left: 10, right: 10, bottom: 10, top: 10, containLabel: true, }, tooltip: { trigger: '', // 悬浮提示框不显示 }, xAxis: [ { type: 'value', show: false, boundaryGap: false, data: [] as any[], // boundaryGap: [0, 0], position: 'top', axisLine: { lineStyle: { color: '#000', // 轴线的颜色 }, }, axisLabel: { color: '#000', // X轴名称颜色 fontSize: 14, }, }, ], yAxis: [ { name: '', type: 'category', inverse: true, // 开启方向坐标轴 data: [], // y轴显示内容 show: true, color: '#000', nameTextStyle: { color: '#000', fontSize: 14, verticalAlign: 'middle', }, max(value: any) { return value.max }, minIntermal: 1, axisLine: { show: false, }, axisLabel: { color: '#000', fontSize: 12, formatter(value, index) { console.log(value, index, '1222322') // const data = props.yAxisData.filter((item: any) => item.includes(value))[0] // const cindex = props.yAxisData.findIndex(data) // 用于修改y轴显示内容 return '{a|NO.}' + `{a|${value.split('-')[1]}}${value.split('-')[0]}` }, // aligin:'right', inside: 'true', verticalAlign: 'bottom', margin: 0, lineHeight: 20, rich: { a: { color: 'blue', }, }, }, }, ], series: [] as any[], } // 数据 if (props.seriesData && props.seriesData.length > 0) { const newSeries = [] as any[] props.seriesData.forEach((item: any, index: number) => { const series = { // name: props.yAxisData[index], type: 'bar', barWidth: item.width, // showBackground: true, barCategoryGap: '100%', label: { show: item.width < 2, // 显示文本 textStyle: { color: '#000', fontSize: '14', }, offset: [-20, -14], formatter: params => params.name.split('-')[2], position: 'right', }, itemStyle: { color: props.colors[0], }, data: item.data, } newSeries.push(series) }) option.series = newSeries } if (props.yAxisData && props.yAxisData.length > 0) { option.yAxis[0].data = props.yAxisData as any[] } return option } // 初始化图表 function initChart() { chart = init(chartRef.value as HTMLElement, tdTheme) chart.setOption({}) } const scorll = () => { clearInterval(timer.value) timer.value = null const option = buildOption() timer.value = setInterval(() => { if (option.dataZoom[0].endValue == props.seriesData[0].data.length - 1) { console.log('归零') option.dataZoom[0].endValue = 5 option.dataZoom[0].startValue = 0 } else { console.log('切换') option.dataZoom[0].endValue = option.dataZoom[0].endValue + 1 option.dataZoom[0].startValue = option.dataZoom[0].startValue + 1 } chart.setOption(option as unknown as ECBasicOption, true) }, 2000) } // 刷新图表 function refreshChart() { if (chart) { const option = buildOption() chart.setOption(option as unknown as ECBasicOption, true) scorll() } } window.addEventListener('resize', () => { chart.resize() }) onMounted(() => { initChart() }) </script> <template> <div :id="id" ref="chartRef" class="chart" :style="{ height, width }" /> </template> <style lang="scss" scoped> .chart { width: 100%; height: 100%; } </style>