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

如何在ReactJS的Victory库中创建分组数据直方图并实现对应需求

实现分组直方图的修改方案

核心修改逻辑

你原有代码的主要问题是x轴使用字符串类型的id导致坐标计算不精准、未开启横向平移能力、缺少分组标签的位置计算逻辑,按以下步骤修改即可实现需求:

1. 数据预处理

先给每条数据分配连续的数值型x索引,同时统计每个分组的x轴区间和中点位置,用于后续渲染顶部分组标签:

// 数据预处理逻辑,放在组件外或者组件内顶部都可以
const processData = (rawData) => {
  let xIndex = 0;
  const groupMap = {};
  const processedData = rawData.map(item => {
    if (!groupMap[item.group_id]) {
      groupMap[item.group_id] = { startX: xIndex, endX: xIndex };
    } else {
      groupMap[item.group_id].endX = xIndex;
    }
    xIndex++;
    return { ...item, x: xIndex - 1 };
  });
  // 生成每个分组的标签位置信息
  const groupLabels = Object.entries(groupMap).map(([groupId, { startX, endX }]) => ({
    groupId,
    centerX: (startX + endX) / 2
  }));
  return { processedData, groupLabels, totalX: xIndex };
};

2. 完整修改后的组件代码

const App = () => {
  // 调用预处理方法处理原始数据
  const { processedData, groupLabels, totalX } = processData(data);
  const sharedAxisStyles = {
    tickLabels: {
      fontSize: 10
    },
    axisLabel: {
      padding: 39,
      fontSize: 12,
    },
    grid: {
      stroke: "#546E7A",
      strokeWidth: 0.1,
    }
  };

  return (
    <VictoryChart
      domainPadding={{
        x: 20,
      }}
      // 配置缩放容器开启横向平移实现滚动效果
      containerComponent={(
        <VictoryZoomContainer
          allowZoom={false}
          allowPan={true}
          zoomDomain={{
            x: [0, 22], // 可见区域的x范围,可自行调整显示的条目数
          }}
          minimumZoom={{x: 1}}
        />
      )}
    >
      <VictoryLabel
        x={225}
        y={10}
        textAnchor="middle"
        text="Group code"
      />
      {/* 渲染顶部分组标签 */}
      {groupLabels.map(item => (
        <VictoryLabel
          key={item.groupId}
          x={item.centerX}
          y={30}
          textAnchor="middle"
          text={item.groupId}
          style={{fontSize: 12, fontWeight: 'bold'}}
        />
      ))}
      <VictoryBar
        data={processedData}
        x="x" // 使用预处理的数值型x索引
        y="value"
        barWidth={15.8}
        style={{
          data: {
            fill: ({datum}) => datum.fill,
          }
        }}
      />
      <VictoryAxis
        tickValues={processedData.map((_, i) => i)}
        tickFormat={(t) => `id_${processedData[t].id}`}
        tickLabelComponent={<VictoryLabel
          angle={-90}
          textAnchor="end"
          style={{ fontSize: 8, fontWeight: 'bold', fill: '#78909C' }}
        />}
      />

      <VictoryAxis
        dependentAxis
        label="Value"
        tickFormat={(t) => {
          return (
            (t).toFixed(2)
          );
        }}
        style={sharedAxisStyles}
      />

    </VictoryChart>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:15:03