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

在react-chartjs-2中正确展示后端返回JSON数据为柱状图的实现问题

Fixing Your Bar Chart Data Mapping Issue

Let's break down what's going wrong with your current code and fix it step by step. The core problem is that you're creating a new dataset entry for every single data point, and each dataset's data array only has one value—no alignment to the correct constituency index. Here's how to adjust the logic to map counts to the right positions:

Step 1: Restructure the Data Mapping Logic

We need to:

  • First collect all unique constituencies and create a lookup for their index in the labels array
  • Initialize each candidate's dataset with zeros for every constituency
  • Then fill in the actual counts based on the raw data

Here's the revised code:

const generateGraph = (data) => {
  // 1. Collect unique constituencies and create an ID-to-index lookup
  const constituencyMap = new Map();
  const conArr = [];
  
  // First pass to get all unique constituencies from the data
  data.forEach(d => {
    if (!constituencyMap.has(d.constituencyId)) {
      const con = constituencies.find(c => c.constituencyId === d.constituencyId);
      if (con) {
        constituencyMap.set(d.constituencyId, conArr.length);
        conArr.push(con.name);
      }
    }
  });

  // 2. Initialize datasets for each unique candidate, with 0s for all constituencies
  const candidateMap = new Map();
  const canArr = [];
  
  data.forEach(d => {
    const can = candidates.find(c => c.candidateId === d.candidateId);
    if (!can) return;
    
    const candidateKey = can.candidateId;
    if (!candidateMap.has(candidateKey)) {
      // Create dataset with 0s matching the length of constituencies
      const newDataset = {
        label: `${can.lastName}, ${can.firstName}`,
        data: Array(conArr.length).fill(0)
      };
      candidateMap.set(candidateKey, canArr.length);
      canArr.push(newDataset);
    }
    
    // 3. Fill in the actual count at the correct constituency index
    const constituencyIndex = constituencyMap.get(d.constituencyId);
    const datasetIndex = candidateMap.get(candidateKey);
    canArr[datasetIndex].data[constituencyIndex] = d.count;
  });

  const chartData = {
    labels: conArr,
    datasets: canArr,
  };
  return chartData;
};

Why This Works

  • Constituency Lookup: We use a Map to store each constituency ID's position in the labels array. This lets us quickly find where to place a count for any given constituency.
  • Zero-Initialized Datasets: Each candidate's dataset starts with an array of zeros that matches the number of constituencies. This ensures every constituency has a value (even 0) for every candidate.
  • Targeted Count Assignment: For each data point, we find the correct constituency index and candidate dataset, then replace the 0 with the actual count.

Example Output

Using your sample scenario where:

  • Person 1 has a count of 1 in Constituency A
  • Person 2 has a count of 1 in Constituency B

The generated chartData will be exactly what you need:

{
  labels: ["A", "B"],
  datasets: [
    { label: "Person 1", data: [1, 0] },
    { label: "Person 2", data: [0, 1] }
  ]
}

This will render correctly: Person 1's bar shows up in Constituency A, Person 2's bar shows up in Constituency B, and empty positions show 0 (no bar, or a bar with height 0 depending on your chart config).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 20:32:29