数据标签在水平系列 Apex 条形图中重叠

问题描述 投票:0回答:1

条形图 - 在此输入图片描述

我需要解决当大量数据列靠近时,所有数据列上方的数据标签相互重叠的问题。 我尝试了许多不同的方法来隐藏重叠的数据,但尝试都没有成功。

代码-

const chartOptions = merge(otherOptions, {
    colors: colorPalette ? undefined : getChartColors('bar'),
    theme: {
      mode: 'light',
      palette: colorPalette,
      monochrome: {
        enabled: enableMonoChromeColors,
        color: monoChromeBaseColor.startsWith('#')
          ? monoChromeBaseColor
          : theme.palette[monoChromeBaseColor].main,
        shadeTo: 'light',
        shadeIntensity: 0.65
      }
    },
    chart: { stacked: stacked },
    legend: {
      show: showLegend,
      itemMargin: { vertical: 4 },
      position: 'bottom',
      offsetY: 5,
      height: 50
    },
    plotOptions: {
      bar: {
        columnWidth: `${barWidth}%`,
        endingShape: 'squared',
        dataLabels: {
          position: 'top',
          hideOverflowingLabels: true,
          orientation: 'horizontal'
        }
      }
    },
    dataLabels: {
      enabled: showDataLabels,
      offsetY: dataLabelsInside ? -5 : -22,
      formatter: function (val, opts) {
        return `${chartFormatter(val, type)} ${unit}`;
      },
      style: {
        fontSize: fontSize,
        colors: dataLabelsInside
          ? [theme.palette.common.white]
          : [theme.palette.grey[600]],
        fontWeight: '500',
        fontFamily: 'Rubik, sans-serif'
      }
    },
    xaxis: {
      show: !hideXAxis,
      categories: data.categories,
      type: type,
      labels: {
        show: !hideXAxis,
        rotate: skewLabels ? -90 : 0,
        hideOverlappingLabels: false,
        showDuplicates: false,
        trim: true,
        style: {
          colors: [],
          fontSize: fontSize
        }
      }
    },
    yaxis: {
      floating: hideYAxis,
      axisTicks: {
        show: !hideYAxis
      },
      axisBorder: {
        show: !hideYAxis
      },
      labels: {
        show: !hideYAxis,
        formatter: (val) => chartFormatter(val, type)
      }
    },
    grid: {
      show: !hideYAxis,
      padding: {
        left: 20,
        right: 20,
        ...paddingOverrides
      }
    },
    tooltip: {
      enabled: tooltipsEnabled,
      fillSeriesColor: true,
      followCursor: false,
      y: {
        formatter: (val) => `${chartFormatter(val, type)} ${unit}`
      },
      title: {
        formatter: (seriesName) => {
          const formatted = (seriesName || EMPTY_STRING).split(' - ');
          return formatted.length > 1 ? formatted[1] : seriesName;
        }
      }
    }
  });

  return (
    <ReactApexChart
      type="bar"
      series={data?.chartData}
      options={chartOptions}
      height={
        chartHeight && hideXAxis && !showLegend
          ? chartHeight - chartHeight * 0.08
          : chartHeight
          ? chartHeight
          : '100%'
      }
    />
  );

我已经尝试在数据标签内使用

hideOverflowingLabels: true,
来避免标签重叠,但没有效果

reactjs bar-chart styling apexcharts react-apexcharts
1个回答
0
投票

要正确格式化 Stack Overflow 的解决方案,请对代码块使用 Markdown 语法。以下是如何以清晰且结构化的方式呈现问题和解决方案:


问题:

当有许多列靠在一起时,条形图列上方的数据标签会重叠。尝试使用

hideOverflowingLabels: true
未能解决问题。

解决方案:

为了防止重叠,请计算每个标签的宽度并隐藏超出相应栏宽度的标签。使用以下辅助函数并相应地更新您的图表配置。

// Helper function to calculate text width
import { FONT_FAMILY } from "../../config/fontVariables";

/**
 * Calculates the approximate width of a string in pixels for a given font size and weight.
 *
 * @param text - The string to measure.
 * @param fontSize - The font size in pixels (e.g., 12 for 12px).
 * @param fontWeight - The font weight (e.g., 'normal', 'bold', '400', '700').
 * @returns The approximate width of the string in pixels.
 */
export function calculateTextWidth(
  text: string,
  fontSize: number,
  fontWeight: string | number
): number {
  // Create a canvas element (in-memory, not added to the DOM)
  const canvas = document.createElement("canvas");
  const context = canvas.getContext("2d");

  if (!context) {
    console.warn("Failed to create canvas rendering context.");
    return 0;
  }

  // Set the font style
  context.font = `${fontWeight} ${fontSize}px ${FONT_FAMILY}`;

  // Measure the text width
  const metrics = context.measureText(text);
  return metrics.width;
}

更新您的条形图配置:

const chartOptions = merge(otherOptions, {
  dataLabels: {
    enabled: showDataLabel,
    style: {
      fontWeight: 400,
    },
    formatter: (val, opts) => {
      const labelWidth = calculateTextWidth(val.toString(), 12, 400);
      const barWidth = opts.w.globals.barWidth;
      
      // Hide label if it exceeds the bar's width
      if (labelWidth > barWidth) {
        return "";
      }
      return val;
    },
  },
});

说明:

  1. 文本测量:
    calculateTextWidth
    函数使用画布元素来测量给定文本字符串的像素宽度。
  2. 标签可见性:
    formatter
    函数将标签的宽度与条形的宽度进行比较。如果标签比栏宽,则通过返回空字符串来隐藏它。
  3. 自定义字体:如有必要,请将
    FONT_FAMILY
    替换为您想要的字体系列。

这种方法可确保数据标签不重叠并保持清晰的可视化效果。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.