Files
railwaysystem/RuoYi-Vue/ruoyi-ui/node_modules1/@antv/scale/src/util/d3-linear.ts
T
2026-09-10 15:40:10 +08:00

124 lines
3.2 KiB
TypeScript

import { ScaleConfig } from '../types';
export default function d3Linear(cfg: ScaleConfig): number[] {
const { min, max, nice, tickCount } = cfg;
const linear = new D3Linear();
linear.domain([min, max]);
if (nice) {
linear.nice(tickCount);
}
return linear.ticks(tickCount);
}
const DEFAULT_COUNT = 5;
const e10 = Math.sqrt(50);
const e5 = Math.sqrt(10);
const e2 = Math.sqrt(2);
// https://github.com/d3/d3-scale
export class D3Linear {
private _domain: number[] = [0, 1];
public domain(domain?: number[]): D3Linear | number[] {
if (domain) {
this._domain = Array.from(domain, Number);
return this;
}
return this._domain.slice();
}
public nice(count = DEFAULT_COUNT) {
const d = this._domain.slice();
let i0 = 0;
let i1 = this._domain.length - 1;
let start = this._domain[i0];
let stop = this._domain[i1];
let step;
if (stop < start) {
[start, stop] = [stop, start];
[i0, i1] = [i1, i0];
}
step = tickIncrement(start, stop, count);
if (step > 0) {
start = Math.floor(start / step) * step;
stop = Math.ceil(stop / step) * step;
step = tickIncrement(start, stop, count);
} else if (step < 0) {
start = Math.ceil(start * step) / step;
stop = Math.floor(stop * step) / step;
step = tickIncrement(start, stop, count);
}
if (step > 0) {
d[i0] = Math.floor(start / step) * step;
d[i1] = Math.ceil(stop / step) * step;
this.domain(d);
} else if (step < 0) {
d[i0] = Math.ceil(start * step) / step;
d[i1] = Math.floor(stop * step) / step;
this.domain(d);
}
return this;
}
public ticks(count = DEFAULT_COUNT): number[] {
return d3ArrayTicks(this._domain[0], this._domain[this._domain.length - 1], count || DEFAULT_COUNT);
}
}
function d3ArrayTicks(start: number, stop: number, count: number): number[] {
let reverse;
let i = -1;
let n;
let ticks;
let step;
(stop = +stop), (start = +start), (count = +count);
if (start === stop && count > 0) {
return [start];
}
// tslint:disable-next-line
if ((reverse = stop < start)) {
(n = start), (start = stop), (stop = n);
}
// tslint:disable-next-line
if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) {
return [];
}
if (step > 0) {
start = Math.ceil(start / step);
stop = Math.floor(stop / step);
ticks = new Array((n = Math.ceil(stop - start + 1)));
while (++i < n) {
ticks[i] = (start + i) * step;
}
} else {
start = Math.floor(start * step);
stop = Math.ceil(stop * step);
ticks = new Array((n = Math.ceil(start - stop + 1)));
while (++i < n) {
ticks[i] = (start - i) / step;
}
}
if (reverse) {
ticks.reverse();
}
return ticks;
}
function tickIncrement(start: number, stop: number, count: number): number {
const step = (stop - start) / Math.max(0, count);
const power = Math.floor(Math.log(step) / Math.LN10);
const error = step / Math.pow(10, power);
return power >= 0
? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)
: -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
}