Skip to content

Commit 348b60e

Browse files
committed
feat(sampling-in-dataZoom): initial commit
1 parent 104df1b commit 348b60e

File tree

4 files changed

+197
-40
lines changed

4 files changed

+197
-40
lines changed

src/component/dataZoom/SliderZoomModel.ts

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

3132
interface SliderHandleLabelOption {
3233
show?: boolean
3334
}
3435

35-
export interface SliderDataZoomOption extends DataZoomOption, BoxLayoutOptionMixin {
36+
export interface SliderDataZoomOption extends
37+
DataZoomOption,
38+
BoxLayoutOptionMixin,
39+
SeriesSamplingOptionMixin {
3640

3741
show?: boolean
3842
/**
@@ -217,8 +221,10 @@ class SliderZoomModel extends DataZoomModel<SliderDataZoomOption> {
217221
moveHandleStyle: {
218222
color: '#8FB0F7'
219223
}
220-
}
224+
},
225+
226+
sampling: 'none'
221227
} as SliderDataZoomOption);
222228
}
223229

224-
export default SliderZoomModel;
230+
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: 47 additions & 32 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;
@@ -72,6 +74,47 @@ const indexSampler = function (frame: ArrayLike<number>) {
7274
return Math.round(frame.length / 2);
7375
};
7476

77+
export function doDataSampling(
78+
data: SeriesData,
79+
sampling: SeriesSamplingOptionMixin['sampling'],
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+
else if (sampling === 'minmax') {
98+
return data.minmaxDownSample(data.mapDimension(valueAxis.dim), 1 / rate);
99+
}
100+
let sampler;
101+
if (isString(sampling)) {
102+
sampler = samplers[sampling];
103+
}
104+
else if (isFunction(sampling)) {
105+
sampler = sampling;
106+
}
107+
if (sampler) {
108+
// Only support sample the first dim mapped from value axis.
109+
return data.downSample(
110+
data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler
111+
);
112+
}
113+
}
114+
}
115+
return null;
116+
}
117+
75118
export default function dataSample(seriesType: string): StageHandler {
76119
return {
77120

@@ -84,38 +127,10 @@ export default function dataSample(seriesType: string): StageHandler {
84127
const data = seriesModel.getData();
85128
const sampling = seriesModel.get('sampling');
86129
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-
else if (sampling === 'minmax') {
103-
seriesModel.setData(data.minmaxDownSample(data.mapDimension(valueAxis.dim), 1 / rate));
104-
}
105-
let sampler;
106-
if (isString(sampling)) {
107-
sampler = samplers[sampling];
108-
}
109-
else if (isFunction(sampling)) {
110-
sampler = sampling;
111-
}
112-
if (sampler) {
113-
// Only support sample the first dim mapped from value axis.
114-
seriesModel.setData(data.downSample(
115-
data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler
116-
));
117-
}
118-
}
130+
const dpr = api.getDevicePixelRatio();
131+
const resampled = doDataSampling(data, sampling, coordSys, dpr);
132+
if (resampled) {
133+
seriesModel.setData(resampled);
119134
}
120135
}
121136
};

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)