@opendata-ai/openchart-engine 8.6.0 → 8.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +4 -0
- package/dist/index.js +56 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1021,6 +1021,10 @@ declare function legendGap(width: number): number;
|
|
|
1021
1021
|
* - If `as` is a string: adds `as` with the bin start value.
|
|
1022
1022
|
* - If `as` is [start, end]: adds both bin start and bin end fields.
|
|
1023
1023
|
*
|
|
1024
|
+
* When `params.scaleType` is `'log'`, bins are log-spaced (equal width in log
|
|
1025
|
+
* space). This is auto-detected by the histogram mark when the x scale is
|
|
1026
|
+
* logarithmic.
|
|
1027
|
+
*
|
|
1024
1028
|
* @param data - Input rows.
|
|
1025
1029
|
* @param transform - Bin transform definition.
|
|
1026
1030
|
* @returns New rows with binned field(s) added.
|
package/dist/index.js
CHANGED
|
@@ -6544,8 +6544,15 @@ function expandEncodingSugar(spec, inheritedData) {
|
|
|
6544
6544
|
const resolvedType = ch.type ?? (specData && specData.length > 0 ? inferFieldType(specData, field) : void 0);
|
|
6545
6545
|
const emitInterval = channel === "x" && resolvedType === "quantitative" && markType === "bar";
|
|
6546
6546
|
const endField = `${outputField}_end`;
|
|
6547
|
+
const chScale = ch.scale;
|
|
6548
|
+
let binDef;
|
|
6549
|
+
if (chScale?.type === "log") {
|
|
6550
|
+
binDef = ch.bin === true ? { scaleType: "log" } : { ...ch.bin, scaleType: "log" };
|
|
6551
|
+
} else {
|
|
6552
|
+
binDef = ch.bin === true ? true : ch.bin;
|
|
6553
|
+
}
|
|
6547
6554
|
const binTransform = {
|
|
6548
|
-
bin:
|
|
6555
|
+
bin: binDef,
|
|
6549
6556
|
field,
|
|
6550
6557
|
as: emitInterval ? [outputField, endField] : outputField
|
|
6551
6558
|
};
|
|
@@ -6914,7 +6921,14 @@ function expandHistogramMark(spec) {
|
|
|
6914
6921
|
const encoding = { ...spec.encoding ?? {} };
|
|
6915
6922
|
const x = { ...encoding.x ?? {} };
|
|
6916
6923
|
if (x.bin == null) {
|
|
6917
|
-
|
|
6924
|
+
const binParams = {
|
|
6925
|
+
maxbins: typeof binCount === "number" ? binCount : HISTOGRAM_DEFAULT_MAXBINS
|
|
6926
|
+
};
|
|
6927
|
+
const xScale = x.scale;
|
|
6928
|
+
if (xScale?.type === "log") {
|
|
6929
|
+
binParams.scaleType = "log";
|
|
6930
|
+
}
|
|
6931
|
+
x.bin = binParams;
|
|
6918
6932
|
}
|
|
6919
6933
|
x.type = x.type ?? "quantitative";
|
|
6920
6934
|
encoding.x = x;
|
|
@@ -14124,11 +14138,11 @@ function compileGeoMap(spec, options) {
|
|
|
14124
14138
|
}
|
|
14125
14139
|
const droppedFeatures = [];
|
|
14126
14140
|
const formatter = buildD3Formatter2(mapSpec.encoding?.color?.format ?? mapSpec.valueFormat) ?? formatNumber4;
|
|
14127
|
-
const neutralFill =
|
|
14141
|
+
const neutralFill = theme.colors.neutral[100];
|
|
14128
14142
|
const noDataPattern = {
|
|
14129
14143
|
type: "diagonal",
|
|
14130
14144
|
base: neutralFill,
|
|
14131
|
-
line:
|
|
14145
|
+
line: theme.colors.neutral[300]
|
|
14132
14146
|
};
|
|
14133
14147
|
let featureMarks;
|
|
14134
14148
|
let continuousLegend = null;
|
|
@@ -19082,6 +19096,19 @@ function computeStep(extent3, maxbins, nice) {
|
|
|
19082
19096
|
}
|
|
19083
19097
|
return step;
|
|
19084
19098
|
}
|
|
19099
|
+
function computeLogBinEdges(extent3, maxbins) {
|
|
19100
|
+
const lo = Math.max(extent3[0], Number.MIN_VALUE);
|
|
19101
|
+
const hi = Math.max(extent3[1], lo);
|
|
19102
|
+
const logMin = Math.log10(lo);
|
|
19103
|
+
const logMax = Math.log10(hi);
|
|
19104
|
+
const logSpan = logMax - logMin;
|
|
19105
|
+
if (logSpan === 0) return [lo, lo * 10];
|
|
19106
|
+
const edges = [];
|
|
19107
|
+
for (let i = 0; i <= maxbins; i++) {
|
|
19108
|
+
edges.push(10 ** (logMin + i / maxbins * logSpan));
|
|
19109
|
+
}
|
|
19110
|
+
return edges;
|
|
19111
|
+
}
|
|
19085
19112
|
function runBin(data, transform) {
|
|
19086
19113
|
const params = transform.bin === true ? {} : transform.bin;
|
|
19087
19114
|
const maxbins = params.maxbins ?? 10;
|
|
@@ -19094,14 +19121,38 @@ function runBin(data, transform) {
|
|
|
19094
19121
|
for (const row of data) {
|
|
19095
19122
|
const v = Number(row[field]);
|
|
19096
19123
|
if (Number.isFinite(v)) {
|
|
19124
|
+
if (params.scaleType === "log" && v <= 0) continue;
|
|
19097
19125
|
if (v < min4) min4 = v;
|
|
19098
19126
|
if (v > max4) max4 = v;
|
|
19099
19127
|
}
|
|
19100
19128
|
}
|
|
19101
19129
|
extent3 = [min4 === Infinity ? 0 : min4, max4 === -Infinity ? 0 : max4];
|
|
19102
19130
|
}
|
|
19103
|
-
const step = params.step ?? computeStep(extent3, maxbins, nice);
|
|
19104
19131
|
const [startAs, endAs] = Array.isArray(transform.as) ? transform.as : [transform.as, void 0];
|
|
19132
|
+
if (params.scaleType === "log") {
|
|
19133
|
+
const edges = computeLogBinEdges(extent3, maxbins);
|
|
19134
|
+
return data.map((row) => {
|
|
19135
|
+
const v = Number(row[field]);
|
|
19136
|
+
const newRow = { ...row };
|
|
19137
|
+
if (!Number.isFinite(v) || v <= 0) {
|
|
19138
|
+
newRow[startAs] = null;
|
|
19139
|
+
if (endAs) newRow[endAs] = null;
|
|
19140
|
+
} else {
|
|
19141
|
+
let lo = 0;
|
|
19142
|
+
let hi = edges.length - 2;
|
|
19143
|
+
while (lo < hi) {
|
|
19144
|
+
const mid = lo + hi + 1 >> 1;
|
|
19145
|
+
if (edges[mid] <= v) lo = mid;
|
|
19146
|
+
else hi = mid - 1;
|
|
19147
|
+
}
|
|
19148
|
+
const idx = Math.min(lo, edges.length - 2);
|
|
19149
|
+
newRow[startAs] = edges[idx];
|
|
19150
|
+
if (endAs) newRow[endAs] = edges[idx + 1];
|
|
19151
|
+
}
|
|
19152
|
+
return newRow;
|
|
19153
|
+
});
|
|
19154
|
+
}
|
|
19155
|
+
const step = params.step ?? computeStep(extent3, maxbins, nice);
|
|
19105
19156
|
return data.map((row) => {
|
|
19106
19157
|
const v = Number(row[field]);
|
|
19107
19158
|
const newRow = { ...row };
|