You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移动端ChartJS v4水平条形图Y轴标签截断问题解决咨询

解决Chart.js水平条形图Y轴长标签截断问题

环境说明

  • 框架:Nuxt 3 + Vue 3(Composition API + TypeScript)
  • 依赖:chart.js@^4.2.1、vue-chartjs@^5.2.0

问题描述

移动端视图下,水平条形图的Y轴长标签会被截断(如图所示),且标签为动态获取(从外部API返回),无法提前预知长度。

Y轴标签被截断的截图

组件代码如下:

<template>
  <div class="chart-container">
    <ClientOnly>
      <Bar :data="data" :options="chartOptions" />
    </ClientOnly>
  </div>
</template>

<script setup lang="ts">
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  BarElement,
  CategoryScale,
  LinearScale,
  ChartOptions,
} from "chart.js";
import { Bar } from "vue-chartjs";

ChartJS.register(
  CategoryScale,
  LinearScale,
  BarElement,
  Title,
  Tooltip,
  Legend
);

// 动态标签示例
const props = defineProps<{
  movies: { name: string; count: number }[]
}>();

const data = {
  labels: props.movies.map((movie) => movie.name),
  datasets: [
    {
      axis: "y",
      label: "Count",
      backgroundColor: "#000",
      data: props.movies.map((movie) => movie.count),
    },
  ],
};

const chartOptions: ChartOptions<"bar"> = {
  responsive: true,
  maintainAspectRatio: false,
  indexAxis: "y",
  plugins: {
    title: {
      display: true,
      text: "Horizontal Bar chart by ChartJS",
      font: { size: 14 },
    },
  },
};
</script>

<style lang="scss" scoped>
.chart-container {
  position: relative;
  height: 25vh;
}
</style>

解决方案

1. 实现标签自动换行

通过Y轴ticks的callback函数处理标签文本,按规则插入换行符,支持动态长文本:

const chartOptions: ChartOptions<"bar"> = {
  // 原有配置...
  scales: {
    y: {
      ticks: {
        // 按单词拆分自动换行,每行最多3个单词
        callback: function(value) {
          const label = value.toString();
          const maxWordPerLine = 3;
          const words = label.split(' ');
          const lines = [];
          
          while (words.length > 0) {
            lines.push(words.splice(0, maxWordPerLine).join(' '));
          }
          
          return lines; // 返回数组会自动换行
        },
        align: 'left', // 左对齐标签,避免截断
        padding: 5 // 增加标签间距,防止重叠
      },
      offset: true // 开启偏移,给标签留出更多空间
    }
  }
};

如果需要按字符长度拆分,可替换回调逻辑:

callback: function(value) {
  const label = value.toString();
  const maxLength = 15; // 每行最多15个字符
  let result = '';
  for (let i = 0; i < label.length; i += maxLength) {
    result += label.substring(i, i + maxLength) + '\n';
  }
  return result.trim(); // 去除末尾换行符
}

2. 调整布局边距

通过layout和Y轴配置增加左侧边距,给长标签预留显示空间:

const chartOptions: ChartOptions<"bar"> = {
  // 原有配置...
  layout: {
    padding: {
      left: 100 // 根据移动端屏幕宽度调整,确保标签不被截断
    }
  },
  scales: {
    y: {
      ticks: {
        align: 'left'
      },
      offset: true
    }
  }
};

3. 响应式调整标签字体大小

根据屏幕宽度动态缩小移动端的标签字体,避免截断:

const chartOptions: ChartOptions<"bar"> = {
  // 原有配置...
  scales: {
    y: {
      ticks: {
        font: {
          size: () => window.innerWidth < 768 ? 10 : 12 // 移动端字体缩小为10px
        }
      }
    }
  }
};

4. 优化工具提示展示完整标签

如果标签过长不适合换行,可让工具提示显示完整标签内容:

const chartOptions: ChartOptions<"bar"> = {
  // 原有配置...
  plugins: {
    // 原有title配置...
    tooltip: {
      callbacks: {
        label: (context) => `${context.label}: ${context.raw}` // 显示完整标签和数值
      }
    }
  }
};

内容的提问来源于stack exchange,提问作者qqq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 05:45:21