293 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			293 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
<!--
 | 
						|
    filename: BarChartBase.vue
 | 
						|
    author: liubin
 | 
						|
    date: 2024-04-10 08:59:28
 | 
						|
    description:
 | 
						|
-->
 | 
						|
 | 
						|
<template>
 | 
						|
  <chart-container class="bar-chart-base">
 | 
						|
    <div class="legend">
 | 
						|
      <span v-for="item in legend" :key="item.label" class="legend-item"
 | 
						|
        :style="{ fontSize: isFullscreen ? '0.58vw' : '0.54vw' }">{{ item.label }}</span>
 | 
						|
    </div>
 | 
						|
    <div ref="chart" style="height:94%;width:100%"></div>
 | 
						|
  </chart-container>
 | 
						|
</template>
 | 
						|
 | 
						|
<script>
 | 
						|
import screenfull from "screenfull";
 | 
						|
import ChartContainer from "./ChartContainer.vue";
 | 
						|
import { debounce } from "@/utils/debounce";
 | 
						|
// import chartMixin from "@/mixins/chart.js";
 | 
						|
import * as echarts from "echarts";
 | 
						|
export default {
 | 
						|
  name: "BarChartBase",
 | 
						|
  components: {
 | 
						|
    ChartContainer,
 | 
						|
  },
 | 
						|
  // mixins: [chartMixin],
 | 
						|
  props: {
 | 
						|
    vHeight: {
 | 
						|
      type: Number,
 | 
						|
      default: 34,
 | 
						|
    },
 | 
						|
    legend: {
 | 
						|
      type: Array,
 | 
						|
      required: true,
 | 
						|
    },
 | 
						|
    xAxis: {
 | 
						|
      type: Array,
 | 
						|
      required: true,
 | 
						|
    },
 | 
						|
    series: {
 | 
						|
      type: Array,
 | 
						|
      required: true,
 | 
						|
    },
 | 
						|
    in: {
 | 
						|
      type: String,
 | 
						|
      default: "",
 | 
						|
    },
 | 
						|
  },
 | 
						|
  data() {
 | 
						|
    return {
 | 
						|
      width: '100%',
 | 
						|
      isFullscreen: false,
 | 
						|
      actualOptions: null,
 | 
						|
      options: {
 | 
						|
        grid: {
 | 
						|
          left: "5%",
 | 
						|
          right: "4%",
 | 
						|
          bottom: "3%",
 | 
						|
          top: "15%",
 | 
						|
          containLabel: true,
 | 
						|
        },
 | 
						|
        tooltip: {},
 | 
						|
        xAxis: {
 | 
						|
          axisTick: {
 | 
						|
            show: false,
 | 
						|
          },
 | 
						|
          axisLine: {
 | 
						|
            lineStyle: {
 | 
						|
              color: "#4561AE",
 | 
						|
            },
 | 
						|
          },
 | 
						|
          axisLabel: {
 | 
						|
            color: "#fff",
 | 
						|
            fontSize: 12,
 | 
						|
          },
 | 
						|
          data: this.xAxis,
 | 
						|
        },
 | 
						|
        yAxis: {
 | 
						|
          name: "单位/片",
 | 
						|
          nameTextStyle: {
 | 
						|
            color: "#fff",
 | 
						|
            fontSize: 12,
 | 
						|
            align: "right",
 | 
						|
          },
 | 
						|
          axisTick: {
 | 
						|
            show: false,
 | 
						|
          },
 | 
						|
          axisLabel: {
 | 
						|
            color: "#fff",
 | 
						|
            fontSize: 12,
 | 
						|
          },
 | 
						|
          axisLine: {
 | 
						|
            show: true,
 | 
						|
            lineStyle: {
 | 
						|
              color: "#4561AE",
 | 
						|
            },
 | 
						|
          },
 | 
						|
          splitLine: {
 | 
						|
            lineStyle: {
 | 
						|
              color: "#4561AE",
 | 
						|
            },
 | 
						|
          },
 | 
						|
        },
 | 
						|
        series: [
 | 
						|
          {
 | 
						|
            name: "", // this.series[0].name,
 | 
						|
            type: "bar",
 | 
						|
            barWidth: 12,
 | 
						|
            itemStyle: {
 | 
						|
              borderRadius: [10, 10, 0, 0],
 | 
						|
              color: {
 | 
						|
                type: "linear",
 | 
						|
                x: 0,
 | 
						|
                y: 0,
 | 
						|
                x2: 0,
 | 
						|
                y2: 1,
 | 
						|
                colorStops: [
 | 
						|
                  {
 | 
						|
                    offset: 0,
 | 
						|
                    color: "#12f7f1", // 0% 处的颜色
 | 
						|
                  },
 | 
						|
                  {
 | 
						|
                    offset: 0.35,
 | 
						|
                    color: "#12f7f177", // 100% 处的颜色
 | 
						|
                  },
 | 
						|
                  {
 | 
						|
                    offset: 0.75,
 | 
						|
                    color: "#12f7f133", // 100% 处的颜色
 | 
						|
                  },
 | 
						|
                  {
 | 
						|
                    offset: 1,
 | 
						|
                    color: "transparent", // 100% 处的颜色
 | 
						|
                  },
 | 
						|
                ],
 | 
						|
                global: false, // 缺省为 false
 | 
						|
              },
 | 
						|
            },
 | 
						|
            data: [], // this.series[0].data,
 | 
						|
          },
 | 
						|
          {
 | 
						|
            name: "", // this.series[1].name,
 | 
						|
            type: "bar",
 | 
						|
            barWidth: 12,
 | 
						|
            // tooltip: {
 | 
						|
            //   valueFormatter: function (value) {
 | 
						|
            //     return value + " ml";
 | 
						|
            //   },
 | 
						|
            // },
 | 
						|
            itemStyle: {
 | 
						|
              borderRadius: [10, 10, 0, 0],
 | 
						|
              color: {
 | 
						|
                type: "linear",
 | 
						|
                x: 0,
 | 
						|
                y: 0,
 | 
						|
                x2: 0,
 | 
						|
                y2: 1,
 | 
						|
                colorStops: [
 | 
						|
                  {
 | 
						|
                    offset: 0,
 | 
						|
                    color: "#57abf8", // 0% 处的颜色
 | 
						|
                  },
 | 
						|
                  {
 | 
						|
                    offset: 1,
 | 
						|
                    color: "#364BFE66", // 100% 处的颜色
 | 
						|
                  },
 | 
						|
                ],
 | 
						|
                global: false, // 缺省为 false
 | 
						|
              },
 | 
						|
            },
 | 
						|
            data: [], // this.series[1].data,
 | 
						|
          },
 | 
						|
        ],
 | 
						|
      },
 | 
						|
    };
 | 
						|
  },
 | 
						|
  computed: {
 | 
						|
    isOpen() {
 | 
						|
      return this.$store.getters.sidebar.opened
 | 
						|
    },
 | 
						|
  },
 | 
						|
  watch: {
 | 
						|
    /** 全屏状态切换时,对柱子粗细和字体大小进行相应调整 */
 | 
						|
    isOpen(val) {
 | 
						|
      // console.log(val)
 | 
						|
      this.canvasReset()
 | 
						|
    },
 | 
						|
    isFullscreen(val) {
 | 
						|
      this.actualOptions.series.map((item) => {
 | 
						|
        item.barWidth = val ? 18 : 12;
 | 
						|
      });
 | 
						|
      this.actualOptions.xAxis.axisLabel.fontSize = val ? 18 : 12;
 | 
						|
      this.actualOptions.yAxis.axisLabel.fontSize = val ? 18 : 12;
 | 
						|
      this.actualOptions.yAxis.nameTextStyle.fontSize = val ? 18 : 12;
 | 
						|
      this.initChart(this.actualOptions);
 | 
						|
      // this.actualOptions.series.map((item) => {
 | 
						|
      //   item.barWidth = val ? 18 : 12;
 | 
						|
      // });
 | 
						|
      // this.actualOptions.xAxis.axisLabel.fontSize = val ? 18 : 12;
 | 
						|
      // this.actualOptions.yAxis.axisLabel.fontSize = val ? 18 : 12;
 | 
						|
      // this.actualOptions.yAxis.nameTextStyle.fontSize = val ? 18 : 12;
 | 
						|
      // this.initChart(this.actualOptions);
 | 
						|
      this.canvasReset()
 | 
						|
    },
 | 
						|
    series(val) {
 | 
						|
      if (!val) {
 | 
						|
        this.initChart(this.options);
 | 
						|
        return;
 | 
						|
      }
 | 
						|
      const actualOptions = JSON.parse(JSON.stringify(this.options));
 | 
						|
      console.log('actualOptions', this.options)
 | 
						|
      actualOptions.series[0].data = val[0].data;
 | 
						|
      actualOptions.series[0].name = val[0].name;
 | 
						|
      actualOptions.series[1].data = val?.[1]?.data || [];
 | 
						|
      actualOptions.series[1].name = val?.[1]?.name || "";
 | 
						|
      this.actualOptions = actualOptions;
 | 
						|
      this.initChart(actualOptions);
 | 
						|
    },
 | 
						|
  },
 | 
						|
  mounted() {
 | 
						|
    if (screenfull.isEnabled) {
 | 
						|
      screenfull.on("change", () => {
 | 
						|
        this.isFullscreen = screenfull.isFullscreen;
 | 
						|
      });
 | 
						|
    }
 | 
						|
    this.actualOptions = this.options
 | 
						|
    this.canvasReset();
 | 
						|
    window.addEventListener("resize", this.canvasReset);
 | 
						|
  },
 | 
						|
  beforeDestroy() {
 | 
						|
    if (this.chart) {
 | 
						|
      this.chart.dispose();
 | 
						|
    }
 | 
						|
  },
 | 
						|
  destroyed() {
 | 
						|
    window.removeEventListener("resize", this.canvasReset);
 | 
						|
  },
 | 
						|
 | 
						|
  methods: {
 | 
						|
    canvasReset() {
 | 
						|
      debounce(() => {
 | 
						|
        this.initChart();
 | 
						|
      }, 500)();
 | 
						|
    },
 | 
						|
    initChart() {
 | 
						|
      if (this.chart) {
 | 
						|
        this.chart.dispose();
 | 
						|
      }
 | 
						|
      this.chart = echarts.init(this.$refs.chart);
 | 
						|
      this.chart.setOption(this.actualOptions);
 | 
						|
    },
 | 
						|
  },
 | 
						|
};
 | 
						|
</script>
 | 
						|
 | 
						|
<style scoped lang="scss">
 | 
						|
.bar-chart-base {
 | 
						|
  // position: relative;
 | 
						|
 | 
						|
  .legend {
 | 
						|
    position: absolute;
 | 
						|
    top: 5.2vh;
 | 
						|
    right: 1vw;
 | 
						|
  }
 | 
						|
 | 
						|
  .legend-item {
 | 
						|
    position: relative;
 | 
						|
    // font-size: 12px;
 | 
						|
    margin-right: 0.67vw;
 | 
						|
 | 
						|
    &::before {
 | 
						|
      content: "";
 | 
						|
      display: inline-block;
 | 
						|
      width: 0.531vw;
 | 
						|
      height: 0.531vw;
 | 
						|
      background-color: #ccc;
 | 
						|
      border-radius: 2px;
 | 
						|
      margin-right: 0.22vw;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  .legend-item:nth-child(1):before {
 | 
						|
    background-color: #12f7f1;
 | 
						|
  }
 | 
						|
 | 
						|
  .legend-item:nth-child(2):before {
 | 
						|
    background-color: #58adfa;
 | 
						|
  }
 | 
						|
}
 | 
						|
</style>
 |