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

如何使用ChartJS将多张子部分垂直折线图合并为单个图表?

如何用ChartJS将多个子部分的折线图合并为单个图表

我有多个带子部分的板块(例如Section A包含Section A(1)等子部分),目前能为每个子部分生成独立的垂直折线图,想要用ChartJS把这些子部分的图表合并成一个单图表(类似多折线合并的样式)。

当前数据结构

[
  {
    "fbID": "f6498d26-ad0c-4abd-bf77-e194489643c6",
    "fbSectionA1": 4,
    "fbSectionA2": 4,
    "fbSectionA3": 3,
    "fbSectionA4": 4,
    "fbSectionA5": 4,
    "fbSectionB1": 4,
    "fbSectionB2": 4,
    "fbSectionB3": 4,
    "fbSectionB4": 3,
    "fbSectionC1": 3,
    "fbSectionD1": 4,
    "fbSectionEAdditional": "Data 1",
    "fbSectionEChanges": "Data 1",
    "fbSectionESuggestions": "Data 1"
  },
  {
    "fbID": "df23aec1-b8eb-47bb-95b5-b85t87c5d135",
    "fbSectionA1": 4,
    "fbSectionA2": 4,
    "fbSectionA3": 4,
    "fbSectionA4": 4,
    "fbSectionA5": 4,
    "fbSectionB1": 4,
    "fbSectionB2": 4,
    "fbSectionB3": 4,
    "fbSectionB4": 4,
    "fbSectionC1": 4,
    "fbSectionD1": 4,
    "fbSectionEAdditional": "-",
    "fbSectionEChanges": "-",
    "fbSectionESuggestions": "-"
  },
  {
    "fbID": "f72c7e26-7bb1-47f7-823d-75c375108c5f",
    "fbSectionA1": 5,
    "fbSectionA2": 4,
    "fbSectionA3": 4,
    "fbSectionA4": 5,
    "fbSectionA5": 5,
    "fbSectionB1": 5,
    "fbSectionB2": 5,
    "fbSectionB3": 5,
    "fbSectionB4": 4,
    "fbSectionC1": 4,
    "fbSectionD1": 5,
    "fbSectionEAdditional": "None",
    "fbSectionEChanges": "None",
    "fbSectionESuggestions": "Data 3"
  }
]

现有代码

循环渲染独立图表

<div className="w-full mb-5">
    {sectionsToDisplay.map((sectionName) => (
        <IndividualFeedback
        key={sectionName}
        sectionName={sectionName}
        feedbackData={feedbackData}
        />
    ))}
</div>

单个图表的数据处理函数

const prepareChartData = () => {
        const labels: string[] = ['Strongly Disagree', 'Disagree', 'Neutral', 'Agree', 'Strongly Agree'];
        const data: number[] = [];

        for (let i = 1; i <= 5; i++) {
            const columnName = `${sectionName}` as keyof FeedbackDataType;
            const ratingCounts = calculateRatingCounts(columnName);
            const ratingData = Object.keys(ratingCounts).map((rating) => ratingCounts[rating]);
            data.push(...ratingData);
            console.log(columnName);
        }

        console.log(data);

        return {
            labels,
            data,
        };
    };
const calculateRatingCounts = (columnName: keyof FeedbackDataType) => {
        const ratingCounts: { [rating: string]: number } = {};

        for (let i = 1; i <= 5; i++) {
            ratingCounts[i.toString()] = 0;
        }

        feedbackData.forEach((feedback) => {
            const rating = parseInt(feedback[columnName], 10);
            if (!isNaN(rating) && rating >= 1 && rating <= 5) {
                ratingCounts[rating.toString()] += 1;
            }
        });

        return ratingCounts;
    };

解决方案

要合并成单图表,核心是为每个子部分生成独立的数据集(dataset),然后让ChartJS一次性渲染所有数据集。

1. 编写合并图表的数据准备函数

修改数据处理逻辑,遍历所有子部分,为每个子部分生成一个dataset:

const prepareCombinedChartData = () => {
  // 评分标签保持不变
  const labels = ['Strongly Disagree', 'Disagree', 'Neutral', 'Agree', 'Strongly Agree'];
  
  // 为每个子部分生成数据集
  const datasets = sectionsToDisplay.map(sectionName => {
    // 复用原有的计数函数
    const ratingCounts = calculateRatingCounts(sectionName as keyof FeedbackDataType);
    // 按标签顺序整理数据(1对应Strongly Disagree,5对应Strongly Agree)
    const data = [1,2,3,4,5].map(rating => ratingCounts[rating.toString()]);
    
    return {
      label: sectionName, // 子部分名称作为折线的图例标签
      data: data,
      borderColor: getRandomColor(), // 为每个折线生成随机颜色,也可以自定义固定配色
      fill: false,
      tension: 0.1 // 折线平滑度
    };
  });

  return { labels, datasets };
};

// 辅助函数:生成随机十六进制颜色
const getRandomColor = () => {
  const letters = '0123456789ABCDEF';
  let color = '#';
  for (let i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
};

2. 替换渲染逻辑,使用单个Chart组件

如果用的是react-chartjs-2库,直接渲染一个Line组件并传入合并后的数据:

import { Line } from 'react-chartjs-2';
import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend } from 'chart.js';

// 注册ChartJS所需的核心组件
ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
);

// 替换原来的循环渲染代码
<div className="w-full mb-5">
  <Line 
    data={prepareCombinedChartData()} 
    options={{
      responsive: true,
      plugins: {
        legend: {
          position: 'top', // 图例位置
        },
        title: {
          display: true,
          text: '所有子部分反馈评分趋势' // 图表标题
        }
      }
    }} 
  />
</div>

关键说明

  • 原prepareChartData里的for (let i=1; i<=5)循环是多余的,因为每个sectionName已经对应单个子部分,现在的逻辑直接遍历所有子部分即可。
  • 每个dataset对应一条折线,ChartJS会自动处理图例、tooltip等交互。
  • 可以自定义borderColor来设置固定的配色方案,避免随机颜色的不确定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:05:55