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

React+D3.js分组堆叠柱状图渲染异常及坐标轴不显示求助

分组堆叠柱状图渲染异常问题

图表显示异常

我尝试为每个年份标签创建分组堆叠柱状图,分为acsGap、qtiGap、qliGap三组,每组包含high和low值,预期生成总计9个图表,但不确定问题出在哪里。

import React, { useEffect, useRef } from 'react';
import * as d3 from 'd3';
import jsonData from "../src/data2.json";

const StackedBarChart = () => {
  const svgRef = useRef();
  const barWidth = 20;
  const chartWidth = 1048;
  const chartHeight = 200;

  useEffect(() => {
    const margin = { top: 32, right: 64, bottom: 24, left: 64 };

    // JSON 데이터 로드
    const data = jsonData.age;
    const dataLabels = ["acsGap", "qtiGap", "qliGap"];
    const dataColumns = ["high", "low"];

    const bar_data = data.map(age => {
      let bar_data = [];
      // let parameter = 0;

      dataLabels.forEach(label => {
        if (age[label]) {
          let accuValue = 0;
          dataColumns.forEach(column => {
            if (age[label][column]) {
              let realValue = age[label][column];
              accuValue += realValue;

              bar_data.push({
                x: dataColumns.indexOf(column) * (barWidth / 3), // Adjust x position based on column index
                y: accuValue,
                height: realValue,
                type: column,
              });
            }
            //parameter += 1;
          });
        }
      });

      return bar_data;
    });
    console.log(bar_data);
    // 색상 스케일 정의
    const color = d3.scaleOrdinal()
      .domain(dataColumns)
      .range(['#008000', '#FFFF00']);

    // x, y 스케일 정의
    const x_scale = d3.scaleBand()
      .domain(data.map(d => d.label))
      .range([margin.left, chartWidth - margin.right])
      .padding(0.3);

    const y_scale = d3.scaleLinear()
      .domain([0, d3.max(bar_data.flat(), d => d.y + d.height)])
      .range([chartHeight - margin.bottom, margin.top]);

    // SVG 요소 선택
    const svg = d3.create('svg')
      .attr("width", chartWidth)
      .attr("height", chartHeight);

    let gSvg = svg.append("g").attr("transform", "translate(" + margin.left / 2 + "," + margin.top +")");

    // 각 연도별로 그룹 생성
    const yearGroups = gSvg.selectAll('g')
      .data(bar_data)
      .enter()
      .append('g')
      .attr("transform", (d, i) => "translate(" + x_scale(i) + "," + (chartHeight - margin.bottom) + ")");

    // 각 그룹 내에서 누적 막대 그래프 생성
    yearGroups.selectAll('rect')
      .data(d => d)
      .enter()
      .append('rect')
      .attr("y", d => y_scale(0))
      .transition()
      .duration(1500)
      .attr('x', d => d.x)
      .attr('y', d => y_scale(d.y))
      .attr('width', barWidth / 3)
      .attr('height', d => y_scale(0) - y_scale(d.height))
      .style("fill", d => color(d.type));

    // 가로 축 추가
    svg.append('g')
      .attr('transform', `translate(0, ${chartHeight - margin.bottom})`)
      .call(d3.axisBottom(x_scale));

    // 세로 축 추가
    svg.append('g')
      .call(d3.axisLeft(y_scale));

    svgRef.current.appendChild(svg.node());

  }, []);

  return (
    <svg ref={svgRef}></svg>
  );
};

export default StackedBarChart;
{
    "age": [
        {"label" : "2005",
        "acsGap" : {"high": 111, "low": 47},
        "qtiGap": {"high": 152, "low": 34},
        "qliGap": {"high": 152, "low": 30}},

        {"label" : "2018",
        "acsGap" : {"high": 127, "low": 90},
        "qtiGap": {"high": 142, "low": 50},
        "qliGap": {"high": 127, "low": 62}},

        {"label" : "2022",
        "acsGap" : {"high": 105, "low": 95},
        "qtiGap": {"high": 145, "low": 55},
        "qliGap": {"high": 145, "low": 73}}],

    "lncome" : [
        {"label" : "2005",
        "acsGap" : {"high": 111, "low": 70},
        "qtiGap": {"high": 128, "low": 61},
        "qliGap": {"high": 145, "low": 57}},

        {"label" : "2018",
        "acsGap" : {"high": 113, "low": 95},
        "qtiGap": {"high": 116, "low": 85},
        "qliGap": {"high": 113, "low": 84}},

        {"label" : "2022",
        "acsGap" : {"high": 103, "low": 99},
        "qtiGap": {"high": 116, "low": 93},
        "qliGap": {"high": 116, "low": 96}}],

    "job" : [
        {"label" : "2005",
        "acsGap" : {"high": 113, "low": 58},
        "qtiGap": {"high": 145, "low": 32},
        "qliGap": {"high": 163, "low": 26}},

        {"label" : "2018",
        "acsGap" : {"high": 122, "low": 91},
        "qtiGap": {"high": 130, "low": 63},
        "qliGap": {"high": 122, "low": 66}},

        {"label" : "2022",
        "acsGap" : {"high": 105, "low": 96},
        "qtiGap": {"high": 134, "low": 70},
        "qliGap": {"high": 134, "low": 79}}]    

}

如附图所示,图表未能正确显示,我也不清楚x轴和y轴未渲染的原因。


内容的提问来源于stack exchange,提问作者김주영

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 03:40:54