Newer
Older
xc-metering-front / src / views / tested / dashboard / components / BarChartHorizontalCustom.vue
liyaguang on 7 Oct 2023 3 KB feat(*): 细节完善
<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%',
  },
  axisLineColor: {
    // 轴线颜色
    type: String,
    default: '#000',
  },
  fontColor: {
    // 轴线上文字颜色
    type: String,
    default: '#000',
  },
  labelColor: {
    // 图形上文本标签颜色
    type: String,
    default: '#000',
  },
  seriesData: {
    // 数据
    type: Array,
    default: () => {
      return []
    },
  },
  yAxisData: {
    // X轴数据
    type: Array,
    default: () => {
      return []
    },
  },
})

// 图表对象
let chart: ECharts
const chartRef: Ref<HTMLElement | null> = ref(null)
// 监听数据变化
watch(() => props.seriesData, () => {
  refreshChart()
}, {
  immediate: true,
  deep: true,
})
watch(() => props.yAxisData, () => {
  refreshChart()
}, {
  immediate: true,
  deep: true,
})
// 构建option
function buildOption() {
  const option = {
    grid: {
      left: 10,
      right: 10,
      bottom: 25,
      top: 10,
      containLabel: true,
    },
    tooltip: {
      trigger: 'item', // 悬浮提示框不显示
    },
    xAxis: [
      {
        type: 'value',
        show: true,
        data: [] as any[],
        boundaryGap: true,
        axisLine: {
          show: true,
          lineStyle: {
            color: props.axisLineColor, // 轴线的颜色
          },
        },
        axisLabel: {
          color: '#000',
          fontSize: 15,
        },
        splitLine: {
          show: true,
          lineStyle: {
            color: ['#000'],
            type: 'dashed',
          },
        },
      },
    ],
    yAxis: [
      {
        type: 'category',
        inverse: false, // 开启方向坐标轴
        data: [], // y轴显示内容
        show: true,
        boundaryGap: true,
        axisLine: {
          show: true,
          lineStyle: {
            color: props.axisLineColor, // 轴线的颜色
          },
        },
        nameTextStyle: { // 坐标轴名称的文字样式
          color: props.fontColor,
          fontSize: '60%',
          verticalAlign: 'middle',
        },
        axisLabel: {
          show: true,
          color: '#000', // y轴名称颜色
          fontSize: 14,
        },
        splitLine: {
          show: false,
          lineStyle: {
            color: ['#000'],
            type: 'dashed',
          },
        },
      },
    ],
    series: [] as any[],
  }
  // 数据
  if (props.seriesData && props.seriesData.length > 0) {
    option.series = {
      data: props.seriesData,
      type: 'bar',
    }
  }
  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({})
}

// 刷新图表
function refreshChart() {
  if (chart) {
    const option = buildOption()
    chart.setOption(option as unknown as ECBasicOption, true)
  }
}

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>