<template> <div class="full_content"> <div class="header"> <!-- <div class="header_desc">{{ $t("跑步能力") }}</div> --> <div class="header_icon" @click="fullScreenClick"> <el-icon><TopRight /></el-icon> </div> </div> <div class="footer"> <div class="chart1" ref="chartRef" style="width: 100%; height: 100%" ></div> </div> <echartsBox :title="$t('跑步能力')" v-model:visible="dialogVisible"> <template #content> <div class="footer" style="width: 750px; height: 400px"> <div class="chart2" ref="chartDialog" style="width: 100%; height: 90%" ></div> </div> </template> </echartsBox> </div> </template> <script setup> import { ref, onMounted, onUnmounted, computed } from "vue"; import * as echarts from "echarts"; const chartRef = ref(null); let myChart = null; // 全屏按钮触发 const dialogVisible = ref(false); const fullScreenClick = () => { console.log(123); dialogVisible.value = true; }; const props = defineProps({ xAxisData: { type: Array, default: [ "00:00", "02:00", "04:00", "06:00", "08:00", "10:00", "12:00", "14:00", "16:00", "18:00", "20:00", "22:00", ], }, title: { type: String, default() { return "跑步能力"; }, }, }); // 常用清晰区分的颜色(适合折线图) const COLOR_PALETTE = [ "#4895ef", // 蓝 "#eb4d4b", // 红 "#f0932b", // 橙 "#36cbcb", // 青 "#9b59b6", // 紫 "#00b894", // 绿松石 ]; const yAxisData = ref([ { name: "单次跑力", data: [70, 10, 75, 39, 60, 80, 75, 65, 55, 70, 75, 70], }, { name: "跑步指数", data: [55, 40, 50, 55, 50, 60, 50, 30, 55, 81, 50, 55], }, { name: "单次", data: [70, 101, 9, 39, 60, 10, 75, 65, 55, 70, 75, 70], }, { name: "跑步", data: [55, 120, 50, 55, 50, 60, 30, 30, 45, 81, 50, 55], }, ]); const legendData = yAxisData.value.map((item) => { return item.name; }); const seriesWithColor = computed(() => { return yAxisData.value.map((series, index) => ({ ...series, lineColor: COLOR_PALETTE[index % COLOR_PALETTE.length], // 循环使用颜色 })); }); const chartSeries = computed(() => { return seriesWithColor.value.map((series, index) => ({ name: series.name, type: "line", data: series.data, yAxisIndex: index, // 每条线绑定到自己的 Y 轴 showSymbol: false, lineStyle: { color: series.lineColor, width: 2.5, }, itemStyle: { color: series.lineColor, }, })); }); const alignToStep = (value, step = 10) => { return Math.ceil(value / step) * step; }; const chartYAxis = computed(() => { const TICK_INTERVAL = 20; return seriesWithColor.value.map((series, index) => { // 左右交替放置 Y 轴,避免全部挤在一起 const isLeft = index % 2 === 0; const position = isLeft ? "left" : "right"; const rawDataMax = Math.max(...series.data); // 向上取整到 TICK_INTERVAL 的倍数 const niceMax = alignToStep(rawDataMax, TICK_INTERVAL); // 根据 index 计算偏移量,每多一个同侧轴就向外推 30px const offset = Math.floor(index / 2) * 30; return { type: "value", position, offset, // 关键:错开 Y 轴位置 axisLabel: { color: series.lineColor, }, nameTextStyle: { color: series.lineColor, }, splitLine: { lineStyle: { color: "#444", type: "solid", width: 1 }, }, min: 0, max: niceMax, // 必须是 interval 的整数倍 interval: TICK_INTERVAL, // 所有 Y 轴强制相同刻度间隔 }; }); }); // const chartYAxis = computed(() => { // const leftSeries = seriesWithColor.value.filter( // (s) => seriesBinding.value[s.name] === "left" // ); // const rightSeries = seriesWithColor.value.filter( // (s) => seriesBinding.value[s.name] === "right" // ); // // 取主色(第一个 series 的颜色)作为 Y 轴文字颜色 // const leftColor = leftSeries.length > 0 ? leftSeries[0].lineColor : "#7a7b7c"; // const rightColor = // rightSeries.length > 0 ? rightSeries[0].lineColor : "#7a7b7c"; // // 通用取整函数 // const getNiceMax = (data, step = 10) => // Math.ceil(Math.max(...data) / step) * step + step; // return [ // { // type: "value", // position: "left", // axisLabel: { color: leftColor }, // nameTextStyle: { color: leftColor }, // splitLine: { lineStyle: { color: "#444" } }, // min: 0, // max: // leftSeries.length > 0 // ? getNiceMax( // leftSeries.flatMap((s) => s.data), // 10 // ) // : 100, // }, // // 右 Y 轴 // { // type: "value", // position: "right", // axisLabel: { color: rightColor }, // nameTextStyle: { color: rightColor }, // splitLine: { show: false }, // min: 0, // max: // rightSeries.length > 0 // ? getNiceMax( // rightSeries.flatMap((s) => s.data), // 10 // ) // : 100, // }, // ]; // }); // 初始化图表的函数 const initChart = () => { myChart = echarts.init(chartRef.value); const option = { title: { text: props.title, left: "center", textStyle: { color: "#0d7ee7", }, }, xAxis: { type: "category", data: props.xAxisData.length > 0 ? props.xAxisData : xAxisData, axisLine: { lineStyle: { color: "#7a7b7c", }, }, axisLabel: { color: "#7a7b7c", }, }, yAxis: chartYAxis.value, series: chartSeries.value, legend: { data: legendData, top: "10%", right: "8%", icon: "circle", textStyle: { color: "#fff", }, }, tooltip: { trigger: "axis", }, grid: { left: "3%", right: "4%", bottom: "3%", containLabel: true, }, }; myChart.setOption(option); }; // 窗口大小变化时调整图表大小的函数 const handleResize = () => { if (myChart) { myChart.resize(); } }; onMounted(() => { initChart(); window.addEventListener("resize", handleResize); }); onUnmounted(() => { if (myChart) { myChart.dispose(); myChart = null; } window.removeEventListener("resize", handleResize); }); </script> <style scoped lang="scss"> .full_content { position: relative; width: 100vw; height: 40vh; width: 600px; min-height: 400px; background-color: rgb(42, 40, 40); .header { width: 100%; height: 10%; display: flex; justify-content: center; position: relative; font-size: 24px; font-weight: bolder; color: #0d7ee7; align-items: center; padding-top: 3%; .header_icon { margin-left: 85%; position: absolute; top: 18px; width: 30px; height: 30px; font-size: 25px; cursor: pointer; color: #ffffff5e; background-size: contain; z-index: 999; } } .footer { position: absolute; top: 20px; width: 100%; height: 85%; } } </style>
这样还是不行