Skip to content

Commit b810646

Browse files
committed
refactor: less copy-paste code
1 parent 76d1816 commit b810646

File tree

4 files changed

+105
-99
lines changed

4 files changed

+105
-99
lines changed

src/component/dataZoom/SliderZoomView.ts

Lines changed: 51 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import {bind, each, isFunction, isString, indexOf} from 'zrender/src/core/util';
2121
import * as eventTool from 'zrender/src/core/event';
22+
import { Dictionary } from 'zrender/src/core/types';
2223
import * as graphic from '../../util/graphic';
2324
import * as throttle from '../../util/throttle';
2425
import DataZoomView from './DataZoomView';
@@ -43,6 +44,7 @@ import { PointLike } from 'zrender/src/core/Point';
4344
import Displayable from 'zrender/src/graphic/Displayable';
4445
import {createTextStyle} from '../../label/labelStyle';
4546
import SeriesData from '../../data/SeriesData';
47+
import { doDataSampling } from '../../processor/dataSample';
4648

4749
const Rect = graphic.Rect;
4850

@@ -384,91 +386,75 @@ class SliderZoomView extends DataZoomView {
384386
];
385387
const otherShadowExtent = [0, size[1]];
386388
const thisShadowExtent = [0, size[0]];
389+
390+
const areaPoints = [[size[0], 0], [0, 0]];
391+
const linePoints: number[][] = [];
392+
387393
let lastIsEmpty: boolean;
388394

