diff --git a/packages/vscale/__tests__/band.test.ts b/packages/vscale/__tests__/band.test.ts index 47258ca..2860cae 100644 --- a/packages/vscale/__tests__/band.test.ts +++ b/packages/vscale/__tests__/band.test.ts @@ -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 () { diff --git a/packages/vscale/src/band-scale.ts b/packages/vscale/src/band-scale.ts index 76d6e71..5ec4ed1 100644 --- a/packages/vscale/src/band-scale.ts +++ b/packages/vscale/src/band-scale.ts @@ -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, @@ -26,6 +26,7 @@ export class BandScale extends OrdinalScale implements IBandLikeScale { protected _paddingOuter: number; protected _align: number; protected _range: Array; + protected _bandRangeState?: { reverse: boolean; start: number; count: number }; constructor(slience?: boolean) { super(); @@ -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 @@ -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 { @@ -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);