Skip to content

Commit c7860d7

Browse files
biggatesAirkro
authored andcommitted
feat(sampling-in-dataZoom): initial commit
1 parent b9f7809 commit c7860d7

File tree

4 files changed

+194
-37
lines changed

4 files changed

+194
-37
lines changed

src/component/dataZoom/SliderZoomModel.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@ import {
2424
LineStyleOption,
2525
AreaStyleOption,
2626
ItemStyleOption,
27-
LabelOption
27+
LabelOption,
28+
SeriesSamplingOptionMixin
2829
} from '../../util/types';
2930
import { inheritDefaultOption } from '../../util/component';
3031

31-
export interface SliderDataZoomOption extends DataZoomOption, BoxLayoutOptionMixin {
32+
export interface SliderDataZoomOption extends
33+
DataZoomOption,
34+
BoxLayoutOptionMixin,
35+
SeriesSamplingOptionMixin {
3236

3337
show?: boolean
3438
/**
@@ -207,8 +211,10 @@ class SliderZoomModel extends DataZoomModel<SliderDataZoomOption> {
207211
moveHandleStyle: {
208212
color: '#8FB0F7'
209213
}
210-
}
214+
},
215+
216+
sampling: 'none'
211217
} as SliderDataZoomOption);
212218
}
213219

214-
export default SliderZoomModel;
220+
export default SliderZoomModel;

src/component/dataZoom/SliderZoomView.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import { PointLike } from 'zrender/src/core/Point';
4343
import Displayable from 'zrender/src/graphic/Displayable';
4444
import {createTextStyle} from '../../label/labelStyle';
4545
import SeriesData from '../../data/SeriesData';
46+
import { doDataSampling } from '../../processor/dataSample';
4647

4748
const Rect = graphic.Rect;
4849

@@ -393,10 +394,34 @@ class SliderZoomView extends DataZoomView {
393394
// Optimize for large data shadow
394395
const stride = Math.round(data.count() / size[0]);
395396
let lastIsEmpty: boolean;
396-
data.each([otherDim], function (value: ParsedValue, index) {
397-
if (stride > 0 && (index % stride)) {
398-
thisCoord += step;
399-
return;
397+
398+
const coordSys = seriesModel.coordinateSystem;
399+
const sampling = this.dataZoomModel.get('sampling');
400+
let sampledData = data;
401+
402+
let useOldSampling = true;
403+
if (data.count() > 10 && coordSys.type === 'cartesian2d' && (sampling && sampling !== 'none')) {
404+
const downsampled = doDataSampling(
405+
data,
406+
sampling,
407+
seriesModel.coordinateSystem,
408+
this.api.getDevicePixelRatio()
409+
);
410+
if (downsampled) {
411+
useOldSampling = false;
412+
sampledData = downsampled;
413+
}
414+
}
415+
416+
sampledData.each([otherDim], function (value: ParsedValue, index) {
417+
if (useOldSampling) {
418+
if (stride > 0 && (index % stride)) {
419+
thisCoord += step;
420+
return;
421+
}
422+
}
423+
else {
424+
thisCoord = index;
400425
}
401426

402427
// FIXME

src/processor/dataSample.ts

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import { StageHandler, SeriesOption, SeriesSamplingOptionMixin } from '../util/t
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;
@@ -88,6 +90,44 @@ const indexSampler = function (frame: ArrayLike<number>) {
8890
return Math.round(frame.length / 2);
8991
};
9092

93+
export function doDataSampling(
94+
data: SeriesData,
95+
sampling: SeriesSamplingOptionMixin['sampling'],
96+
coordSys: CoordinateSystem,
97+
dpr: number
98+
) {
99+
const count = data.count();
100+
// Only cartesian2d support down sampling. Disable it when there is few data.
101+
if (count > 10 && coordSys.type === 'cartesian2d' && sampling) {
102+
const baseAxis = coordSys.getBaseAxis();
103+
const valueAxis = coordSys.getOtherAxis(baseAxis);
104+
const extent = baseAxis.getExtent();
105+
// Coordinste system has been resized
106+
const size = Math.abs(extent[1] - extent[0]) * (dpr || 1);
107+
const rate = Math.round(count / size);
108+
109+
if (isFinite(rate) && rate > 1) {
110+
if (sampling === 'lttb') {
111+
return data.lttbDownSample(data.mapDimension(valueAxis.dim), 1 / rate);
112+
}
113+
let sampler;
114+
if (isString(sampling)) {
115+
sampler = samplers[sampling];
116+
}
117+
else if (isFunction(sampling)) {
118+
sampler = sampling;
119+
}
120+
if (sampler) {
121+
// Only support sample the first dim mapped from value axis.
122+
return data.downSample(
123+
data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler
124+
);
125+
}
126+
}
127+
}
128+
return null;
129+
}
130+
91131
export default function dataSample(seriesType: string): StageHandler {
92132
return {
93133

@@ -100,35 +140,10 @@ export default function dataSample(seriesType: string): StageHandler {
100140
const data = seriesModel.getData();
101141
const sampling = seriesModel.get('sampling');
102142
const coordSys = seriesModel.coordinateSystem;
103-
const count = data.count();
104-
// Only cartesian2d support down sampling. Disable it when there is few data.
105-
if (count > 10 && coordSys.type === 'cartesian2d' && sampling) {
106-
const baseAxis = coordSys.getBaseAxis();
107-
const valueAxis = coordSys.getOtherAxis(baseAxis);
108-
const extent = baseAxis.getExtent();
109-
const dpr = api.getDevicePixelRatio();
110-
// Coordinste system has been resized
111-
const size = Math.abs(extent[1] - extent[0]) * (dpr || 1);
112-
const rate = Math.round(count / size);
113-
114-
if (isFinite(rate) && rate > 1) {
115-
if (sampling === 'lttb') {
116-
seriesModel.setData(data.lttbDownSample(data.mapDimension(valueAxis.dim), 1 / rate));
117-
}
118-
let sampler;
119-
if (isString(sampling)) {
120-
sampler = samplers[sampling];
121-
}
122-
else if (isFunction(sampling)) {
123-
sampler = sampling;
124-
}
125-
if (sampler) {
126-
// Only support sample the first dim mapped from value axis.
127-
seriesModel.setData(data.downSample(
128-
data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler
129-
));
130-
}
131-
}
143+
const dpr = api.getDevicePixelRatio();
144+
const resampled = doDataSampling(data, sampling, coordSys, dpr);
145+
if (resampled) {
146+
seriesModel.setData(resampled);
132147
}
133148
}
134149
};

test/dataZoom-sampling.html

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

0 commit comments

Comments
 (0)