如何将D3.js中scalePow的顶点(Scheitelpunkt)设置为指定值(如6000)
调整D3幂比例尺的顶点至指定值(6000)
原代码中的d3.scalePow().exponent(2)默认以定义域左端点作为二次映射的顶点(即您所说的Scheitelpunkt),当前逻辑下2000对应映射的"峰值"位置。要将顶点移到6000,让该数值附近的映射间隔更大、两端间隔更窄,需要自定义二次映射逻辑——原生scalePow不支持直接指定顶点位置。
解决方案:自定义顶点中心的二次比例尺
核心思路是构建开口向下的抛物线映射,以6000为顶点,将定义域[2000,10000]映射至值域[600,0]:
- 输入值为6000时,映射结果为600(值域最大值,对应顶点)
- 输入值离6000越远,映射结果越接近0,且变化速率逐渐减慢
实现代码如下:
// 定义核心参数 const apex = 6000; // 目标顶点 const inputDomain = [2000, 10000]; const outputRange = [600, 0]; // 计算顶点到定义域两端的最大距离,保证偏移区间对称 const maxOffset = Math.max(apex - inputDomain[0], inputDomain[1] - apex); // 创建自定义二次比例尺 this.y = d3.scaleLinear() .domain(inputDomain) .range([-maxOffset, maxOffset]) // 先映射到以顶点为中心的对称偏移区间 .clamp(true) // 限制输入值在定义域范围内 .interpolate(function() { return function(offset) { // 二次变换:偏移量的平方运算,确保离顶点越远变化率越低 const normalized = 1 - Math.pow(Math.abs(offset) / maxOffset, 2); // 映射到目标值域 return outputRange[0] + normalized * (outputRange[1] - outputRange[0]); }; });
代码说明
- 偏移转换:将输入值转换为相对于顶点6000的偏移量,把原定义域[2000,10000]转换成对称的偏移区间[-4000,4000]
- 二次变换:对偏移量取绝对值后做平方运算,实现"顶点附近映射间隔大、两端间隔窄"的效果
- 值域映射:将变换后的数值映射到目标值域[600,0],保证顶点6000对应值域最大值600,两端对应0
测试验证
console.log(this.y(2000)); // 输出 0 console.log(this.y(6000)); // 输出 600 console.log(this.y(10000)); // 输出 0 console.log(this.y(5000)); // 输出 375(比原逻辑的映射值更接近600,间隔更大) console.log(this.y(7000)); // 输出 375(与5000对称)
内容的提问来源于stack exchange,提问作者efkah
相关产品推荐
相关产品推荐

