我有多个带有最小值和最大值的数值。假定最小值应以5px的圆圈显示,最大值应以50px的圆圈显示,我需要为所有其他值计算比例因子。
50 / maxValue * value
...效果不佳,因为它没有考虑最小值。
const array = [5, 20, 50, 100]
const min = 5 // => 5px
const max = 100 // => 50px
答案 0 :(得分:0)
使用所谓的Linear Interpolation方法。
以下功能带有3个参数:
function mix(a, b, amount) {
return (1 - amount) * a + amount * b
}
想象一下从A到B的直线,并在其上画了一个圆圈:
A ---- o --------------------------- B
const array = [5, 20, 50, 100]
const minpx = 5 // => 5px
const maxpx = 50 // => 50px
const min = Math.min(...array) // 5
const max = Math.max(...array) // 100
function mix(a, b, amount) {
return (1 - amount) * a + amount * b
}
array.map(value => mix(minpx, maxpx, (value-min) / (max-min)))
// [ 5, 12.105263157894736, 26.31578947368421, 50 ]
答案 1 :(得分:0)
const array = [5, 20, 50, 100]
const minpx = 5 // => 5px
const maxpx = 50 // => 50px
let max = Math.max(...array)
let min = Math.min(...array)
// (x-min)/(max-min) the ratio
// * (maxpx-minpx) the new range
// + minpx the new offset
let transform = x=>(x-min)/(max-min)*(maxpx-minpx)+minpx
console.log(array.map(transform))
答案 2 :(得分:0)
d3-scale
正是为您做到的。
您只需要创建一个scaleLinear
,定义domain
(输入值范围)和range
(对应的期望输出值)即可。
请看下面的代码片段
const array = [5, 20, 50, 100]
const min = 5 // => 5px
const max = 100 // => 50px
// define the scaling function
const size = d3.scaleLinear()
.domain([min, max])
.range([5, 50])
// call it for each value in the input array
array.forEach(function(val) {
console.log(val, Math.round(size(val)) + 'px')
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/d3-scale@3.2.0/dist/d3-scale.min.js"></script>