389395
// Optimize for large data shadow
390396
const stride = Math.round(data.count() / size[0]);
391397
const coordSys = seriesModel.coordinateSystem;
392398
const sampling = this.dataZoomModel.get('sampling');
393-
if (data.count() > 10 && coordSys.type === 'cartesian2d' && (sampling && sampling !== 'none')) {
394-
const baseAxis = coordSys.getBaseAxis();
395-
const valueAxis = coordSys.getOtherAxis(baseAxis);
399+
let sampledData = data;
396400

397-
let downsampled = data;
398-
if (sampling === 'lttb') {
399-
downsampled = data.lttbDownSample(data.mapDimension(valueAxis.dim), 1 / stride);
401+
let useOldSampling = true;
402+
if (data.count() > 10 && coordSys.type === 'cartesian2d' && (sampling && sampling !== 'none')) {
403+
const downsampled = doDataSampling(
404+
data,
405+
sampling,
406+
seriesModel.coordinateSystem,
407+
this.api.getDevicePixelRatio()
408+
);
409+
if (downsampled) {
410+
useOldSampling = false;
411+
sampledData = downsampled;
400412
}
401-
// TODO: 支持其他类型的 sampling
402-
403-
const lp = [[size[0], 0], [0, 0]];
404-
const ap: number[][] = [];
405-
downsampled.each([otherDim], function (value: ParsedValue, index) {
406-
const isEmpty = value == null || isNaN(value as number) || value === '';
407-
// See #4235.
408-
const otherCoord = isEmpty
409-
? 0 : linearMap(value as number, otherDataExtent, otherShadowExtent, true);
410-
411-
// Attempt to draw data shadow precisely when there are empty value.
412-
if (isEmpty && !lastIsEmpty && index) {
413-
ap.push([ap[ap.length - 1][0], 0]);
414-
lp.push([lp[lp.length - 1][0], 0]);
415-
}
416-
else if (!isEmpty && lastIsEmpty) {
417-
ap.push([index, 0]);
418-
lp.push([index, 0]);
419-
}
420-
421-
ap.push([index, otherCoord]);
422-
lp.push([index, otherCoord]);
423-
424-
lastIsEmpty = isEmpty;
425-
});
426-
427-
polygonPts = this._shadowPolygonPts = ap;
428-
polylinePts = this._shadowPolylinePts = lp;
429413
}
430-
else {
431-
const areaPoints = [[size[0], 0], [0, 0]];
432-
const linePoints: number[][] = [];
433-
const step = thisShadowExtent[1] / (data.count() - 1);
434-
let thisCoord = 0;
435414

436-
data.each([otherDim], function (value: ParsedValue, index) {
415+
const step = thisShadowExtent[1] / (data.count() - 1);
416+
let thisCoord = 0;
417+
418+
sampledData.each([otherDim], function (value: ParsedValue, index) {
419+
if (useOldSampling) {
437420
if (stride > 0 && (index % stride)) {
438421
thisCoord += step;
439422
return;
440423
}
424+
}
425+
else {
426+
thisCoord = index;
427+
}
441428

442-
// FIXME
443-
// Should consider axis.min/axis.max when drawing dataShadow.
429+
// FIXME
430+
// Should consider axis.min/axis.max when drawing dataShadow.
444431

445-
// FIXME
446-
// 应该使用统一的空判断?还是在list里进行空判断?
447-
const isEmpty = value == null || isNaN(value as number) || value === '';
448-
// See #4235.
449-
const otherCoord = isEmpty
450-
? 0 : linearMap(value as number, otherDataExtent, otherShadowExtent, true);
432+
// FIXME
433+
// 应该使用统一的空判断?还是在list里进行空判断?
434+
const isEmpty = value == null || isNaN(value as number) || value === '';
435+
// See #4235.
436+
const otherCoord = isEmpty
437+
? 0 : linearMap(value as number, otherDataExtent, otherShadowExtent, true);
451438

452-
// Attempt to draw data shadow precisely when there are empty value.
453-
if (isEmpty && !lastIsEmpty && index) {
454-
areaPoints.push([areaPoints[areaPoints.length - 1][0], 0]);
455-
linePoints.push([linePoints[linePoints.length - 1][0], 0]);
456-
}
457-
else if (!isEmpty && lastIsEmpty) {
458-
areaPoints.push([thisCoord, 0]);
459-
linePoints.push([thisCoord, 0]);
460-
}
439+
// Attempt to draw data shadow precisely when there are empty value.
440+
if (isEmpty && !lastIsEmpty && index) {
441+
areaPoints.push([areaPoints[areaPoints.length - 1][0], 0]);
442+
linePoints.push([linePoints[linePoints.length - 1][0], 0]);
443+
}
444+
else if (!isEmpty && lastIsEmpty) {
445+
areaPoints.push([thisCoord, 0]);
446+
linePoints.push([thisCoord, 0]);
447+
}
461448

462-
areaPoints.push([thisCoord, otherCoord]);
463-
linePoints.push([thisCoord, otherCoord]);
449+
areaPoints.push([thisCoord, otherCoord]);
450+
linePoints.push([thisCoord, otherCoord]);
464451

465-
thisCoord += step;
466-
lastIsEmpty = isEmpty;
467-
});
452+
thisCoord += step;
453+
lastIsEmpty = isEmpty;
454+
});
468455

469-
polygonPts = this._shadowPolygonPts = areaPoints;
470-
polylinePts = this._shadowPolylinePts = linePoints;
471-
}
456+
polygonPts = this._shadowPolygonPts = areaPoints;
457+
polylinePts = this._shadowPolylinePts = linePoints;
472458

473459
}
474460
this._shadowData = data;

src/processor/dataSample.ts

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
* under the License.
1818
*/
1919

20-
import { StageHandler, SeriesOption, SeriesSamplingOptionMixin } from '../util/types';
20+
import { StageHandler, SeriesOption, SeriesSamplingOptionMixin, SamplingValues } from '../util/types';
2121
import { Dictionary } from 'zrender/src/core/types';
2222
import SeriesModel from '../model/Series';
2323
import { isFunction, isString } from 'zrender/src/core/util';
24+
import SeriesData from '../data/SeriesData';
25+
import { CoordinateSystem } from '../coord/CoordinateSystem';
2426

2527

2628
type Sampler = (frame: ArrayLike<number>) => number;
@@ -72,6 +74,44 @@ const indexSampler = function (frame: ArrayLike<number>) {
7274
return Math.round(frame.length / 2);
7375
};
7476

77+
export function doDataSampling(
78+
data: SeriesData,
79+
sampling: SamplingValues,
80+
coordSys: CoordinateSystem,
81+
dpr: number
82+
) {
83+
const count = data.count();
84+
// Only cartesian2d support down sampling. Disable it when there is few data.
85+
if (count > 10 && coordSys.type === 'cartesian2d' && sampling) {
86+
const baseAxis = coordSys.getBaseAxis();
87+
const valueAxis = coordSys.getOtherAxis(baseAxis);
88+
const extent = baseAxis.getExtent();
89+
// Coordinste system has been resized
90+
const size = Math.abs(extent[1] - extent[0]) * (dpr || 1);
91+
const rate = Math.round(count / size);
92+
93+
if (isFinite(rate) && rate > 1) {
94+
if (sampling === 'lttb') {
95+
return data.lttbDownSample(data.mapDimension(valueAxis.dim), 1 / rate);
96+
}
97+
let sampler;
98+
if (isString(sampling)) {
99+
sampler = samplers[sampling];
100+
}
101+
else if (isFunction(sampling)) {
102+
sampler = sampling;
103+
}
104+
if (sampler) {
105+
// Only support sample the first dim mapped from value axis.
106+
return data.downSample(
107+
data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler
108+
);
109+
}
110+
}
111+
}
112+
return null;
113+
}
114+
75115
export default function dataSample(seriesType: string): StageHandler {
76116
return {
77117

@@ -84,36 +124,11 @@ export default function dataSample(seriesType: string): StageHandler {
84124
const data = seriesModel.getData();
85125
const sampling = seriesModel.get('sampling');
86126
const coordSys = seriesModel.coordinateSystem;
87-
const count = data.count();
88-
// Only cartesian2d support down sampling. Disable it when there is few data.
89-
if (count > 10 && coordSys.type === 'cartesian2d' && sampling) {
90-
const baseAxis = coordSys.getBaseAxis();
91-
const valueAxis = coordSys.getOtherAxis(baseAxis);
92-
const extent = baseAxis.getExtent();
93-
const dpr = api.getDevicePixelRatio();
94-
// Coordinste system has been resized
95-
const size = Math.abs(extent[1] - extent[0]) * (dpr || 1);
96-
const rate = Math.round(count / size);
97-
98-
if (isFinite(rate) && rate > 1) {
99-
if (sampling === 'lttb') {
100-
seriesModel.setData(data.lttbDownSample(data.mapDimension(valueAxis.dim), 1 / rate));
101-
}
102-
let sampler;
103-
if (isString(sampling)) {
104-
sampler = samplers[sampling];
105-
}
106-
else if (isFunction(sampling)) {
107-
sampler = sampling;
108-
}
109-
if (sampler) {
110-
// Only support sample the first dim mapped from value axis.
111-
seriesModel.setData(data.downSample(
112-
data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler
113-
));
114-
}
115-
}
127+
const dpr = api.getDevicePixelRatio();
128+
const resampled = doDataSampling(data, sampling, coordSys, dpr);
129+
if (resampled) {
130+
seriesModel.setData(resampled);
116131
}
117132
}
118133
};
119-
}
134+
}

src/util/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1673,8 +1673,9 @@ export interface SeriesStackOptionMixin {
16731673

16741674
type SamplingFunc = (frame: ArrayLike<number>) => number;
16751675

1676+
export type SamplingValues = 'none' | 'average' | 'min' | 'max' | 'sum' | 'lttb' | SamplingFunc;
16761677
export interface SeriesSamplingOptionMixin {
1677-
sampling?: 'none' | 'average' | 'min' | 'max' | 'sum' | 'lttb' | SamplingFunc
1678+
sampling?: SamplingValues
16781679
}
16791680

16801681
export interface SeriesEncodeOptionMixin {

test/dataZoom-sampling.html

Lines changed: 6 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)