Skip to content

Commit a25b339

Browse files
committed
2 parents 7bcd5ce + 25e1343 commit a25b339

8 files changed

Lines changed: 200 additions & 4 deletions

dist/apexcharts.common.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/apexcharts.esm.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15888,6 +15888,8 @@ class Data {
1588815888
if (Array.isArray(sampleY)) {
1588915889
if (sampleY.length === 4) {
1589015890
reduced = Data.ohlcAggregate(windowed, targetPoints);
15891+
} else if (sampleY.length === 2) {
15892+
reduced = Data.rangeAggregate(windowed, targetPoints);
1589115893
}
1589215894
} else {
1589315895
reduced = Data.lttbDownsample(windowed, targetPoints);
@@ -16576,6 +16578,53 @@ class Data {
1657616578
}
1657716579
return out;
1657816580
}
16581+
/**
16582+
* Bucket-aggregate 2-tuple range data (`y: [low, high]`, rangeArea/rangeBar)
16583+
* into `targetPoints` points, the range analog of {@link ohlcAggregate}. Each
16584+
* bucket emits `[min low, max high]` so the band's vertical extent is never
16585+
* understated by downsampling (LTTB, built for scalar y, would drop these
16586+
* extremes). Order-agnostic: the min/max scan both tuple slots, so it is
16587+
* correct whether a point is stored `[low, high]` or `[high, low]`.
16588+
*
16589+
* Null bounds (e.g. an indicator's warm-up period) are ignored, not treated
16590+
* as 0 — `Math.min(null, x)` would coerce to 0 and pin the band to the
16591+
* baseline. A bucket with no finite bounds emits `[null, null]` so it renders
16592+
* as a gap, matching the un-downsampled series.
16593+
* @param {any[]} data
16594+
* @param {number} targetPoints
16595+
* @returns {any[]}
16596+
*/
16597+
static rangeAggregate(data, targetPoints) {
16598+
const len = data.length;
16599+
if (targetPoints >= len || targetPoints < 1) return data;
16600+
const isXY = !Array.isArray(data[0]);
16601+
const getX = isXY ? (p) => p.x : (p) => p[0];
16602+
const getY = isXY ? (p) => p.y : (p) => p[1];
16603+
const make = isXY ? (x, y) => ({ x, y }) : (x, y) => [x, y];
16604+
const out = [];
16605+
const bucketSize = len / targetPoints;
16606+
for (let i = 0; i < targetPoints; i++) {
16607+
const start = Math.floor(i * bucketSize);
16608+
const end = i === targetPoints - 1 ? len : Math.floor((i + 1) * bucketSize);
16609+
if (end <= start) continue;
16610+
let low = Infinity;
16611+
let high = -Infinity;
16612+
for (let j = start; j < end; j++) {
16613+
const y = getY(data[j]);
16614+
if (y == null) continue;
16615+
for (let k = 0; k < 2; k++) {
16616+
const v = y[k];
16617+
if (v == null || !isFinite(v)) continue;
16618+
if (v < low) low = v;
16619+
if (v > high) high = v;
16620+
}
16621+
}
16622+
out.push(
16623+
make(getX(data[start]), low === Infinity ? [null, null] : [low, high])
16624+
);
16625+
}
16626+
return out;
16627+
}
1657916628
excludeCollapsedSeriesInYAxis() {
1658016629
const w = this.w;
1658116630
const yAxisIndexes = [];

dist/apexcharts.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15892,6 +15892,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
1589215892
if (Array.isArray(sampleY)) {
1589315893
if (sampleY.length === 4) {
1589415894
reduced = Data.ohlcAggregate(windowed, targetPoints);
15895+
} else if (sampleY.length === 2) {
15896+
reduced = Data.rangeAggregate(windowed, targetPoints);
1589515897
}
1589615898
} else {
1589715899
reduced = Data.lttbDownsample(windowed, targetPoints);
@@ -16580,6 +16582,53 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
1658016582
}
1658116583
return out;
1658216584
}
16585+
/**
16586+
* Bucket-aggregate 2-tuple range data (`y: [low, high]`, rangeArea/rangeBar)
16587+
* into `targetPoints` points, the range analog of {@link ohlcAggregate}. Each
16588+
* bucket emits `[min low, max high]` so the band's vertical extent is never
16589+
* understated by downsampling (LTTB, built for scalar y, would drop these
16590+
* extremes). Order-agnostic: the min/max scan both tuple slots, so it is
16591+
* correct whether a point is stored `[low, high]` or `[high, low]`.
16592+
*
16593+
* Null bounds (e.g. an indicator's warm-up period) are ignored, not treated
16594+
* as 0 — `Math.min(null, x)` would coerce to 0 and pin the band to the
16595+
* baseline. A bucket with no finite bounds emits `[null, null]` so it renders
16596+
* as a gap, matching the un-downsampled series.
16597+
* @param {any[]} data
16598+
* @param {number} targetPoints
16599+
* @returns {any[]}
16600+
*/
16601+
static rangeAggregate(data, targetPoints) {
16602+
const len = data.length;
16603+
if (targetPoints >= len || targetPoints < 1) return data;
16604+
const isXY = !Array.isArray(data[0]);
16605+
const getX = isXY ? (p) => p.x : (p) => p[0];
16606+
const getY = isXY ? (p) => p.y : (p) => p[1];
16607+
const make = isXY ? (x, y) => ({ x, y }) : (x, y) => [x, y];
16608+
const out = [];
16609+
const bucketSize = len / targetPoints;
16610+
for (let i = 0; i < targetPoints; i++) {
16611+
const start = Math.floor(i * bucketSize);
16612+
const end = i === targetPoints - 1 ? len : Math.floor((i + 1) * bucketSize);
16613+
if (end <= start) continue;
16614+
let low = Infinity;
16615+
let high = -Infinity;
16616+
for (let j = start; j < end; j++) {
16617+
const y = getY(data[j]);
16618+
if (y == null) continue;
16619+
for (let k = 0; k < 2; k++) {
16620+
const v = y[k];
16621+
if (v == null || !isFinite(v)) continue;
16622+
if (v < low) low = v;
16623+
if (v > high) high = v;
16624+
}
16625+
}
16626+
out.push(
16627+
make(getX(data[start]), low === Infinity ? [null, null] : [low, high])
16628+
);
16629+
}
16630+
return out;
16631+
}
1658316632
excludeCollapsedSeriesInYAxis() {
1658416633
const w = this.w;
1658516634
const yAxisIndexes = [];

dist/apexcharts.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/apexcharts.ssr.common.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/apexcharts.ssr.esm.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15908,6 +15908,8 @@ class Data {
1590815908
if (Array.isArray(sampleY)) {
1590915909
if (sampleY.length === 4) {
1591015910
reduced = Data.ohlcAggregate(windowed, targetPoints);
15911+
} else if (sampleY.length === 2) {
15912+
reduced = Data.rangeAggregate(windowed, targetPoints);
1591115913
}
1591215914
} else {
1591315915
reduced = Data.lttbDownsample(windowed, targetPoints);
@@ -16596,6 +16598,53 @@ class Data {
1659616598
}
1659716599
return out;
1659816600
}
16601+
/**
16602+
* Bucket-aggregate 2-tuple range data (`y: [low, high]`, rangeArea/rangeBar)
16603+
* into `targetPoints` points, the range analog of {@link ohlcAggregate}. Each
16604+
* bucket emits `[min low, max high]` so the band's vertical extent is never
16605+
* understated by downsampling (LTTB, built for scalar y, would drop these
16606+
* extremes). Order-agnostic: the min/max scan both tuple slots, so it is
16607+
* correct whether a point is stored `[low, high]` or `[high, low]`.
16608+
*
16609+
* Null bounds (e.g. an indicator's warm-up period) are ignored, not treated
16610+
* as 0 — `Math.min(null, x)` would coerce to 0 and pin the band to the
16611+
* baseline. A bucket with no finite bounds emits `[null, null]` so it renders
16612+
* as a gap, matching the un-downsampled series.
16613+
* @param {any[]} data
16614+
* @param {number} targetPoints
16615+
* @returns {any[]}
16616+
*/
16617+
static rangeAggregate(data, targetPoints) {
16618+
const len = data.length;
16619+
if (targetPoints >= len || targetPoints < 1) return data;
16620+
const isXY = !Array.isArray(data[0]);
16621+
const getX = isXY ? (p) => p.x : (p) => p[0];
16622+
const getY = isXY ? (p) => p.y : (p) => p[1];
16623+
const make = isXY ? (x, y) => ({ x, y }) : (x, y) => [x, y];
16624+
const out = [];
16625+
const bucketSize = len / targetPoints;
16626+
for (let i = 0; i < targetPoints; i++) {
16627+
const start = Math.floor(i * bucketSize);
16628+
const end = i === targetPoints - 1 ? len : Math.floor((i + 1) * bucketSize);
16629+
if (end <= start) continue;
16630+
let low = Infinity;
16631+
let high = -Infinity;
16632+
for (let j = start; j < end; j++) {
16633+
const y = getY(data[j]);
16634+
if (y == null) continue;
16635+
for (let k = 0; k < 2; k++) {
16636+
const v = y[k];
16637+
if (v == null || !isFinite(v)) continue;
16638+
if (v < low) low = v;
16639+
if (v > high) high = v;
16640+
}
16641+
}
16642+
out.push(
16643+
make(getX(data[start]), low === Infinity ? [null, null] : [low, high])
16644+
);
16645+
}
16646+
return out;
16647+
}
1659916648
excludeCollapsedSeriesInYAxis() {
1660016649
const w = this.w;
1660116650
const yAxisIndexes = [];

dist/core.common.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/core.esm.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15888,6 +15888,8 @@ class Data {
1588815888
if (Array.isArray(sampleY)) {
1588915889
if (sampleY.length === 4) {
1589015890
reduced = Data.ohlcAggregate(windowed, targetPoints);
15891+
} else if (sampleY.length === 2) {
15892+
reduced = Data.rangeAggregate(windowed, targetPoints);
1589115893
}
1589215894
} else {
1589315895
reduced = Data.lttbDownsample(windowed, targetPoints);
@@ -16576,6 +16578,53 @@ class Data {
1657616578
}
1657716579
return out;
1657816580
}
16581+
/**
16582+
* Bucket-aggregate 2-tuple range data (`y: [low, high]`, rangeArea/rangeBar)
16583+
* into `targetPoints` points, the range analog of {@link ohlcAggregate}. Each
16584+
* bucket emits `[min low, max high]` so the band's vertical extent is never
16585+
* understated by downsampling (LTTB, built for scalar y, would drop these
16586+
* extremes). Order-agnostic: the min/max scan both tuple slots, so it is
16587+
* correct whether a point is stored `[low, high]` or `[high, low]`.
16588+
*
16589+
* Null bounds (e.g. an indicator's warm-up period) are ignored, not treated
16590+
* as 0 — `Math.min(null, x)` would coerce to 0 and pin the band to the
16591+
* baseline. A bucket with no finite bounds emits `[null, null]` so it renders
16592+
* as a gap, matching the un-downsampled series.
16593+
* @param {any[]} data
16594+
* @param {number} targetPoints
16595+
* @returns {any[]}
16596+
*/
16597+
static rangeAggregate(data, targetPoints) {
16598+
const len = data.length;
16599+
if (targetPoints >= len || targetPoints < 1) return data;
16600+
const isXY = !Array.isArray(data[0]);
16601+
const getX = isXY ? (p) => p.x : (p) => p[0];
16602+
const getY = isXY ? (p) => p.y : (p) => p[1];
16603+
const make = isXY ? (x, y) => ({ x, y }) : (x, y) => [x, y];
16604+
const out = [];
16605+
const bucketSize = len / targetPoints;
16606+
for (let i = 0; i < targetPoints; i++) {
16607+
const start = Math.floor(i * bucketSize);
16608+
const end = i === targetPoints - 1 ? len : Math.floor((i + 1) * bucketSize);
16609+
if (end <= start) continue;
16610+
let low = Infinity;
16611+
let high = -Infinity;
16612+
for (let j = start; j < end; j++) {
16613+
const y = getY(data[j]);
16614+
if (y == null) continue;
16615+
for (let k = 0; k < 2; k++) {
16616+
const v = y[k];
16617+
if (v == null || !isFinite(v)) continue;
16618+
if (v < low) low = v;
16619+
if (v > high) high = v;
16620+
}
16621+
}
16622+
out.push(
16623+
make(getX(data[start]), low === Infinity ? [null, null] : [low, high])
16624+
);
16625+
}
16626+
return out;
16627+
}
1657916628
excludeCollapsedSeriesInYAxis() {
1658016629
const w = this.w;
1658116630
const yAxisIndexes = [];

0 commit comments

Comments
 (0)