比例因子的计算

时间:2019-11-03 13:50:41

标签: javascript

我有多个带有最小值和最大值的数值。假定最小值应以5px的圆圈显示,最大值应以50px的圆圈显示,我需要为所有其他值计算比例因子。

50 / maxValue * value

...效果不佳,因为它没有考虑最小值。

const array = [5, 20, 50, 100]
const min = 5 // => 5px
const max = 100 // => 50px

3 个答案:

答案 0 :(得分:0)

使用所谓的Linear Interpolation方法。

以下功能带有3个参数:

  • a:起始值
  • b:目标值
  • amount:用于控制线性插值的标准值或实际值(0到1之间的百分比)
function mix(a, b, amount) {
  return (1 - amount) * a + amount * b
}

想象一下从A到B的直线,并在其上画了一个圆圈:

A ---- o --------------------------- B

  • 如果您的正常值等于1,则圆圈将立即从A切换为B。
  • 如果您的正常值等于0,圆将不会移动。
  • 法线越接近0,插值就越平滑。
  • 法线越接近1,插值就越清晰。
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>