294 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			294 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <!--
 | |
|  * @Author: zhp
 | |
|  * @Date: 2024-05-23 15:49:14
 | |
|  * @LastEditTime: 2024-06-04 08:54:10
 | |
|  * @LastEditors: zhp
 | |
|  * @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="ftoChart" 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.ftoChart);
 | |
|       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>
 |