You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

D3.js V4版本字符串定义域比例尺选型与实现方法求助

Solution for String-to-Number Scale in D3.js

Got it, let's break down how to create the exact scale you need for drawing those vertical lines.

Step 1: Pick the Right Scale Type

For mapping a discrete set of strings (like ["A", "B", "C", "D", "E"]) to a continuous numerical range ([0, width]), you want d3.scalePoint()—it's purpose-built for this exact use case. Unlike ordinal scales (which map discrete to discrete) or linear scales (continuous to continuous), scalePoint() takes your string domain and evenly spaces each value across your numerical range, returning a single number for each input string.

Step 2: Set Up the Scale

Here's how to initialize the scale correctly:

// Define your domain and range (replace `width` with your actual SVG width)
const scale = d3.scalePoint()
  .domain(["A", "B", "C", "D", "E"])
  .range([0, width])
  .padding(0.1); // Optional: adds space between points so they don't hug the SVG edges

Now calling scale("A") will return the numerical x-position for that category, exactly matching your desired scale(domain: string): number behavior.

Step 3: Draw Your Vertical Lines

You can use D3's data binding to cleanly draw a line for each domain value. Here's the adjusted code (we'll add stroke styling so lines are visible):

// Assuming `svgNode` is your SVG selection, and `height` is your SVG height
svgNode.selectAll('line')
  .data(["A", "B", "C", "D", "E"])
  .enter()
  .append('line')
  .attr('x1', d => Math.round(scale(d)))
  .attr('y1', 0)
  .attr('x2', d => Math.round(scale(d)))
  .attr('y2', height)
  .attr('stroke', '#000') // Add a black stroke
  .attr('stroke-width', 1); // Set line thickness

Alternative: Using d3.scaleBand() (If You Need Category Intervals)

If you later want to add bars or need each category to occupy a range of space, you can use d3.scaleBand() instead. To get the center position of each band (for your vertical line), just add half the band width to the band's start position:

const scale = d3.scaleBand()
  .domain(["A", "B", "C", "D", "E"])
  .range([0, width])
  .padding(0.2); // Controls space between bands

svgNode.selectAll('line')
  .data(["A", "B", "C", "D", "E"])
  .enter()
  .append('line')
  .attr('x1', d => Math.round(scale(d) + scale.bandwidth() / 2))
  .attr('y1', 0)
  .attr('x2', d => Math.round(scale(d) + scale.bandwidth() / 2))
  .attr('y2', height)
  .attr('stroke', '#000');

Key Notes

  • scalePoint() automatically calculates even spacing between your domain values, so you don't have to do the math manually.
  • The padding() method is optional but recommended to prevent your first/last lines from being cut off at the SVG edges.

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

火山引擎 最新活动