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

React中使用react-chartjs-2时X轴出现双标签如何解决?

React + Chart.js + react-chartjs-2 折线图X轴双标签问题

我在React项目中使用Chart.js结合react-chartjs-2绘制折线图时,X轴下方出现了双标签。希望保留上方需要的标签,移除下方多余的,但设置xAxis.display=false会把需要的标签也隐藏,尝试多种方法均未解决,想了解出现双标签的原因及解决办法。

原代码

import 'chartjs-adapter-moment';
import moment from 'moment';
import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
  TimeScale,
} from 'chart.js';
import type { ChartData, ChartOptions } from 'chart.js';
import { Line } from 'react-chartjs-2';
import zoomPlugin from 'chartjs-plugin-zoom';
import { useRef } from 'react';

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  TimeScale,
  LineElement,
  Title,
  Tooltip,
  Legend,
  zoomPlugin
);

const dump = [
  {
    time: 1675056240000,
    soc: 62,
  },
  {
    time: 1675056270000,
    soc: 62,
  },
  {
    time: 1675056300000,
    soc: 62,
  },
  {
    time: 1675056330000,
    soc: 62,
  },
  {
    time: 1675056360000,
    soc: 62,
  },
];

let lables: number[] = [];
let values: number[] = [];

dump.map((x, i) => {
  lables.push(x.time);
  values.push(x.soc);
});

const data: ChartData<'line'> = {
  labels: lables,
  datasets: [
    {
      label: 'Soc',
      data: values,
      backgroundColor: '#03c782',
      borderColor: '#03c782',
      borderWidth: 1,
    },
  ],
};

export default function Main() {
  const lineGraphRef = useRef<ChartJS<'line', number[], string>>(null);

  const options: ChartOptions<'line'> = {
    responsive: true,
    animation: false,

    scales: {
      y: {
        ticks: {
          color: 'white',
        },
        type: 'linear',
        display: true,
        position: 'left',
      },
      xAxis: {
        type: 'time',
        ticks: {
          major: {
            enabled: true,
          },
          maxRotation: 45,
          minRotation: 45,
          maxTicksLimit: 12,
          color: 'white',
        },
        display: true,
      },
    },
    datasets: {
      line: {
        pointRadius: 0,
        showLine: true,
      },
    },

    hover: {
      mode: 'x',
    },
    onHover: (e: any) => {
      if (lineGraphRef !== null && lineGraphRef.current !== null) {
        lineGraphRef.current.clear();
        lineGraphRef.current.draw();

        const y = e.y;
        const bottomY = lineGraphRef.current.scales.y.bottom;

        let ctx = e.chart.ctx;
        ctx.save();
        ctx.beginPath();
        ctx.moveTo(e.x, 0);
        ctx.lineTo(e.x, bottomY);
        ctx.lineWidth = 1;
        ctx.strokeStyle = '#FFAB50';
        ctx.stroke();
        ctx.restore();
      }
    },

    plugins: {
      legend: {
        labels: {
          color: 'white',
          boxWidth: 13,
        },
      },
      tooltip: {
        enabled: false,
        external: (context) => {
          // 自定义tooltip逻辑
        },
      },
      zoom: {
        zoom: {
          drag: {
            enabled: true,
            threshold: 10,
          },
          mode: 'x',
        },
      },
    },
  };
  return (
    <Line
      options={options}
      data={data}
      ref={lineGraphRef}
    />
  );
}

问题原因

你同时注册了CategoryScale(分类轴)和TimeScale(时间轴),并且在数据中提供了labels数组(这会触发Chart.js默认生成一个基于分类轴的X轴),同时又手动配置了一个xAxis(基于时间轴)。两个X轴重叠显示,就出现了双标签的问题。

解决办法

1. 移除冗余的Scale注册

删掉ChartJS.register中的CategoryScale,因为你使用的是时间轴,不需要分类轴:

ChartJS.register(
  LinearScale,
  PointElement,
  TimeScale,
  LineElement,
  Title,
  Tooltip,
  Legend,
  zoomPlugin
);

2. 修改数据结构,移除独立的labels数组

将时间和数值绑定到datasets.data中,让TimeScale自动解析时间数据,不再需要单独的labels:

// 替换原有的data定义
const data: ChartData<'line'> = {
  datasets: [
    {
      label: 'Soc',
      // 直接传递包含x(时间)和y(数值)的对象数组
      data: dump.map(item => ({ x: item.time, y: item.soc })),
      backgroundColor: '#03c782',
      borderColor: '#03c782',
      borderWidth: 1,
    },
  ],
};

3. 清理冗余代码

删掉原有的lables和values数组以及对应的map逻辑,因为现在不需要这些了。

完成以上修改后,X轴只会显示基于TimeScale的标签,双标签问题就会解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 23:03:08