Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: optimize the performance of band-scale #152

Merged
merged 1 commit into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/vscale/__tests__/band.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,12 @@ test('band.range(values) makes a copy of the specified range values', function (
expect(s.range()).toEqual([1, 2]);
});

test('band.range() returns a copy of the range', function () {
test('band.range() should not returns a copy of the range', function () {
const s = new BandScale().range([1, 2]);
const range = s.range();
expect(range).toEqual([1, 2]);
range.push('blue');
expect(s.range()).toEqual([1, 2]);
expect(s.range()).toEqual([1, 2, 'blue']);
});

test('band.range(values) accepts an iterable', function () {
Expand Down
45 changes: 37 additions & 8 deletions packages/vscale/src/band-scale.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { range, toNumber, isGreater, isLess, isNumber, isValid, isNil } from '@visactor/vutils';
import { OrdinalScale } from './ordinal-scale';
import { toNumber, isGreater, isLess, isNumber, isValid, isNil } from '@visactor/vutils';
import { OrdinalScale, implicit } from './ordinal-scale';
import {
bandSpace,
calculateBandwidthFromWholeRangeSize,
Expand All @@ -26,6 +26,7 @@ export class BandScale extends OrdinalScale implements IBandLikeScale {
protected _paddingOuter: number;
protected _align: number;
protected _range: Array<number>;
protected _bandRangeState?: { reverse: boolean; start: number; count: number };

constructor(slience?: boolean) {
super();
Expand Down Expand Up @@ -69,16 +70,44 @@ export class BandScale extends OrdinalScale implements IBandLikeScale {
this._bandwidth = Math.round(this._bandwidth);
}
}
const values = range(n).map((i: number) => {
return start + this._step * i;
});
super.range(reverse ? values.reverse() : values);

this._bandRangeState = {
reverse,
start: reverse ? start + this._step * (n - 1) : start,
count: n
};

this.generateFishEyeTransform();

return this;
}

scale(d: any): any {
if (!this._bandRangeState) {
return undefined;
}
const key = `${d}`;
const special = this._getSpecifiedValue(key);
if (special !== undefined) {
return special;
}
let i = this._index.get(key);
if (!i) {
if (this._unknown !== implicit) {
return this._unknown;
}
// TODO checkPoint
i = this._domain.push(d);
this._index.set(key, i);
}
const { count, start, reverse } = this._bandRangeState;
const stepIndex = (i - 1) % count;

const output = start + (reverse ? -1 : 1) * stepIndex * this._step;

return this._fishEyeTransform ? this._fishEyeTransform(output) : output;
}

/**
* 根据可见 range 计算 scale 的整体 range
* @param range 可见 range
Expand Down Expand Up @@ -209,7 +238,7 @@ export class BandScale extends OrdinalScale implements IBandLikeScale {
this._range = [toNumber(_[0]), toNumber(_[1])];
return this.rescale(slience);
}
return this._range.slice();
return this._range;
}

rangeRound(_: any[], slience?: boolean): this {
Expand All @@ -223,7 +252,7 @@ export class BandScale extends OrdinalScale implements IBandLikeScale {

if (count === -1) {
// return domain as ticks when count is -1
return d.slice();
return d;
}

const tickIndexList = ticks(0, d.length - 1, count, false);
Expand Down