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

D3.js图表问题:仅一个圆形可见其余超出SVG高度

Troubleshooting: Only One Circle Visible in D3.js SVG

Hey there! Let's figure out why only one of your circles is showing up—this is a super common gotcha with D3.js and SVG coordinate systems.

The Root Cause

Chances are, you're not using a scale to map your score data values to the actual height of your SVG container. Here's the breakdown:

  • Your internal SVG height (after margins) is 500 - 40 - 40 = 420 pixels.
  • Your score values range from 100 all the way up to 2000. If you're setting cy directly to d.score, any score over 420 will place the circle below the visible area of your SVG. Only the smallest score (100) would land within the 0-420 pixel range, hence only one circle showing up.
  • On top of that, SVG's y-axis starts at the top (y=0 is the top edge), so even if you did fit values, your largest scores would be at the bottom unless you reverse the scale.

Fix Steps

Let's walk through the corrections you need to make:

  1. Add a Linear Scale for the Y-Axis
    Create a scale that maps your score data domain to the pixel range of your SVG. We'll reverse the range so larger scores appear higher up (more intuitive for most charts):

    // Calculate the min/max of your score data
    const scoreExtent = d3.extent(data, d => d.score);
    // Create the y-scale
    const yScale = d3.scaleLinear()
      .domain(scoreExtent) // Data range: [100, 2000]
      .range([height, 0]); // SVG pixel range: bottom (height) to top (0)
    
  2. Use the Scale to Position Circles
    When setting the cy attribute for your circles, use the scale instead of the raw score value:

    // First, make sure your SVG is set up with margins correctly
    const svg = d3.select("body")
      .append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", `translate(${margin.left}, ${margin.top})`);
    
    // Now draw the circles
    svg.selectAll("circle")
      .data(data)
      .enter()
      .append("circle")
      .attr("cx", d => {
        // Add an x-scale for age to spread circles horizontally
        const xScale = d3.scaleLinear()
          .domain(d3.extent(data, d => d.age))
          .range([0, width]);
        return xScale(d.age);
      })
      .attr("cy", d => yScale(d.score)) // Use the y-scale here!
      .attr("r", 8)
      .attr("fill", "#2c3e50");
    
  3. Verify SVG Container Size
    Double-check that your main SVG element includes the margin values in its total width/height. If you forget this, even scaled elements might get clipped at the edges.

Why This Works

  • The scale compresses your large score values (like 2000) down to fit within the 0-420 pixel height of your SVG's internal group.
  • Reversing the range([height, 0]) ensures that higher scores are positioned near the top of the SVG, which matches how we typically read charts.

Give this a try, and all your circles should show up properly within the SVG bounds!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:09:38