You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2020/09/23 12:04:25 UTC
[incubator-echarts] branch pr/13317 updated: fix(sample): fix lttb
downsample with dataZoom
This is an automated email from the ASF dual-hosted git repository.
shenyi pushed a commit to branch pr/13317
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
The following commit(s) were added to refs/heads/pr/13317 by this push:
new 255b019 fix(sample): fix lttb downsample with dataZoom
255b019 is described below
commit 255b019616445c40477d2a5515a69a6120d7e544
Author: pissang <bm...@gmail.com>
AuthorDate: Wed Sep 23 19:49:31 2020 +0800
fix(sample): fix lttb downsample with dataZoom
---
src/data/List.ts | 121 +++++++++++++++++++++-----------------------
src/processor/dataSample.ts | 2 +-
2 files changed, 58 insertions(+), 65 deletions(-)
diff --git a/src/data/List.ts b/src/data/List.ts
index 84a50bc..cb4b3e0 100644
--- a/src/data/List.ts
+++ b/src/data/List.ts
@@ -1697,12 +1697,12 @@ class List<
* Large data down sampling using largest-triangle-three-buckets
* @param {string} baseDimension
* @param {string} valueDimension
- * @param {number} rate
+ * @param {number} targetCount
*/
lttbDownSample(
baseDimension: DimensionName,
valueDimension: DimensionName,
- rate: number
+ targetCount: number
) {
const list = cloneListForMapAndSample(this, [baseDimension, valueDimension]);
const targetStorage = list._storage;
@@ -1714,81 +1714,74 @@ class List<
let sampledIndex = 0;
- const frameSize = mathFloor(1 / rate);
+ const frameSize = (len - 2) / (targetCount - 2);
- let currentSelectedIdx = 0;
+ let currentRawIndex = this.getRawIndex(0);
let maxArea;
let area;
- let nextSelectedIdx;
-
- for (let chunkIdx = 0; chunkIdx < this._chunkCount; chunkIdx++) {
- const chunkOffset = chunkSize * chunkIdx;
- const selfChunkSize = Math.min(len - chunkOffset, chunkSize);
- const chunkFrameCount = Math.ceil((selfChunkSize - 2) / frameSize);
- const baseDimChunk = baseDimStore[chunkIdx];
- const valueDimChunk = valueDimStore[chunkIdx];
-
- // The first frame is the first data.
- newIndices[sampledIndex++] = currentSelectedIdx;
-
- for (let frame = 0; frame < chunkFrameCount - 2; frame++) {
- let avgX = 0;
- let avgY = 0;
- let avgRangeStart = (frame + 1) * frameSize + 1 + chunkOffset;
- const avgRangeEnd = Math.min((frame + 2) * frameSize + 1, selfChunkSize) + chunkOffset;
-
- const avgRangeLength = avgRangeEnd - avgRangeStart;
-
- for (; avgRangeStart < avgRangeEnd; avgRangeStart++) {
- const x = baseDimChunk[avgRangeStart] as number;
- const y = valueDimChunk[avgRangeStart] as number;
- if (isNaN(x) || isNaN(y)) {
- continue;
- }
- avgX += x;
- avgY += y;
+ let nextRawIndex;
+
+ newIndices[sampledIndex++] = currentRawIndex;
+ for (let i = 0; i < targetCount - 2; i++) {
+ let avgX = 0;
+ let avgY = 0;
+ const avgRangeStart = mathFloor((i + 1) * frameSize) + 1;
+ const avgRangeEnd = Math.min(mathFloor((i + 2) * frameSize) + 1, len);
+
+ const avgRangeLength = avgRangeEnd - avgRangeStart;
+
+ for (let idx = avgRangeStart; idx < avgRangeEnd; idx++) {
+ const rawIndex = this.getRawIndex(idx);
+ const chunkIndex = mathFloor(rawIndex / chunkSize);
+ const chunkOffset = rawIndex % chunkSize;
+ const x = baseDimStore[chunkIndex][chunkOffset] as number;
+ const y = valueDimStore[chunkIndex][chunkOffset] as number;
+ if (isNaN(x) || isNaN(y)) {
+ continue;
}
- avgX /= avgRangeLength;
- avgY /= avgRangeLength;
+ avgX += baseDimStore[chunkIndex][chunkOffset] as number;
+ avgY += valueDimStore[chunkIndex][chunkOffset] as number;
+ }
+ avgX /= avgRangeLength;
+ avgY /= avgRangeLength;
- // Get the range for this bucket
- let rangeOffs = (frame) * frameSize + 1 + chunkOffset;
- const rangeTo = (frame + 1) * frameSize + 1 + chunkOffset;
+ const rangeOffs = mathFloor((i) * frameSize) + 1;
+ const rangeTo = mathFloor((i + 1) * frameSize) + 1;
- // Point A
- const pointAX = baseDimChunk[currentSelectedIdx] as number;
- const pointAY = valueDimChunk[currentSelectedIdx] as number;
- let allNaN = true;
+ const chunkIndex = mathFloor(currentRawIndex / chunkSize);
+ const chunkOffset = currentRawIndex % chunkSize;
+ const pointAX = baseDimStore[chunkIndex][chunkOffset] as number;
+ const pointAY = valueDimStore[chunkIndex][chunkOffset] as number;
- maxArea = area = -1;
+ maxArea = area = -1;
- for (; rangeOffs < rangeTo; rangeOffs++) {
- const y = valueDimChunk[rangeOffs] as number;
- const x = baseDimChunk[rangeOffs] as number;
- if (isNaN(x) || isNaN(y)) {
- continue;
- }
- allNaN = false;
- // Calculate triangle area over three buckets
- area = Math.abs((pointAX - avgX) * (y - pointAY)
- - (pointAX - x) * (avgY - pointAY)
- );
- if (area > maxArea) {
- maxArea = area;
- nextSelectedIdx = rangeOffs; // Next a is this b
- }
+ // Find a point from current frame that construct a triangel with largest area with previous selected point
+ // And the average of next frame.
+ for (let idx = rangeOffs; idx < rangeTo; idx++) {
+ const rawIndex = this.getRawIndex(idx);
+ const chunkIndex = mathFloor(rawIndex / chunkSize);
+ const chunkOffset = rawIndex % chunkSize;
+ const x = baseDimStore[chunkIndex][chunkOffset] as number;
+ const y = valueDimStore[chunkIndex][chunkOffset] as number;
+ if (isNaN(x) || isNaN(y)) {
+ continue;
}
-
- if (!allNaN) {
- newIndices[sampledIndex++] = nextSelectedIdx;
+ // Calculate triangle area over three buckets
+ area = Math.abs((pointAX - avgX) * (y - pointAY)
+ - (pointAX - x) * (avgY - pointAY)
+ );
+ if (area > maxArea) {
+ maxArea = area;
+ nextRawIndex = rawIndex; // Next a is this b
}
-
- currentSelectedIdx = nextSelectedIdx; // This a is the next a (chosen b)
}
- // The last frame is the last data.
- newIndices[sampledIndex++] = selfChunkSize - 1;
+
+ newIndices[sampledIndex++] = nextRawIndex;
+
+ currentRawIndex = nextRawIndex; // This a is the next a (chosen b)
}
+ newIndices[sampledIndex++] = this.getRawIndex(len - 1);
list._count = sampledIndex;
list._indices = newIndices;
diff --git a/src/processor/dataSample.ts b/src/processor/dataSample.ts
index 7d81fd6..485f6df 100644
--- a/src/processor/dataSample.ts
+++ b/src/processor/dataSample.ts
@@ -95,7 +95,7 @@ export default function (seriesType: string): StageHandler {
if (rate > 1) {
if (sampling === 'lttb') {
seriesModel.setData(data.lttbDownSample(
- data.mapDimension(baseAxis.dim), data.mapDimension(valueAxis.dim), 1 / rate
+ data.mapDimension(baseAxis.dim), data.mapDimension(valueAxis.dim), size
));
}
let sampler;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org