创建由多个域组成的比例

时间:2019-03-02 19:48:52

标签: d3.js

如何定义由一个域组成的多个域的D3标尺?

示例

在此示例中,我有3个大小不同的域,我希望它们转换为相等范围的三分之一。

我想做什么:

const yScale = linearScale()
  .domain([ [0, 10], [11, 50], [51, 500] ])
  .range([0, 100])

我目前正在做什么:

const yScale1 = linearScale().domain([0, 10]).range([0, 33]);
const yScale2 = linearScale().domain([11, 50]).range([34, 66]);
const yScale3 = linearScale().domain([51, 500]).range([67, 100]);

if (val > 51) { 
  return yScale3(val);
} else if (val > 11) { 
  return yScale2(val);
} else {
  return yScale1(val);
}

1 个答案:

答案 0 :(得分:2)

D3线性刻度允许您传递域和范围的多个值。如API中所述:

  

尽管连续刻度通常在其域和范围中每个都有两个值,但指定两个以上的值会产生分段刻度。

您的情况是:

const scale = d3.scaleLinear()
    .domain([0,10,50,500])
    .range([0, 33.3, 66.6, 100]);

或者,使用D3 v5.8速记的单行代码:

const scale = d3.scaleLinear([0,10,50,500], [0, 33.3, 66.6, 100]);

让我们看看它的作用:

const svg = d3.select("svg");
const scale = d3.scaleLinear()
  .domain([0, 10, 50, 500])
  .range([0, 33.3, 66.6, 100]);
const circles = svg.selectAll(null)
  .data(d3.range(0, 500, 2))
  .enter()
  .append("circle")
  .attr("r", 2)
  .attr("cx", (_, i) => 5 + i * 2 + 1)
  .attr("cy", d => 105 - scale(d));
svg {
  background-color: wheat;
}

circle {
  fill: none;
  stroke: gray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="510" height="110"></svg>

当然,更好的做法是根据域中元素的数量动态创建范围:

const scale = d3.scaleLinear()
  .domain([0, 10, 50, 500]);

scale.range(d3.range(0, 100 + 100 / (scale.domain().length - 1), 100 / (scale.domain().length - 1)))

console.log(scale.range())
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>