54 lines
1.1 KiB
JavaScript
54 lines
1.1 KiB
JavaScript
|
class RelativeScale {
|
||
|
static scale (data, tickCount) {
|
||
|
const [min, max] = RelativeScale.calculateBounds(data)
|
||
|
|
||
|
let factor = 1
|
||
|
|
||
|
while (true) {
|
||
|
const scale = Math.pow(10, factor)
|
||
|
|
||
|
const scaledMin = min - (min % scale)
|
||
|
const scaledMax = max + (max % scale === 0 ? 0 : (scale - (max % scale)))
|
||
|
|
||
|
const ticks = (scaledMax - scaledMin) / scale
|
||
|
|
||
|
if (ticks + 1 <= tickCount) {
|
||
|
return [scaledMin, scaledMax, scale]
|
||
|
} else {
|
||
|
// Too many steps between min/max, increase factor and try again
|
||
|
factor++
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static generateTicks (min, max, step) {
|
||
|
const ticks = []
|
||
|
for (let i = min; i <= max; i += step) {
|
||
|
ticks.push(i)
|
||
|
}
|
||
|
return ticks
|
||
|
}
|
||
|
|
||
|
static calculateBounds (data) {
|
||
|
if (data.length === 0) {
|
||
|
return [0, 0]
|
||
|
} else {
|
||
|
let min = Number.MAX_VALUE
|
||
|
let max = Number.MIN_VALUE
|
||
|
|
||
|
for (const point of data) {
|
||
|
if (point > max) {
|
||
|
max = point
|
||
|
}
|
||
|
if (point < min) {
|
||
|
min = point
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return [min, max]
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = RelativeScale
|