<!-- * @Author: zhp * @Date: 2024-05-23 15:49:14 * @LastEditTime: 2024-07-03 14:08:52 * @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: { trigger: "axis", axisPointer: { // type: "cross", crossStyle: { color: "rgba(237,237,237,0.5)", }, }, extraCssText: 'box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.38); border- radius: 4px;opacity: 0.6;backdrop- filter: blur(6px);', backgroundColor: '#001829', borderColor: '#001829', formatter: params => { console.log('params', params) var res = `<span style='color:rgba(255,255,255,0.85)'>${params[0].axisValueLabel}</span>`; for (var i = 0, l = params.length; i < l; i++) { let color = Object.prototype.toString.call(params[i].color) == "[object String]" ? params[i].color : params[i].color.colorStops ? params[i].color.colorStops[0].color : '' // console.log(item.color, color); res += "<br/>" + `<span style='display:inline-block;margin-right:4px;width:10px;height:10px;background-color:${color}'></span>` + `<span style='display:inline-block;width:150px;color:rgba(255,255,255,.85);font-size:14px;'>${params[i].seriesName}</span>` + `<span style='color:rgba(255,255,255,0.65);font-size:14px;'>${params[i].value ? params[i].value + '片' : 0 + '片'}</span>`; } return res; }, }, 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.options.series.map((item) => { item.barWidth = val ? 18 : 12; }); this.options.xAxis.axisLabel.fontSize = val ? 18 : 12; this.options.yAxis.axisLabel.fontSize = val ? 18 : 12; this.options.yAxis.nameTextStyle.fontSize = val ? 18 : 12; this.initChart(this.options); // 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) this.options.series[0].data = val[0].data; this.options.series[0].name = val[0].name; this.options.series[1].data = val[1].data; this.options.series[1].name = val[1].name; // this.actualOptions = actualOptions; this.initChart(this.options); }, }, 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.options); }, }, }; </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>