@uwdata/mosaic-plot 0.8.0 → 0.10.0
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/mosaic-plot.js +2150 -1439
- package/dist/mosaic-plot.min.js +11 -11
- package/package.json +6 -6
- package/src/index.js +1 -0
- package/src/interactors/Highlight.js +6 -3
- package/src/interactors/Interval1D.js +8 -8
- package/src/interactors/Interval2D.js +10 -15
- package/src/interactors/Nearest.js +79 -33
- package/src/interactors/PanZoom.js +4 -7
- package/src/interactors/Toggle.js +19 -28
- package/src/legend.js +26 -8
- package/src/marks/Density1DMark.js +1 -1
- package/src/marks/ErrorBarMark.js +50 -0
- package/src/marks/Grid2DMark.js +2 -2
- package/src/marks/HexbinMark.js +39 -49
- package/src/marks/Mark.js +28 -21
- package/src/marks/RasterMark.js +9 -3
- package/src/marks/RasterTileMark.js +8 -2
- package/src/marks/RegressionMark.js +2 -2
- package/src/marks/util/is-constant-option.js +2 -1
- package/src/marks/util/permute.js +10 -0
- package/src/marks/util/stats.js +88 -0
- package/src/plot-attributes.js +1 -0
- package/src/plot-renderer.js +21 -22
- package/src/plot.js +14 -2
- package/src/transforms/bin-step.js +43 -0
- package/src/transforms/bin.js +40 -48
- package/src/transforms/time-interval.js +53 -0
- package/src/marks/util/to-data-columns.js +0 -71
package/dist/mosaic-plot.js
CHANGED
|
@@ -155,8 +155,8 @@ var require_interval_tree = __commonJS({
|
|
|
155
155
|
a2.rightPoints = b.rightPoints;
|
|
156
156
|
a2.count = b.count;
|
|
157
157
|
}
|
|
158
|
-
function rebuild(node,
|
|
159
|
-
var ntree = createIntervalTree(
|
|
158
|
+
function rebuild(node, intervals2) {
|
|
159
|
+
var ntree = createIntervalTree(intervals2);
|
|
160
160
|
node.mid = ntree.mid;
|
|
161
161
|
node.left = ntree.left;
|
|
162
162
|
node.right = ntree.right;
|
|
@@ -165,18 +165,18 @@ var require_interval_tree = __commonJS({
|
|
|
165
165
|
node.count = ntree.count;
|
|
166
166
|
}
|
|
167
167
|
function rebuildWithInterval(node, interval2) {
|
|
168
|
-
var
|
|
169
|
-
|
|
170
|
-
rebuild(node,
|
|
168
|
+
var intervals2 = node.intervals([]);
|
|
169
|
+
intervals2.push(interval2);
|
|
170
|
+
rebuild(node, intervals2);
|
|
171
171
|
}
|
|
172
172
|
function rebuildWithoutInterval(node, interval2) {
|
|
173
|
-
var
|
|
174
|
-
var idx =
|
|
173
|
+
var intervals2 = node.intervals([]);
|
|
174
|
+
var idx = intervals2.indexOf(interval2);
|
|
175
175
|
if (idx < 0) {
|
|
176
176
|
return NOT_FOUND;
|
|
177
177
|
}
|
|
178
|
-
|
|
179
|
-
rebuild(node,
|
|
178
|
+
intervals2.splice(idx, 1);
|
|
179
|
+
rebuild(node, intervals2);
|
|
180
180
|
return SUCCESS;
|
|
181
181
|
}
|
|
182
182
|
proto.intervals = function(result) {
|
|
@@ -393,21 +393,21 @@ var require_interval_tree = __commonJS({
|
|
|
393
393
|
}
|
|
394
394
|
return a2[0] - b[0];
|
|
395
395
|
}
|
|
396
|
-
function createIntervalTree(
|
|
397
|
-
if (
|
|
396
|
+
function createIntervalTree(intervals2) {
|
|
397
|
+
if (intervals2.length === 0) {
|
|
398
398
|
return null;
|
|
399
399
|
}
|
|
400
400
|
var pts = [];
|
|
401
|
-
for (var i = 0; i <
|
|
402
|
-
pts.push(
|
|
401
|
+
for (var i = 0; i < intervals2.length; ++i) {
|
|
402
|
+
pts.push(intervals2[i][0], intervals2[i][1]);
|
|
403
403
|
}
|
|
404
404
|
pts.sort(compareNumbers);
|
|
405
405
|
var mid2 = pts[pts.length >> 1];
|
|
406
406
|
var leftIntervals = [];
|
|
407
407
|
var rightIntervals = [];
|
|
408
408
|
var centerIntervals = [];
|
|
409
|
-
for (var i = 0; i <
|
|
410
|
-
var s2 =
|
|
409
|
+
for (var i = 0; i < intervals2.length; ++i) {
|
|
410
|
+
var s2 = intervals2[i];
|
|
411
411
|
if (s2[1] < mid2) {
|
|
412
412
|
leftIntervals.push(s2);
|
|
413
413
|
} else if (mid2 < s2[0]) {
|
|
@@ -475,11 +475,11 @@ var require_interval_tree = __commonJS({
|
|
|
475
475
|
return [];
|
|
476
476
|
}
|
|
477
477
|
});
|
|
478
|
-
function createWrapper(
|
|
479
|
-
if (!
|
|
478
|
+
function createWrapper(intervals2) {
|
|
479
|
+
if (!intervals2 || intervals2.length === 0) {
|
|
480
480
|
return new IntervalTree2(null);
|
|
481
481
|
}
|
|
482
|
-
return new IntervalTree2(createIntervalTree(
|
|
482
|
+
return new IntervalTree2(createIntervalTree(intervals2));
|
|
483
483
|
}
|
|
484
484
|
}
|
|
485
485
|
});
|
|
@@ -608,7 +608,6 @@ var MosaicClient = class {
|
|
|
608
608
|
* @returns {this}
|
|
609
609
|
*/
|
|
610
610
|
queryError(error) {
|
|
611
|
-
console.error(error);
|
|
612
611
|
return this;
|
|
613
612
|
}
|
|
614
613
|
/**
|
|
@@ -632,7 +631,7 @@ var MosaicClient = class {
|
|
|
632
631
|
/**
|
|
633
632
|
* Requests a client update.
|
|
634
633
|
* For example to (re-)render an interface component.
|
|
635
|
-
*
|
|
634
|
+
*
|
|
636
635
|
* @returns {this | Promise<any>}
|
|
637
636
|
*/
|
|
638
637
|
update() {
|
|
@@ -696,16 +695,24 @@ function __await(v2) {
|
|
|
696
695
|
function __asyncGenerator(thisArg, _arguments, generator) {
|
|
697
696
|
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
698
697
|
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
699
|
-
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
|
|
698
|
+
return i = {}, verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function() {
|
|
700
699
|
return this;
|
|
701
700
|
}, i;
|
|
702
|
-
function
|
|
703
|
-
|
|
704
|
-
return
|
|
705
|
-
q.push([n, v2, a2, b]) > 1 || resume(n, v2);
|
|
706
|
-
});
|
|
701
|
+
function awaitReturn(f) {
|
|
702
|
+
return function(v2) {
|
|
703
|
+
return Promise.resolve(v2).then(f, reject);
|
|
707
704
|
};
|
|
708
705
|
}
|
|
706
|
+
function verb(n, f) {
|
|
707
|
+
if (g[n]) {
|
|
708
|
+
i[n] = function(v2) {
|
|
709
|
+
return new Promise(function(a2, b) {
|
|
710
|
+
q.push([n, v2, a2, b]) > 1 || resume(n, v2);
|
|
711
|
+
});
|
|
712
|
+
};
|
|
713
|
+
if (f) i[n] = f(i[n]);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
709
716
|
function resume(n, v2) {
|
|
710
717
|
try {
|
|
711
718
|
step(g[n](v2));
|
|
@@ -1325,26 +1332,26 @@ var IntervalUnit;
|
|
|
1325
1332
|
IntervalUnit2[IntervalUnit2["MONTH_DAY_NANO"] = 2] = "MONTH_DAY_NANO";
|
|
1326
1333
|
})(IntervalUnit || (IntervalUnit = {}));
|
|
1327
1334
|
|
|
1328
|
-
// ../../node_modules/flatbuffers/mjs/constants.js
|
|
1335
|
+
// ../../node_modules/apache-arrow/node_modules/flatbuffers/mjs/constants.js
|
|
1329
1336
|
var SIZEOF_SHORT = 2;
|
|
1330
1337
|
var SIZEOF_INT = 4;
|
|
1331
1338
|
var FILE_IDENTIFIER_LENGTH = 4;
|
|
1332
1339
|
var SIZE_PREFIX_LENGTH = 4;
|
|
1333
1340
|
|
|
1334
|
-
// ../../node_modules/flatbuffers/mjs/utils.js
|
|
1341
|
+
// ../../node_modules/apache-arrow/node_modules/flatbuffers/mjs/utils.js
|
|
1335
1342
|
var int32 = new Int32Array(2);
|
|
1336
1343
|
var float32 = new Float32Array(int32.buffer);
|
|
1337
1344
|
var float64 = new Float64Array(int32.buffer);
|
|
1338
1345
|
var isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
|
|
1339
1346
|
|
|
1340
|
-
// ../../node_modules/flatbuffers/mjs/encoding.js
|
|
1347
|
+
// ../../node_modules/apache-arrow/node_modules/flatbuffers/mjs/encoding.js
|
|
1341
1348
|
var Encoding;
|
|
1342
1349
|
(function(Encoding2) {
|
|
1343
1350
|
Encoding2[Encoding2["UTF8_BYTES"] = 1] = "UTF8_BYTES";
|
|
1344
1351
|
Encoding2[Encoding2["UTF16_STRING"] = 2] = "UTF16_STRING";
|
|
1345
1352
|
})(Encoding || (Encoding = {}));
|
|
1346
1353
|
|
|
1347
|
-
// ../../node_modules/flatbuffers/mjs/byte-buffer.js
|
|
1354
|
+
// ../../node_modules/apache-arrow/node_modules/flatbuffers/mjs/byte-buffer.js
|
|
1348
1355
|
var ByteBuffer = class _ByteBuffer {
|
|
1349
1356
|
/**
|
|
1350
1357
|
* Create a new ByteBuffer with a given array of bytes (`Uint8Array`)
|
|
@@ -1588,7 +1595,7 @@ var ByteBuffer = class _ByteBuffer {
|
|
|
1588
1595
|
}
|
|
1589
1596
|
};
|
|
1590
1597
|
|
|
1591
|
-
// ../../node_modules/flatbuffers/mjs/builder.js
|
|
1598
|
+
// ../../node_modules/apache-arrow/node_modules/flatbuffers/mjs/builder.js
|
|
1592
1599
|
var Builder = class _Builder {
|
|
1593
1600
|
/**
|
|
1594
1601
|
* Create a FlatBufferBuilder.
|
|
@@ -2028,9 +2035,22 @@ var Builder = class _Builder {
|
|
|
2028
2035
|
this.addInt8(0);
|
|
2029
2036
|
this.startVector(1, utf8.length, 1);
|
|
2030
2037
|
this.bb.setPosition(this.space -= utf8.length);
|
|
2031
|
-
|
|
2032
|
-
|
|
2038
|
+
this.bb.bytes().set(utf8, this.space);
|
|
2039
|
+
return this.endVector();
|
|
2040
|
+
}
|
|
2041
|
+
/**
|
|
2042
|
+
* Create a byte vector.
|
|
2043
|
+
*
|
|
2044
|
+
* @param v The bytes to add
|
|
2045
|
+
* @returns The offset in the buffer where the byte vector starts
|
|
2046
|
+
*/
|
|
2047
|
+
createByteVector(v2) {
|
|
2048
|
+
if (v2 === null || v2 === void 0) {
|
|
2049
|
+
return 0;
|
|
2033
2050
|
}
|
|
2051
|
+
this.startVector(1, v2.length, 1);
|
|
2052
|
+
this.bb.setPosition(this.space -= v2.length);
|
|
2053
|
+
this.bb.bytes().set(v2, this.space);
|
|
2034
2054
|
return this.endVector();
|
|
2035
2055
|
}
|
|
2036
2056
|
/**
|
|
@@ -3633,9 +3653,9 @@ var BufferType;
|
|
|
3633
3653
|
// ../../node_modules/apache-arrow/util/vector.mjs
|
|
3634
3654
|
var vector_exports = {};
|
|
3635
3655
|
__export(vector_exports, {
|
|
3636
|
-
clampIndex: () => clampIndex,
|
|
3637
3656
|
clampRange: () => clampRange,
|
|
3638
|
-
createElementComparator: () => createElementComparator
|
|
3657
|
+
createElementComparator: () => createElementComparator,
|
|
3658
|
+
wrapIndex: () => wrapIndex
|
|
3639
3659
|
});
|
|
3640
3660
|
|
|
3641
3661
|
// ../../node_modules/apache-arrow/util/pretty.mjs
|
|
@@ -3676,9 +3696,23 @@ var bn_exports = {};
|
|
|
3676
3696
|
__export(bn_exports, {
|
|
3677
3697
|
BN: () => BN,
|
|
3678
3698
|
bigNumToBigInt: () => bigNumToBigInt,
|
|
3699
|
+
bigNumToNumber: () => bigNumToNumber,
|
|
3679
3700
|
bigNumToString: () => bigNumToString,
|
|
3680
3701
|
isArrowBigNumSymbol: () => isArrowBigNumSymbol
|
|
3681
3702
|
});
|
|
3703
|
+
|
|
3704
|
+
// ../../node_modules/apache-arrow/util/bigint.mjs
|
|
3705
|
+
function bigIntToNumber(number7) {
|
|
3706
|
+
if (typeof number7 === "bigint" && (number7 < Number.MIN_SAFE_INTEGER || number7 > Number.MAX_SAFE_INTEGER)) {
|
|
3707
|
+
throw new TypeError(`${number7} is not safe to convert to a number.`);
|
|
3708
|
+
}
|
|
3709
|
+
return Number(number7);
|
|
3710
|
+
}
|
|
3711
|
+
function divideBigInts(number7, divisor) {
|
|
3712
|
+
return bigIntToNumber(number7 / divisor) + bigIntToNumber(number7 % divisor) / bigIntToNumber(divisor);
|
|
3713
|
+
}
|
|
3714
|
+
|
|
3715
|
+
// ../../node_modules/apache-arrow/util/bn.mjs
|
|
3682
3716
|
var isArrowBigNumSymbol = Symbol.for("isArrowBigNum");
|
|
3683
3717
|
function BigNum(x3, ...xs) {
|
|
3684
3718
|
if (xs.length === 0) {
|
|
@@ -3690,8 +3724,8 @@ BigNum.prototype[isArrowBigNumSymbol] = true;
|
|
|
3690
3724
|
BigNum.prototype.toJSON = function() {
|
|
3691
3725
|
return `"${bigNumToString(this)}"`;
|
|
3692
3726
|
};
|
|
3693
|
-
BigNum.prototype.valueOf = function() {
|
|
3694
|
-
return bigNumToNumber(this);
|
|
3727
|
+
BigNum.prototype.valueOf = function(scale3) {
|
|
3728
|
+
return bigNumToNumber(this, scale3);
|
|
3695
3729
|
};
|
|
3696
3730
|
BigNum.prototype.toString = function() {
|
|
3697
3731
|
return bigNumToString(this);
|
|
@@ -3722,25 +3756,34 @@ Object.setPrototypeOf(DecimalBigNum.prototype, Object.create(Uint32Array.prototy
|
|
|
3722
3756
|
Object.assign(SignedBigNum.prototype, BigNum.prototype, { "constructor": SignedBigNum, "signed": true, "TypedArray": Int32Array, "BigIntArray": BigInt64Array });
|
|
3723
3757
|
Object.assign(UnsignedBigNum.prototype, BigNum.prototype, { "constructor": UnsignedBigNum, "signed": false, "TypedArray": Uint32Array, "BigIntArray": BigUint64Array });
|
|
3724
3758
|
Object.assign(DecimalBigNum.prototype, BigNum.prototype, { "constructor": DecimalBigNum, "signed": true, "TypedArray": Uint32Array, "BigIntArray": BigUint64Array });
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3759
|
+
var TWO_TO_THE_64 = BigInt(4294967296) * BigInt(4294967296);
|
|
3760
|
+
var TWO_TO_THE_64_MINUS_1 = TWO_TO_THE_64 - BigInt(1);
|
|
3761
|
+
function bigNumToNumber(bn, scale3) {
|
|
3762
|
+
const { buffer, byteOffset, byteLength, "signed": signed } = bn;
|
|
3763
|
+
const words = new BigUint64Array(buffer, byteOffset, byteLength / 8);
|
|
3728
3764
|
const negative2 = signed && words.at(-1) & BigInt(1) << BigInt(63);
|
|
3729
|
-
let number7 =
|
|
3730
|
-
let i =
|
|
3731
|
-
if (
|
|
3765
|
+
let number7 = BigInt(0);
|
|
3766
|
+
let i = 0;
|
|
3767
|
+
if (negative2) {
|
|
3732
3768
|
for (const word of words) {
|
|
3733
|
-
number7
|
|
3769
|
+
number7 |= (word ^ TWO_TO_THE_64_MINUS_1) * (BigInt(1) << BigInt(64 * i++));
|
|
3734
3770
|
}
|
|
3771
|
+
number7 *= BigInt(-1);
|
|
3772
|
+
number7 -= BigInt(1);
|
|
3735
3773
|
} else {
|
|
3736
3774
|
for (const word of words) {
|
|
3737
|
-
number7
|
|
3775
|
+
number7 |= word * (BigInt(1) << BigInt(64 * i++));
|
|
3738
3776
|
}
|
|
3739
|
-
number7 *= BigInt(-1);
|
|
3740
3777
|
}
|
|
3741
|
-
|
|
3778
|
+
if (typeof scale3 === "number") {
|
|
3779
|
+
const denominator = BigInt(Math.pow(10, scale3));
|
|
3780
|
+
const quotient = number7 / denominator;
|
|
3781
|
+
const remainder = number7 % denominator;
|
|
3782
|
+
return bigIntToNumber(quotient) + bigIntToNumber(remainder) / bigIntToNumber(denominator);
|
|
3783
|
+
}
|
|
3784
|
+
return bigIntToNumber(number7);
|
|
3742
3785
|
}
|
|
3743
|
-
|
|
3786
|
+
function bigNumToString(a2) {
|
|
3744
3787
|
if (a2.byteLength === 8) {
|
|
3745
3788
|
const bigIntArray = new a2["BigIntArray"](a2.buffer, a2.byteOffset, 1);
|
|
3746
3789
|
return `${bigIntArray[0]}`;
|
|
@@ -3763,15 +3806,15 @@ var bigNumToString = (a2) => {
|
|
|
3763
3806
|
}
|
|
3764
3807
|
const negated = unsignedBigNumToString(array4);
|
|
3765
3808
|
return `-${negated}`;
|
|
3766
|
-
}
|
|
3767
|
-
|
|
3809
|
+
}
|
|
3810
|
+
function bigNumToBigInt(a2) {
|
|
3768
3811
|
if (a2.byteLength === 8) {
|
|
3769
3812
|
const bigIntArray = new a2["BigIntArray"](a2.buffer, a2.byteOffset, 1);
|
|
3770
3813
|
return bigIntArray[0];
|
|
3771
3814
|
} else {
|
|
3772
3815
|
return bigNumToString(a2);
|
|
3773
3816
|
}
|
|
3774
|
-
}
|
|
3817
|
+
}
|
|
3775
3818
|
function unsignedBigNumToString(a2) {
|
|
3776
3819
|
let digits = "";
|
|
3777
3820
|
const base64 = new Uint32Array(2);
|
|
@@ -3828,14 +3871,6 @@ var BN = class _BN {
|
|
|
3828
3871
|
}
|
|
3829
3872
|
};
|
|
3830
3873
|
|
|
3831
|
-
// ../../node_modules/apache-arrow/util/bigint.mjs
|
|
3832
|
-
function bigIntToNumber(number7) {
|
|
3833
|
-
if (typeof number7 === "bigint" && (number7 < Number.MIN_SAFE_INTEGER || number7 > Number.MAX_SAFE_INTEGER)) {
|
|
3834
|
-
throw new TypeError(`${number7} is not safe to convert to a number.`);
|
|
3835
|
-
}
|
|
3836
|
-
return Number(number7);
|
|
3837
|
-
}
|
|
3838
|
-
|
|
3839
3874
|
// ../../node_modules/apache-arrow/type.mjs
|
|
3840
3875
|
var _a;
|
|
3841
3876
|
var _b;
|
|
@@ -4210,11 +4245,13 @@ var Date_ = class extends DataType {
|
|
|
4210
4245
|
toString() {
|
|
4211
4246
|
return `Date${(this.unit + 1) * 32}<${DateUnit[this.unit]}>`;
|
|
4212
4247
|
}
|
|
4248
|
+
get ArrayType() {
|
|
4249
|
+
return this.unit === DateUnit.DAY ? Int32Array : BigInt64Array;
|
|
4250
|
+
}
|
|
4213
4251
|
};
|
|
4214
4252
|
_l = Symbol.toStringTag;
|
|
4215
4253
|
Date_[_l] = ((proto) => {
|
|
4216
4254
|
proto.unit = null;
|
|
4217
|
-
proto.ArrayType = Int32Array;
|
|
4218
4255
|
return proto[Symbol.toStringTag] = "Date";
|
|
4219
4256
|
})(Date_.prototype);
|
|
4220
4257
|
var Time_ = class extends DataType {
|
|
@@ -4256,7 +4293,7 @@ _o = Symbol.toStringTag;
|
|
|
4256
4293
|
Timestamp_[_o] = ((proto) => {
|
|
4257
4294
|
proto.unit = null;
|
|
4258
4295
|
proto.timezone = null;
|
|
4259
|
-
proto.ArrayType =
|
|
4296
|
+
proto.ArrayType = BigInt64Array;
|
|
4260
4297
|
return proto[Symbol.toStringTag] = "Timestamp";
|
|
4261
4298
|
})(Timestamp_.prototype);
|
|
4262
4299
|
var Interval_ = class extends DataType {
|
|
@@ -4428,9 +4465,9 @@ Map_[_w] = ((proto) => {
|
|
|
4428
4465
|
})(Map_.prototype);
|
|
4429
4466
|
var getId = /* @__PURE__ */ ((atomicDictionaryId) => () => ++atomicDictionaryId)(-1);
|
|
4430
4467
|
var Dictionary = class extends DataType {
|
|
4431
|
-
constructor(dictionary,
|
|
4468
|
+
constructor(dictionary, indices2, id2, isOrdered2) {
|
|
4432
4469
|
super(Type2.Dictionary);
|
|
4433
|
-
this.indices =
|
|
4470
|
+
this.indices = indices2;
|
|
4434
4471
|
this.dictionary = dictionary;
|
|
4435
4472
|
this.isOrdered = isOrdered2 || false;
|
|
4436
4473
|
this.id = id2 == null ? getId() : bigIntToNumber(id2);
|
|
@@ -4461,10 +4498,6 @@ function strideForType(type2) {
|
|
|
4461
4498
|
switch (type2.typeId) {
|
|
4462
4499
|
case Type2.Decimal:
|
|
4463
4500
|
return type2.bitWidth / 32;
|
|
4464
|
-
case Type2.Timestamp:
|
|
4465
|
-
return 2;
|
|
4466
|
-
case Type2.Date:
|
|
4467
|
-
return 1 + t.unit;
|
|
4468
4501
|
case Type2.Interval:
|
|
4469
4502
|
return 1 + t.unit;
|
|
4470
4503
|
case Type2.FixedSizeList:
|
|
@@ -4931,19 +4964,7 @@ function wrapSet(fn) {
|
|
|
4931
4964
|
};
|
|
4932
4965
|
}
|
|
4933
4966
|
var setEpochMsToDays = (data, index2, epochMs) => {
|
|
4934
|
-
data[index2] = Math.
|
|
4935
|
-
};
|
|
4936
|
-
var setEpochMsToMillisecondsLong = (data, index2, epochMs) => {
|
|
4937
|
-
data[index2] = Math.trunc(epochMs % 4294967296);
|
|
4938
|
-
data[index2 + 1] = Math.trunc(epochMs / 4294967296);
|
|
4939
|
-
};
|
|
4940
|
-
var setEpochMsToMicrosecondsLong = (data, index2, epochMs) => {
|
|
4941
|
-
data[index2] = Math.trunc(epochMs * 1e3 % 4294967296);
|
|
4942
|
-
data[index2 + 1] = Math.trunc(epochMs * 1e3 / 4294967296);
|
|
4943
|
-
};
|
|
4944
|
-
var setEpochMsToNanosecondsLong = (data, index2, epochMs) => {
|
|
4945
|
-
data[index2] = Math.trunc(epochMs * 1e6 % 4294967296);
|
|
4946
|
-
data[index2 + 1] = Math.trunc(epochMs * 1e6 / 4294967296);
|
|
4967
|
+
data[index2] = Math.floor(epochMs / 864e5);
|
|
4947
4968
|
};
|
|
4948
4969
|
var setVariableWidthBytes = (values2, valueOffsets, index2, value) => {
|
|
4949
4970
|
if (index2 + 1 < valueOffsets.length) {
|
|
@@ -4978,7 +4999,7 @@ var setDateDay = ({ values: values2 }, index2, value) => {
|
|
|
4978
4999
|
setEpochMsToDays(values2, index2, value.valueOf());
|
|
4979
5000
|
};
|
|
4980
5001
|
var setDateMillisecond = ({ values: values2 }, index2, value) => {
|
|
4981
|
-
|
|
5002
|
+
values2[index2] = BigInt(value);
|
|
4982
5003
|
};
|
|
4983
5004
|
var setFixedSizeBinary = ({ stride, values: values2 }, index2, value) => {
|
|
4984
5005
|
values2.set(value.subarray(0, stride), stride * index2);
|
|
@@ -4988,10 +5009,18 @@ var setUtf8 = ({ values: values2, valueOffsets }, index2, value) => setVariableW
|
|
|
4988
5009
|
var setDate = (data, index2, value) => {
|
|
4989
5010
|
data.type.unit === DateUnit.DAY ? setDateDay(data, index2, value) : setDateMillisecond(data, index2, value);
|
|
4990
5011
|
};
|
|
4991
|
-
var setTimestampSecond = ({ values: values2 }, index2, value) =>
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
var
|
|
5012
|
+
var setTimestampSecond = ({ values: values2 }, index2, value) => {
|
|
5013
|
+
values2[index2] = BigInt(value / 1e3);
|
|
5014
|
+
};
|
|
5015
|
+
var setTimestampMillisecond = ({ values: values2 }, index2, value) => {
|
|
5016
|
+
values2[index2] = BigInt(value);
|
|
5017
|
+
};
|
|
5018
|
+
var setTimestampMicrosecond = ({ values: values2 }, index2, value) => {
|
|
5019
|
+
values2[index2] = BigInt(value * 1e3);
|
|
5020
|
+
};
|
|
5021
|
+
var setTimestampNanosecond = ({ values: values2 }, index2, value) => {
|
|
5022
|
+
values2[index2] = BigInt(value * 1e6);
|
|
5023
|
+
};
|
|
4995
5024
|
var setTimestamp = (data, index2, value) => {
|
|
4996
5025
|
switch (data.type.unit) {
|
|
4997
5026
|
case TimeUnit.SECOND:
|
|
@@ -5296,12 +5325,6 @@ function wrapGet(fn) {
|
|
|
5296
5325
|
return (data, _1) => data.getValid(_1) ? fn(data, _1) : null;
|
|
5297
5326
|
}
|
|
5298
5327
|
var epochDaysToMs = (data, index2) => 864e5 * data[index2];
|
|
5299
|
-
var epochMillisecondsLongToMs = (data, index2) => 4294967296 * data[index2 + 1] + (data[index2] >>> 0);
|
|
5300
|
-
var epochMicrosecondsLongToMs = (data, index2) => 4294967296 * (data[index2 + 1] / 1e3) + (data[index2] >>> 0) / 1e3;
|
|
5301
|
-
var epochNanosecondsLongToMs = (data, index2) => 4294967296 * (data[index2 + 1] / 1e6) + (data[index2] >>> 0) / 1e6;
|
|
5302
|
-
var epochMillisecondsToDate = (epochMs) => new Date(epochMs);
|
|
5303
|
-
var epochDaysToDate = (data, index2) => epochMillisecondsToDate(epochDaysToMs(data, index2));
|
|
5304
|
-
var epochMillisecondsLongToDate = (data, index2) => epochMillisecondsToDate(epochMillisecondsLongToMs(data, index2));
|
|
5305
5328
|
var getNull = (_data, _index) => null;
|
|
5306
5329
|
var getVariableWidthBytes = (values2, valueOffsets, index2) => {
|
|
5307
5330
|
if (index2 + 1 >= valueOffsets.length) {
|
|
@@ -5316,8 +5339,8 @@ var getBool = ({ offset: offset2, values: values2 }, index2) => {
|
|
|
5316
5339
|
const byte = values2[idx >> 3];
|
|
5317
5340
|
return (byte & 1 << idx % 8) !== 0;
|
|
5318
5341
|
};
|
|
5319
|
-
var getDateDay = ({ values: values2 }, index2) =>
|
|
5320
|
-
var getDateMillisecond = ({ values: values2 }, index2) =>
|
|
5342
|
+
var getDateDay = ({ values: values2 }, index2) => epochDaysToMs(values2, index2);
|
|
5343
|
+
var getDateMillisecond = ({ values: values2 }, index2) => bigIntToNumber(values2[index2]);
|
|
5321
5344
|
var getNumeric = ({ stride, values: values2 }, index2) => values2[stride * index2];
|
|
5322
5345
|
var getFloat16 = ({ stride, values: values2 }, index2) => uint16ToFloat64(values2[stride * index2]);
|
|
5323
5346
|
var getBigInts = ({ values: values2 }, index2) => values2[index2];
|
|
@@ -5330,10 +5353,10 @@ var getUtf8 = ({ values: values2, valueOffsets }, index2) => {
|
|
|
5330
5353
|
var getInt = ({ values: values2 }, index2) => values2[index2];
|
|
5331
5354
|
var getFloat = ({ type: type2, values: values2 }, index2) => type2.precision !== Precision.HALF ? values2[index2] : uint16ToFloat64(values2[index2]);
|
|
5332
5355
|
var getDate = (data, index2) => data.type.unit === DateUnit.DAY ? getDateDay(data, index2) : getDateMillisecond(data, index2);
|
|
5333
|
-
var getTimestampSecond = ({ values: values2 }, index2) => 1e3 *
|
|
5334
|
-
var getTimestampMillisecond = ({ values: values2 }, index2) =>
|
|
5335
|
-
var getTimestampMicrosecond = ({ values: values2 }, index2) =>
|
|
5336
|
-
var getTimestampNanosecond = ({ values: values2 }, index2) =>
|
|
5356
|
+
var getTimestampSecond = ({ values: values2 }, index2) => 1e3 * bigIntToNumber(values2[index2]);
|
|
5357
|
+
var getTimestampMillisecond = ({ values: values2 }, index2) => bigIntToNumber(values2[index2]);
|
|
5358
|
+
var getTimestampMicrosecond = ({ values: values2 }, index2) => divideBigInts(values2[index2], BigInt(1e3));
|
|
5359
|
+
var getTimestampNanosecond = ({ values: values2 }, index2) => divideBigInts(values2[index2], BigInt(1e6));
|
|
5337
5360
|
var getTimestamp = (data, index2) => {
|
|
5338
5361
|
switch (data.type.unit) {
|
|
5339
5362
|
case TimeUnit.SECOND:
|
|
@@ -5482,12 +5505,18 @@ var instance2 = new GetVisitor();
|
|
|
5482
5505
|
// ../../node_modules/apache-arrow/row/map.mjs
|
|
5483
5506
|
var kKeys = Symbol.for("keys");
|
|
5484
5507
|
var kVals = Symbol.for("vals");
|
|
5508
|
+
var kKeysAsStrings = Symbol.for("kKeysAsStrings");
|
|
5509
|
+
var _kKeysAsStrings = Symbol.for("_kKeysAsStrings");
|
|
5485
5510
|
var MapRow = class {
|
|
5486
5511
|
constructor(slice4) {
|
|
5487
5512
|
this[kKeys] = new Vector([slice4.children[0]]).memoize();
|
|
5488
5513
|
this[kVals] = slice4.children[1];
|
|
5489
5514
|
return new Proxy(this, new MapRowProxyHandler());
|
|
5490
5515
|
}
|
|
5516
|
+
/** @ignore */
|
|
5517
|
+
get [kKeysAsStrings]() {
|
|
5518
|
+
return this[_kKeysAsStrings] || (this[_kKeysAsStrings] = Array.from(this[kKeys].toArray(), String));
|
|
5519
|
+
}
|
|
5491
5520
|
[Symbol.iterator]() {
|
|
5492
5521
|
return new MapRowIterator(this[kKeys], this[kVals]);
|
|
5493
5522
|
}
|
|
@@ -5549,13 +5578,13 @@ var MapRowProxyHandler = class {
|
|
|
5549
5578
|
return true;
|
|
5550
5579
|
}
|
|
5551
5580
|
ownKeys(row) {
|
|
5552
|
-
return row[
|
|
5581
|
+
return row[kKeysAsStrings];
|
|
5553
5582
|
}
|
|
5554
5583
|
has(row, key) {
|
|
5555
|
-
return row[
|
|
5584
|
+
return row[kKeysAsStrings].includes(key);
|
|
5556
5585
|
}
|
|
5557
5586
|
getOwnPropertyDescriptor(row, key) {
|
|
5558
|
-
const idx = row[
|
|
5587
|
+
const idx = row[kKeysAsStrings].indexOf(key);
|
|
5559
5588
|
if (idx !== -1) {
|
|
5560
5589
|
return { writable: true, enumerable: true, configurable: true };
|
|
5561
5590
|
}
|
|
@@ -5565,7 +5594,7 @@ var MapRowProxyHandler = class {
|
|
|
5565
5594
|
if (Reflect.has(row, key)) {
|
|
5566
5595
|
return row[key];
|
|
5567
5596
|
}
|
|
5568
|
-
const idx = row[
|
|
5597
|
+
const idx = row[kKeysAsStrings].indexOf(key);
|
|
5569
5598
|
if (idx !== -1) {
|
|
5570
5599
|
const val = instance2.visit(Reflect.get(row, kVals), idx);
|
|
5571
5600
|
Reflect.set(row, key, val);
|
|
@@ -5573,7 +5602,7 @@ var MapRowProxyHandler = class {
|
|
|
5573
5602
|
}
|
|
5574
5603
|
}
|
|
5575
5604
|
set(row, key, val) {
|
|
5576
|
-
const idx = row[
|
|
5605
|
+
const idx = row[kKeysAsStrings].indexOf(key);
|
|
5577
5606
|
if (idx !== -1) {
|
|
5578
5607
|
instance.visit(Reflect.get(row, kVals), idx, val);
|
|
5579
5608
|
return Reflect.set(row, key, val);
|
|
@@ -5586,15 +5615,11 @@ var MapRowProxyHandler = class {
|
|
|
5586
5615
|
Object.defineProperties(MapRow.prototype, {
|
|
5587
5616
|
[Symbol.toStringTag]: { enumerable: false, configurable: false, value: "Row" },
|
|
5588
5617
|
[kKeys]: { writable: true, enumerable: false, configurable: false, value: null },
|
|
5589
|
-
[kVals]: { writable: true, enumerable: false, configurable: false, value: null }
|
|
5618
|
+
[kVals]: { writable: true, enumerable: false, configurable: false, value: null },
|
|
5619
|
+
[_kKeysAsStrings]: { writable: true, enumerable: false, configurable: false, value: null }
|
|
5590
5620
|
});
|
|
5591
5621
|
|
|
5592
5622
|
// ../../node_modules/apache-arrow/util/vector.mjs
|
|
5593
|
-
function clampIndex(source, index2, then) {
|
|
5594
|
-
const length4 = source.length;
|
|
5595
|
-
const adjust = index2 > -1 ? index2 : length4 + index2 % length4;
|
|
5596
|
-
return then ? then(source, adjust) : adjust;
|
|
5597
|
-
}
|
|
5598
5623
|
var tmp;
|
|
5599
5624
|
function clampRange(source, begin, end, then) {
|
|
5600
5625
|
const { length: len = 0 } = source;
|
|
@@ -5606,6 +5631,7 @@ function clampRange(source, begin, end, then) {
|
|
|
5606
5631
|
rhs > len && (rhs = len);
|
|
5607
5632
|
return then ? then(source, lhs, rhs) : [lhs, rhs];
|
|
5608
5633
|
}
|
|
5634
|
+
var wrapIndex = (index2, len) => index2 < 0 ? len + index2 : index2;
|
|
5609
5635
|
var isNaNFast = (value) => value !== value;
|
|
5610
5636
|
function createElementComparator(search) {
|
|
5611
5637
|
const typeofSearch = typeof search;
|
|
@@ -5894,7 +5920,10 @@ var Data = class _Data {
|
|
|
5894
5920
|
let nullCount = this._nullCount;
|
|
5895
5921
|
let nullBitmap;
|
|
5896
5922
|
if (nullCount <= kUnknownNullCount && (nullBitmap = this.nullBitmap)) {
|
|
5897
|
-
this._nullCount = nullCount =
|
|
5923
|
+
this._nullCount = nullCount = nullBitmap.length === 0 ? (
|
|
5924
|
+
// no null bitmap, so all values are valid
|
|
5925
|
+
0
|
|
5926
|
+
) : this.length - popcnt_bit_range(nullBitmap, this.offset, this.offset + this.length);
|
|
5898
5927
|
}
|
|
5899
5928
|
return nullCount;
|
|
5900
5929
|
}
|
|
@@ -5956,12 +5985,14 @@ var Data = class _Data {
|
|
|
5956
5985
|
nullBitmap = new Uint8Array((offset2 + length4 + 63 & ~63) >> 3).fill(255);
|
|
5957
5986
|
if (this.nullCount > 0) {
|
|
5958
5987
|
nullBitmap.set(truncateBitmap(offset2, length4, this.nullBitmap), 0);
|
|
5988
|
+
Object.assign(this, { nullBitmap });
|
|
5989
|
+
} else {
|
|
5990
|
+
Object.assign(this, { nullBitmap, _nullCount: 0 });
|
|
5959
5991
|
}
|
|
5960
|
-
Object.assign(this, { nullBitmap, _nullCount: -1 });
|
|
5961
5992
|
}
|
|
5962
5993
|
const byte = nullBitmap[byteOffset];
|
|
5963
5994
|
prev = (byte & mask) !== 0;
|
|
5964
|
-
|
|
5995
|
+
nullBitmap[byteOffset] = value ? byte | mask : byte & ~mask;
|
|
5965
5996
|
}
|
|
5966
5997
|
if (prev !== !!value) {
|
|
5967
5998
|
this._nullCount = this.nullCount + (value ? -1 : 1);
|
|
@@ -6402,7 +6433,9 @@ var IteratorVisitor = class extends Visitor {
|
|
|
6402
6433
|
};
|
|
6403
6434
|
function vectorIterator(vector2) {
|
|
6404
6435
|
const { type: type2 } = vector2;
|
|
6405
|
-
if (vector2.nullCount === 0 && vector2.stride === 1 &&
|
|
6436
|
+
if (vector2.nullCount === 0 && vector2.stride === 1 && // Don't defer to native iterator for timestamps since Numbers are expected
|
|
6437
|
+
// (DataType.isTimestamp(type)) && type.unit === TimeUnit.MILLISECOND ||
|
|
6438
|
+
(DataType.isInt(type2) && type2.bitWidth !== 64 || DataType.isTime(type2) && type2.bitWidth !== 64 || DataType.isFloat(type2) && type2.precision !== Precision.HALF)) {
|
|
6406
6439
|
return new ChunkedIterator(vector2.data.length, (chunkIndex) => {
|
|
6407
6440
|
const data = vector2.data[chunkIndex];
|
|
6408
6441
|
return data.values.subarray(0, data.length)[Symbol.iterator]();
|
|
@@ -6576,6 +6609,13 @@ var Vector = class _Vector {
|
|
|
6576
6609
|
get(index2) {
|
|
6577
6610
|
return null;
|
|
6578
6611
|
}
|
|
6612
|
+
/**
|
|
6613
|
+
* Get an element value by position.
|
|
6614
|
+
* @param index The index of the element to read. A negative index will count back from the last element.
|
|
6615
|
+
*/
|
|
6616
|
+
at(index2) {
|
|
6617
|
+
return this.get(wrapIndex(index2, this.length));
|
|
6618
|
+
}
|
|
6579
6619
|
/**
|
|
6580
6620
|
* Set an element value by position.
|
|
6581
6621
|
* @param index The index of the element to write.
|
|
@@ -7853,8 +7893,8 @@ var AsyncByteStreamSource = class {
|
|
|
7853
7893
|
return (yield this.next(size, "peek")).value;
|
|
7854
7894
|
});
|
|
7855
7895
|
}
|
|
7856
|
-
next(
|
|
7857
|
-
return __awaiter(this,
|
|
7896
|
+
next(size_1) {
|
|
7897
|
+
return __awaiter(this, arguments, void 0, function* (size, cmd = "read") {
|
|
7858
7898
|
return yield this.source.next({ cmd, size });
|
|
7859
7899
|
});
|
|
7860
7900
|
}
|
|
@@ -8595,9 +8635,9 @@ var DictionaryBuilder = class extends Builder2 {
|
|
|
8595
8635
|
return this.indices.isValid(value);
|
|
8596
8636
|
}
|
|
8597
8637
|
setValid(index2, valid2) {
|
|
8598
|
-
const
|
|
8599
|
-
valid2 =
|
|
8600
|
-
this.length =
|
|
8638
|
+
const indices2 = this.indices;
|
|
8639
|
+
valid2 = indices2.setValid(index2, valid2);
|
|
8640
|
+
this.length = indices2.length;
|
|
8601
8641
|
return valid2;
|
|
8602
8642
|
}
|
|
8603
8643
|
setValue(index2, value) {
|
|
@@ -9431,6 +9471,14 @@ var Table = class _Table {
|
|
|
9431
9471
|
get(index2) {
|
|
9432
9472
|
return null;
|
|
9433
9473
|
}
|
|
9474
|
+
/**
|
|
9475
|
+
* Get an element value by position.
|
|
9476
|
+
* @param index The index of the element to read. A negative index will count back from the last element.
|
|
9477
|
+
*/
|
|
9478
|
+
// @ts-ignore
|
|
9479
|
+
at(index2) {
|
|
9480
|
+
return this.get(wrapIndex(index2, this.numRows));
|
|
9481
|
+
}
|
|
9434
9482
|
/**
|
|
9435
9483
|
* Set an element value by position.
|
|
9436
9484
|
*
|
|
@@ -9573,16 +9621,16 @@ var Table = class _Table {
|
|
|
9573
9621
|
}
|
|
9574
9622
|
assign(other) {
|
|
9575
9623
|
const fields = this.schema.fields;
|
|
9576
|
-
const [
|
|
9577
|
-
const [
|
|
9624
|
+
const [indices2, oldToNew] = other.schema.fields.reduce((memo2, f2, newIdx) => {
|
|
9625
|
+
const [indices3, oldToNew2] = memo2;
|
|
9578
9626
|
const i = fields.findIndex((f) => f.name === f2.name);
|
|
9579
|
-
~i ? oldToNew2[i] = newIdx :
|
|
9627
|
+
~i ? oldToNew2[i] = newIdx : indices3.push(newIdx);
|
|
9580
9628
|
return memo2;
|
|
9581
9629
|
}, [[], []]);
|
|
9582
9630
|
const schema = this.schema.assign(other.schema);
|
|
9583
9631
|
const columns = [
|
|
9584
9632
|
...fields.map((_, i) => [i, oldToNew[i]]).map(([i, j]) => j === void 0 ? this.getChildAt(i) : other.getChildAt(j)),
|
|
9585
|
-
...
|
|
9633
|
+
...indices2.map((i) => other.getChildAt(i))
|
|
9586
9634
|
].filter(Boolean);
|
|
9587
9635
|
return new _Table(...distributeVectorsIntoRecordBatches(schema, columns));
|
|
9588
9636
|
}
|
|
@@ -9668,7 +9716,7 @@ var RecordBatch2 = class _RecordBatch {
|
|
|
9668
9716
|
return this.data.nullCount;
|
|
9669
9717
|
}
|
|
9670
9718
|
/**
|
|
9671
|
-
* Check whether an
|
|
9719
|
+
* Check whether an row is null.
|
|
9672
9720
|
* @param index The index at which to read the validity bitmap.
|
|
9673
9721
|
*/
|
|
9674
9722
|
isValid(index2) {
|
|
@@ -9676,14 +9724,21 @@ var RecordBatch2 = class _RecordBatch {
|
|
|
9676
9724
|
}
|
|
9677
9725
|
/**
|
|
9678
9726
|
* Get a row by position.
|
|
9679
|
-
* @param index The index of the
|
|
9727
|
+
* @param index The index of the row to read.
|
|
9680
9728
|
*/
|
|
9681
9729
|
get(index2) {
|
|
9682
9730
|
return instance2.visit(this.data, index2);
|
|
9683
9731
|
}
|
|
9732
|
+
/**
|
|
9733
|
+
* Get a row value by position.
|
|
9734
|
+
* @param index The index of the row to read. A negative index will count back from the last row.
|
|
9735
|
+
*/
|
|
9736
|
+
at(index2) {
|
|
9737
|
+
return this.get(wrapIndex(index2, this.numRows));
|
|
9738
|
+
}
|
|
9684
9739
|
/**
|
|
9685
9740
|
* Set a row by position.
|
|
9686
|
-
* @param index The index of the
|
|
9741
|
+
* @param index The index of the row to write.
|
|
9687
9742
|
* @param value The value to set.
|
|
9688
9743
|
*/
|
|
9689
9744
|
set(index2, value) {
|
|
@@ -9720,7 +9775,7 @@ var RecordBatch2 = class _RecordBatch {
|
|
|
9720
9775
|
/**
|
|
9721
9776
|
* Return a zero-copy sub-section of this RecordBatch.
|
|
9722
9777
|
* @param start The beginning of the specified portion of the RecordBatch.
|
|
9723
|
-
* @param end The end of the specified portion of the RecordBatch. This is exclusive of the
|
|
9778
|
+
* @param end The end of the specified portion of the RecordBatch. This is exclusive of the row at the index 'end'.
|
|
9724
9779
|
*/
|
|
9725
9780
|
slice(begin, end) {
|
|
9726
9781
|
const [slice4] = new Vector([this.data]).slice(begin, end).data;
|
|
@@ -10808,8 +10863,8 @@ var AsyncMessageReader = class {
|
|
|
10808
10863
|
);
|
|
10809
10864
|
});
|
|
10810
10865
|
}
|
|
10811
|
-
readSchema(
|
|
10812
|
-
return __awaiter(this,
|
|
10866
|
+
readSchema() {
|
|
10867
|
+
return __awaiter(this, arguments, void 0, function* (throwIfNull = false) {
|
|
10813
10868
|
const type2 = MessageHeader.Schema;
|
|
10814
10869
|
const message = yield this.readMessage(type2);
|
|
10815
10870
|
const schema = message === null || message === void 0 ? void 0 : message.header();
|
|
@@ -11057,8 +11112,8 @@ var AsyncRecordBatchStreamReader = class extends RecordBatchReader {
|
|
|
11057
11112
|
this._impl = _impl;
|
|
11058
11113
|
}
|
|
11059
11114
|
readAll() {
|
|
11060
|
-
var _a5, e_1, _b2, _c2;
|
|
11061
11115
|
return __awaiter(this, void 0, void 0, function* () {
|
|
11116
|
+
var _a5, e_1, _b2, _c2;
|
|
11062
11117
|
const batches = new Array();
|
|
11063
11118
|
try {
|
|
11064
11119
|
for (var _d2 = true, _e2 = __asyncValues(this), _f2; _f2 = yield _e2.next(), _a5 = _f2.done, !_a5; _d2 = true) {
|
|
@@ -11431,8 +11486,8 @@ var AsyncRecordBatchFileReaderImpl = class extends AsyncRecordBatchStreamReaderI
|
|
|
11431
11486
|
});
|
|
11432
11487
|
}
|
|
11433
11488
|
readRecordBatch(index2) {
|
|
11434
|
-
var _a5;
|
|
11435
11489
|
return __awaiter(this, void 0, void 0, function* () {
|
|
11490
|
+
var _a5;
|
|
11436
11491
|
if (this.closed) {
|
|
11437
11492
|
return null;
|
|
11438
11493
|
}
|
|
@@ -11453,8 +11508,8 @@ var AsyncRecordBatchFileReaderImpl = class extends AsyncRecordBatchStreamReaderI
|
|
|
11453
11508
|
});
|
|
11454
11509
|
}
|
|
11455
11510
|
_readDictionaryBatch(index2) {
|
|
11456
|
-
var _a5;
|
|
11457
11511
|
return __awaiter(this, void 0, void 0, function* () {
|
|
11512
|
+
var _a5;
|
|
11458
11513
|
const block = (_a5 = this._footer) === null || _a5 === void 0 ? void 0 : _a5.getDictionaryBatch(index2);
|
|
11459
11514
|
if (block && (yield this._handle.seek(block.offset))) {
|
|
11460
11515
|
const message = yield this._reader.readMessage(MessageHeader.DictionaryBatch);
|
|
@@ -11959,9 +12014,9 @@ function writeAll(writer, input) {
|
|
|
11959
12014
|
return writer.finish();
|
|
11960
12015
|
}
|
|
11961
12016
|
function writeAllAsync(writer, batches) {
|
|
11962
|
-
var _a5, batches_1, batches_1_1;
|
|
11963
|
-
var _b2, e_1, _c2, _d2;
|
|
11964
12017
|
return __awaiter(this, void 0, void 0, function* () {
|
|
12018
|
+
var _a5, batches_1, batches_1_1;
|
|
12019
|
+
var _b2, e_1, _c2, _d2;
|
|
11965
12020
|
try {
|
|
11966
12021
|
for (_a5 = true, batches_1 = __asyncValues(batches); batches_1_1 = yield batches_1.next(), _b2 = batches_1_1.done, !_b2; _a5 = true) {
|
|
11967
12022
|
_d2 = batches_1_1.value;
|
|
@@ -12324,6 +12379,13 @@ function socketConnector(uri = "ws://localhost:3000/") {
|
|
|
12324
12379
|
get connected() {
|
|
12325
12380
|
return connected;
|
|
12326
12381
|
},
|
|
12382
|
+
/**
|
|
12383
|
+
* Query the DuckDB server.
|
|
12384
|
+
* @param {object} query
|
|
12385
|
+
* @param {'exec' | 'arrow' | 'json'} [query.type] The query type: 'exec', 'arrow', or 'json'.
|
|
12386
|
+
* @param {string} query.sql A SQL query string.
|
|
12387
|
+
* @returns the query result
|
|
12388
|
+
*/
|
|
12327
12389
|
query(query) {
|
|
12328
12390
|
return new Promise(
|
|
12329
12391
|
(resolve, reject) => enqueue(query, resolve, reject)
|
|
@@ -12394,7 +12456,7 @@ function literalToSQL(value) {
|
|
|
12394
12456
|
case "boolean":
|
|
12395
12457
|
return value ? "TRUE" : "FALSE";
|
|
12396
12458
|
case "string":
|
|
12397
|
-
return `'${value}'`;
|
|
12459
|
+
return `'${value.replace(`'`, `''`)}'`;
|
|
12398
12460
|
case "number":
|
|
12399
12461
|
return Number.isFinite(value) ? String(value) : "NULL";
|
|
12400
12462
|
default:
|
|
@@ -12477,7 +12539,7 @@ var SQLExpression = class {
|
|
|
12477
12539
|
/**
|
|
12478
12540
|
* Annotate this expression instance with additional properties.
|
|
12479
12541
|
* @param {object[]} [props] One or more objects with properties to add.
|
|
12480
|
-
* @returns
|
|
12542
|
+
* @returns This SQL expression.
|
|
12481
12543
|
*/
|
|
12482
12544
|
annotate(...props) {
|
|
12483
12545
|
return Object.assign(this, ...props);
|
|
@@ -12739,6 +12801,9 @@ var last_value = winf("LAST_VALUE");
|
|
|
12739
12801
|
var nth_value = winf("NTH_VALUE");
|
|
12740
12802
|
|
|
12741
12803
|
// ../sql/src/aggregates.js
|
|
12804
|
+
function agg(strings, ...exprs) {
|
|
12805
|
+
return sql(strings, ...exprs).annotate({ aggregate: true });
|
|
12806
|
+
}
|
|
12742
12807
|
var AggregateFunction = class _AggregateFunction extends SQLExpression {
|
|
12743
12808
|
/**
|
|
12744
12809
|
* Create a new AggregateFunction instance.
|
|
@@ -12869,6 +12934,7 @@ var entropy = aggf("ENTROPY");
|
|
|
12869
12934
|
var varPop = aggf("VAR_POP");
|
|
12870
12935
|
var stddevPop = aggf("STDDEV_POP");
|
|
12871
12936
|
var corr = aggf("CORR");
|
|
12937
|
+
var covariance = aggf("COVAR_SAMP");
|
|
12872
12938
|
var covarPop = aggf("COVAR_POP");
|
|
12873
12939
|
var regrIntercept = aggf("REGR_INTERCEPT");
|
|
12874
12940
|
var regrSlope = aggf("REGR_SLOPE");
|
|
@@ -12910,6 +12976,11 @@ var castDouble = (expr) => cast(expr, "DOUBLE");
|
|
|
12910
12976
|
var epoch_ms = (expr) => {
|
|
12911
12977
|
return sql`epoch_ms(${asColumn(expr)})`;
|
|
12912
12978
|
};
|
|
12979
|
+
function dateBin(expr, interval2, steps = 1) {
|
|
12980
|
+
const i = `INTERVAL ${steps} ${interval2}`;
|
|
12981
|
+
const d = asColumn(expr);
|
|
12982
|
+
return sql`TIME_BUCKET(${i}, ${d})`.annotate({ label: interval2 });
|
|
12983
|
+
}
|
|
12913
12984
|
|
|
12914
12985
|
// ../sql/src/spatial.js
|
|
12915
12986
|
var geojson = functionCall("ST_AsGeoJSON");
|
|
@@ -13031,7 +13102,8 @@ var Query = class _Query {
|
|
|
13031
13102
|
}
|
|
13032
13103
|
}
|
|
13033
13104
|
}
|
|
13034
|
-
|
|
13105
|
+
const keys = new Set(list.map((x3) => x3.as));
|
|
13106
|
+
query.select = query.select.filter((x3) => !keys.has(x3.as)).concat(list.filter((x3) => x3.expr));
|
|
13035
13107
|
return this;
|
|
13036
13108
|
}
|
|
13037
13109
|
}
|
|
@@ -13504,6 +13576,7 @@ function scaleTime() {
|
|
|
13504
13576
|
};
|
|
13505
13577
|
}
|
|
13506
13578
|
var scales = {
|
|
13579
|
+
identity: scaleLinear,
|
|
13507
13580
|
linear: scaleLinear,
|
|
13508
13581
|
log: scaleLog,
|
|
13509
13582
|
symlog: scaleSymlog,
|
|
@@ -13526,179 +13599,97 @@ function create(name, query, {
|
|
|
13526
13599
|
return "CREATE" + (replace ? " OR REPLACE " : " ") + (temp ? "TEMP " : "") + (view ? "VIEW" : "TABLE") + (replace ? " " : " IF NOT EXISTS ") + name + " AS " + query;
|
|
13527
13600
|
}
|
|
13528
13601
|
|
|
13529
|
-
// ../core/src/util/
|
|
13530
|
-
function
|
|
13531
|
-
|
|
13532
|
-
for (let i = 0, n = v2.length; i < n; ++i) {
|
|
13533
|
-
const c4 = v2.charCodeAt(i);
|
|
13534
|
-
const d = c4 & 65280;
|
|
13535
|
-
if (d) a2 = fnv_multiply(a2 ^ d >> 8);
|
|
13536
|
-
a2 = fnv_multiply(a2 ^ c4 & 255);
|
|
13537
|
-
}
|
|
13538
|
-
return fnv_mix(a2);
|
|
13539
|
-
}
|
|
13540
|
-
function fnv_multiply(a2) {
|
|
13541
|
-
return a2 + (a2 << 1) + (a2 << 4) + (a2 << 7) + (a2 << 8) + (a2 << 24);
|
|
13542
|
-
}
|
|
13543
|
-
function fnv_mix(a2) {
|
|
13544
|
-
a2 += a2 << 13;
|
|
13545
|
-
a2 ^= a2 >>> 7;
|
|
13546
|
-
a2 += a2 << 3;
|
|
13547
|
-
a2 ^= a2 >>> 17;
|
|
13548
|
-
a2 += a2 << 5;
|
|
13549
|
-
return a2 & 4294967295;
|
|
13550
|
-
}
|
|
13551
|
-
|
|
13552
|
-
// ../core/src/DataCubeIndexer.js
|
|
13553
|
-
var DataCubeIndexer = class {
|
|
13554
|
-
/**
|
|
13555
|
-
*
|
|
13556
|
-
* @param {import('./Coordinator.js').Coordinator} mc a Mosaic coordinator
|
|
13557
|
-
* @param {*} options Options hash to configure the data cube indexes and pass selections to the coordinator.
|
|
13558
|
-
*/
|
|
13559
|
-
constructor(mc, { selection: selection2, temp = true }) {
|
|
13560
|
-
this.mc = mc;
|
|
13561
|
-
this.selection = selection2;
|
|
13562
|
-
this.temp = temp;
|
|
13563
|
-
this.reset();
|
|
13564
|
-
}
|
|
13565
|
-
reset() {
|
|
13566
|
-
this.enabled = false;
|
|
13567
|
-
this.clients = null;
|
|
13568
|
-
this.indices = null;
|
|
13569
|
-
this.activeView = null;
|
|
13570
|
-
}
|
|
13571
|
-
clear() {
|
|
13572
|
-
if (this.indices) {
|
|
13573
|
-
this.mc.cancel(Array.from(this.indices.values(), (index2) => index2.result));
|
|
13574
|
-
this.indices = null;
|
|
13575
|
-
}
|
|
13576
|
-
}
|
|
13577
|
-
index(clients, active) {
|
|
13578
|
-
if (this.clients !== clients) {
|
|
13579
|
-
const cols = Array.from(clients, getIndexColumns);
|
|
13580
|
-
const from = cols[0]?.from;
|
|
13581
|
-
this.enabled = cols.every((c4) => c4 && c4.from === from);
|
|
13582
|
-
this.clients = clients;
|
|
13583
|
-
this.activeView = null;
|
|
13584
|
-
this.clear();
|
|
13585
|
-
}
|
|
13586
|
-
if (!this.enabled) return false;
|
|
13587
|
-
active = active || this.selection.active;
|
|
13588
|
-
const { source } = active;
|
|
13589
|
-
if (source && source === this.activeView?.source) return true;
|
|
13590
|
-
this.clear();
|
|
13591
|
-
if (!source) return false;
|
|
13592
|
-
const activeView = this.activeView = getActiveView(active);
|
|
13593
|
-
if (!activeView) return false;
|
|
13594
|
-
this.mc.logger().warn("DATA CUBE INDEX CONSTRUCTION");
|
|
13595
|
-
const sel = this.selection.remove(source);
|
|
13596
|
-
const indices = this.indices = /* @__PURE__ */ new Map();
|
|
13597
|
-
const { mc, temp } = this;
|
|
13598
|
-
for (const client of clients) {
|
|
13599
|
-
if (sel.skip(client, active)) continue;
|
|
13600
|
-
const index2 = getIndexColumns(client);
|
|
13601
|
-
const query = client.query(sel.predicate(client)).select({ ...activeView.columns, ...index2.aux }).groupby(Object.keys(activeView.columns));
|
|
13602
|
-
const [subq] = query.subqueries;
|
|
13603
|
-
if (subq) {
|
|
13604
|
-
const cols = Object.values(activeView.columns).map((c4) => c4.columns[0]);
|
|
13605
|
-
subqueryPushdown(subq, cols);
|
|
13606
|
-
}
|
|
13607
|
-
const order = query.orderby();
|
|
13608
|
-
query.query.orderby = [];
|
|
13609
|
-
const sql2 = query.toString();
|
|
13610
|
-
const id2 = (fnv_hash(sql2) >>> 0).toString(16);
|
|
13611
|
-
const table = `cube_index_${id2}`;
|
|
13612
|
-
const result = mc.exec(create(table, sql2, { temp }));
|
|
13613
|
-
indices.set(client, { table, result, order, ...index2 });
|
|
13614
|
-
}
|
|
13615
|
-
return true;
|
|
13616
|
-
}
|
|
13617
|
-
async update() {
|
|
13618
|
-
const { clients, selection: selection2, activeView } = this;
|
|
13619
|
-
const filter3 = activeView.predicate(selection2.active.predicate);
|
|
13620
|
-
return Promise.all(
|
|
13621
|
-
Array.from(clients).map((client) => this.updateClient(client, filter3))
|
|
13622
|
-
);
|
|
13623
|
-
}
|
|
13624
|
-
async updateClient(client, filter3) {
|
|
13625
|
-
const index2 = this.indices.get(client);
|
|
13626
|
-
if (!index2) return;
|
|
13627
|
-
if (!filter3) {
|
|
13628
|
-
filter3 = this.activeView.predicate(this.selection.active.predicate);
|
|
13629
|
-
}
|
|
13630
|
-
const { table, dims, aggr, order = [] } = index2;
|
|
13631
|
-
const query = Query.select(dims, aggr).from(table).groupby(dims).where(filter3).orderby(order);
|
|
13632
|
-
return this.mc.updateClient(client, query);
|
|
13633
|
-
}
|
|
13634
|
-
};
|
|
13635
|
-
function getActiveView(clause) {
|
|
13636
|
-
const { source, schema } = clause;
|
|
13637
|
-
let columns = clause.predicate?.columns;
|
|
13638
|
-
if (!schema || !columns) return null;
|
|
13639
|
-
const { type: type2, scales: scales2, pixelSize = 1 } = schema;
|
|
13640
|
-
let predicate;
|
|
13641
|
-
if (type2 === "interval" && scales2) {
|
|
13642
|
-
const bins2 = scales2.map((s2) => binInterval(s2, pixelSize));
|
|
13643
|
-
if (bins2.some((b) => b == null)) return null;
|
|
13644
|
-
if (bins2.length === 1) {
|
|
13645
|
-
predicate = (p) => p ? isBetween("active0", p.range.map(bins2[0])) : [];
|
|
13646
|
-
columns = { active0: bins2[0](clause.predicate.field) };
|
|
13647
|
-
} else {
|
|
13648
|
-
predicate = (p) => p ? and(p.children.map(({ range: range3 }, i) => isBetween(`active${i}`, range3.map(bins2[i])))) : [];
|
|
13649
|
-
columns = Object.fromEntries(
|
|
13650
|
-
clause.predicate.children.map((p, i) => [`active${i}`, bins2[i](p.field)])
|
|
13651
|
-
);
|
|
13652
|
-
}
|
|
13653
|
-
} else if (type2 === "point") {
|
|
13654
|
-
predicate = (x3) => x3;
|
|
13655
|
-
columns = Object.fromEntries(columns.map((col) => [col.toString(), col]));
|
|
13656
|
-
} else {
|
|
13657
|
-
return null;
|
|
13658
|
-
}
|
|
13659
|
-
return { source, columns, predicate };
|
|
13660
|
-
}
|
|
13661
|
-
function binInterval(scale3, pixelSize) {
|
|
13662
|
-
const { apply: apply2, sqlApply } = scaleTransform(scale3);
|
|
13663
|
-
if (apply2) {
|
|
13664
|
-
const { domain, range: range3 } = scale3;
|
|
13665
|
-
const lo = apply2(Math.min(...domain));
|
|
13666
|
-
const hi = apply2(Math.max(...domain));
|
|
13667
|
-
const a2 = Math.abs(range3[1] - range3[0]) / (hi - lo) / pixelSize;
|
|
13668
|
-
const s2 = pixelSize === 1 ? "" : `${pixelSize}::INTEGER * `;
|
|
13669
|
-
return (value) => sql`${s2}FLOOR(${a2}::DOUBLE * (${sqlApply(value)} - ${lo}::DOUBLE))::INTEGER`;
|
|
13670
|
-
}
|
|
13671
|
-
}
|
|
13672
|
-
var NO_INDEX = { from: NaN };
|
|
13673
|
-
function getIndexColumns(client) {
|
|
13674
|
-
if (!client.filterIndexable) return NO_INDEX;
|
|
13602
|
+
// ../core/src/util/index-columns.js
|
|
13603
|
+
function indexColumns(client) {
|
|
13604
|
+
if (!client.filterIndexable) return null;
|
|
13675
13605
|
const q = client.query();
|
|
13676
13606
|
const from = getBaseTable(q);
|
|
13677
|
-
if (
|
|
13678
|
-
const g = new Set(q.groupby().map((c4) => c4.column));
|
|
13607
|
+
if (typeof from !== "string" || !q.select) return null;
|
|
13679
13608
|
const aggr = [];
|
|
13680
13609
|
const dims = [];
|
|
13681
13610
|
const aux = {};
|
|
13682
|
-
let auxAs;
|
|
13683
13611
|
for (const entry of q.select()) {
|
|
13684
13612
|
const { as, expr: { aggregate, args } } = entry;
|
|
13685
13613
|
const op = aggregate?.toUpperCase?.();
|
|
13686
13614
|
switch (op) {
|
|
13687
13615
|
case "COUNT":
|
|
13688
13616
|
case "SUM":
|
|
13689
|
-
aggr.push({ [as]:
|
|
13617
|
+
aggr.push({ [as]: agg`SUM("${as}")::DOUBLE` });
|
|
13690
13618
|
break;
|
|
13691
13619
|
case "AVG":
|
|
13692
|
-
|
|
13693
|
-
aggr.push({ [as]: sql`(SUM("${as}" * ${auxAs}) / SUM(${auxAs}))::DOUBLE` });
|
|
13620
|
+
aggr.push({ [as]: avgExpr(aux, as, args[0]) });
|
|
13694
13621
|
break;
|
|
13695
13622
|
case "ARG_MAX":
|
|
13696
|
-
|
|
13697
|
-
aggr.push({ [as]: sql`ARG_MAX("${as}", ${auxAs})` });
|
|
13623
|
+
aggr.push({ [as]: argmaxExpr(aux, as, args) });
|
|
13698
13624
|
break;
|
|
13699
13625
|
case "ARG_MIN":
|
|
13700
|
-
|
|
13701
|
-
|
|
13626
|
+
aggr.push({ [as]: argminExpr(aux, as, args) });
|
|
13627
|
+
break;
|
|
13628
|
+
case "VARIANCE":
|
|
13629
|
+
case "VAR_SAMP":
|
|
13630
|
+
aux[as] = null;
|
|
13631
|
+
aggr.push({ [as]: varianceExpr(aux, args[0], from) });
|
|
13632
|
+
break;
|
|
13633
|
+
case "VAR_POP":
|
|
13634
|
+
aux[as] = null;
|
|
13635
|
+
aggr.push({ [as]: varianceExpr(aux, args[0], from, false) });
|
|
13636
|
+
break;
|
|
13637
|
+
case "STDDEV":
|
|
13638
|
+
case "STDDEV_SAMP":
|
|
13639
|
+
aux[as] = null;
|
|
13640
|
+
aggr.push({ [as]: agg`SQRT(${varianceExpr(aux, args[0], from)})` });
|
|
13641
|
+
break;
|
|
13642
|
+
case "STDDEV_POP":
|
|
13643
|
+
aux[as] = null;
|
|
13644
|
+
aggr.push({ [as]: agg`SQRT(${varianceExpr(aux, args[0], from, false)})` });
|
|
13645
|
+
break;
|
|
13646
|
+
case "COVAR_SAMP":
|
|
13647
|
+
aux[as] = null;
|
|
13648
|
+
aggr.push({ [as]: covarianceExpr(aux, args, from) });
|
|
13649
|
+
break;
|
|
13650
|
+
case "COVAR_POP":
|
|
13651
|
+
aux[as] = null;
|
|
13652
|
+
aggr.push({ [as]: covarianceExpr(aux, args, from, false) });
|
|
13653
|
+
break;
|
|
13654
|
+
case "CORR":
|
|
13655
|
+
aux[as] = null;
|
|
13656
|
+
aggr.push({ [as]: corrExpr(aux, args, from) });
|
|
13657
|
+
break;
|
|
13658
|
+
case "REGR_COUNT":
|
|
13659
|
+
aux[as] = null;
|
|
13660
|
+
aggr.push({ [as]: agg`${regrCountExpr(aux, args)}::DOUBLE` });
|
|
13661
|
+
break;
|
|
13662
|
+
case "REGR_AVGX":
|
|
13663
|
+
aux[as] = null;
|
|
13664
|
+
aggr.push({ [as]: regrAvgXExpr(aux, args) });
|
|
13665
|
+
break;
|
|
13666
|
+
case "REGR_AVGY":
|
|
13667
|
+
aux[as] = null;
|
|
13668
|
+
aggr.push({ [as]: regrAvgYExpr(aux, args) });
|
|
13669
|
+
break;
|
|
13670
|
+
case "REGR_SYY":
|
|
13671
|
+
aux[as] = null;
|
|
13672
|
+
aggr.push({ [as]: regrVarExpr(aux, 0, args, from) });
|
|
13673
|
+
break;
|
|
13674
|
+
case "REGR_SXX":
|
|
13675
|
+
aux[as] = null;
|
|
13676
|
+
aggr.push({ [as]: regrVarExpr(aux, 1, args, from) });
|
|
13677
|
+
break;
|
|
13678
|
+
case "REGR_SXY":
|
|
13679
|
+
aux[as] = null;
|
|
13680
|
+
aggr.push({ [as]: covarianceExpr(aux, args, from, null) });
|
|
13681
|
+
break;
|
|
13682
|
+
case "REGR_SLOPE":
|
|
13683
|
+
aux[as] = null;
|
|
13684
|
+
aggr.push({ [as]: regrSlopeExpr(aux, args, from) });
|
|
13685
|
+
break;
|
|
13686
|
+
case "REGR_INTERCEPT":
|
|
13687
|
+
aux[as] = null;
|
|
13688
|
+
aggr.push({ [as]: regrInterceptExpr(aux, args, from) });
|
|
13689
|
+
break;
|
|
13690
|
+
case "REGR_R2":
|
|
13691
|
+
aux[as] = null;
|
|
13692
|
+
aggr.push({ [as]: agg`(${corrExpr(aux, args, from)}) ** 2` });
|
|
13702
13693
|
break;
|
|
13703
13694
|
case "MAX":
|
|
13704
13695
|
case "MIN":
|
|
@@ -13708,14 +13699,22 @@ function getIndexColumns(client) {
|
|
|
13708
13699
|
case "BOOL_AND":
|
|
13709
13700
|
case "BOOL_OR":
|
|
13710
13701
|
case "PRODUCT":
|
|
13711
|
-
aggr.push({ [as]:
|
|
13702
|
+
aggr.push({ [as]: agg`${op}("${as}")` });
|
|
13712
13703
|
break;
|
|
13713
13704
|
default:
|
|
13714
|
-
if (
|
|
13705
|
+
if (!aggregate) dims.push(as);
|
|
13715
13706
|
else return null;
|
|
13716
13707
|
}
|
|
13717
13708
|
}
|
|
13718
|
-
|
|
13709
|
+
if (!aggr.length) return null;
|
|
13710
|
+
return { from, dims, aggr, aux };
|
|
13711
|
+
}
|
|
13712
|
+
function auxName(type2, ...args) {
|
|
13713
|
+
const cols = args.length ? "_" + args.map(sanitize).join("_") : "";
|
|
13714
|
+
return `__${type2}${cols}__`;
|
|
13715
|
+
}
|
|
13716
|
+
function sanitize(col) {
|
|
13717
|
+
return `${col}`.replaceAll('"', "").replaceAll(" ", "_");
|
|
13719
13718
|
}
|
|
13720
13719
|
function getBaseTable(query) {
|
|
13721
13720
|
const subq = query.subqueries;
|
|
@@ -13732,6 +13731,291 @@ function getBaseTable(query) {
|
|
|
13732
13731
|
}
|
|
13733
13732
|
return base;
|
|
13734
13733
|
}
|
|
13734
|
+
function countExpr(aux, arg) {
|
|
13735
|
+
const n = auxName("count", arg);
|
|
13736
|
+
aux[n] = agg`COUNT(${arg})`;
|
|
13737
|
+
return agg`SUM(${n})`.annotate({ name: n });
|
|
13738
|
+
}
|
|
13739
|
+
function avgExpr(aux, as, arg) {
|
|
13740
|
+
const n = countExpr(aux, arg);
|
|
13741
|
+
return agg`(SUM("${as}" * ${n.name}) / ${n})`;
|
|
13742
|
+
}
|
|
13743
|
+
function avg2(x3, from) {
|
|
13744
|
+
return sql`(SELECT AVG(${x3}) FROM "${from}")`;
|
|
13745
|
+
}
|
|
13746
|
+
function argmaxExpr(aux, as, [, y3]) {
|
|
13747
|
+
const max4 = auxName("max", y3);
|
|
13748
|
+
aux[max4] = agg`MAX(${y3})`;
|
|
13749
|
+
return agg`ARG_MAX("${as}", ${max4})`;
|
|
13750
|
+
}
|
|
13751
|
+
function argminExpr(aux, as, [, y3]) {
|
|
13752
|
+
const min5 = auxName("min", y3);
|
|
13753
|
+
aux[min5] = agg`MIN(${y3})`;
|
|
13754
|
+
return agg`ARG_MIN("${as}", ${min5})`;
|
|
13755
|
+
}
|
|
13756
|
+
function varianceExpr(aux, x3, from, correction = true) {
|
|
13757
|
+
const n = countExpr(aux, x3);
|
|
13758
|
+
const ssq = auxName("rssq", x3);
|
|
13759
|
+
const sum4 = auxName("rsum", x3);
|
|
13760
|
+
const delta = sql`${x3} - ${avg2(x3, from)}`;
|
|
13761
|
+
aux[ssq] = agg`SUM((${delta}) ** 2)`;
|
|
13762
|
+
aux[sum4] = agg`SUM(${delta})`;
|
|
13763
|
+
const adj = correction ? ` - 1` : "";
|
|
13764
|
+
return agg`(SUM(${ssq}) - (SUM(${sum4}) ** 2 / ${n})) / (${n}${adj})`;
|
|
13765
|
+
}
|
|
13766
|
+
function covarianceExpr(aux, args, from, correction = true) {
|
|
13767
|
+
const n = regrCountExpr(aux, args);
|
|
13768
|
+
const sxy = regrSumXYExpr(aux, args, from);
|
|
13769
|
+
const sx = regrSumExpr(aux, 1, args, from);
|
|
13770
|
+
const sy = regrSumExpr(aux, 0, args, from);
|
|
13771
|
+
const adj = correction === null ? "" : correction ? ` / (${n} - 1)` : ` / ${n}`;
|
|
13772
|
+
return agg`(${sxy} - ${sx} * ${sy} / ${n})${adj}`;
|
|
13773
|
+
}
|
|
13774
|
+
function corrExpr(aux, args, from) {
|
|
13775
|
+
const n = regrCountExpr(aux, args);
|
|
13776
|
+
const sxy = regrSumXYExpr(aux, args, from);
|
|
13777
|
+
const sxx = regrSumSqExpr(aux, 1, args, from);
|
|
13778
|
+
const syy = regrSumSqExpr(aux, 0, args, from);
|
|
13779
|
+
const sx = regrSumExpr(aux, 1, args, from);
|
|
13780
|
+
const sy = regrSumExpr(aux, 0, args, from);
|
|
13781
|
+
const vx = agg`(${sxx} - (${sx} ** 2) / ${n})`;
|
|
13782
|
+
const vy = agg`(${syy} - (${sy} ** 2) / ${n})`;
|
|
13783
|
+
return agg`(${sxy} - ${sx} * ${sy} / ${n}) / SQRT(${vx} * ${vy})`;
|
|
13784
|
+
}
|
|
13785
|
+
function regrCountExpr(aux, [y3, x3]) {
|
|
13786
|
+
const n = auxName("count", y3, x3);
|
|
13787
|
+
aux[n] = agg`REGR_COUNT(${y3}, ${x3})`;
|
|
13788
|
+
return agg`SUM(${n})`.annotate({ name: n });
|
|
13789
|
+
}
|
|
13790
|
+
function regrSumExpr(aux, i, args, from) {
|
|
13791
|
+
const v2 = args[i];
|
|
13792
|
+
const o = args[1 - i];
|
|
13793
|
+
const sum4 = auxName("rs", v2);
|
|
13794
|
+
aux[sum4] = agg`SUM(${v2} - ${avg2(v2, from)}) FILTER (${o} IS NOT NULL)`;
|
|
13795
|
+
return agg`SUM(${sum4})`;
|
|
13796
|
+
}
|
|
13797
|
+
function regrSumSqExpr(aux, i, args, from) {
|
|
13798
|
+
const v2 = args[i];
|
|
13799
|
+
const u4 = args[1 - i];
|
|
13800
|
+
const ssq = auxName("rss", v2);
|
|
13801
|
+
aux[ssq] = agg`SUM((${v2} - ${avg2(v2, from)}) ** 2) FILTER (${u4} IS NOT NULL)`;
|
|
13802
|
+
return agg`SUM(${ssq})`;
|
|
13803
|
+
}
|
|
13804
|
+
function regrSumXYExpr(aux, args, from) {
|
|
13805
|
+
const [y3, x3] = args;
|
|
13806
|
+
const sxy = auxName("sxy", y3, x3);
|
|
13807
|
+
aux[sxy] = agg`SUM((${x3} - ${avg2(x3, from)}) * (${y3} - ${avg2(y3, from)}))`;
|
|
13808
|
+
return agg`SUM(${sxy})`;
|
|
13809
|
+
}
|
|
13810
|
+
function regrAvgXExpr(aux, args) {
|
|
13811
|
+
const [y3, x3] = args;
|
|
13812
|
+
const n = regrCountExpr(aux, args);
|
|
13813
|
+
const a2 = auxName("avg", x3, y3);
|
|
13814
|
+
aux[a2] = agg`REGR_AVGX(${y3}, ${x3})`;
|
|
13815
|
+
return agg`(SUM(${a2} * ${n.name}) / ${n})`;
|
|
13816
|
+
}
|
|
13817
|
+
function regrAvgYExpr(aux, args) {
|
|
13818
|
+
const [y3, x3] = args;
|
|
13819
|
+
const n = regrCountExpr(aux, args);
|
|
13820
|
+
const a2 = auxName("avg", y3, x3);
|
|
13821
|
+
aux[a2] = agg`REGR_AVGY(${y3}, ${x3})`;
|
|
13822
|
+
return agg`(SUM(${a2} * ${n.name}) / ${n})`;
|
|
13823
|
+
}
|
|
13824
|
+
function regrVarExpr(aux, i, args, from) {
|
|
13825
|
+
const n = regrCountExpr(aux, args);
|
|
13826
|
+
const sum4 = regrSumExpr(aux, i, args, from);
|
|
13827
|
+
const ssq = regrSumSqExpr(aux, i, args, from);
|
|
13828
|
+
return agg`(${ssq} - (${sum4} ** 2 / ${n}))`;
|
|
13829
|
+
}
|
|
13830
|
+
function regrSlopeExpr(aux, args, from) {
|
|
13831
|
+
const cov = covarianceExpr(aux, args, from, null);
|
|
13832
|
+
const varx = regrVarExpr(aux, 1, args, from);
|
|
13833
|
+
return agg`(${cov}) / ${varx}`;
|
|
13834
|
+
}
|
|
13835
|
+
function regrInterceptExpr(aux, args, from) {
|
|
13836
|
+
const ax = regrAvgXExpr(aux, args);
|
|
13837
|
+
const ay = regrAvgYExpr(aux, args);
|
|
13838
|
+
const m = regrSlopeExpr(aux, args, from);
|
|
13839
|
+
return agg`${ay} - (${m}) * ${ax}`;
|
|
13840
|
+
}
|
|
13841
|
+
|
|
13842
|
+
// ../core/src/util/hash.js
|
|
13843
|
+
function fnv_hash(v2) {
|
|
13844
|
+
let a2 = 2166136261;
|
|
13845
|
+
for (let i = 0, n = v2.length; i < n; ++i) {
|
|
13846
|
+
const c4 = v2.charCodeAt(i);
|
|
13847
|
+
const d = c4 & 65280;
|
|
13848
|
+
if (d) a2 = fnv_multiply(a2 ^ d >> 8);
|
|
13849
|
+
a2 = fnv_multiply(a2 ^ c4 & 255);
|
|
13850
|
+
}
|
|
13851
|
+
return fnv_mix(a2);
|
|
13852
|
+
}
|
|
13853
|
+
function fnv_multiply(a2) {
|
|
13854
|
+
return a2 + (a2 << 1) + (a2 << 4) + (a2 << 7) + (a2 << 8) + (a2 << 24);
|
|
13855
|
+
}
|
|
13856
|
+
function fnv_mix(a2) {
|
|
13857
|
+
a2 += a2 << 13;
|
|
13858
|
+
a2 ^= a2 >>> 7;
|
|
13859
|
+
a2 += a2 << 3;
|
|
13860
|
+
a2 ^= a2 >>> 17;
|
|
13861
|
+
a2 += a2 << 5;
|
|
13862
|
+
return a2 & 4294967295;
|
|
13863
|
+
}
|
|
13864
|
+
|
|
13865
|
+
// ../core/src/DataCubeIndexer.js
|
|
13866
|
+
var Skip = { skip: true, result: null };
|
|
13867
|
+
var DataCubeIndexer = class {
|
|
13868
|
+
/**
|
|
13869
|
+
* Create a new data cube index table manager.
|
|
13870
|
+
* @param {import('./Coordinator.js').Coordinator} coordinator A Mosaic coordinator.
|
|
13871
|
+
* @param {object} [options] Indexer options.
|
|
13872
|
+
* @param {boolean} [options.enabled=true] Flag to enable/disable indexer.
|
|
13873
|
+
* @param {boolean} [options.temp=true] Flag to indicate if generated data
|
|
13874
|
+
* cube index tables should be temporary tables.
|
|
13875
|
+
*/
|
|
13876
|
+
constructor(coordinator2, {
|
|
13877
|
+
enabled = true,
|
|
13878
|
+
temp = true
|
|
13879
|
+
} = {}) {
|
|
13880
|
+
this.indexes = /* @__PURE__ */ new Map();
|
|
13881
|
+
this.active = null;
|
|
13882
|
+
this.temp = temp;
|
|
13883
|
+
this.mc = coordinator2;
|
|
13884
|
+
this._enabled = enabled;
|
|
13885
|
+
}
|
|
13886
|
+
/**
|
|
13887
|
+
* Set the enabled state of this indexer. If false, any cached state is
|
|
13888
|
+
* cleared and subsequent index calls will return null until re-enabled.
|
|
13889
|
+
* @param {boolean} state The enabled state.
|
|
13890
|
+
*/
|
|
13891
|
+
enabled(state) {
|
|
13892
|
+
if (state === void 0) {
|
|
13893
|
+
return this._enabled;
|
|
13894
|
+
} else if (this._enabled !== state) {
|
|
13895
|
+
if (!state) this.clear();
|
|
13896
|
+
this._enabled = state;
|
|
13897
|
+
}
|
|
13898
|
+
}
|
|
13899
|
+
/**
|
|
13900
|
+
* Clear the cache of data cube index table entries for the current active
|
|
13901
|
+
* selection clause. This method will also cancel any queued data cube table
|
|
13902
|
+
* creation queries that have not yet been submitted to the database. This
|
|
13903
|
+
* method does _not_ drop any existing data cube tables.
|
|
13904
|
+
*/
|
|
13905
|
+
clear() {
|
|
13906
|
+
this.mc.cancel(Array.from(this.indexes.values(), (info) => info?.result));
|
|
13907
|
+
this.indexes.clear();
|
|
13908
|
+
this.active = null;
|
|
13909
|
+
}
|
|
13910
|
+
/**
|
|
13911
|
+
* Return data cube index table information for the active state of a
|
|
13912
|
+
* client-selection pair, or null if the client is not indexable. This
|
|
13913
|
+
* method has multiple possible side effects, including data cube table
|
|
13914
|
+
* generation and updating internal caches.
|
|
13915
|
+
* @param {import('./MosaicClient.js').MosaicClient} client A Mosaic client.
|
|
13916
|
+
* @param {import('./Selection.js').Selection} selection A Mosaic selection
|
|
13917
|
+
* to filter the client by.
|
|
13918
|
+
* @param {import('./util/selection-types.js').SelectionClause} activeClause
|
|
13919
|
+
* A representative active selection clause for which to (possibly) generate
|
|
13920
|
+
* data cube index tables.
|
|
13921
|
+
* @returns {DataCubeInfo | Skip | null} Data cube index table
|
|
13922
|
+
* information and query generator, or null if the client is not indexable.
|
|
13923
|
+
*/
|
|
13924
|
+
index(client, selection2, activeClause) {
|
|
13925
|
+
if (!this._enabled) return null;
|
|
13926
|
+
const { indexes: indexes2, mc, temp } = this;
|
|
13927
|
+
const { source } = activeClause;
|
|
13928
|
+
if (!source) return null;
|
|
13929
|
+
if (this.active) {
|
|
13930
|
+
if (this.active.source !== source) this.clear();
|
|
13931
|
+
if (this.active?.source === null) return null;
|
|
13932
|
+
}
|
|
13933
|
+
let { active } = this;
|
|
13934
|
+
if (!active) {
|
|
13935
|
+
this.active = active = activeColumns(activeClause);
|
|
13936
|
+
if (active.source === null) return null;
|
|
13937
|
+
}
|
|
13938
|
+
if (indexes2.has(client)) {
|
|
13939
|
+
return indexes2.get(client);
|
|
13940
|
+
}
|
|
13941
|
+
const indexCols = indexColumns(client);
|
|
13942
|
+
let info;
|
|
13943
|
+
if (!indexCols) {
|
|
13944
|
+
info = null;
|
|
13945
|
+
} else if (selection2.skip(client, activeClause)) {
|
|
13946
|
+
info = Skip;
|
|
13947
|
+
} else {
|
|
13948
|
+
const filter3 = selection2.remove(source).predicate(client);
|
|
13949
|
+
info = dataCubeInfo(client.query(filter3), active, indexCols);
|
|
13950
|
+
info.result = mc.exec(create(info.table, info.create, { temp }));
|
|
13951
|
+
info.result.catch((e) => mc.logger().error(e));
|
|
13952
|
+
}
|
|
13953
|
+
indexes2.set(client, info);
|
|
13954
|
+
return info;
|
|
13955
|
+
}
|
|
13956
|
+
};
|
|
13957
|
+
function activeColumns(clause) {
|
|
13958
|
+
const { source, meta } = clause;
|
|
13959
|
+
const clausePred = clause.predicate;
|
|
13960
|
+
const clauseCols = clausePred?.columns;
|
|
13961
|
+
let predicate;
|
|
13962
|
+
let columns;
|
|
13963
|
+
if (!meta || !clauseCols) {
|
|
13964
|
+
return { source: null, columns, predicate };
|
|
13965
|
+
}
|
|
13966
|
+
const { type: type2, scales: scales2, bin: bin3, pixelSize = 1 } = meta;
|
|
13967
|
+
if (type2 === "point") {
|
|
13968
|
+
predicate = (x3) => x3;
|
|
13969
|
+
columns = Object.fromEntries(
|
|
13970
|
+
clauseCols.map((col) => [`${col}`, asColumn(col)])
|
|
13971
|
+
);
|
|
13972
|
+
} else if (type2 === "interval" && scales2) {
|
|
13973
|
+
const bins2 = scales2.map((s2) => binInterval(s2, pixelSize, bin3));
|
|
13974
|
+
if (bins2.some((b) => !b)) {
|
|
13975
|
+
} else if (bins2.length === 1) {
|
|
13976
|
+
predicate = (p) => p ? isBetween("active0", p.range.map(bins2[0])) : [];
|
|
13977
|
+
columns = { active0: bins2[0](clausePred.field) };
|
|
13978
|
+
} else {
|
|
13979
|
+
predicate = (p) => p ? and(p.children.map(
|
|
13980
|
+
({ range: range3 }, i) => isBetween(`active${i}`, range3.map(bins2[i]))
|
|
13981
|
+
)) : [];
|
|
13982
|
+
columns = Object.fromEntries(
|
|
13983
|
+
// @ts-ignore
|
|
13984
|
+
clausePred.children.map((p, i) => [`active${i}`, bins2[i](p.field)])
|
|
13985
|
+
);
|
|
13986
|
+
}
|
|
13987
|
+
}
|
|
13988
|
+
return { source: columns ? source : null, columns, predicate };
|
|
13989
|
+
}
|
|
13990
|
+
var BIN = { ceil: "CEIL", round: "ROUND" };
|
|
13991
|
+
function binInterval(scale3, pixelSize, bin3) {
|
|
13992
|
+
const { type: type2, domain, range: range3, apply: apply2, sqlApply } = scaleTransform(scale3);
|
|
13993
|
+
if (!apply2) return;
|
|
13994
|
+
const fn = BIN[`${bin3}`.toLowerCase()] || "FLOOR";
|
|
13995
|
+
const lo = apply2(Math.min(...domain));
|
|
13996
|
+
const hi = apply2(Math.max(...domain));
|
|
13997
|
+
const a2 = type2 === "identity" ? 1 : Math.abs(range3[1] - range3[0]) / (hi - lo);
|
|
13998
|
+
const s2 = a2 / pixelSize === 1 ? "" : `${a2 / pixelSize}::DOUBLE * `;
|
|
13999
|
+
const d = lo === 0 ? "" : ` - ${lo}::DOUBLE`;
|
|
14000
|
+
return (value) => sql`${fn}(${s2}(${sqlApply(value)}${d}))::INTEGER`;
|
|
14001
|
+
}
|
|
14002
|
+
function dataCubeInfo(clientQuery, active, indexCols) {
|
|
14003
|
+
const { dims, aggr, aux } = indexCols;
|
|
14004
|
+
const { columns } = active;
|
|
14005
|
+
const query = clientQuery.select({ ...columns, ...aux }).groupby(Object.keys(columns));
|
|
14006
|
+
const [subq] = query.subqueries;
|
|
14007
|
+
if (subq) {
|
|
14008
|
+
const cols = Object.values(columns).flatMap((c4) => c4.columns);
|
|
14009
|
+
subqueryPushdown(subq, cols);
|
|
14010
|
+
}
|
|
14011
|
+
const order = query.orderby();
|
|
14012
|
+
query.query.orderby = [];
|
|
14013
|
+
const create4 = query.toString();
|
|
14014
|
+
const id2 = (fnv_hash(create4) >>> 0).toString(16);
|
|
14015
|
+
const table = `cube_index_${id2}`;
|
|
14016
|
+
const select2 = Query.select(dims, aggr).from(table).groupby(dims).orderby(order);
|
|
14017
|
+
return new DataCubeInfo({ table, create: create4, active, select: select2 });
|
|
14018
|
+
}
|
|
13735
14019
|
function subqueryPushdown(query, cols) {
|
|
13736
14020
|
const memo2 = /* @__PURE__ */ new Set();
|
|
13737
14021
|
const pushdown = (q) => {
|
|
@@ -13744,78 +14028,65 @@ function subqueryPushdown(query, cols) {
|
|
|
13744
14028
|
};
|
|
13745
14029
|
pushdown(query);
|
|
13746
14030
|
}
|
|
13747
|
-
|
|
13748
|
-
// ../core/src/FilterGroup.js
|
|
13749
|
-
var FilterGroup = class {
|
|
14031
|
+
var DataCubeInfo = class {
|
|
13750
14032
|
/**
|
|
13751
|
-
*
|
|
13752
|
-
* @param {
|
|
13753
|
-
* @param {*} index Boolean flag or options hash for data cube indexer.
|
|
13754
|
-
* Falsy values disable indexing.
|
|
14033
|
+
* Create a new DataCubeInfo instance.
|
|
14034
|
+
* @param {object} options
|
|
13755
14035
|
*/
|
|
13756
|
-
constructor(
|
|
13757
|
-
this.
|
|
13758
|
-
this.
|
|
13759
|
-
this.
|
|
13760
|
-
this.
|
|
13761
|
-
|
|
13762
|
-
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
|
|
13766
|
-
|
|
13767
|
-
|
|
13768
|
-
|
|
13769
|
-
|
|
13770
|
-
|
|
13771
|
-
this.
|
|
13772
|
-
}
|
|
13773
|
-
reset() {
|
|
13774
|
-
this.indexer?.reset();
|
|
14036
|
+
constructor({ table, create: create4, active, select: select2 } = {}) {
|
|
14037
|
+
this.table = table;
|
|
14038
|
+
this.create = create4;
|
|
14039
|
+
this.result = null;
|
|
14040
|
+
this.active = active;
|
|
14041
|
+
this.select = select2;
|
|
14042
|
+
this.skip = false;
|
|
14043
|
+
}
|
|
14044
|
+
/**
|
|
14045
|
+
* Generate a data cube index table query for the given predicate.
|
|
14046
|
+
* @param {import('@uwdata/mosaic-sql').SQLExpression} predicate The current
|
|
14047
|
+
* active clause predicate.
|
|
14048
|
+
* @returns {Query} A data cube index table query.
|
|
14049
|
+
*/
|
|
14050
|
+
query(predicate) {
|
|
14051
|
+
return this.select.clone().where(this.active.predicate(predicate));
|
|
13775
14052
|
}
|
|
13776
|
-
|
|
13777
|
-
|
|
13778
|
-
|
|
14053
|
+
};
|
|
14054
|
+
|
|
14055
|
+
// ../core/src/util/query-result.js
|
|
14056
|
+
var QueryResult = class extends Promise {
|
|
14057
|
+
/**
|
|
14058
|
+
* Create a new query result Promise.
|
|
14059
|
+
*/
|
|
14060
|
+
constructor() {
|
|
14061
|
+
let resolve;
|
|
14062
|
+
let reject;
|
|
14063
|
+
super((r, e) => {
|
|
14064
|
+
resolve = r;
|
|
14065
|
+
reject = e;
|
|
14066
|
+
});
|
|
14067
|
+
this._resolve = resolve;
|
|
14068
|
+
this._reject = reject;
|
|
13779
14069
|
}
|
|
13780
|
-
|
|
13781
|
-
|
|
13782
|
-
|
|
13783
|
-
|
|
14070
|
+
/**
|
|
14071
|
+
* Resolve the result Promise with the provided value.
|
|
14072
|
+
* @param {*} value The result value.
|
|
14073
|
+
* @returns {this}
|
|
14074
|
+
*/
|
|
14075
|
+
fulfill(value) {
|
|
14076
|
+
this._resolve(value);
|
|
13784
14077
|
return this;
|
|
13785
14078
|
}
|
|
13786
14079
|
/**
|
|
13787
|
-
*
|
|
13788
|
-
*
|
|
13789
|
-
* @returns {
|
|
14080
|
+
* Rejects the result Promise with the provided error.
|
|
14081
|
+
* @param {*} error The error value.
|
|
14082
|
+
* @returns {this}
|
|
13790
14083
|
*/
|
|
13791
|
-
|
|
13792
|
-
|
|
13793
|
-
|
|
13794
|
-
return hasIndex ? indexer.update() : defaultUpdate(mc, clients, selection2);
|
|
14084
|
+
reject(error) {
|
|
14085
|
+
this._reject(error);
|
|
14086
|
+
return this;
|
|
13795
14087
|
}
|
|
13796
14088
|
};
|
|
13797
|
-
|
|
13798
|
-
return Promise.all(Array.from(clients).map((client) => {
|
|
13799
|
-
const filter3 = selection2.predicate(client);
|
|
13800
|
-
if (filter3 != null) {
|
|
13801
|
-
return mc.updateClient(client, client.query(filter3));
|
|
13802
|
-
}
|
|
13803
|
-
}));
|
|
13804
|
-
}
|
|
13805
|
-
|
|
13806
|
-
// ../core/src/util/query-result.js
|
|
13807
|
-
function queryResult() {
|
|
13808
|
-
let resolve;
|
|
13809
|
-
let reject;
|
|
13810
|
-
const p = new Promise((r, e) => {
|
|
13811
|
-
resolve = r;
|
|
13812
|
-
reject = e;
|
|
13813
|
-
});
|
|
13814
|
-
return Object.assign(p, {
|
|
13815
|
-
fulfill: (value) => (resolve(value), p),
|
|
13816
|
-
reject: (err) => (reject(err), p)
|
|
13817
|
-
});
|
|
13818
|
-
}
|
|
14089
|
+
QueryResult.prototype.constructor = Promise;
|
|
13819
14090
|
|
|
13820
14091
|
// ../core/src/QueryConsolidator.js
|
|
13821
14092
|
function wait(callback) {
|
|
@@ -13891,7 +14162,7 @@ function consolidate(group3, enqueue, record) {
|
|
|
13891
14162
|
record: false,
|
|
13892
14163
|
query: group3.query = consolidatedQuery(group3, record)
|
|
13893
14164
|
},
|
|
13894
|
-
result: group3.result =
|
|
14165
|
+
result: group3.result = new QueryResult()
|
|
13895
14166
|
});
|
|
13896
14167
|
} else {
|
|
13897
14168
|
for (const { entry, priority } of group3) {
|
|
@@ -14107,115 +14378,124 @@ function priorityQueue(ranks) {
|
|
|
14107
14378
|
|
|
14108
14379
|
// ../core/src/QueryManager.js
|
|
14109
14380
|
var Priority = { High: 0, Normal: 1, Low: 2 };
|
|
14110
|
-
|
|
14111
|
-
|
|
14112
|
-
|
|
14113
|
-
|
|
14114
|
-
|
|
14115
|
-
|
|
14116
|
-
|
|
14117
|
-
|
|
14118
|
-
|
|
14119
|
-
|
|
14120
|
-
|
|
14121
|
-
|
|
14122
|
-
pending.
|
|
14123
|
-
|
|
14124
|
-
|
|
14381
|
+
var QueryManager = class {
|
|
14382
|
+
constructor() {
|
|
14383
|
+
this.queue = priorityQueue(3);
|
|
14384
|
+
this.db = null;
|
|
14385
|
+
this.clientCache = null;
|
|
14386
|
+
this._logger = null;
|
|
14387
|
+
this._logQueries = false;
|
|
14388
|
+
this.recorders = [];
|
|
14389
|
+
this.pending = null;
|
|
14390
|
+
this._consolidate = null;
|
|
14391
|
+
}
|
|
14392
|
+
next() {
|
|
14393
|
+
if (this.pending || this.queue.isEmpty()) return;
|
|
14394
|
+
const { request, result } = this.queue.next();
|
|
14395
|
+
this.pending = this.submit(request, result);
|
|
14396
|
+
this.pending.finally(() => {
|
|
14397
|
+
this.pending = null;
|
|
14398
|
+
this.next();
|
|
14125
14399
|
});
|
|
14126
14400
|
}
|
|
14127
|
-
|
|
14128
|
-
queue.insert(entry, priority);
|
|
14129
|
-
next();
|
|
14401
|
+
enqueue(entry, priority = Priority.Normal) {
|
|
14402
|
+
this.queue.insert(entry, priority);
|
|
14403
|
+
this.next();
|
|
14130
14404
|
}
|
|
14131
|
-
|
|
14132
|
-
if (recorders.length && sql2) {
|
|
14133
|
-
recorders.forEach((rec) => rec.add(sql2));
|
|
14405
|
+
recordQuery(sql2) {
|
|
14406
|
+
if (this.recorders.length && sql2) {
|
|
14407
|
+
this.recorders.forEach((rec) => rec.add(sql2));
|
|
14134
14408
|
}
|
|
14135
14409
|
}
|
|
14136
|
-
async
|
|
14410
|
+
async submit(request, result) {
|
|
14137
14411
|
try {
|
|
14138
14412
|
const { query, type: type2, cache = false, record = true, options } = request;
|
|
14139
14413
|
const sql2 = query ? `${query}` : null;
|
|
14140
14414
|
if (record) {
|
|
14141
|
-
recordQuery(sql2);
|
|
14415
|
+
this.recordQuery(sql2);
|
|
14142
14416
|
}
|
|
14143
14417
|
if (cache) {
|
|
14144
|
-
const cached = clientCache.get(sql2);
|
|
14418
|
+
const cached = this.clientCache.get(sql2);
|
|
14145
14419
|
if (cached) {
|
|
14146
|
-
|
|
14420
|
+
this._logger.debug("Cache");
|
|
14147
14421
|
result.fulfill(cached);
|
|
14148
14422
|
return;
|
|
14149
14423
|
}
|
|
14150
14424
|
}
|
|
14151
14425
|
const t03 = performance.now();
|
|
14152
|
-
|
|
14153
|
-
|
|
14154
|
-
|
|
14426
|
+
if (this._logQueries) {
|
|
14427
|
+
this._logger.debug("Query", { type: type2, sql: sql2, ...options });
|
|
14428
|
+
}
|
|
14429
|
+
const data = await this.db.query({ type: type2, sql: sql2, ...options });
|
|
14430
|
+
if (cache) this.clientCache.set(sql2, data);
|
|
14431
|
+
this._logger.debug(`Request: ${(performance.now() - t03).toFixed(1)}`);
|
|
14155
14432
|
result.fulfill(data);
|
|
14156
14433
|
} catch (err) {
|
|
14157
14434
|
result.reject(err);
|
|
14158
14435
|
}
|
|
14159
14436
|
}
|
|
14160
|
-
|
|
14161
|
-
|
|
14162
|
-
|
|
14163
|
-
|
|
14164
|
-
|
|
14165
|
-
|
|
14166
|
-
|
|
14167
|
-
|
|
14168
|
-
|
|
14169
|
-
|
|
14170
|
-
|
|
14171
|
-
|
|
14172
|
-
|
|
14173
|
-
|
|
14174
|
-
|
|
14175
|
-
|
|
14176
|
-
|
|
14177
|
-
request(request, priority = Priority.Normal) {
|
|
14178
|
-
const result = queryResult();
|
|
14179
|
-
const entry = { request, result };
|
|
14180
|
-
if (consolidate2) {
|
|
14181
|
-
consolidate2.add(entry, priority);
|
|
14182
|
-
} else {
|
|
14183
|
-
enqueue(entry, priority);
|
|
14184
|
-
}
|
|
14185
|
-
return result;
|
|
14186
|
-
},
|
|
14187
|
-
cancel(requests) {
|
|
14188
|
-
const set3 = new Set(requests);
|
|
14189
|
-
queue.remove(({ result }) => set3.has(result));
|
|
14190
|
-
},
|
|
14191
|
-
clear() {
|
|
14192
|
-
queue.remove(({ result }) => {
|
|
14193
|
-
result.reject("Cleared");
|
|
14194
|
-
return true;
|
|
14195
|
-
});
|
|
14196
|
-
},
|
|
14197
|
-
record() {
|
|
14198
|
-
let state = [];
|
|
14199
|
-
const recorder = {
|
|
14200
|
-
add(query) {
|
|
14201
|
-
state.push(query);
|
|
14202
|
-
},
|
|
14203
|
-
reset() {
|
|
14204
|
-
state = [];
|
|
14205
|
-
},
|
|
14206
|
-
snapshot() {
|
|
14207
|
-
return state.slice();
|
|
14208
|
-
},
|
|
14209
|
-
stop() {
|
|
14210
|
-
recorders = recorders.filter((x3) => x3 !== recorder);
|
|
14211
|
-
return state;
|
|
14212
|
-
}
|
|
14213
|
-
};
|
|
14214
|
-
recorders.push(recorder);
|
|
14215
|
-
return recorder;
|
|
14437
|
+
cache(value) {
|
|
14438
|
+
return value !== void 0 ? this.clientCache = value === true ? lruCache() : value || voidCache() : this.clientCache;
|
|
14439
|
+
}
|
|
14440
|
+
logger(value) {
|
|
14441
|
+
return value ? this._logger = value : this._logger;
|
|
14442
|
+
}
|
|
14443
|
+
logQueries(value) {
|
|
14444
|
+
return value !== void 0 ? this._logQueries = !!value : this._logQueries;
|
|
14445
|
+
}
|
|
14446
|
+
connector(connector) {
|
|
14447
|
+
return connector ? this.db = connector : this.db;
|
|
14448
|
+
}
|
|
14449
|
+
consolidate(flag) {
|
|
14450
|
+
if (flag && !this._consolidate) {
|
|
14451
|
+
this._consolidate = consolidator(this.enqueue.bind(this), this.clientCache, this.recordQuery.bind(this));
|
|
14452
|
+
} else if (!flag && this._consolidate) {
|
|
14453
|
+
this._consolidate = null;
|
|
14216
14454
|
}
|
|
14217
|
-
}
|
|
14218
|
-
|
|
14455
|
+
}
|
|
14456
|
+
request(request, priority = Priority.Normal) {
|
|
14457
|
+
const result = new QueryResult();
|
|
14458
|
+
const entry = { request, result };
|
|
14459
|
+
if (this._consolidate) {
|
|
14460
|
+
this._consolidate.add(entry, priority);
|
|
14461
|
+
} else {
|
|
14462
|
+
this.enqueue(entry, priority);
|
|
14463
|
+
}
|
|
14464
|
+
return result;
|
|
14465
|
+
}
|
|
14466
|
+
cancel(requests) {
|
|
14467
|
+
const set3 = new Set(requests);
|
|
14468
|
+
if (set3.size) {
|
|
14469
|
+
this.queue.remove(({ result }) => set3.has(result));
|
|
14470
|
+
}
|
|
14471
|
+
}
|
|
14472
|
+
clear() {
|
|
14473
|
+
this.queue.remove(({ result }) => {
|
|
14474
|
+
result.reject("Cleared");
|
|
14475
|
+
return true;
|
|
14476
|
+
});
|
|
14477
|
+
}
|
|
14478
|
+
record() {
|
|
14479
|
+
let state = [];
|
|
14480
|
+
const recorder = {
|
|
14481
|
+
add(query) {
|
|
14482
|
+
state.push(query);
|
|
14483
|
+
},
|
|
14484
|
+
reset() {
|
|
14485
|
+
state = [];
|
|
14486
|
+
},
|
|
14487
|
+
snapshot() {
|
|
14488
|
+
return state.slice();
|
|
14489
|
+
},
|
|
14490
|
+
stop() {
|
|
14491
|
+
this.recorders = this.recorders.filter((x3) => x3 !== recorder);
|
|
14492
|
+
return state;
|
|
14493
|
+
}
|
|
14494
|
+
};
|
|
14495
|
+
this.recorders.push(recorder);
|
|
14496
|
+
return recorder;
|
|
14497
|
+
}
|
|
14498
|
+
};
|
|
14219
14499
|
|
|
14220
14500
|
// ../core/src/util/js-type.js
|
|
14221
14501
|
function jsType(type2) {
|
|
@@ -14296,23 +14576,26 @@ function convertArrowColumn(column3) {
|
|
|
14296
14576
|
}
|
|
14297
14577
|
if (DataType.isInt(type2) && type2.bitWidth >= 64) {
|
|
14298
14578
|
const size = column3.length;
|
|
14299
|
-
const array4 = new Float64Array(size);
|
|
14579
|
+
const array4 = column3.nullCount ? new Array(size) : new Float64Array(size);
|
|
14300
14580
|
for (let row = 0; row < size; ++row) {
|
|
14301
14581
|
const v2 = column3.get(row);
|
|
14302
|
-
array4[row] = v2 == null ?
|
|
14582
|
+
array4[row] = v2 == null ? null : Number(v2);
|
|
14303
14583
|
}
|
|
14304
14584
|
return array4;
|
|
14305
14585
|
}
|
|
14306
14586
|
if (DataType.isDecimal(type2)) {
|
|
14307
14587
|
const scale3 = 1 / Math.pow(10, type2.scale);
|
|
14308
14588
|
const size = column3.length;
|
|
14309
|
-
const array4 = new Float64Array(size);
|
|
14589
|
+
const array4 = column3.nullCount ? new Array(size) : new Float64Array(size);
|
|
14310
14590
|
for (let row = 0; row < size; ++row) {
|
|
14311
14591
|
const v2 = column3.get(row);
|
|
14312
|
-
array4[row] = v2 == null ?
|
|
14592
|
+
array4[row] = v2 == null ? null : decimalToNumber(v2, scale3);
|
|
14313
14593
|
}
|
|
14314
14594
|
return array4;
|
|
14315
14595
|
}
|
|
14596
|
+
if (column3.nullCount) {
|
|
14597
|
+
return Array.from(column3);
|
|
14598
|
+
}
|
|
14316
14599
|
return column3.toArray();
|
|
14317
14600
|
}
|
|
14318
14601
|
var BASE32 = Array.from(
|
|
@@ -14419,58 +14702,92 @@ function coordinator(instance8) {
|
|
|
14419
14702
|
return _instance;
|
|
14420
14703
|
}
|
|
14421
14704
|
var Coordinator = class {
|
|
14422
|
-
constructor(db = socketConnector(),
|
|
14423
|
-
|
|
14424
|
-
|
|
14425
|
-
|
|
14426
|
-
|
|
14705
|
+
constructor(db = socketConnector(), {
|
|
14706
|
+
logger = console,
|
|
14707
|
+
manager = new QueryManager(),
|
|
14708
|
+
cache = true,
|
|
14709
|
+
consolidate: consolidate2 = true,
|
|
14710
|
+
indexes: indexes2 = {}
|
|
14711
|
+
} = {}) {
|
|
14427
14712
|
this.manager = manager;
|
|
14713
|
+
this.manager.cache(cache);
|
|
14714
|
+
this.manager.consolidate(consolidate2);
|
|
14715
|
+
this.dataCubeIndexer = new DataCubeIndexer(this, indexes2);
|
|
14428
14716
|
this.logger(logger);
|
|
14429
|
-
this.configure(options);
|
|
14430
14717
|
this.databaseConnector(db);
|
|
14431
14718
|
this.clear();
|
|
14432
14719
|
}
|
|
14433
|
-
logger(logger) {
|
|
14434
|
-
if (arguments.length) {
|
|
14435
|
-
this._logger = logger || voidLogger();
|
|
14436
|
-
this.manager.logger(this._logger);
|
|
14437
|
-
}
|
|
14438
|
-
return this._logger;
|
|
14439
|
-
}
|
|
14440
14720
|
/**
|
|
14441
|
-
*
|
|
14442
|
-
* @param {object} [options]
|
|
14443
|
-
* @param {boolean} [options.
|
|
14444
|
-
* @param {boolean} [options.
|
|
14445
|
-
* @param {boolean|object} [options.indexes=true] Boolean flag to enable/disable
|
|
14446
|
-
* automatic data cube indexes or an index options object.
|
|
14721
|
+
* Clear the coordinator state.
|
|
14722
|
+
* @param {object} [options] Options object.
|
|
14723
|
+
* @param {boolean} [options.clients=true] If true, disconnect all clients.
|
|
14724
|
+
* @param {boolean} [options.cache=true] If true, clear the query cache.
|
|
14447
14725
|
*/
|
|
14448
|
-
configure({ cache = true, consolidate: consolidate2 = true, indexes: indexes2 = true } = {}) {
|
|
14449
|
-
this.manager.cache(cache);
|
|
14450
|
-
this.manager.consolidate(consolidate2);
|
|
14451
|
-
this.indexes = indexes2;
|
|
14452
|
-
}
|
|
14453
14726
|
clear({ clients = true, cache = true } = {}) {
|
|
14454
14727
|
this.manager.clear();
|
|
14455
14728
|
if (clients) {
|
|
14729
|
+
this.filterGroups?.forEach((group3) => group3.disconnect());
|
|
14730
|
+
this.filterGroups = /* @__PURE__ */ new Map();
|
|
14456
14731
|
this.clients?.forEach((client) => this.disconnect(client));
|
|
14457
|
-
this.filterGroups?.forEach((group3) => group3.finalize());
|
|
14458
14732
|
this.clients = /* @__PURE__ */ new Set();
|
|
14459
|
-
this.filterGroups = /* @__PURE__ */ new Map();
|
|
14460
14733
|
}
|
|
14461
14734
|
if (cache) this.manager.cache().clear();
|
|
14462
14735
|
}
|
|
14736
|
+
/**
|
|
14737
|
+
* Get or set the database connector.
|
|
14738
|
+
* @param {*} [db] The database connector to use.
|
|
14739
|
+
* @returns The current database connector.
|
|
14740
|
+
*/
|
|
14463
14741
|
databaseConnector(db) {
|
|
14464
14742
|
return this.manager.connector(db);
|
|
14465
14743
|
}
|
|
14744
|
+
/**
|
|
14745
|
+
* Get or set the logger.
|
|
14746
|
+
* @param {*} logger The logger to use.
|
|
14747
|
+
* @returns The current logger
|
|
14748
|
+
*/
|
|
14749
|
+
logger(logger) {
|
|
14750
|
+
if (arguments.length) {
|
|
14751
|
+
this._logger = logger || voidLogger();
|
|
14752
|
+
this.manager.logger(this._logger);
|
|
14753
|
+
}
|
|
14754
|
+
return this._logger;
|
|
14755
|
+
}
|
|
14466
14756
|
// -- Query Management ----
|
|
14757
|
+
/**
|
|
14758
|
+
* Cancel previosuly submitted query requests. These queries will be
|
|
14759
|
+
* canceled if they are queued but have not yet been submitted.
|
|
14760
|
+
* @param {import('./util/query-result.js').QueryResult[]} requests An array
|
|
14761
|
+
* of query result objects, such as those returned by the `query` method.
|
|
14762
|
+
*/
|
|
14467
14763
|
cancel(requests) {
|
|
14468
14764
|
this.manager.cancel(requests);
|
|
14469
14765
|
}
|
|
14766
|
+
/**
|
|
14767
|
+
* Issue a query for which no result (return value) is needed.
|
|
14768
|
+
* @param {import('@uwdata/mosaic-sql').Query | string} query The query.
|
|
14769
|
+
* @param {object} [options] An options object.
|
|
14770
|
+
* @param {number} [options.priority] The query priority, defaults to
|
|
14771
|
+
* `Priority.Normal`.
|
|
14772
|
+
* @returns {import('./util/query-result.js').QueryResult} A query result
|
|
14773
|
+
* promise.
|
|
14774
|
+
*/
|
|
14470
14775
|
exec(query, { priority = Priority.Normal } = {}) {
|
|
14471
14776
|
query = Array.isArray(query) ? query.join(";\n") : query;
|
|
14472
14777
|
return this.manager.request({ type: "exec", query }, priority);
|
|
14473
14778
|
}
|
|
14779
|
+
/**
|
|
14780
|
+
* Issue a query to the backing database. The submitted query may be
|
|
14781
|
+
* consolidate with other queries and its results may be cached.
|
|
14782
|
+
* @param {import('@uwdata/mosaic-sql').Query | string} query The query.
|
|
14783
|
+
* @param {object} [options] An options object.
|
|
14784
|
+
* @param {'arrow' | 'json'} [options.type] The query result format type.
|
|
14785
|
+
* @param {boolean} [options.cache=true] If true, cache the query result.
|
|
14786
|
+
* @param {number} [options.priority] The query priority, defaults to
|
|
14787
|
+
* `Priority.Normal`.
|
|
14788
|
+
* @returns {import('./util/query-result.js').QueryResult} A query result
|
|
14789
|
+
* promise.
|
|
14790
|
+
*/
|
|
14474
14791
|
query(query, {
|
|
14475
14792
|
type: type2 = "arrow",
|
|
14476
14793
|
cache = true,
|
|
@@ -14479,6 +14796,15 @@ var Coordinator = class {
|
|
|
14479
14796
|
} = {}) {
|
|
14480
14797
|
return this.manager.request({ type: type2, query, cache, options }, priority);
|
|
14481
14798
|
}
|
|
14799
|
+
/**
|
|
14800
|
+
* Issue a query to prefetch data for later use. The query result is cached
|
|
14801
|
+
* for efficient future access.
|
|
14802
|
+
* @param {import('@uwdata/mosaic-sql').Query | string} query The query.
|
|
14803
|
+
* @param {object} [options] An options object.
|
|
14804
|
+
* @param {'arrow' | 'json'} [options.type] The query result format type.
|
|
14805
|
+
* @returns {import('./util/query-result.js').QueryResult} A query result
|
|
14806
|
+
* promise.
|
|
14807
|
+
*/
|
|
14482
14808
|
prefetch(query, options = {}) {
|
|
14483
14809
|
return this.query(query, { ...options, cache: true, priority: Priority.Low });
|
|
14484
14810
|
}
|
|
@@ -14491,26 +14817,44 @@ var Coordinator = class {
|
|
|
14491
14817
|
return this.manager.request({ type: "load-bundle", options }, priority);
|
|
14492
14818
|
}
|
|
14493
14819
|
// -- Client Management ----
|
|
14820
|
+
/**
|
|
14821
|
+
* Update client data by submitting the given query and returning the
|
|
14822
|
+
* data (or error) to the client.
|
|
14823
|
+
* @param {import('./MosaicClient.js').MosaicClient} client A Mosaic client.
|
|
14824
|
+
* @param {import('@uwdata/mosaic-sql').Query | string} query The data query.
|
|
14825
|
+
* @param {number} [priority] The query priority.
|
|
14826
|
+
* @returns {Promise} A Promise that resolves upon completion of the update.
|
|
14827
|
+
*/
|
|
14494
14828
|
updateClient(client, query, priority = Priority.Normal) {
|
|
14495
14829
|
client.queryPending();
|
|
14496
14830
|
return this.query(query, { priority }).then(
|
|
14497
14831
|
(data) => client.queryResult(data).update(),
|
|
14498
14832
|
(err) => {
|
|
14499
|
-
client.queryError(err);
|
|
14500
14833
|
this._logger.error(err);
|
|
14834
|
+
client.queryError(err);
|
|
14501
14835
|
}
|
|
14502
|
-
);
|
|
14836
|
+
).catch((err) => this._logger.error(err));
|
|
14503
14837
|
}
|
|
14838
|
+
/**
|
|
14839
|
+
* Issue a query request for a client. If the query is null or undefined,
|
|
14840
|
+
* the client is simply updated. Otherwise `updateClient` is called. As a
|
|
14841
|
+
* side effect, this method clears the current data cube indexer state.
|
|
14842
|
+
* @param {import('./MosaicClient.js').MosaicClient} client The client
|
|
14843
|
+
* to update.
|
|
14844
|
+
* @param {import('@uwdata/mosaic-sql').Query | string | null} [query]
|
|
14845
|
+
* The query to issue.
|
|
14846
|
+
*/
|
|
14504
14847
|
requestQuery(client, query) {
|
|
14505
|
-
this.
|
|
14848
|
+
this.dataCubeIndexer.clear();
|
|
14506
14849
|
return query ? this.updateClient(client, query) : client.update();
|
|
14507
14850
|
}
|
|
14508
14851
|
/**
|
|
14509
14852
|
* Connect a client to the coordinator.
|
|
14510
|
-
* @param {import('./MosaicClient.js').MosaicClient} client
|
|
14853
|
+
* @param {import('./MosaicClient.js').MosaicClient} client The Mosaic
|
|
14854
|
+
* client to connect.
|
|
14511
14855
|
*/
|
|
14512
14856
|
async connect(client) {
|
|
14513
|
-
const { clients
|
|
14857
|
+
const { clients } = this;
|
|
14514
14858
|
if (clients.has(client)) {
|
|
14515
14859
|
throw new Error("Client already connected.");
|
|
14516
14860
|
}
|
|
@@ -14520,30 +14864,64 @@ var Coordinator = class {
|
|
|
14520
14864
|
if (fields?.length) {
|
|
14521
14865
|
client.fieldInfo(await queryFieldInfo(this, fields));
|
|
14522
14866
|
}
|
|
14523
|
-
|
|
14524
|
-
if (filter3) {
|
|
14525
|
-
if (filterGroups.has(filter3)) {
|
|
14526
|
-
filterGroups.get(filter3).add(client);
|
|
14527
|
-
} else {
|
|
14528
|
-
const group3 = new FilterGroup(this, filter3, indexes2);
|
|
14529
|
-
filterGroups.set(filter3, group3.add(client));
|
|
14530
|
-
}
|
|
14531
|
-
}
|
|
14867
|
+
connectSelection(this, client.filterBy, client);
|
|
14532
14868
|
client.requestQuery();
|
|
14533
14869
|
}
|
|
14534
14870
|
/**
|
|
14535
14871
|
* Disconnect a client from the coordinator.
|
|
14536
|
-
*
|
|
14537
|
-
*
|
|
14872
|
+
* @param {import('./MosaicClient.js').MosaicClient} client The Mosaic
|
|
14873
|
+
* client to disconnect.
|
|
14538
14874
|
*/
|
|
14539
14875
|
disconnect(client) {
|
|
14540
14876
|
const { clients, filterGroups } = this;
|
|
14541
14877
|
if (!clients.has(client)) return;
|
|
14542
14878
|
clients.delete(client);
|
|
14543
|
-
filterGroups.get(client.filterBy)?.remove(client);
|
|
14544
14879
|
client.coordinator = null;
|
|
14880
|
+
const group3 = filterGroups.get(client.filterBy);
|
|
14881
|
+
if (group3) {
|
|
14882
|
+
group3.clients.delete(client);
|
|
14883
|
+
}
|
|
14545
14884
|
}
|
|
14546
14885
|
};
|
|
14886
|
+
function connectSelection(mc, selection2, client) {
|
|
14887
|
+
if (!selection2) return;
|
|
14888
|
+
let entry = mc.filterGroups.get(selection2);
|
|
14889
|
+
if (!entry) {
|
|
14890
|
+
const activate = (clause) => activateSelection(mc, selection2, clause);
|
|
14891
|
+
const value = () => updateSelection(mc, selection2);
|
|
14892
|
+
selection2.addEventListener("activate", activate);
|
|
14893
|
+
selection2.addEventListener("value", value);
|
|
14894
|
+
entry = {
|
|
14895
|
+
selection: selection2,
|
|
14896
|
+
clients: /* @__PURE__ */ new Set(),
|
|
14897
|
+
disconnect() {
|
|
14898
|
+
selection2.removeEventListener("activate", activate);
|
|
14899
|
+
selection2.removeEventListener("value", value);
|
|
14900
|
+
}
|
|
14901
|
+
};
|
|
14902
|
+
mc.filterGroups.set(selection2, entry);
|
|
14903
|
+
}
|
|
14904
|
+
entry.clients.add(client);
|
|
14905
|
+
}
|
|
14906
|
+
function activateSelection(mc, selection2, clause) {
|
|
14907
|
+
const { dataCubeIndexer, filterGroups } = mc;
|
|
14908
|
+
const { clients } = filterGroups.get(selection2);
|
|
14909
|
+
for (const client of clients) {
|
|
14910
|
+
dataCubeIndexer.index(client, selection2, clause);
|
|
14911
|
+
}
|
|
14912
|
+
}
|
|
14913
|
+
function updateSelection(mc, selection2) {
|
|
14914
|
+
const { dataCubeIndexer, filterGroups } = mc;
|
|
14915
|
+
const { clients } = filterGroups.get(selection2);
|
|
14916
|
+
const { active } = selection2;
|
|
14917
|
+
return Promise.allSettled(Array.from(clients, (client) => {
|
|
14918
|
+
const info = dataCubeIndexer.index(client, selection2, active);
|
|
14919
|
+
const filter3 = info ? null : selection2.predicate(client);
|
|
14920
|
+
if (info?.skip || !info && !filter3) return;
|
|
14921
|
+
const query = info?.query(active.predicate) ?? client.query(filter3);
|
|
14922
|
+
return mc.updateClient(client, query);
|
|
14923
|
+
}));
|
|
14924
|
+
}
|
|
14547
14925
|
|
|
14548
14926
|
// ../core/src/util/AsyncDispatch.js
|
|
14549
14927
|
var AsyncDispatch = class {
|
|
@@ -14600,7 +14978,7 @@ var AsyncDispatch = class {
|
|
|
14600
14978
|
* queue of unemitted event values prior to enqueueing a new value.
|
|
14601
14979
|
* This default implementation simply returns null, indicating that
|
|
14602
14980
|
* any other unemitted event values should be dropped (that is, all
|
|
14603
|
-
* queued events are filtered)
|
|
14981
|
+
* queued events are filtered).
|
|
14604
14982
|
* @param {string} type The event type.
|
|
14605
14983
|
* @param {*} value The new event value that will be enqueued.
|
|
14606
14984
|
* @returns {(value: *) => boolean|null} A dispatch queue filter
|
|
@@ -14617,6 +14995,16 @@ var AsyncDispatch = class {
|
|
|
14617
14995
|
const entry = this._callbacks.get(type2);
|
|
14618
14996
|
entry?.queue.clear();
|
|
14619
14997
|
}
|
|
14998
|
+
/**
|
|
14999
|
+
* Returns a promise that resolves when any pending updates complete for
|
|
15000
|
+
* the event of the given type currently being processed. The Promise will
|
|
15001
|
+
* resolve immediately if the queue for the given event type is empty.
|
|
15002
|
+
* @param {string} type The event type to wait for.
|
|
15003
|
+
* @returns {Promise} A pending event promise.
|
|
15004
|
+
*/
|
|
15005
|
+
async pending(type2) {
|
|
15006
|
+
await this._callbacks.get(type2)?.pending;
|
|
15007
|
+
}
|
|
14620
15008
|
/**
|
|
14621
15009
|
* Emit an event value to listeners for the given event type.
|
|
14622
15010
|
* If a previous emit has not yet resolved, the event value
|
|
@@ -14804,10 +15192,13 @@ var Selection = class _Selection extends Param {
|
|
|
14804
15192
|
* @param {boolean} [options.cross=false] Boolean flag indicating
|
|
14805
15193
|
* cross-filtered resolution. If true, selection clauses will not
|
|
14806
15194
|
* be applied to the clients they are associated with.
|
|
15195
|
+
* @param {boolean} [options.empty=false] Boolean flag indicating if a lack
|
|
15196
|
+
* of clauses should correspond to an empty selection with no records. This
|
|
15197
|
+
* setting determines the default selection state.
|
|
14807
15198
|
* @returns {Selection} The new Selection instance.
|
|
14808
15199
|
*/
|
|
14809
|
-
static intersect({ cross: cross3 = false } = {}) {
|
|
14810
|
-
return new _Selection(new SelectionResolver({ cross: cross3 }));
|
|
15200
|
+
static intersect({ cross: cross3 = false, empty: empty4 = false } = {}) {
|
|
15201
|
+
return new _Selection(new SelectionResolver({ cross: cross3, empty: empty4 }));
|
|
14811
15202
|
}
|
|
14812
15203
|
/**
|
|
14813
15204
|
* Create a new Selection instance with a
|
|
@@ -14816,10 +15207,13 @@ var Selection = class _Selection extends Param {
|
|
|
14816
15207
|
* @param {boolean} [options.cross=false] Boolean flag indicating
|
|
14817
15208
|
* cross-filtered resolution. If true, selection clauses will not
|
|
14818
15209
|
* be applied to the clients they are associated with.
|
|
15210
|
+
* @param {boolean} [options.empty=false] Boolean flag indicating if a lack
|
|
15211
|
+
* of clauses should correspond to an empty selection with no records. This
|
|
15212
|
+
* setting determines the default selection state.
|
|
14819
15213
|
* @returns {Selection} The new Selection instance.
|
|
14820
15214
|
*/
|
|
14821
|
-
static union({ cross: cross3 = false } = {}) {
|
|
14822
|
-
return new _Selection(new SelectionResolver({ cross: cross3, union: true }));
|
|
15215
|
+
static union({ cross: cross3 = false, empty: empty4 = false } = {}) {
|
|
15216
|
+
return new _Selection(new SelectionResolver({ cross: cross3, empty: empty4, union: true }));
|
|
14823
15217
|
}
|
|
14824
15218
|
/**
|
|
14825
15219
|
* Create a new Selection instance with a singular resolution strategy
|
|
@@ -14828,18 +15222,25 @@ var Selection = class _Selection extends Param {
|
|
|
14828
15222
|
* @param {boolean} [options.cross=false] Boolean flag indicating
|
|
14829
15223
|
* cross-filtered resolution. If true, selection clauses will not
|
|
14830
15224
|
* be applied to the clients they are associated with.
|
|
15225
|
+
* @param {boolean} [options.empty=false] Boolean flag indicating if a lack
|
|
15226
|
+
* of clauses should correspond to an empty selection with no records. This
|
|
15227
|
+
* setting determines the default selection state.
|
|
14831
15228
|
* @returns {Selection} The new Selection instance.
|
|
14832
15229
|
*/
|
|
14833
|
-
static single({ cross: cross3 = false } = {}) {
|
|
14834
|
-
return new _Selection(new SelectionResolver({ cross: cross3, single: true }));
|
|
15230
|
+
static single({ cross: cross3 = false, empty: empty4 = false } = {}) {
|
|
15231
|
+
return new _Selection(new SelectionResolver({ cross: cross3, empty: empty4, single: true }));
|
|
14835
15232
|
}
|
|
14836
15233
|
/**
|
|
14837
15234
|
* Create a new Selection instance with a
|
|
14838
15235
|
* cross-filtered intersect resolution strategy.
|
|
15236
|
+
* @param {object} [options] The selection options.
|
|
15237
|
+
* @param {boolean} [options.empty=false] Boolean flag indicating if a lack
|
|
15238
|
+
* of clauses should correspond to an empty selection with no records. This
|
|
15239
|
+
* setting determines the default selection state.
|
|
14839
15240
|
* @returns {Selection} The new Selection instance.
|
|
14840
15241
|
*/
|
|
14841
|
-
static crossfilter() {
|
|
14842
|
-
return new _Selection(new SelectionResolver({ cross: true }));
|
|
15242
|
+
static crossfilter({ empty: empty4 = false } = {}) {
|
|
15243
|
+
return new _Selection(new SelectionResolver({ cross: true, empty: empty4 }));
|
|
14843
15244
|
}
|
|
14844
15245
|
/**
|
|
14845
15246
|
* Create a new Selection instance.
|
|
@@ -14872,6 +15273,24 @@ var Selection = class _Selection extends Param {
|
|
|
14872
15273
|
s2._value.active = { source };
|
|
14873
15274
|
return s2;
|
|
14874
15275
|
}
|
|
15276
|
+
/**
|
|
15277
|
+
* The selection clause resolver.
|
|
15278
|
+
*/
|
|
15279
|
+
get resolver() {
|
|
15280
|
+
return this._resolver;
|
|
15281
|
+
}
|
|
15282
|
+
/**
|
|
15283
|
+
* Indicate if this selection has a single resolution strategy.
|
|
15284
|
+
*/
|
|
15285
|
+
get single() {
|
|
15286
|
+
return this._resolver.single;
|
|
15287
|
+
}
|
|
15288
|
+
/**
|
|
15289
|
+
* The current array of selection clauses.
|
|
15290
|
+
*/
|
|
15291
|
+
get clauses() {
|
|
15292
|
+
return super.value;
|
|
15293
|
+
}
|
|
14875
15294
|
/**
|
|
14876
15295
|
* The current active (most recently updated) selection clause.
|
|
14877
15296
|
*/
|
|
@@ -14886,16 +15305,12 @@ var Selection = class _Selection extends Param {
|
|
|
14886
15305
|
return this.active?.value;
|
|
14887
15306
|
}
|
|
14888
15307
|
/**
|
|
14889
|
-
* The
|
|
15308
|
+
* The value corresponding to a given source. Returns undefined if
|
|
15309
|
+
* this selection does not include a clause from this source.
|
|
15310
|
+
* @param {*} source The clause source to look up the value for.
|
|
14890
15311
|
*/
|
|
14891
|
-
|
|
14892
|
-
return
|
|
14893
|
-
}
|
|
14894
|
-
/**
|
|
14895
|
-
* Indicate if this selection has a single resolution strategy.
|
|
14896
|
-
*/
|
|
14897
|
-
get single() {
|
|
14898
|
-
return this._resolver.single;
|
|
15312
|
+
valueFor(source) {
|
|
15313
|
+
return this.clauses.find((c4) => c4.source === source)?.value;
|
|
14899
15314
|
}
|
|
14900
15315
|
/**
|
|
14901
15316
|
* Emit an activate event with the given selection clause.
|
|
@@ -14973,11 +15388,15 @@ var SelectionResolver = class {
|
|
|
14973
15388
|
* If false, an intersection strategy is used.
|
|
14974
15389
|
* @param {boolean} [options.cross=false] Boolean flag to indicate cross-filtering.
|
|
14975
15390
|
* @param {boolean} [options.single=false] Boolean flag to indicate single clauses only.
|
|
15391
|
+
* @param {boolean} [options.empty=false] Boolean flag indicating if a lack
|
|
15392
|
+
* of clauses should correspond to an empty selection with no records. This
|
|
15393
|
+
* setting determines the default selection state.
|
|
14976
15394
|
*/
|
|
14977
|
-
constructor({ union, cross: cross3, single } = {}) {
|
|
15395
|
+
constructor({ union, cross: cross3, single, empty: empty4 } = {}) {
|
|
14978
15396
|
this.union = !!union;
|
|
14979
15397
|
this.cross = !!cross3;
|
|
14980
15398
|
this.single = !!single;
|
|
15399
|
+
this.empty = !!empty4;
|
|
14981
15400
|
}
|
|
14982
15401
|
/**
|
|
14983
15402
|
* Resolve a list of selection clauses according to the resolution strategy.
|
|
@@ -15012,7 +15431,10 @@ var SelectionResolver = class {
|
|
|
15012
15431
|
* based on the current state of this selection.
|
|
15013
15432
|
*/
|
|
15014
15433
|
predicate(clauseList, active, client) {
|
|
15015
|
-
const { union } = this;
|
|
15434
|
+
const { empty: empty4, union } = this;
|
|
15435
|
+
if (empty4 && !clauseList.length) {
|
|
15436
|
+
return ["FALSE"];
|
|
15437
|
+
}
|
|
15016
15438
|
if (this.skip(client, active)) return void 0;
|
|
15017
15439
|
const predicates = clauseList.filter((clause) => !this.skip(client, clause)).map((clause) => clause.predicate);
|
|
15018
15440
|
return union && predicates.length > 1 ? or(predicates) : predicates;
|
|
@@ -15032,6 +15454,50 @@ var SelectionResolver = class {
|
|
|
15032
15454
|
}
|
|
15033
15455
|
};
|
|
15034
15456
|
|
|
15457
|
+
// ../core/src/SelectionClause.js
|
|
15458
|
+
function clausePoints(fields, value, {
|
|
15459
|
+
source,
|
|
15460
|
+
clients = source ? /* @__PURE__ */ new Set([source]) : void 0
|
|
15461
|
+
}) {
|
|
15462
|
+
let predicate = null;
|
|
15463
|
+
if (value) {
|
|
15464
|
+
const clauses = value.map((vals) => {
|
|
15465
|
+
const list = vals.map((v2, i) => isNotDistinct(fields[i], literal(v2)));
|
|
15466
|
+
return list.length > 1 ? and(list) : list[0];
|
|
15467
|
+
});
|
|
15468
|
+
predicate = clauses.length > 1 ? or(clauses) : clauses[0];
|
|
15469
|
+
}
|
|
15470
|
+
return {
|
|
15471
|
+
meta: { type: "point" },
|
|
15472
|
+
source,
|
|
15473
|
+
clients,
|
|
15474
|
+
value,
|
|
15475
|
+
predicate
|
|
15476
|
+
};
|
|
15477
|
+
}
|
|
15478
|
+
function clauseInterval(field2, value, {
|
|
15479
|
+
source,
|
|
15480
|
+
clients = source ? /* @__PURE__ */ new Set([source]) : void 0,
|
|
15481
|
+
bin: bin3,
|
|
15482
|
+
scale: scale3,
|
|
15483
|
+
pixelSize = 1
|
|
15484
|
+
}) {
|
|
15485
|
+
const predicate = value != null ? isBetween(field2, value) : null;
|
|
15486
|
+
const meta = { type: "interval", scales: scale3 && [scale3], bin: bin3, pixelSize };
|
|
15487
|
+
return { meta, source, clients, value, predicate };
|
|
15488
|
+
}
|
|
15489
|
+
function clauseIntervals(fields, value, {
|
|
15490
|
+
source,
|
|
15491
|
+
clients = source ? /* @__PURE__ */ new Set([source]) : void 0,
|
|
15492
|
+
bin: bin3,
|
|
15493
|
+
scales: scales2 = [],
|
|
15494
|
+
pixelSize = 1
|
|
15495
|
+
}) {
|
|
15496
|
+
const predicate = value != null ? and(fields.map((f, i) => isBetween(f, value[i]))) : null;
|
|
15497
|
+
const meta = { type: "interval", scales: scales2, bin: bin3, pixelSize };
|
|
15498
|
+
return { meta, source, clients, value, predicate };
|
|
15499
|
+
}
|
|
15500
|
+
|
|
15035
15501
|
// ../core/src/util/synchronizer.js
|
|
15036
15502
|
function synchronizer() {
|
|
15037
15503
|
const set3 = /* @__PURE__ */ new Set();
|
|
@@ -15076,6 +15542,39 @@ function synchronizer() {
|
|
|
15076
15542
|
};
|
|
15077
15543
|
}
|
|
15078
15544
|
|
|
15545
|
+
// ../core/src/util/to-data-columns.js
|
|
15546
|
+
function toDataColumns(data) {
|
|
15547
|
+
return isArrowTable(data) ? arrowToColumns(data) : arrayToColumns(data);
|
|
15548
|
+
}
|
|
15549
|
+
function arrowToColumns(data) {
|
|
15550
|
+
const { numRows, numCols, schema: { fields } } = data;
|
|
15551
|
+
const columns = {};
|
|
15552
|
+
for (let col = 0; col < numCols; ++col) {
|
|
15553
|
+
const name = fields[col].name;
|
|
15554
|
+
if (columns[name]) {
|
|
15555
|
+
console.warn(`Redundant column name "${name}". Skipping...`);
|
|
15556
|
+
} else {
|
|
15557
|
+
columns[name] = convertArrowColumn(data.getChildAt(col));
|
|
15558
|
+
}
|
|
15559
|
+
}
|
|
15560
|
+
return { numRows, columns };
|
|
15561
|
+
}
|
|
15562
|
+
function arrayToColumns(data) {
|
|
15563
|
+
const numRows = data.length;
|
|
15564
|
+
if (typeof data[0] === "object") {
|
|
15565
|
+
const names = numRows ? Object.keys(data[0]) : [];
|
|
15566
|
+
const columns = {};
|
|
15567
|
+
if (names.length > 0) {
|
|
15568
|
+
names.forEach((name) => {
|
|
15569
|
+
columns[name] = data.map((d) => d[name]);
|
|
15570
|
+
});
|
|
15571
|
+
}
|
|
15572
|
+
return { numRows, columns };
|
|
15573
|
+
} else {
|
|
15574
|
+
return { numRows, values: data };
|
|
15575
|
+
}
|
|
15576
|
+
}
|
|
15577
|
+
|
|
15079
15578
|
// ../../node_modules/@observablehq/plot/src/index.js
|
|
15080
15579
|
var src_exports = {};
|
|
15081
15580
|
__export(src_exports, {
|
|
@@ -15147,6 +15646,7 @@ __export(src_exports, {
|
|
|
15147
15646
|
find: () => find2,
|
|
15148
15647
|
formatIsoDate: () => formatIsoDate,
|
|
15149
15648
|
formatMonth: () => formatMonth,
|
|
15649
|
+
formatNumber: () => formatNumber,
|
|
15150
15650
|
formatWeekday: () => formatWeekday,
|
|
15151
15651
|
frame: () => frame2,
|
|
15152
15652
|
geo: () => geo,
|
|
@@ -15186,6 +15686,7 @@ __export(src_exports, {
|
|
|
15186
15686
|
normalize: () => normalize3,
|
|
15187
15687
|
normalizeX: () => normalizeX,
|
|
15188
15688
|
normalizeY: () => normalizeY,
|
|
15689
|
+
numberInterval: () => numberInterval,
|
|
15189
15690
|
plot: () => plot,
|
|
15190
15691
|
pointer: () => pointer,
|
|
15191
15692
|
pointerX: () => pointerX,
|
|
@@ -15221,11 +15722,13 @@ __export(src_exports, {
|
|
|
15221
15722
|
textY: () => textY,
|
|
15222
15723
|
tickX: () => tickX,
|
|
15223
15724
|
tickY: () => tickY,
|
|
15725
|
+
timeInterval: () => timeInterval2,
|
|
15224
15726
|
tip: () => tip,
|
|
15225
15727
|
transform: () => basic,
|
|
15226
15728
|
tree: () => tree,
|
|
15227
15729
|
treeLink: () => treeLink,
|
|
15228
15730
|
treeNode: () => treeNode,
|
|
15731
|
+
utcInterval: () => utcInterval,
|
|
15229
15732
|
valueof: () => valueof,
|
|
15230
15733
|
vector: () => vector,
|
|
15231
15734
|
vectorX: () => vectorX,
|
|
@@ -27791,10 +28294,10 @@ function parseTimeInterval(input) {
|
|
|
27791
28294
|
if (period > 1 && !interval2.every) throw new Error(`non-periodic interval: ${name}`);
|
|
27792
28295
|
return [name, period];
|
|
27793
28296
|
}
|
|
27794
|
-
function
|
|
28297
|
+
function timeInterval2(input) {
|
|
27795
28298
|
return asInterval(parseTimeInterval(input), "time");
|
|
27796
28299
|
}
|
|
27797
|
-
function
|
|
28300
|
+
function utcInterval(input) {
|
|
27798
28301
|
return asInterval(parseTimeInterval(input), "utc");
|
|
27799
28302
|
}
|
|
27800
28303
|
function asInterval([name, period], type2) {
|
|
@@ -27812,7 +28315,7 @@ function generalizeTimeInterval(interval2, n) {
|
|
|
27812
28315
|
if (!tickIntervals.some(([, d]) => d === duration)) return;
|
|
27813
28316
|
if (duration % durationDay2 === 0 && durationDay2 < duration && duration < durationMonth2) return;
|
|
27814
28317
|
const [i] = tickIntervals[bisector(([, step]) => Math.log(step)).center(tickIntervals, Math.log(duration * n))];
|
|
27815
|
-
return (interval2[intervalType] === "time" ?
|
|
28318
|
+
return (interval2[intervalType] === "time" ? timeInterval2 : utcInterval)(i);
|
|
27816
28319
|
}
|
|
27817
28320
|
function formatTimeInterval(name, type2, anchor) {
|
|
27818
28321
|
const format3 = type2 === "time" ? timeFormat : utcFormat;
|
|
@@ -27877,7 +28380,7 @@ function valueof(data, value, type2) {
|
|
|
27877
28380
|
return valueType === "string" ? maybeTypedMap(data, field(value), type2) : valueType === "function" ? maybeTypedMap(data, value, type2) : valueType === "number" || value instanceof Date || valueType === "boolean" ? map2(data, constant(value), type2) : typeof value?.transform === "function" ? maybeTypedArrayify(value.transform(data), type2) : maybeTake(maybeTypedArrayify(value, type2), data?.[reindex]);
|
|
27878
28381
|
}
|
|
27879
28382
|
function maybeTake(values2, index2) {
|
|
27880
|
-
return index2 ? take(values2, index2) : values2;
|
|
28383
|
+
return values2 != null && index2 ? take(values2, index2) : values2;
|
|
27881
28384
|
}
|
|
27882
28385
|
function maybeTypedMap(data, f, type2) {
|
|
27883
28386
|
return map2(data, type2?.prototype instanceof TypedArray ? floater(f) : f, type2);
|
|
@@ -28048,26 +28551,26 @@ function maybeIntervalTransform(interval2, type2) {
|
|
|
28048
28551
|
}
|
|
28049
28552
|
function maybeInterval(interval2, type2) {
|
|
28050
28553
|
if (interval2 == null) return;
|
|
28051
|
-
if (typeof interval2 === "number")
|
|
28052
|
-
|
|
28053
|
-
const n = Math.abs(interval2);
|
|
28054
|
-
return interval2 < 0 ? {
|
|
28055
|
-
floor: (d) => Math.floor(d * n) / n,
|
|
28056
|
-
offset: (d) => (d * n + 1) / n,
|
|
28057
|
-
// note: no optional step for simplicity
|
|
28058
|
-
range: (lo, hi) => range(Math.ceil(lo * n), hi * n).map((x3) => x3 / n)
|
|
28059
|
-
} : {
|
|
28060
|
-
floor: (d) => Math.floor(d / n) * n,
|
|
28061
|
-
offset: (d) => d + n,
|
|
28062
|
-
// note: no optional step for simplicity
|
|
28063
|
-
range: (lo, hi) => range(Math.ceil(lo / n), hi / n).map((x3) => x3 * n)
|
|
28064
|
-
};
|
|
28065
|
-
}
|
|
28066
|
-
if (typeof interval2 === "string") return (type2 === "time" ? maybeTimeInterval : maybeUtcInterval)(interval2);
|
|
28554
|
+
if (typeof interval2 === "number") return numberInterval(interval2);
|
|
28555
|
+
if (typeof interval2 === "string") return (type2 === "time" ? timeInterval2 : utcInterval)(interval2);
|
|
28067
28556
|
if (typeof interval2.floor !== "function") throw new Error("invalid interval; missing floor method");
|
|
28068
28557
|
if (typeof interval2.offset !== "function") throw new Error("invalid interval; missing offset method");
|
|
28069
28558
|
return interval2;
|
|
28070
28559
|
}
|
|
28560
|
+
function numberInterval(interval2) {
|
|
28561
|
+
interval2 = +interval2;
|
|
28562
|
+
if (0 < interval2 && interval2 < 1 && Number.isInteger(1 / interval2)) interval2 = -1 / interval2;
|
|
28563
|
+
const n = Math.abs(interval2);
|
|
28564
|
+
return interval2 < 0 ? {
|
|
28565
|
+
floor: (d) => Math.floor(d * n) / n,
|
|
28566
|
+
offset: (d, s2 = 1) => (d * n + Math.floor(s2)) / n,
|
|
28567
|
+
range: (lo, hi) => range(Math.ceil(lo * n), hi * n).map((x3) => x3 / n)
|
|
28568
|
+
} : {
|
|
28569
|
+
floor: (d) => Math.floor(d / n) * n,
|
|
28570
|
+
offset: (d, s2 = 1) => d + n * Math.floor(s2),
|
|
28571
|
+
range: (lo, hi) => range(Math.ceil(lo / n), hi / n).map((x3) => x3 * n)
|
|
28572
|
+
};
|
|
28573
|
+
}
|
|
28071
28574
|
function maybeRangeInterval(interval2, type2) {
|
|
28072
28575
|
interval2 = maybeInterval(interval2, type2);
|
|
28073
28576
|
if (interval2 && typeof interval2.range !== "function") throw new Error("invalid interval: missing range method");
|
|
@@ -28938,251 +29441,6 @@ function getSource(channels, key) {
|
|
|
28938
29441
|
return channel.source === null ? null : channel;
|
|
28939
29442
|
}
|
|
28940
29443
|
|
|
28941
|
-
// ../../node_modules/@observablehq/plot/src/context.js
|
|
28942
|
-
function createContext(options = {}) {
|
|
28943
|
-
const { document: document2 = typeof window !== "undefined" ? window.document : void 0, clip } = options;
|
|
28944
|
-
return { document: document2, clip: maybeClip(clip) };
|
|
28945
|
-
}
|
|
28946
|
-
function create3(name, { document: document2 }) {
|
|
28947
|
-
return select_default2(creator_default(name).call(document2.documentElement));
|
|
28948
|
-
}
|
|
28949
|
-
|
|
28950
|
-
// ../../node_modules/@observablehq/plot/src/warnings.js
|
|
28951
|
-
var warnings = 0;
|
|
28952
|
-
var lastMessage;
|
|
28953
|
-
function consumeWarnings() {
|
|
28954
|
-
const w = warnings;
|
|
28955
|
-
warnings = 0;
|
|
28956
|
-
lastMessage = void 0;
|
|
28957
|
-
return w;
|
|
28958
|
-
}
|
|
28959
|
-
function warn(message) {
|
|
28960
|
-
if (message === lastMessage) return;
|
|
28961
|
-
lastMessage = message;
|
|
28962
|
-
console.warn(message);
|
|
28963
|
-
++warnings;
|
|
28964
|
-
}
|
|
28965
|
-
|
|
28966
|
-
// ../../node_modules/@observablehq/plot/src/projection.js
|
|
28967
|
-
var pi4 = Math.PI;
|
|
28968
|
-
var tau5 = 2 * pi4;
|
|
28969
|
-
var defaultAspectRatio = 0.618;
|
|
28970
|
-
function createProjection({
|
|
28971
|
-
projection: projection3,
|
|
28972
|
-
inset: globalInset = 0,
|
|
28973
|
-
insetTop = globalInset,
|
|
28974
|
-
insetRight = globalInset,
|
|
28975
|
-
insetBottom = globalInset,
|
|
28976
|
-
insetLeft = globalInset
|
|
28977
|
-
} = {}, dimensions) {
|
|
28978
|
-
if (projection3 == null) return;
|
|
28979
|
-
if (typeof projection3.stream === "function") return projection3;
|
|
28980
|
-
let options;
|
|
28981
|
-
let domain;
|
|
28982
|
-
let clip = "frame";
|
|
28983
|
-
if (isObject2(projection3)) {
|
|
28984
|
-
let inset;
|
|
28985
|
-
({
|
|
28986
|
-
type: projection3,
|
|
28987
|
-
domain,
|
|
28988
|
-
inset,
|
|
28989
|
-
insetTop = inset !== void 0 ? inset : insetTop,
|
|
28990
|
-
insetRight = inset !== void 0 ? inset : insetRight,
|
|
28991
|
-
insetBottom = inset !== void 0 ? inset : insetBottom,
|
|
28992
|
-
insetLeft = inset !== void 0 ? inset : insetLeft,
|
|
28993
|
-
clip = clip,
|
|
28994
|
-
...options
|
|
28995
|
-
} = projection3);
|
|
28996
|
-
if (projection3 == null) return;
|
|
28997
|
-
}
|
|
28998
|
-
if (typeof projection3 !== "function") ({ type: projection3 } = namedProjection(projection3));
|
|
28999
|
-
const { width, height, marginLeft, marginRight, marginTop, marginBottom } = dimensions;
|
|
29000
|
-
const dx = width - marginLeft - marginRight - insetLeft - insetRight;
|
|
29001
|
-
const dy = height - marginTop - marginBottom - insetTop - insetBottom;
|
|
29002
|
-
projection3 = projection3?.({ width: dx, height: dy, clip, ...options });
|
|
29003
|
-
if (projection3 == null) return;
|
|
29004
|
-
clip = maybePostClip(clip, marginLeft, marginTop, width - marginRight, height - marginBottom);
|
|
29005
|
-
let tx = marginLeft + insetLeft;
|
|
29006
|
-
let ty = marginTop + insetTop;
|
|
29007
|
-
let transform3;
|
|
29008
|
-
if (domain != null) {
|
|
29009
|
-
const [[x06, y06], [x12, y12]] = path_default(projection3).bounds(domain);
|
|
29010
|
-
const k2 = Math.min(dx / (x12 - x06), dy / (y12 - y06));
|
|
29011
|
-
if (k2 > 0) {
|
|
29012
|
-
tx -= (k2 * (x06 + x12) - dx) / 2;
|
|
29013
|
-
ty -= (k2 * (y06 + y12) - dy) / 2;
|
|
29014
|
-
transform3 = transform_default({
|
|
29015
|
-
point(x3, y3) {
|
|
29016
|
-
this.stream.point(x3 * k2 + tx, y3 * k2 + ty);
|
|
29017
|
-
}
|
|
29018
|
-
});
|
|
29019
|
-
} else {
|
|
29020
|
-
warn(`Warning: the projection could not be fit to the specified domain; using the default scale.`);
|
|
29021
|
-
}
|
|
29022
|
-
}
|
|
29023
|
-
transform3 ??= tx === 0 && ty === 0 ? identity8() : transform_default({
|
|
29024
|
-
point(x3, y3) {
|
|
29025
|
-
this.stream.point(x3 + tx, y3 + ty);
|
|
29026
|
-
}
|
|
29027
|
-
});
|
|
29028
|
-
return { stream: (s2) => projection3.stream(transform3.stream(clip(s2))) };
|
|
29029
|
-
}
|
|
29030
|
-
function namedProjection(projection3) {
|
|
29031
|
-
switch (`${projection3}`.toLowerCase()) {
|
|
29032
|
-
case "albers-usa":
|
|
29033
|
-
return scaleProjection(albersUsa_default, 0.7463, 0.4673);
|
|
29034
|
-
case "albers":
|
|
29035
|
-
return conicProjection2(albers_default, 0.7463, 0.4673);
|
|
29036
|
-
case "azimuthal-equal-area":
|
|
29037
|
-
return scaleProjection(azimuthalEqualArea_default, 4, 4);
|
|
29038
|
-
case "azimuthal-equidistant":
|
|
29039
|
-
return scaleProjection(azimuthalEquidistant_default, tau5, tau5);
|
|
29040
|
-
case "conic-conformal":
|
|
29041
|
-
return conicProjection2(conicConformal_default, tau5, tau5);
|
|
29042
|
-
case "conic-equal-area":
|
|
29043
|
-
return conicProjection2(conicEqualArea_default, 6.1702, 2.9781);
|
|
29044
|
-
case "conic-equidistant":
|
|
29045
|
-
return conicProjection2(conicEquidistant_default, 7.312, 3.6282);
|
|
29046
|
-
case "equal-earth":
|
|
29047
|
-
return scaleProjection(equalEarth_default, 5.4133, 2.6347);
|
|
29048
|
-
case "equirectangular":
|
|
29049
|
-
return scaleProjection(equirectangular_default, tau5, pi4);
|
|
29050
|
-
case "gnomonic":
|
|
29051
|
-
return scaleProjection(gnomonic_default, 3.4641, 3.4641);
|
|
29052
|
-
case "identity":
|
|
29053
|
-
return { type: identity8 };
|
|
29054
|
-
case "reflect-y":
|
|
29055
|
-
return { type: reflectY };
|
|
29056
|
-
case "mercator":
|
|
29057
|
-
return scaleProjection(mercator_default, tau5, tau5);
|
|
29058
|
-
case "orthographic":
|
|
29059
|
-
return scaleProjection(orthographic_default, 2, 2);
|
|
29060
|
-
case "stereographic":
|
|
29061
|
-
return scaleProjection(stereographic_default, 2, 2);
|
|
29062
|
-
case "transverse-mercator":
|
|
29063
|
-
return scaleProjection(transverseMercator_default, tau5, tau5);
|
|
29064
|
-
default:
|
|
29065
|
-
throw new Error(`unknown projection type: ${projection3}`);
|
|
29066
|
-
}
|
|
29067
|
-
}
|
|
29068
|
-
function maybePostClip(clip, x12, y12, x22, y22) {
|
|
29069
|
-
if (clip === false || clip == null || typeof clip === "number") return (s2) => s2;
|
|
29070
|
-
if (clip === true) clip = "frame";
|
|
29071
|
-
switch (`${clip}`.toLowerCase()) {
|
|
29072
|
-
case "frame":
|
|
29073
|
-
return clipRectangle(x12, y12, x22, y22);
|
|
29074
|
-
default:
|
|
29075
|
-
throw new Error(`unknown projection clip type: ${clip}`);
|
|
29076
|
-
}
|
|
29077
|
-
}
|
|
29078
|
-
function scaleProjection(createProjection2, kx2, ky2) {
|
|
29079
|
-
return {
|
|
29080
|
-
type: ({ width, height, rotate, precision = 0.15, clip }) => {
|
|
29081
|
-
const projection3 = createProjection2();
|
|
29082
|
-
if (precision != null) projection3.precision?.(precision);
|
|
29083
|
-
if (rotate != null) projection3.rotate?.(rotate);
|
|
29084
|
-
if (typeof clip === "number") projection3.clipAngle?.(clip);
|
|
29085
|
-
projection3.scale(Math.min(width / kx2, height / ky2));
|
|
29086
|
-
projection3.translate([width / 2, height / 2]);
|
|
29087
|
-
return projection3;
|
|
29088
|
-
},
|
|
29089
|
-
aspectRatio: ky2 / kx2
|
|
29090
|
-
};
|
|
29091
|
-
}
|
|
29092
|
-
function conicProjection2(createProjection2, kx2, ky2) {
|
|
29093
|
-
const { type: type2, aspectRatio } = scaleProjection(createProjection2, kx2, ky2);
|
|
29094
|
-
return {
|
|
29095
|
-
type: (options) => {
|
|
29096
|
-
const { parallels, domain, width, height } = options;
|
|
29097
|
-
const projection3 = type2(options);
|
|
29098
|
-
if (parallels != null) {
|
|
29099
|
-
projection3.parallels(parallels);
|
|
29100
|
-
if (domain === void 0) {
|
|
29101
|
-
projection3.fitSize([width, height], { type: "Sphere" });
|
|
29102
|
-
}
|
|
29103
|
-
}
|
|
29104
|
-
return projection3;
|
|
29105
|
-
},
|
|
29106
|
-
aspectRatio
|
|
29107
|
-
};
|
|
29108
|
-
}
|
|
29109
|
-
var identity8 = constant({ stream: (stream) => stream });
|
|
29110
|
-
var reflectY = constant(
|
|
29111
|
-
transform_default({
|
|
29112
|
-
point(x3, y3) {
|
|
29113
|
-
this.stream.point(x3, -y3);
|
|
29114
|
-
}
|
|
29115
|
-
})
|
|
29116
|
-
);
|
|
29117
|
-
function project(cx, cy, values2, projection3) {
|
|
29118
|
-
const x3 = values2[cx];
|
|
29119
|
-
const y3 = values2[cy];
|
|
29120
|
-
const n = x3.length;
|
|
29121
|
-
const X3 = values2[cx] = new Float64Array(n).fill(NaN);
|
|
29122
|
-
const Y3 = values2[cy] = new Float64Array(n).fill(NaN);
|
|
29123
|
-
let i;
|
|
29124
|
-
const stream = projection3.stream({
|
|
29125
|
-
point(x4, y4) {
|
|
29126
|
-
X3[i] = x4;
|
|
29127
|
-
Y3[i] = y4;
|
|
29128
|
-
}
|
|
29129
|
-
});
|
|
29130
|
-
for (i = 0; i < n; ++i) {
|
|
29131
|
-
stream.point(x3[i], y3[i]);
|
|
29132
|
-
}
|
|
29133
|
-
}
|
|
29134
|
-
function hasProjection({ projection: projection3 } = {}) {
|
|
29135
|
-
if (projection3 == null) return false;
|
|
29136
|
-
if (typeof projection3.stream === "function") return true;
|
|
29137
|
-
if (isObject2(projection3)) projection3 = projection3.type;
|
|
29138
|
-
return projection3 != null;
|
|
29139
|
-
}
|
|
29140
|
-
function projectionAspectRatio(projection3) {
|
|
29141
|
-
if (typeof projection3?.stream === "function") return defaultAspectRatio;
|
|
29142
|
-
if (isObject2(projection3)) projection3 = projection3.type;
|
|
29143
|
-
if (projection3 == null) return;
|
|
29144
|
-
if (typeof projection3 !== "function") {
|
|
29145
|
-
const { aspectRatio } = namedProjection(projection3);
|
|
29146
|
-
if (aspectRatio) return aspectRatio;
|
|
29147
|
-
}
|
|
29148
|
-
return defaultAspectRatio;
|
|
29149
|
-
}
|
|
29150
|
-
function applyPosition(channels, scales2, { projection: projection3 }) {
|
|
29151
|
-
const { x: x3, y: y3 } = channels;
|
|
29152
|
-
let position3 = {};
|
|
29153
|
-
if (x3) position3.x = x3;
|
|
29154
|
-
if (y3) position3.y = y3;
|
|
29155
|
-
position3 = valueObject(position3, scales2);
|
|
29156
|
-
if (projection3 && x3?.scale === "x" && y3?.scale === "y") project("x", "y", position3, projection3);
|
|
29157
|
-
if (x3) position3.x = coerceNumbers(position3.x);
|
|
29158
|
-
if (y3) position3.y = coerceNumbers(position3.y);
|
|
29159
|
-
return position3;
|
|
29160
|
-
}
|
|
29161
|
-
function getGeometryChannels(channel) {
|
|
29162
|
-
const X3 = [];
|
|
29163
|
-
const Y3 = [];
|
|
29164
|
-
const x3 = { scale: "x", value: X3 };
|
|
29165
|
-
const y3 = { scale: "y", value: Y3 };
|
|
29166
|
-
const sink = {
|
|
29167
|
-
point(x4, y4) {
|
|
29168
|
-
X3.push(x4);
|
|
29169
|
-
Y3.push(y4);
|
|
29170
|
-
},
|
|
29171
|
-
lineStart() {
|
|
29172
|
-
},
|
|
29173
|
-
lineEnd() {
|
|
29174
|
-
},
|
|
29175
|
-
polygonStart() {
|
|
29176
|
-
},
|
|
29177
|
-
polygonEnd() {
|
|
29178
|
-
},
|
|
29179
|
-
sphere() {
|
|
29180
|
-
}
|
|
29181
|
-
};
|
|
29182
|
-
for (const object of channel.value) stream_default(object, sink);
|
|
29183
|
-
return [x3, y3];
|
|
29184
|
-
}
|
|
29185
|
-
|
|
29186
29444
|
// ../../node_modules/@observablehq/plot/src/scales/schemes.js
|
|
29187
29445
|
var categoricalSchemes = /* @__PURE__ */ new Map([
|
|
29188
29446
|
["accent", Accent_default],
|
|
@@ -29427,8 +29685,9 @@ function createScaleQ(key, scale3, channels, {
|
|
|
29427
29685
|
const [min5, max4] = extent(domain);
|
|
29428
29686
|
if (min5 > 0 || max4 < 0) {
|
|
29429
29687
|
domain = slice3(domain);
|
|
29430
|
-
|
|
29431
|
-
|
|
29688
|
+
const o = orderof(domain) || 1;
|
|
29689
|
+
if (o === Math.sign(min5)) domain[0] = 0;
|
|
29690
|
+
else domain[domain.length - 1] = 0;
|
|
29432
29691
|
}
|
|
29433
29692
|
}
|
|
29434
29693
|
if (reverse3) domain = reverse(domain);
|
|
@@ -29579,6 +29838,22 @@ function interpolatePiecewise(interpolate) {
|
|
|
29579
29838
|
return (i, j) => (t) => interpolate(i + t * (j - i));
|
|
29580
29839
|
}
|
|
29581
29840
|
|
|
29841
|
+
// ../../node_modules/@observablehq/plot/src/warnings.js
|
|
29842
|
+
var warnings = 0;
|
|
29843
|
+
var lastMessage;
|
|
29844
|
+
function consumeWarnings() {
|
|
29845
|
+
const w = warnings;
|
|
29846
|
+
warnings = 0;
|
|
29847
|
+
lastMessage = void 0;
|
|
29848
|
+
return w;
|
|
29849
|
+
}
|
|
29850
|
+
function warn(message) {
|
|
29851
|
+
if (message === lastMessage) return;
|
|
29852
|
+
lastMessage = message;
|
|
29853
|
+
console.warn(message);
|
|
29854
|
+
++warnings;
|
|
29855
|
+
}
|
|
29856
|
+
|
|
29582
29857
|
// ../../node_modules/@observablehq/plot/src/scales/diverging.js
|
|
29583
29858
|
function createScaleD(key, scale3, transform3, channels, {
|
|
29584
29859
|
type: type2,
|
|
@@ -30234,6 +30509,373 @@ function exposeScale({ scale: scale3, type: type2, domain, range: range3, interp
|
|
|
30234
30509
|
};
|
|
30235
30510
|
}
|
|
30236
30511
|
|
|
30512
|
+
// ../../node_modules/@observablehq/plot/src/facet.js
|
|
30513
|
+
function createFacets(channelsByScale, options) {
|
|
30514
|
+
const { fx, fy } = createScales(channelsByScale, options);
|
|
30515
|
+
const fxDomain = fx?.scale.domain();
|
|
30516
|
+
const fyDomain = fy?.scale.domain();
|
|
30517
|
+
return fxDomain && fyDomain ? cross(fxDomain, fyDomain).map(([x3, y3], i) => ({ x: x3, y: y3, i })) : fxDomain ? fxDomain.map((x3, i) => ({ x: x3, i })) : fyDomain ? fyDomain.map((y3, i) => ({ y: y3, i })) : void 0;
|
|
30518
|
+
}
|
|
30519
|
+
function recreateFacets(facets, { x: X3, y: Y3 }) {
|
|
30520
|
+
X3 &&= facetIndex(X3);
|
|
30521
|
+
Y3 &&= facetIndex(Y3);
|
|
30522
|
+
return facets.filter(
|
|
30523
|
+
X3 && Y3 ? (f) => X3.has(f.x) && Y3.has(f.y) : X3 ? (f) => X3.has(f.x) : (f) => Y3.has(f.y)
|
|
30524
|
+
).sort(
|
|
30525
|
+
X3 && Y3 ? (a2, b) => X3.get(a2.x) - X3.get(b.x) || Y3.get(a2.y) - Y3.get(b.y) : X3 ? (a2, b) => X3.get(a2.x) - X3.get(b.x) : (a2, b) => Y3.get(a2.y) - Y3.get(b.y)
|
|
30526
|
+
);
|
|
30527
|
+
}
|
|
30528
|
+
function facetGroups(data, { fx, fy }) {
|
|
30529
|
+
const I = range2(data);
|
|
30530
|
+
const FX = fx?.value;
|
|
30531
|
+
const FY = fy?.value;
|
|
30532
|
+
return fx && fy ? rollup(
|
|
30533
|
+
I,
|
|
30534
|
+
(G) => (G.fx = FX[G[0]], G.fy = FY[G[0]], G),
|
|
30535
|
+
(i) => FX[i],
|
|
30536
|
+
(i) => FY[i]
|
|
30537
|
+
) : fx ? rollup(
|
|
30538
|
+
I,
|
|
30539
|
+
(G) => (G.fx = FX[G[0]], G),
|
|
30540
|
+
(i) => FX[i]
|
|
30541
|
+
) : rollup(
|
|
30542
|
+
I,
|
|
30543
|
+
(G) => (G.fy = FY[G[0]], G),
|
|
30544
|
+
(i) => FY[i]
|
|
30545
|
+
);
|
|
30546
|
+
}
|
|
30547
|
+
function facetTranslator(fx, fy, { marginTop, marginLeft }) {
|
|
30548
|
+
return fx && fy ? ({ x: x3, y: y3 }) => `translate(${fx(x3) - marginLeft},${fy(y3) - marginTop})` : fx ? ({ x: x3 }) => `translate(${fx(x3) - marginLeft},0)` : ({ y: y3 }) => `translate(0,${fy(y3) - marginTop})`;
|
|
30549
|
+
}
|
|
30550
|
+
function facetExclude(index2) {
|
|
30551
|
+
const ex = [];
|
|
30552
|
+
const e = new Uint32Array(sum2(index2, (d) => d.length));
|
|
30553
|
+
for (const i of index2) {
|
|
30554
|
+
let n = 0;
|
|
30555
|
+
for (const j of index2) {
|
|
30556
|
+
if (i === j) continue;
|
|
30557
|
+
e.set(j, n);
|
|
30558
|
+
n += j.length;
|
|
30559
|
+
}
|
|
30560
|
+
ex.push(e.slice(0, n));
|
|
30561
|
+
}
|
|
30562
|
+
return ex;
|
|
30563
|
+
}
|
|
30564
|
+
var facetAnchors = /* @__PURE__ */ new Map([
|
|
30565
|
+
["top", facetAnchorTop],
|
|
30566
|
+
["right", facetAnchorRight],
|
|
30567
|
+
["bottom", facetAnchorBottom],
|
|
30568
|
+
["left", facetAnchorLeft],
|
|
30569
|
+
["top-left", and2(facetAnchorTop, facetAnchorLeft)],
|
|
30570
|
+
["top-right", and2(facetAnchorTop, facetAnchorRight)],
|
|
30571
|
+
["bottom-left", and2(facetAnchorBottom, facetAnchorLeft)],
|
|
30572
|
+
["bottom-right", and2(facetAnchorBottom, facetAnchorRight)],
|
|
30573
|
+
["top-empty", facetAnchorTopEmpty],
|
|
30574
|
+
["right-empty", facetAnchorRightEmpty],
|
|
30575
|
+
["bottom-empty", facetAnchorBottomEmpty],
|
|
30576
|
+
["left-empty", facetAnchorLeftEmpty],
|
|
30577
|
+
["empty", facetAnchorEmpty]
|
|
30578
|
+
]);
|
|
30579
|
+
function maybeFacetAnchor(facetAnchor) {
|
|
30580
|
+
if (facetAnchor == null) return null;
|
|
30581
|
+
const anchor = facetAnchors.get(`${facetAnchor}`.toLowerCase());
|
|
30582
|
+
if (anchor) return anchor;
|
|
30583
|
+
throw new Error(`invalid facet anchor: ${facetAnchor}`);
|
|
30584
|
+
}
|
|
30585
|
+
var indexCache = /* @__PURE__ */ new WeakMap();
|
|
30586
|
+
function facetIndex(V) {
|
|
30587
|
+
let I = indexCache.get(V);
|
|
30588
|
+
if (!I) indexCache.set(V, I = new InternMap(map2(V, (v2, i) => [v2, i])));
|
|
30589
|
+
return I;
|
|
30590
|
+
}
|
|
30591
|
+
function facetIndexOf(V, v2) {
|
|
30592
|
+
return facetIndex(V).get(v2);
|
|
30593
|
+
}
|
|
30594
|
+
function facetFind(facets, x3, y3) {
|
|
30595
|
+
x3 = keyof2(x3);
|
|
30596
|
+
y3 = keyof2(y3);
|
|
30597
|
+
return facets.find((f) => Object.is(keyof2(f.x), x3) && Object.is(keyof2(f.y), y3));
|
|
30598
|
+
}
|
|
30599
|
+
function facetEmpty(facets, x3, y3) {
|
|
30600
|
+
return facetFind(facets, x3, y3)?.empty;
|
|
30601
|
+
}
|
|
30602
|
+
function facetAnchorTop(facets, { y: Y3 }, { y: y3 }) {
|
|
30603
|
+
return Y3 ? facetIndexOf(Y3, y3) === 0 : true;
|
|
30604
|
+
}
|
|
30605
|
+
function facetAnchorBottom(facets, { y: Y3 }, { y: y3 }) {
|
|
30606
|
+
return Y3 ? facetIndexOf(Y3, y3) === Y3.length - 1 : true;
|
|
30607
|
+
}
|
|
30608
|
+
function facetAnchorLeft(facets, { x: X3 }, { x: x3 }) {
|
|
30609
|
+
return X3 ? facetIndexOf(X3, x3) === 0 : true;
|
|
30610
|
+
}
|
|
30611
|
+
function facetAnchorRight(facets, { x: X3 }, { x: x3 }) {
|
|
30612
|
+
return X3 ? facetIndexOf(X3, x3) === X3.length - 1 : true;
|
|
30613
|
+
}
|
|
30614
|
+
function facetAnchorTopEmpty(facets, { y: Y3 }, { x: x3, y: y3, empty: empty4 }) {
|
|
30615
|
+
if (empty4) return false;
|
|
30616
|
+
if (!Y3) return;
|
|
30617
|
+
const i = facetIndexOf(Y3, y3);
|
|
30618
|
+
if (i > 0) return facetEmpty(facets, x3, Y3[i - 1]);
|
|
30619
|
+
}
|
|
30620
|
+
function facetAnchorBottomEmpty(facets, { y: Y3 }, { x: x3, y: y3, empty: empty4 }) {
|
|
30621
|
+
if (empty4) return false;
|
|
30622
|
+
if (!Y3) return;
|
|
30623
|
+
const i = facetIndexOf(Y3, y3);
|
|
30624
|
+
if (i < Y3.length - 1) return facetEmpty(facets, x3, Y3[i + 1]);
|
|
30625
|
+
}
|
|
30626
|
+
function facetAnchorLeftEmpty(facets, { x: X3 }, { x: x3, y: y3, empty: empty4 }) {
|
|
30627
|
+
if (empty4) return false;
|
|
30628
|
+
if (!X3) return;
|
|
30629
|
+
const i = facetIndexOf(X3, x3);
|
|
30630
|
+
if (i > 0) return facetEmpty(facets, X3[i - 1], y3);
|
|
30631
|
+
}
|
|
30632
|
+
function facetAnchorRightEmpty(facets, { x: X3 }, { x: x3, y: y3, empty: empty4 }) {
|
|
30633
|
+
if (empty4) return false;
|
|
30634
|
+
if (!X3) return;
|
|
30635
|
+
const i = facetIndexOf(X3, x3);
|
|
30636
|
+
if (i < X3.length - 1) return facetEmpty(facets, X3[i + 1], y3);
|
|
30637
|
+
}
|
|
30638
|
+
function facetAnchorEmpty(facets, channels, { empty: empty4 }) {
|
|
30639
|
+
return empty4;
|
|
30640
|
+
}
|
|
30641
|
+
function and2(a2, b) {
|
|
30642
|
+
return function() {
|
|
30643
|
+
return a2.apply(null, arguments) && b.apply(null, arguments);
|
|
30644
|
+
};
|
|
30645
|
+
}
|
|
30646
|
+
function facetFilter(facets, { channels: { fx, fy }, groups: groups2 }) {
|
|
30647
|
+
return fx && fy ? facets.map(({ x: x3, y: y3 }) => groups2.get(x3)?.get(y3) ?? []) : fx ? facets.map(({ x: x3 }) => groups2.get(x3) ?? []) : facets.map(({ y: y3 }) => groups2.get(y3) ?? []);
|
|
30648
|
+
}
|
|
30649
|
+
|
|
30650
|
+
// ../../node_modules/@observablehq/plot/src/projection.js
|
|
30651
|
+
var pi4 = Math.PI;
|
|
30652
|
+
var tau5 = 2 * pi4;
|
|
30653
|
+
var defaultAspectRatio = 0.618;
|
|
30654
|
+
function createProjection({
|
|
30655
|
+
projection: projection3,
|
|
30656
|
+
inset: globalInset = 0,
|
|
30657
|
+
insetTop = globalInset,
|
|
30658
|
+
insetRight = globalInset,
|
|
30659
|
+
insetBottom = globalInset,
|
|
30660
|
+
insetLeft = globalInset
|
|
30661
|
+
} = {}, dimensions) {
|
|
30662
|
+
if (projection3 == null) return;
|
|
30663
|
+
if (typeof projection3.stream === "function") return projection3;
|
|
30664
|
+
let options;
|
|
30665
|
+
let domain;
|
|
30666
|
+
let clip = "frame";
|
|
30667
|
+
if (isObject2(projection3)) {
|
|
30668
|
+
let inset;
|
|
30669
|
+
({
|
|
30670
|
+
type: projection3,
|
|
30671
|
+
domain,
|
|
30672
|
+
inset,
|
|
30673
|
+
insetTop = inset !== void 0 ? inset : insetTop,
|
|
30674
|
+
insetRight = inset !== void 0 ? inset : insetRight,
|
|
30675
|
+
insetBottom = inset !== void 0 ? inset : insetBottom,
|
|
30676
|
+
insetLeft = inset !== void 0 ? inset : insetLeft,
|
|
30677
|
+
clip = clip,
|
|
30678
|
+
...options
|
|
30679
|
+
} = projection3);
|
|
30680
|
+
if (projection3 == null) return;
|
|
30681
|
+
}
|
|
30682
|
+
if (typeof projection3 !== "function") ({ type: projection3 } = namedProjection(projection3));
|
|
30683
|
+
const { width, height, marginLeft, marginRight, marginTop, marginBottom } = dimensions;
|
|
30684
|
+
const dx = width - marginLeft - marginRight - insetLeft - insetRight;
|
|
30685
|
+
const dy = height - marginTop - marginBottom - insetTop - insetBottom;
|
|
30686
|
+
projection3 = projection3?.({ width: dx, height: dy, clip, ...options });
|
|
30687
|
+
if (projection3 == null) return;
|
|
30688
|
+
clip = maybePostClip(clip, marginLeft, marginTop, width - marginRight, height - marginBottom);
|
|
30689
|
+
let tx = marginLeft + insetLeft;
|
|
30690
|
+
let ty = marginTop + insetTop;
|
|
30691
|
+
let transform3;
|
|
30692
|
+
if (domain != null) {
|
|
30693
|
+
const [[x06, y06], [x12, y12]] = path_default(projection3).bounds(domain);
|
|
30694
|
+
const k2 = Math.min(dx / (x12 - x06), dy / (y12 - y06));
|
|
30695
|
+
if (k2 > 0) {
|
|
30696
|
+
tx -= (k2 * (x06 + x12) - dx) / 2;
|
|
30697
|
+
ty -= (k2 * (y06 + y12) - dy) / 2;
|
|
30698
|
+
transform3 = transform_default({
|
|
30699
|
+
point(x3, y3) {
|
|
30700
|
+
this.stream.point(x3 * k2 + tx, y3 * k2 + ty);
|
|
30701
|
+
}
|
|
30702
|
+
});
|
|
30703
|
+
} else {
|
|
30704
|
+
warn(`Warning: the projection could not be fit to the specified domain; using the default scale.`);
|
|
30705
|
+
}
|
|
30706
|
+
}
|
|
30707
|
+
transform3 ??= tx === 0 && ty === 0 ? identity8() : transform_default({
|
|
30708
|
+
point(x3, y3) {
|
|
30709
|
+
this.stream.point(x3 + tx, y3 + ty);
|
|
30710
|
+
}
|
|
30711
|
+
});
|
|
30712
|
+
return { stream: (s2) => projection3.stream(transform3.stream(clip(s2))) };
|
|
30713
|
+
}
|
|
30714
|
+
function namedProjection(projection3) {
|
|
30715
|
+
switch (`${projection3}`.toLowerCase()) {
|
|
30716
|
+
case "albers-usa":
|
|
30717
|
+
return scaleProjection(albersUsa_default, 0.7463, 0.4673);
|
|
30718
|
+
case "albers":
|
|
30719
|
+
return conicProjection2(albers_default, 0.7463, 0.4673);
|
|
30720
|
+
case "azimuthal-equal-area":
|
|
30721
|
+
return scaleProjection(azimuthalEqualArea_default, 4, 4);
|
|
30722
|
+
case "azimuthal-equidistant":
|
|
30723
|
+
return scaleProjection(azimuthalEquidistant_default, tau5, tau5);
|
|
30724
|
+
case "conic-conformal":
|
|
30725
|
+
return conicProjection2(conicConformal_default, tau5, tau5);
|
|
30726
|
+
case "conic-equal-area":
|
|
30727
|
+
return conicProjection2(conicEqualArea_default, 6.1702, 2.9781);
|
|
30728
|
+
case "conic-equidistant":
|
|
30729
|
+
return conicProjection2(conicEquidistant_default, 7.312, 3.6282);
|
|
30730
|
+
case "equal-earth":
|
|
30731
|
+
return scaleProjection(equalEarth_default, 5.4133, 2.6347);
|
|
30732
|
+
case "equirectangular":
|
|
30733
|
+
return scaleProjection(equirectangular_default, tau5, pi4);
|
|
30734
|
+
case "gnomonic":
|
|
30735
|
+
return scaleProjection(gnomonic_default, 3.4641, 3.4641);
|
|
30736
|
+
case "identity":
|
|
30737
|
+
return { type: identity8 };
|
|
30738
|
+
case "reflect-y":
|
|
30739
|
+
return { type: reflectY };
|
|
30740
|
+
case "mercator":
|
|
30741
|
+
return scaleProjection(mercator_default, tau5, tau5);
|
|
30742
|
+
case "orthographic":
|
|
30743
|
+
return scaleProjection(orthographic_default, 2, 2);
|
|
30744
|
+
case "stereographic":
|
|
30745
|
+
return scaleProjection(stereographic_default, 2, 2);
|
|
30746
|
+
case "transverse-mercator":
|
|
30747
|
+
return scaleProjection(transverseMercator_default, tau5, tau5);
|
|
30748
|
+
default:
|
|
30749
|
+
throw new Error(`unknown projection type: ${projection3}`);
|
|
30750
|
+
}
|
|
30751
|
+
}
|
|
30752
|
+
function maybePostClip(clip, x12, y12, x22, y22) {
|
|
30753
|
+
if (clip === false || clip == null || typeof clip === "number") return (s2) => s2;
|
|
30754
|
+
if (clip === true) clip = "frame";
|
|
30755
|
+
switch (`${clip}`.toLowerCase()) {
|
|
30756
|
+
case "frame":
|
|
30757
|
+
return clipRectangle(x12, y12, x22, y22);
|
|
30758
|
+
default:
|
|
30759
|
+
throw new Error(`unknown projection clip type: ${clip}`);
|
|
30760
|
+
}
|
|
30761
|
+
}
|
|
30762
|
+
function scaleProjection(createProjection2, kx2, ky2) {
|
|
30763
|
+
return {
|
|
30764
|
+
type: ({ width, height, rotate, precision = 0.15, clip }) => {
|
|
30765
|
+
const projection3 = createProjection2();
|
|
30766
|
+
if (precision != null) projection3.precision?.(precision);
|
|
30767
|
+
if (rotate != null) projection3.rotate?.(rotate);
|
|
30768
|
+
if (typeof clip === "number") projection3.clipAngle?.(clip);
|
|
30769
|
+
projection3.scale(Math.min(width / kx2, height / ky2));
|
|
30770
|
+
projection3.translate([width / 2, height / 2]);
|
|
30771
|
+
return projection3;
|
|
30772
|
+
},
|
|
30773
|
+
aspectRatio: ky2 / kx2
|
|
30774
|
+
};
|
|
30775
|
+
}
|
|
30776
|
+
function conicProjection2(createProjection2, kx2, ky2) {
|
|
30777
|
+
const { type: type2, aspectRatio } = scaleProjection(createProjection2, kx2, ky2);
|
|
30778
|
+
return {
|
|
30779
|
+
type: (options) => {
|
|
30780
|
+
const { parallels, domain, width, height } = options;
|
|
30781
|
+
const projection3 = type2(options);
|
|
30782
|
+
if (parallels != null) {
|
|
30783
|
+
projection3.parallels(parallels);
|
|
30784
|
+
if (domain === void 0) {
|
|
30785
|
+
projection3.fitSize([width, height], { type: "Sphere" });
|
|
30786
|
+
}
|
|
30787
|
+
}
|
|
30788
|
+
return projection3;
|
|
30789
|
+
},
|
|
30790
|
+
aspectRatio
|
|
30791
|
+
};
|
|
30792
|
+
}
|
|
30793
|
+
var identity8 = constant({ stream: (stream) => stream });
|
|
30794
|
+
var reflectY = constant(
|
|
30795
|
+
transform_default({
|
|
30796
|
+
point(x3, y3) {
|
|
30797
|
+
this.stream.point(x3, -y3);
|
|
30798
|
+
}
|
|
30799
|
+
})
|
|
30800
|
+
);
|
|
30801
|
+
function project(cx, cy, values2, projection3) {
|
|
30802
|
+
const x3 = values2[cx];
|
|
30803
|
+
const y3 = values2[cy];
|
|
30804
|
+
const n = x3.length;
|
|
30805
|
+
const X3 = values2[cx] = new Float64Array(n).fill(NaN);
|
|
30806
|
+
const Y3 = values2[cy] = new Float64Array(n).fill(NaN);
|
|
30807
|
+
let i;
|
|
30808
|
+
const stream = projection3.stream({
|
|
30809
|
+
point(x4, y4) {
|
|
30810
|
+
X3[i] = x4;
|
|
30811
|
+
Y3[i] = y4;
|
|
30812
|
+
}
|
|
30813
|
+
});
|
|
30814
|
+
for (i = 0; i < n; ++i) {
|
|
30815
|
+
stream.point(x3[i], y3[i]);
|
|
30816
|
+
}
|
|
30817
|
+
}
|
|
30818
|
+
function hasProjection({ projection: projection3 } = {}) {
|
|
30819
|
+
if (projection3 == null) return false;
|
|
30820
|
+
if (typeof projection3.stream === "function") return true;
|
|
30821
|
+
if (isObject2(projection3)) projection3 = projection3.type;
|
|
30822
|
+
return projection3 != null;
|
|
30823
|
+
}
|
|
30824
|
+
function projectionAspectRatio(projection3) {
|
|
30825
|
+
if (typeof projection3?.stream === "function") return defaultAspectRatio;
|
|
30826
|
+
if (isObject2(projection3)) projection3 = projection3.type;
|
|
30827
|
+
if (projection3 == null) return;
|
|
30828
|
+
if (typeof projection3 !== "function") {
|
|
30829
|
+
const { aspectRatio } = namedProjection(projection3);
|
|
30830
|
+
if (aspectRatio) return aspectRatio;
|
|
30831
|
+
}
|
|
30832
|
+
return defaultAspectRatio;
|
|
30833
|
+
}
|
|
30834
|
+
function applyPosition(channels, scales2, { projection: projection3 }) {
|
|
30835
|
+
const { x: x3, y: y3 } = channels;
|
|
30836
|
+
let position3 = {};
|
|
30837
|
+
if (x3) position3.x = x3;
|
|
30838
|
+
if (y3) position3.y = y3;
|
|
30839
|
+
position3 = valueObject(position3, scales2);
|
|
30840
|
+
if (projection3 && x3?.scale === "x" && y3?.scale === "y") project("x", "y", position3, projection3);
|
|
30841
|
+
if (x3) position3.x = coerceNumbers(position3.x);
|
|
30842
|
+
if (y3) position3.y = coerceNumbers(position3.y);
|
|
30843
|
+
return position3;
|
|
30844
|
+
}
|
|
30845
|
+
function getGeometryChannels(channel) {
|
|
30846
|
+
const X3 = [];
|
|
30847
|
+
const Y3 = [];
|
|
30848
|
+
const x3 = { scale: "x", value: X3 };
|
|
30849
|
+
const y3 = { scale: "y", value: Y3 };
|
|
30850
|
+
const sink = {
|
|
30851
|
+
point(x4, y4) {
|
|
30852
|
+
X3.push(x4);
|
|
30853
|
+
Y3.push(y4);
|
|
30854
|
+
},
|
|
30855
|
+
lineStart() {
|
|
30856
|
+
},
|
|
30857
|
+
lineEnd() {
|
|
30858
|
+
},
|
|
30859
|
+
polygonStart() {
|
|
30860
|
+
},
|
|
30861
|
+
polygonEnd() {
|
|
30862
|
+
},
|
|
30863
|
+
sphere() {
|
|
30864
|
+
}
|
|
30865
|
+
};
|
|
30866
|
+
for (const object of channel.value) stream_default(object, sink);
|
|
30867
|
+
return [x3, y3];
|
|
30868
|
+
}
|
|
30869
|
+
|
|
30870
|
+
// ../../node_modules/@observablehq/plot/src/context.js
|
|
30871
|
+
function createContext(options = {}) {
|
|
30872
|
+
const { document: document2 = typeof window !== "undefined" ? window.document : void 0, clip } = options;
|
|
30873
|
+
return { document: document2, clip: maybeClip(clip) };
|
|
30874
|
+
}
|
|
30875
|
+
function create3(name, { document: document2 }) {
|
|
30876
|
+
return select_default2(creator_default(name).call(document2.documentElement));
|
|
30877
|
+
}
|
|
30878
|
+
|
|
30237
30879
|
// ../../node_modules/@observablehq/plot/src/memoize.js
|
|
30238
30880
|
function memoize1(compute) {
|
|
30239
30881
|
let cacheValue, cacheKeys;
|
|
@@ -30598,6 +31240,153 @@ function applyFrameAnchor({ frameAnchor }, { width, height, marginTop, marginRig
|
|
|
30598
31240
|
];
|
|
30599
31241
|
}
|
|
30600
31242
|
|
|
31243
|
+
// ../../node_modules/@observablehq/plot/src/mark.js
|
|
31244
|
+
var Mark = class {
|
|
31245
|
+
constructor(data, channels = {}, options = {}, defaults23) {
|
|
31246
|
+
const {
|
|
31247
|
+
facet = "auto",
|
|
31248
|
+
facetAnchor,
|
|
31249
|
+
fx,
|
|
31250
|
+
fy,
|
|
31251
|
+
sort: sort3,
|
|
31252
|
+
dx = 0,
|
|
31253
|
+
dy = 0,
|
|
31254
|
+
margin = 0,
|
|
31255
|
+
marginTop = margin,
|
|
31256
|
+
marginRight = margin,
|
|
31257
|
+
marginBottom = margin,
|
|
31258
|
+
marginLeft = margin,
|
|
31259
|
+
clip = defaults23?.clip,
|
|
31260
|
+
channels: extraChannels,
|
|
31261
|
+
tip: tip2,
|
|
31262
|
+
render
|
|
31263
|
+
} = options;
|
|
31264
|
+
this.data = data;
|
|
31265
|
+
this.sort = isDomainSort(sort3) ? sort3 : null;
|
|
31266
|
+
this.initializer = initializer(options).initializer;
|
|
31267
|
+
this.transform = this.initializer ? options.transform : basic(options).transform;
|
|
31268
|
+
if (facet === null || facet === false) {
|
|
31269
|
+
this.facet = null;
|
|
31270
|
+
} else {
|
|
31271
|
+
this.facet = keyword(facet === true ? "include" : facet, "facet", ["auto", "include", "exclude", "super"]);
|
|
31272
|
+
this.fx = data === singleton && typeof fx === "string" ? [fx] : fx;
|
|
31273
|
+
this.fy = data === singleton && typeof fy === "string" ? [fy] : fy;
|
|
31274
|
+
}
|
|
31275
|
+
this.facetAnchor = maybeFacetAnchor(facetAnchor);
|
|
31276
|
+
channels = maybeNamed(channels);
|
|
31277
|
+
if (extraChannels !== void 0) channels = { ...maybeChannels(extraChannels), ...channels };
|
|
31278
|
+
if (defaults23 !== void 0) channels = { ...styles(this, options, defaults23), ...channels };
|
|
31279
|
+
this.channels = Object.fromEntries(
|
|
31280
|
+
Object.entries(channels).map(([name, channel]) => {
|
|
31281
|
+
if (isOptions(channel.value)) {
|
|
31282
|
+
const { value, label = channel.label, scale: scale3 = channel.scale } = channel.value;
|
|
31283
|
+
channel = { ...channel, label, scale: scale3, value };
|
|
31284
|
+
}
|
|
31285
|
+
if (data === singleton && typeof channel.value === "string") {
|
|
31286
|
+
const { value } = channel;
|
|
31287
|
+
channel = { ...channel, value: [value] };
|
|
31288
|
+
}
|
|
31289
|
+
return [name, channel];
|
|
31290
|
+
}).filter(([name, { value, optional: optional2 }]) => {
|
|
31291
|
+
if (value != null) return true;
|
|
31292
|
+
if (optional2) return false;
|
|
31293
|
+
throw new Error(`missing channel value: ${name}`);
|
|
31294
|
+
})
|
|
31295
|
+
);
|
|
31296
|
+
this.dx = +dx;
|
|
31297
|
+
this.dy = +dy;
|
|
31298
|
+
this.marginTop = +marginTop;
|
|
31299
|
+
this.marginRight = +marginRight;
|
|
31300
|
+
this.marginBottom = +marginBottom;
|
|
31301
|
+
this.marginLeft = +marginLeft;
|
|
31302
|
+
this.clip = maybeClip(clip);
|
|
31303
|
+
this.tip = maybeTip(tip2);
|
|
31304
|
+
if (this.facet === "super") {
|
|
31305
|
+
if (fx || fy) throw new Error(`super-faceting cannot use fx or fy`);
|
|
31306
|
+
for (const name in this.channels) {
|
|
31307
|
+
const { scale: scale3 } = channels[name];
|
|
31308
|
+
if (scale3 !== "x" && scale3 !== "y") continue;
|
|
31309
|
+
throw new Error(`super-faceting cannot use x or y`);
|
|
31310
|
+
}
|
|
31311
|
+
}
|
|
31312
|
+
if (render != null) {
|
|
31313
|
+
this.render = composeRender(render, this.render);
|
|
31314
|
+
}
|
|
31315
|
+
}
|
|
31316
|
+
initialize(facets, facetChannels, plotOptions) {
|
|
31317
|
+
let data = arrayify2(this.data);
|
|
31318
|
+
if (facets === void 0 && data != null) facets = [range2(data)];
|
|
31319
|
+
const originalFacets = facets;
|
|
31320
|
+
if (this.transform != null) ({ facets, data } = this.transform(data, facets, plotOptions)), data = arrayify2(data);
|
|
31321
|
+
if (facets !== void 0) facets.original = originalFacets;
|
|
31322
|
+
const channels = createChannels(this.channels, data);
|
|
31323
|
+
if (this.sort != null) channelDomain(data, facets, channels, facetChannels, this.sort);
|
|
31324
|
+
return { data, facets, channels };
|
|
31325
|
+
}
|
|
31326
|
+
filter(index2, channels, values2) {
|
|
31327
|
+
for (const name in channels) {
|
|
31328
|
+
const { filter: filter3 = defined } = channels[name];
|
|
31329
|
+
if (filter3 !== null) {
|
|
31330
|
+
const value = values2[name];
|
|
31331
|
+
index2 = index2.filter((i) => filter3(value[i]));
|
|
31332
|
+
}
|
|
31333
|
+
}
|
|
31334
|
+
return index2;
|
|
31335
|
+
}
|
|
31336
|
+
// If there is a projection, and there are paired x and y channels associated
|
|
31337
|
+
// with the x and y scale respectively (and not already in screen coordinates
|
|
31338
|
+
// as with an initializer), then apply the projection, replacing the x and y
|
|
31339
|
+
// values. Note that the x and y scales themselves don’t exist if there is a
|
|
31340
|
+
// projection, but whether the channels are associated with scales still
|
|
31341
|
+
// determines whether the projection should apply; think of the projection as
|
|
31342
|
+
// a combination xy-scale.
|
|
31343
|
+
project(channels, values2, context) {
|
|
31344
|
+
for (const cx in channels) {
|
|
31345
|
+
if (channels[cx].scale === "x" && /^x|x$/.test(cx)) {
|
|
31346
|
+
const cy = cx.replace(/^x|x$/, "y");
|
|
31347
|
+
if (cy in channels && channels[cy].scale === "y") {
|
|
31348
|
+
project(cx, cy, values2, context.projection);
|
|
31349
|
+
}
|
|
31350
|
+
}
|
|
31351
|
+
}
|
|
31352
|
+
}
|
|
31353
|
+
scale(channels, scales2, context) {
|
|
31354
|
+
const values2 = valueObject(channels, scales2);
|
|
31355
|
+
if (context.projection) this.project(channels, values2, context);
|
|
31356
|
+
return values2;
|
|
31357
|
+
}
|
|
31358
|
+
};
|
|
31359
|
+
function marks(...marks2) {
|
|
31360
|
+
marks2.plot = Mark.prototype.plot;
|
|
31361
|
+
return marks2;
|
|
31362
|
+
}
|
|
31363
|
+
function composeRender(r1, r2) {
|
|
31364
|
+
if (r1 == null) return r2 === null ? void 0 : r2;
|
|
31365
|
+
if (r2 == null) return r1 === null ? void 0 : r1;
|
|
31366
|
+
if (typeof r1 !== "function") throw new TypeError(`invalid render transform: ${r1}`);
|
|
31367
|
+
if (typeof r2 !== "function") throw new TypeError(`invalid render transform: ${r2}`);
|
|
31368
|
+
return function(i, s2, v2, d, c4, next) {
|
|
31369
|
+
return r1.call(this, i, s2, v2, d, c4, (i2, s3, v3, d2, c5) => {
|
|
31370
|
+
return r2.call(this, i2, s3, v3, d2, c5, next);
|
|
31371
|
+
});
|
|
31372
|
+
};
|
|
31373
|
+
}
|
|
31374
|
+
function maybeChannels(channels) {
|
|
31375
|
+
return Object.fromEntries(
|
|
31376
|
+
Object.entries(maybeNamed(channels)).map(([name, channel]) => {
|
|
31377
|
+
channel = typeof channel === "string" ? { value: channel, label: name } : maybeValue(channel);
|
|
31378
|
+
if (channel.filter === void 0 && channel.scale == null) channel = { ...channel, filter: null };
|
|
31379
|
+
return [name, channel];
|
|
31380
|
+
})
|
|
31381
|
+
);
|
|
31382
|
+
}
|
|
31383
|
+
function maybeTip(tip2) {
|
|
31384
|
+
return tip2 === true ? "xy" : tip2 === false || tip2 == null ? null : typeof tip2 === "string" ? keyword(tip2, "tip", ["x", "y", "xy"]) : tip2;
|
|
31385
|
+
}
|
|
31386
|
+
function withTip(options, pointer2) {
|
|
31387
|
+
return options?.tip === true ? { ...options, tip: pointer2 } : isObject2(options?.tip) && options.tip.pointer === void 0 ? { ...options, tip: { ...options.tip, pointer: pointer2 } } : options;
|
|
31388
|
+
}
|
|
31389
|
+
|
|
30601
31390
|
// ../../node_modules/@observablehq/plot/src/dimensions.js
|
|
30602
31391
|
function createDimensions(scales2, marks2, options = {}) {
|
|
30603
31392
|
let marginTopDefault = 0.5 - offset, marginRightDefault = 0.5 + offset, marginBottomDefault = 0.5 + offset, marginLeftDefault = 0.5 - offset;
|
|
@@ -30708,291 +31497,6 @@ function aspectRatioLength(k2, scale3) {
|
|
|
30708
31497
|
return Math.abs(transform3(max4) - transform3(min5));
|
|
30709
31498
|
}
|
|
30710
31499
|
|
|
30711
|
-
// ../../node_modules/@observablehq/plot/src/facet.js
|
|
30712
|
-
function createFacets(channelsByScale, options) {
|
|
30713
|
-
const { fx, fy } = createScales(channelsByScale, options);
|
|
30714
|
-
const fxDomain = fx?.scale.domain();
|
|
30715
|
-
const fyDomain = fy?.scale.domain();
|
|
30716
|
-
return fxDomain && fyDomain ? cross(fxDomain, fyDomain).map(([x3, y3], i) => ({ x: x3, y: y3, i })) : fxDomain ? fxDomain.map((x3, i) => ({ x: x3, i })) : fyDomain ? fyDomain.map((y3, i) => ({ y: y3, i })) : void 0;
|
|
30717
|
-
}
|
|
30718
|
-
function recreateFacets(facets, { x: X3, y: Y3 }) {
|
|
30719
|
-
X3 &&= facetIndex(X3);
|
|
30720
|
-
Y3 &&= facetIndex(Y3);
|
|
30721
|
-
return facets.filter(
|
|
30722
|
-
X3 && Y3 ? (f) => X3.has(f.x) && Y3.has(f.y) : X3 ? (f) => X3.has(f.x) : (f) => Y3.has(f.y)
|
|
30723
|
-
).sort(
|
|
30724
|
-
X3 && Y3 ? (a2, b) => X3.get(a2.x) - X3.get(b.x) || Y3.get(a2.y) - Y3.get(b.y) : X3 ? (a2, b) => X3.get(a2.x) - X3.get(b.x) : (a2, b) => Y3.get(a2.y) - Y3.get(b.y)
|
|
30725
|
-
);
|
|
30726
|
-
}
|
|
30727
|
-
function facetGroups(data, { fx, fy }) {
|
|
30728
|
-
const I = range2(data);
|
|
30729
|
-
const FX = fx?.value;
|
|
30730
|
-
const FY = fy?.value;
|
|
30731
|
-
return fx && fy ? rollup(
|
|
30732
|
-
I,
|
|
30733
|
-
(G) => (G.fx = FX[G[0]], G.fy = FY[G[0]], G),
|
|
30734
|
-
(i) => FX[i],
|
|
30735
|
-
(i) => FY[i]
|
|
30736
|
-
) : fx ? rollup(
|
|
30737
|
-
I,
|
|
30738
|
-
(G) => (G.fx = FX[G[0]], G),
|
|
30739
|
-
(i) => FX[i]
|
|
30740
|
-
) : rollup(
|
|
30741
|
-
I,
|
|
30742
|
-
(G) => (G.fy = FY[G[0]], G),
|
|
30743
|
-
(i) => FY[i]
|
|
30744
|
-
);
|
|
30745
|
-
}
|
|
30746
|
-
function facetTranslator(fx, fy, { marginTop, marginLeft }) {
|
|
30747
|
-
return fx && fy ? ({ x: x3, y: y3 }) => `translate(${fx(x3) - marginLeft},${fy(y3) - marginTop})` : fx ? ({ x: x3 }) => `translate(${fx(x3) - marginLeft},0)` : ({ y: y3 }) => `translate(0,${fy(y3) - marginTop})`;
|
|
30748
|
-
}
|
|
30749
|
-
function facetExclude(index2) {
|
|
30750
|
-
const ex = [];
|
|
30751
|
-
const e = new Uint32Array(sum2(index2, (d) => d.length));
|
|
30752
|
-
for (const i of index2) {
|
|
30753
|
-
let n = 0;
|
|
30754
|
-
for (const j of index2) {
|
|
30755
|
-
if (i === j) continue;
|
|
30756
|
-
e.set(j, n);
|
|
30757
|
-
n += j.length;
|
|
30758
|
-
}
|
|
30759
|
-
ex.push(e.slice(0, n));
|
|
30760
|
-
}
|
|
30761
|
-
return ex;
|
|
30762
|
-
}
|
|
30763
|
-
var facetAnchors = /* @__PURE__ */ new Map([
|
|
30764
|
-
["top", facetAnchorTop],
|
|
30765
|
-
["right", facetAnchorRight],
|
|
30766
|
-
["bottom", facetAnchorBottom],
|
|
30767
|
-
["left", facetAnchorLeft],
|
|
30768
|
-
["top-left", and2(facetAnchorTop, facetAnchorLeft)],
|
|
30769
|
-
["top-right", and2(facetAnchorTop, facetAnchorRight)],
|
|
30770
|
-
["bottom-left", and2(facetAnchorBottom, facetAnchorLeft)],
|
|
30771
|
-
["bottom-right", and2(facetAnchorBottom, facetAnchorRight)],
|
|
30772
|
-
["top-empty", facetAnchorTopEmpty],
|
|
30773
|
-
["right-empty", facetAnchorRightEmpty],
|
|
30774
|
-
["bottom-empty", facetAnchorBottomEmpty],
|
|
30775
|
-
["left-empty", facetAnchorLeftEmpty],
|
|
30776
|
-
["empty", facetAnchorEmpty]
|
|
30777
|
-
]);
|
|
30778
|
-
function maybeFacetAnchor(facetAnchor) {
|
|
30779
|
-
if (facetAnchor == null) return null;
|
|
30780
|
-
const anchor = facetAnchors.get(`${facetAnchor}`.toLowerCase());
|
|
30781
|
-
if (anchor) return anchor;
|
|
30782
|
-
throw new Error(`invalid facet anchor: ${facetAnchor}`);
|
|
30783
|
-
}
|
|
30784
|
-
var indexCache = /* @__PURE__ */ new WeakMap();
|
|
30785
|
-
function facetIndex(V) {
|
|
30786
|
-
let I = indexCache.get(V);
|
|
30787
|
-
if (!I) indexCache.set(V, I = new InternMap(map2(V, (v2, i) => [v2, i])));
|
|
30788
|
-
return I;
|
|
30789
|
-
}
|
|
30790
|
-
function facetIndexOf(V, v2) {
|
|
30791
|
-
return facetIndex(V).get(v2);
|
|
30792
|
-
}
|
|
30793
|
-
function facetFind(facets, x3, y3) {
|
|
30794
|
-
x3 = keyof2(x3);
|
|
30795
|
-
y3 = keyof2(y3);
|
|
30796
|
-
return facets.find((f) => Object.is(keyof2(f.x), x3) && Object.is(keyof2(f.y), y3));
|
|
30797
|
-
}
|
|
30798
|
-
function facetEmpty(facets, x3, y3) {
|
|
30799
|
-
return facetFind(facets, x3, y3)?.empty;
|
|
30800
|
-
}
|
|
30801
|
-
function facetAnchorTop(facets, { y: Y3 }, { y: y3 }) {
|
|
30802
|
-
return Y3 ? facetIndexOf(Y3, y3) === 0 : true;
|
|
30803
|
-
}
|
|
30804
|
-
function facetAnchorBottom(facets, { y: Y3 }, { y: y3 }) {
|
|
30805
|
-
return Y3 ? facetIndexOf(Y3, y3) === Y3.length - 1 : true;
|
|
30806
|
-
}
|
|
30807
|
-
function facetAnchorLeft(facets, { x: X3 }, { x: x3 }) {
|
|
30808
|
-
return X3 ? facetIndexOf(X3, x3) === 0 : true;
|
|
30809
|
-
}
|
|
30810
|
-
function facetAnchorRight(facets, { x: X3 }, { x: x3 }) {
|
|
30811
|
-
return X3 ? facetIndexOf(X3, x3) === X3.length - 1 : true;
|
|
30812
|
-
}
|
|
30813
|
-
function facetAnchorTopEmpty(facets, { y: Y3 }, { x: x3, y: y3, empty: empty4 }) {
|
|
30814
|
-
if (empty4) return false;
|
|
30815
|
-
if (!Y3) return;
|
|
30816
|
-
const i = facetIndexOf(Y3, y3);
|
|
30817
|
-
if (i > 0) return facetEmpty(facets, x3, Y3[i - 1]);
|
|
30818
|
-
}
|
|
30819
|
-
function facetAnchorBottomEmpty(facets, { y: Y3 }, { x: x3, y: y3, empty: empty4 }) {
|
|
30820
|
-
if (empty4) return false;
|
|
30821
|
-
if (!Y3) return;
|
|
30822
|
-
const i = facetIndexOf(Y3, y3);
|
|
30823
|
-
if (i < Y3.length - 1) return facetEmpty(facets, x3, Y3[i + 1]);
|
|
30824
|
-
}
|
|
30825
|
-
function facetAnchorLeftEmpty(facets, { x: X3 }, { x: x3, y: y3, empty: empty4 }) {
|
|
30826
|
-
if (empty4) return false;
|
|
30827
|
-
if (!X3) return;
|
|
30828
|
-
const i = facetIndexOf(X3, x3);
|
|
30829
|
-
if (i > 0) return facetEmpty(facets, X3[i - 1], y3);
|
|
30830
|
-
}
|
|
30831
|
-
function facetAnchorRightEmpty(facets, { x: X3 }, { x: x3, y: y3, empty: empty4 }) {
|
|
30832
|
-
if (empty4) return false;
|
|
30833
|
-
if (!X3) return;
|
|
30834
|
-
const i = facetIndexOf(X3, x3);
|
|
30835
|
-
if (i < X3.length - 1) return facetEmpty(facets, X3[i + 1], y3);
|
|
30836
|
-
}
|
|
30837
|
-
function facetAnchorEmpty(facets, channels, { empty: empty4 }) {
|
|
30838
|
-
return empty4;
|
|
30839
|
-
}
|
|
30840
|
-
function and2(a2, b) {
|
|
30841
|
-
return function() {
|
|
30842
|
-
return a2.apply(null, arguments) && b.apply(null, arguments);
|
|
30843
|
-
};
|
|
30844
|
-
}
|
|
30845
|
-
function facetFilter(facets, { channels: { fx, fy }, groups: groups2 }) {
|
|
30846
|
-
return fx && fy ? facets.map(({ x: x3, y: y3 }) => groups2.get(x3)?.get(y3) ?? []) : fx ? facets.map(({ x: x3 }) => groups2.get(x3) ?? []) : facets.map(({ y: y3 }) => groups2.get(y3) ?? []);
|
|
30847
|
-
}
|
|
30848
|
-
|
|
30849
|
-
// ../../node_modules/@observablehq/plot/src/mark.js
|
|
30850
|
-
var Mark = class {
|
|
30851
|
-
constructor(data, channels = {}, options = {}, defaults23) {
|
|
30852
|
-
const {
|
|
30853
|
-
facet = "auto",
|
|
30854
|
-
facetAnchor,
|
|
30855
|
-
fx,
|
|
30856
|
-
fy,
|
|
30857
|
-
sort: sort3,
|
|
30858
|
-
dx = 0,
|
|
30859
|
-
dy = 0,
|
|
30860
|
-
margin = 0,
|
|
30861
|
-
marginTop = margin,
|
|
30862
|
-
marginRight = margin,
|
|
30863
|
-
marginBottom = margin,
|
|
30864
|
-
marginLeft = margin,
|
|
30865
|
-
clip = defaults23?.clip,
|
|
30866
|
-
channels: extraChannels,
|
|
30867
|
-
tip: tip2,
|
|
30868
|
-
render
|
|
30869
|
-
} = options;
|
|
30870
|
-
this.data = data;
|
|
30871
|
-
this.sort = isDomainSort(sort3) ? sort3 : null;
|
|
30872
|
-
this.initializer = initializer(options).initializer;
|
|
30873
|
-
this.transform = this.initializer ? options.transform : basic(options).transform;
|
|
30874
|
-
if (facet === null || facet === false) {
|
|
30875
|
-
this.facet = null;
|
|
30876
|
-
} else {
|
|
30877
|
-
this.facet = keyword(facet === true ? "include" : facet, "facet", ["auto", "include", "exclude", "super"]);
|
|
30878
|
-
this.fx = data === singleton && typeof fx === "string" ? [fx] : fx;
|
|
30879
|
-
this.fy = data === singleton && typeof fy === "string" ? [fy] : fy;
|
|
30880
|
-
}
|
|
30881
|
-
this.facetAnchor = maybeFacetAnchor(facetAnchor);
|
|
30882
|
-
channels = maybeNamed(channels);
|
|
30883
|
-
if (extraChannels !== void 0) channels = { ...maybeChannels(extraChannels), ...channels };
|
|
30884
|
-
if (defaults23 !== void 0) channels = { ...styles(this, options, defaults23), ...channels };
|
|
30885
|
-
this.channels = Object.fromEntries(
|
|
30886
|
-
Object.entries(channels).map(([name, channel]) => {
|
|
30887
|
-
if (isOptions(channel.value)) {
|
|
30888
|
-
const { value, label = channel.label, scale: scale3 = channel.scale } = channel.value;
|
|
30889
|
-
channel = { ...channel, label, scale: scale3, value };
|
|
30890
|
-
}
|
|
30891
|
-
if (data === singleton && typeof channel.value === "string") {
|
|
30892
|
-
const { value } = channel;
|
|
30893
|
-
channel = { ...channel, value: [value] };
|
|
30894
|
-
}
|
|
30895
|
-
return [name, channel];
|
|
30896
|
-
}).filter(([name, { value, optional: optional2 }]) => {
|
|
30897
|
-
if (value != null) return true;
|
|
30898
|
-
if (optional2) return false;
|
|
30899
|
-
throw new Error(`missing channel value: ${name}`);
|
|
30900
|
-
})
|
|
30901
|
-
);
|
|
30902
|
-
this.dx = +dx;
|
|
30903
|
-
this.dy = +dy;
|
|
30904
|
-
this.marginTop = +marginTop;
|
|
30905
|
-
this.marginRight = +marginRight;
|
|
30906
|
-
this.marginBottom = +marginBottom;
|
|
30907
|
-
this.marginLeft = +marginLeft;
|
|
30908
|
-
this.clip = maybeClip(clip);
|
|
30909
|
-
this.tip = maybeTip(tip2);
|
|
30910
|
-
if (this.facet === "super") {
|
|
30911
|
-
if (fx || fy) throw new Error(`super-faceting cannot use fx or fy`);
|
|
30912
|
-
for (const name in this.channels) {
|
|
30913
|
-
const { scale: scale3 } = channels[name];
|
|
30914
|
-
if (scale3 !== "x" && scale3 !== "y") continue;
|
|
30915
|
-
throw new Error(`super-faceting cannot use x or y`);
|
|
30916
|
-
}
|
|
30917
|
-
}
|
|
30918
|
-
if (render != null) {
|
|
30919
|
-
this.render = composeRender(render, this.render);
|
|
30920
|
-
}
|
|
30921
|
-
}
|
|
30922
|
-
initialize(facets, facetChannels, plotOptions) {
|
|
30923
|
-
let data = arrayify2(this.data);
|
|
30924
|
-
if (facets === void 0 && data != null) facets = [range2(data)];
|
|
30925
|
-
const originalFacets = facets;
|
|
30926
|
-
if (this.transform != null) ({ facets, data } = this.transform(data, facets, plotOptions)), data = arrayify2(data);
|
|
30927
|
-
if (facets !== void 0) facets.original = originalFacets;
|
|
30928
|
-
const channels = createChannels(this.channels, data);
|
|
30929
|
-
if (this.sort != null) channelDomain(data, facets, channels, facetChannels, this.sort);
|
|
30930
|
-
return { data, facets, channels };
|
|
30931
|
-
}
|
|
30932
|
-
filter(index2, channels, values2) {
|
|
30933
|
-
for (const name in channels) {
|
|
30934
|
-
const { filter: filter3 = defined } = channels[name];
|
|
30935
|
-
if (filter3 !== null) {
|
|
30936
|
-
const value = values2[name];
|
|
30937
|
-
index2 = index2.filter((i) => filter3(value[i]));
|
|
30938
|
-
}
|
|
30939
|
-
}
|
|
30940
|
-
return index2;
|
|
30941
|
-
}
|
|
30942
|
-
// If there is a projection, and there are paired x and y channels associated
|
|
30943
|
-
// with the x and y scale respectively (and not already in screen coordinates
|
|
30944
|
-
// as with an initializer), then apply the projection, replacing the x and y
|
|
30945
|
-
// values. Note that the x and y scales themselves don’t exist if there is a
|
|
30946
|
-
// projection, but whether the channels are associated with scales still
|
|
30947
|
-
// determines whether the projection should apply; think of the projection as
|
|
30948
|
-
// a combination xy-scale.
|
|
30949
|
-
project(channels, values2, context) {
|
|
30950
|
-
for (const cx in channels) {
|
|
30951
|
-
if (channels[cx].scale === "x" && /^x|x$/.test(cx)) {
|
|
30952
|
-
const cy = cx.replace(/^x|x$/, "y");
|
|
30953
|
-
if (cy in channels && channels[cy].scale === "y") {
|
|
30954
|
-
project(cx, cy, values2, context.projection);
|
|
30955
|
-
}
|
|
30956
|
-
}
|
|
30957
|
-
}
|
|
30958
|
-
}
|
|
30959
|
-
scale(channels, scales2, context) {
|
|
30960
|
-
const values2 = valueObject(channels, scales2);
|
|
30961
|
-
if (context.projection) this.project(channels, values2, context);
|
|
30962
|
-
return values2;
|
|
30963
|
-
}
|
|
30964
|
-
};
|
|
30965
|
-
function marks(...marks2) {
|
|
30966
|
-
marks2.plot = Mark.prototype.plot;
|
|
30967
|
-
return marks2;
|
|
30968
|
-
}
|
|
30969
|
-
function composeRender(r1, r2) {
|
|
30970
|
-
if (r1 == null) return r2 === null ? void 0 : r2;
|
|
30971
|
-
if (r2 == null) return r1 === null ? void 0 : r1;
|
|
30972
|
-
if (typeof r1 !== "function") throw new TypeError(`invalid render transform: ${r1}`);
|
|
30973
|
-
if (typeof r2 !== "function") throw new TypeError(`invalid render transform: ${r2}`);
|
|
30974
|
-
return function(i, s2, v2, d, c4, next) {
|
|
30975
|
-
return r1.call(this, i, s2, v2, d, c4, (i2, s3, v3, d2, c5) => {
|
|
30976
|
-
return r2.call(this, i2, s3, v3, d2, c5, next);
|
|
30977
|
-
});
|
|
30978
|
-
};
|
|
30979
|
-
}
|
|
30980
|
-
function maybeChannels(channels) {
|
|
30981
|
-
return Object.fromEntries(
|
|
30982
|
-
Object.entries(maybeNamed(channels)).map(([name, channel]) => {
|
|
30983
|
-
channel = typeof channel === "string" ? { value: channel, label: name } : maybeValue(channel);
|
|
30984
|
-
if (channel.filter === void 0 && channel.scale == null) channel = { ...channel, filter: null };
|
|
30985
|
-
return [name, channel];
|
|
30986
|
-
})
|
|
30987
|
-
);
|
|
30988
|
-
}
|
|
30989
|
-
function maybeTip(tip2) {
|
|
30990
|
-
return tip2 === true ? "xy" : tip2 === false || tip2 == null ? null : typeof tip2 === "string" ? keyword(tip2, "tip", ["x", "y", "xy"]) : tip2;
|
|
30991
|
-
}
|
|
30992
|
-
function withTip(options, pointer2) {
|
|
30993
|
-
return options?.tip === true ? { ...options, tip: pointer2 } : isObject2(options?.tip) && options.tip.pointer === void 0 ? { ...options, tip: { ...options.tip, pointer: pointer2 } } : options;
|
|
30994
|
-
}
|
|
30995
|
-
|
|
30996
31500
|
// ../../node_modules/@observablehq/plot/src/interactions/pointer.js
|
|
30997
31501
|
var states = /* @__PURE__ */ new WeakMap();
|
|
30998
31502
|
function pointerK(kx2, ky2, { x: x3, y: y3, px, py, maxRadius = 40, channels, render, ...options } = {}) {
|
|
@@ -32537,7 +33041,7 @@ function inferTextChannel(scale3, data, ticks2, tickFormat2, anchor) {
|
|
|
32537
33041
|
return { value: inferTickFormat(scale3, data, ticks2, tickFormat2, anchor) };
|
|
32538
33042
|
}
|
|
32539
33043
|
function inferTickFormat(scale3, data, ticks2, tickFormat2, anchor) {
|
|
32540
|
-
return typeof tickFormat2 === "function" ? tickFormat2 : tickFormat2 === void 0 && data && isTemporal(data) ? inferTimeFormat(scale3.type, data, anchor) ?? formatDefault : scale3.tickFormat ? scale3.tickFormat(typeof ticks2 === "number" ? ticks2 : null, tickFormat2) : tickFormat2 === void 0 ? formatDefault : typeof tickFormat2 === "string" ? (isTemporal(scale3.domain()) ? utcFormat : format)(tickFormat2) : constant(tickFormat2);
|
|
33044
|
+
return typeof tickFormat2 === "function" && !(scale3.type === "log" && scale3.tickFormat) ? tickFormat2 : tickFormat2 === void 0 && data && isTemporal(data) ? inferTimeFormat(scale3.type, data, anchor) ?? formatDefault : scale3.tickFormat ? scale3.tickFormat(typeof ticks2 === "number" ? ticks2 : null, tickFormat2) : tickFormat2 === void 0 ? formatDefault : typeof tickFormat2 === "string" ? (isTemporal(scale3.domain()) ? utcFormat : format)(tickFormat2) : constant(tickFormat2);
|
|
32541
33045
|
}
|
|
32542
33046
|
function inclusiveRange(interval2, min5, max4) {
|
|
32543
33047
|
return interval2.range(min5, interval2.offset(interval2.floor(max4)));
|
|
@@ -32906,7 +33410,7 @@ var Tip = class extends Mark {
|
|
|
32906
33410
|
for (const key in defaults5) if (key in this.channels) this[key] = defaults5[key];
|
|
32907
33411
|
this.splitLines = splitter2(this);
|
|
32908
33412
|
this.clipLine = clipper(this);
|
|
32909
|
-
this.format = { ...format3 };
|
|
33413
|
+
this.format = typeof format3 === "string" || typeof format3 === "function" ? { title: format3 } : { ...format3 };
|
|
32910
33414
|
}
|
|
32911
33415
|
render(index2, scales2, values2, dimensions, context) {
|
|
32912
33416
|
const mark = this;
|
|
@@ -32925,10 +33429,10 @@ var Tip = class extends Mark {
|
|
|
32925
33429
|
const ee = widthof(ellipsis);
|
|
32926
33430
|
let sources, format3;
|
|
32927
33431
|
if ("title" in values2) {
|
|
32928
|
-
sources = values2.channels;
|
|
33432
|
+
sources = getSourceChannels.call(this, { title: values2.channels.title }, scales2);
|
|
32929
33433
|
format3 = formatTitle;
|
|
32930
33434
|
} else {
|
|
32931
|
-
sources = getSourceChannels.call(this, values2, scales2);
|
|
33435
|
+
sources = getSourceChannels.call(this, values2.channels, scales2);
|
|
32932
33436
|
format3 = formatChannels;
|
|
32933
33437
|
}
|
|
32934
33438
|
const g = create3("svg:g", context).call(applyIndirectStyles, this, dimensions, context).call(applyIndirectTextStyles, this).call(applyTransform, this, { x: X3 && x3, y: Y3 && y3 }).call(
|
|
@@ -33064,7 +33568,7 @@ function getPath(anchor, m, r, width, height) {
|
|
|
33064
33568
|
return `M0,0l${m / 2},${-m / 2}v${m / 2 - h / 2}h${w}v${h}h${-w}v${m / 2 - h / 2}z`;
|
|
33065
33569
|
}
|
|
33066
33570
|
}
|
|
33067
|
-
function getSourceChannels(
|
|
33571
|
+
function getSourceChannels(channels, scales2) {
|
|
33068
33572
|
const sources = {};
|
|
33069
33573
|
let format3 = this.format;
|
|
33070
33574
|
format3 = maybeExpandPairedFormat(format3, channels, "x");
|
|
@@ -33113,7 +33617,7 @@ function maybeExpandPairedFormat(format3, channels, key) {
|
|
|
33113
33617
|
return Object.fromEntries(entries);
|
|
33114
33618
|
}
|
|
33115
33619
|
function formatTitle(i, index2, { title }) {
|
|
33116
|
-
return
|
|
33620
|
+
return this.format.title(title.value[i], i);
|
|
33117
33621
|
}
|
|
33118
33622
|
function* formatChannels(i, index2, channels, scales2, values2) {
|
|
33119
33623
|
for (const key in channels) {
|
|
@@ -33364,6 +33868,7 @@ function plot(options = {}) {
|
|
|
33364
33868
|
if (subtitle != null) figure.append(createTitleElement(document2, subtitle, "h3"));
|
|
33365
33869
|
figure.append(...legends, svg);
|
|
33366
33870
|
if (caption != null) figure.append(createFigcaption(document2, caption));
|
|
33871
|
+
if ("value" in svg) figure.value = svg.value, delete svg.value;
|
|
33367
33872
|
}
|
|
33368
33873
|
figure.scale = exposeScales(scales2.scales);
|
|
33369
33874
|
figure.legend = exposeLegends(scaleDescriptors, context, options);
|
|
@@ -33384,10 +33889,6 @@ function createFigcaption(document2, caption) {
|
|
|
33384
33889
|
e.append(caption);
|
|
33385
33890
|
return e;
|
|
33386
33891
|
}
|
|
33387
|
-
function plotThis({ marks: marks2 = [], ...options } = {}) {
|
|
33388
|
-
return plot({ ...options, marks: [...marks2, this] });
|
|
33389
|
-
}
|
|
33390
|
-
Mark.prototype.plot = plotThis;
|
|
33391
33892
|
function flatMarks(marks2) {
|
|
33392
33893
|
return marks2.flat(Infinity).filter((mark) => mark != null).map(markify);
|
|
33393
33894
|
}
|
|
@@ -33414,7 +33915,7 @@ function applyScaleTransform(channel, options) {
|
|
|
33414
33915
|
type: type2,
|
|
33415
33916
|
percent,
|
|
33416
33917
|
interval: interval2,
|
|
33417
|
-
transform: transform3 = percent ? (x3) => x3 * 100 : maybeIntervalTransform(interval2, type2)
|
|
33918
|
+
transform: transform3 = percent ? (x3) => x3 == null ? NaN : x3 * 100 : maybeIntervalTransform(interval2, type2)
|
|
33418
33919
|
} = options[scale3] ?? {};
|
|
33419
33920
|
if (transform3 == null) return;
|
|
33420
33921
|
channel.value = map2(channel.value, transform3);
|
|
@@ -33973,7 +34474,7 @@ function maybeThresholds(thresholds, interval2, defaultThresholds = thresholdAut
|
|
|
33973
34474
|
case "auto":
|
|
33974
34475
|
return thresholdAuto;
|
|
33975
34476
|
}
|
|
33976
|
-
return
|
|
34477
|
+
return utcInterval(thresholds);
|
|
33977
34478
|
}
|
|
33978
34479
|
return thresholds;
|
|
33979
34480
|
}
|
|
@@ -36128,14 +36629,15 @@ function interpolatorBarycentric({ random = lcg(42) } = {}) {
|
|
|
36128
36629
|
if (x3 < 0 || x3 >= width || y3 < 0 || y3 >= height) continue;
|
|
36129
36630
|
const xp = x3 + 0.5;
|
|
36130
36631
|
const yp = y3 + 0.5;
|
|
36131
|
-
const
|
|
36132
|
-
|
|
36133
|
-
|
|
36134
|
-
|
|
36135
|
-
|
|
36136
|
-
|
|
36632
|
+
const s2 = Math.sign(z);
|
|
36633
|
+
const ga = (By - Cy) * (xp - Cx) + (yp - Cy) * (Cx - Bx);
|
|
36634
|
+
if (ga * s2 < 0) continue;
|
|
36635
|
+
const gb = (Cy - Ay) * (xp - Cx) + (yp - Cy) * (Ax - Cx);
|
|
36636
|
+
if (gb * s2 < 0) continue;
|
|
36637
|
+
const gc = z - (ga + gb);
|
|
36638
|
+
if (gc * s2 < 0) continue;
|
|
36137
36639
|
const i2 = x3 + width * y3;
|
|
36138
|
-
W[i2] = mix(va, ga, vb, gb, vc, gc, x3, y3);
|
|
36640
|
+
W[i2] = mix(va, ga / z, vb, gb / z, vc, gc / z, x3, y3);
|
|
36139
36641
|
S[i2] = 1;
|
|
36140
36642
|
}
|
|
36141
36643
|
}
|
|
@@ -37934,7 +38436,7 @@ function dodge(y3, x3, anchor, padding, r, options) {
|
|
|
37934
38436
|
for (let I of facets) {
|
|
37935
38437
|
const tree2 = (0, import_interval_tree_1d.default)();
|
|
37936
38438
|
I = I.filter(R ? (i) => finite2(X3[i]) && positive(R[i]) : (i) => finite2(X3[i]));
|
|
37937
|
-
const
|
|
38439
|
+
const intervals2 = new Float64Array(2 * I.length + 2);
|
|
37938
38440
|
for (const i of I) {
|
|
37939
38441
|
const ri = radius2(i);
|
|
37940
38442
|
const y06 = ky2 ? ri + padding : 0;
|
|
@@ -37946,14 +38448,14 @@ function dodge(y3, x3, anchor, padding, r, options) {
|
|
|
37946
38448
|
const dx = X3[i] - X3[j];
|
|
37947
38449
|
const dr = padding + (R ? R[i] + R[j] : 2 * cr);
|
|
37948
38450
|
const dy = Math.sqrt(dr * dr - dx * dx);
|
|
37949
|
-
|
|
37950
|
-
|
|
38451
|
+
intervals2[k2++] = yj - dy;
|
|
38452
|
+
intervals2[k2++] = yj + dy;
|
|
37951
38453
|
});
|
|
37952
|
-
let candidates =
|
|
38454
|
+
let candidates = intervals2.slice(0, k2);
|
|
37953
38455
|
if (ky2) candidates = candidates.filter((y4) => y4 >= 0);
|
|
37954
38456
|
out: for (const y4 of candidates.sort(compare)) {
|
|
37955
38457
|
for (let j = 0; j < k2; j += 2) {
|
|
37956
|
-
if (
|
|
38458
|
+
if (intervals2[j] + 1e-6 < y4 && y4 < intervals2[j + 1] - 1e-6) {
|
|
37957
38459
|
continue out;
|
|
37958
38460
|
}
|
|
37959
38461
|
}
|
|
@@ -38194,6 +38696,11 @@ function selectChannel(v2, selector, options) {
|
|
|
38194
38696
|
});
|
|
38195
38697
|
}
|
|
38196
38698
|
|
|
38699
|
+
// ../../node_modules/@observablehq/plot/src/index.js
|
|
38700
|
+
Mark.prototype.plot = function({ marks: marks2 = [], ...options } = {}) {
|
|
38701
|
+
return plot({ ...options, marks: [...marks2, this] });
|
|
38702
|
+
};
|
|
38703
|
+
|
|
38197
38704
|
// src/plot-attributes.js
|
|
38198
38705
|
var attributeMap = /* @__PURE__ */ new Map([
|
|
38199
38706
|
["style", "style"],
|
|
@@ -38379,6 +38886,7 @@ var attributeMap = /* @__PURE__ */ new Map([
|
|
|
38379
38886
|
["rRange", "r.range"],
|
|
38380
38887
|
["rClamp", "r.clamp"],
|
|
38381
38888
|
["rNice", "r.nice"],
|
|
38889
|
+
["rLabel", "r.label"],
|
|
38382
38890
|
["rPercent", "r.percent"],
|
|
38383
38891
|
["rZero", "r.zero"],
|
|
38384
38892
|
["rBase", "r.base"],
|
|
@@ -38438,39 +38946,35 @@ var OPTIONS_ONLY_MARKS = /* @__PURE__ */ new Set([
|
|
|
38438
38946
|
"sphere",
|
|
38439
38947
|
"graticule"
|
|
38440
38948
|
]);
|
|
38949
|
+
var SELECT_TRANSFORMS = /* @__PURE__ */ new Map([
|
|
38950
|
+
["first", selectFirst],
|
|
38951
|
+
["last", selectLast],
|
|
38952
|
+
["maxX", selectMaxX],
|
|
38953
|
+
["maxY", selectMaxY],
|
|
38954
|
+
["minX", selectMinX],
|
|
38955
|
+
["minY", selectMinY],
|
|
38956
|
+
["nearest", pointer],
|
|
38957
|
+
["nearestX", pointerX],
|
|
38958
|
+
["nearestXY", pointerY]
|
|
38959
|
+
]);
|
|
38441
38960
|
async function plotRenderer(plot2) {
|
|
38442
38961
|
const spec = { marks: [] };
|
|
38443
38962
|
const symbols3 = [];
|
|
38444
38963
|
const { attributes, marks: marks2 } = plot2;
|
|
38445
38964
|
setAttributes(attributes, spec, symbols3);
|
|
38446
|
-
const
|
|
38965
|
+
const indices2 = [];
|
|
38447
38966
|
for (const mark of marks2) {
|
|
38448
38967
|
for (const { type: type2, data, options } of mark.plotSpecs()) {
|
|
38449
|
-
|
|
38450
|
-
|
|
38451
|
-
|
|
38452
|
-
|
|
38453
|
-
|
|
38454
|
-
let val = v2;
|
|
38455
|
-
if (typeof v2 === "string") {
|
|
38456
|
-
val = data.getChild(v2) ?? v2;
|
|
38457
|
-
} else if (typeof v2 === "object") {
|
|
38458
|
-
const value = data.getChild(v2.value);
|
|
38459
|
-
val = value ? { value } : v2;
|
|
38460
|
-
}
|
|
38461
|
-
return [k2, val];
|
|
38462
|
-
})
|
|
38463
|
-
);
|
|
38464
|
-
spec.marks.push(src_exports[type2]({ length: data.numRows }, opts));
|
|
38465
|
-
} else {
|
|
38466
|
-
spec.marks.push(src_exports[type2](data, options));
|
|
38467
|
-
}
|
|
38468
|
-
indices.push(mark.index);
|
|
38968
|
+
const { select: select2, ...rest } = options;
|
|
38969
|
+
const opt = SELECT_TRANSFORMS.get(select2)?.(rest) ?? rest;
|
|
38970
|
+
const arg = OPTIONS_ONLY_MARKS.has(type2) ? [opt] : [data, opt];
|
|
38971
|
+
spec.marks.push(src_exports[type2](...arg));
|
|
38972
|
+
indices2.push(mark.index);
|
|
38469
38973
|
}
|
|
38470
38974
|
}
|
|
38471
38975
|
inferLabels(spec, plot2);
|
|
38472
38976
|
const svg = plot(spec);
|
|
38473
|
-
annotatePlot(svg,
|
|
38977
|
+
annotatePlot(svg, indices2);
|
|
38474
38978
|
setSymbolAttributes(plot2, svg, attributes, symbols3);
|
|
38475
38979
|
for (const interactor of plot2.interactors) {
|
|
38476
38980
|
await interactor.init(svg);
|
|
@@ -38536,27 +39040,28 @@ function inferLabel(key, spec, marks2) {
|
|
|
38536
39040
|
}
|
|
38537
39041
|
spec[key] = { ...scale3, label: candidate };
|
|
38538
39042
|
}
|
|
38539
|
-
function annotatePlot(svg,
|
|
39043
|
+
function annotatePlot(svg, indices2) {
|
|
38540
39044
|
const facets = svg.querySelectorAll('g[aria-label="facet"]');
|
|
38541
39045
|
if (facets.length) {
|
|
38542
39046
|
for (const facet of facets) {
|
|
38543
|
-
annotateMarks(facet,
|
|
39047
|
+
annotateMarks(facet, indices2);
|
|
38544
39048
|
}
|
|
38545
39049
|
} else {
|
|
38546
|
-
annotateMarks(svg,
|
|
39050
|
+
annotateMarks(svg, indices2);
|
|
38547
39051
|
}
|
|
38548
39052
|
}
|
|
38549
|
-
function annotateMarks(svg,
|
|
39053
|
+
function annotateMarks(svg, indices2) {
|
|
38550
39054
|
let index2 = -1;
|
|
38551
39055
|
for (const child of svg.children) {
|
|
38552
39056
|
const aria = child.getAttribute("aria-label") || "";
|
|
38553
39057
|
const skip = child.nodeName === "style" || aria.includes("-axis") || aria.includes("-grid");
|
|
38554
39058
|
if (!skip) {
|
|
38555
|
-
child.setAttribute("data-index",
|
|
39059
|
+
child.setAttribute("data-index", indices2[++index2]);
|
|
38556
39060
|
}
|
|
38557
39061
|
}
|
|
38558
39062
|
}
|
|
38559
39063
|
function getType(data, channel) {
|
|
39064
|
+
if (!data) return;
|
|
38560
39065
|
const { columns } = data;
|
|
38561
39066
|
const col = columns[channel] ?? columns[channel + "1"] ?? columns[channel + "2"];
|
|
38562
39067
|
if (col) {
|
|
@@ -38606,8 +39111,8 @@ var Plot = class {
|
|
|
38606
39111
|
innerHeight(defaultValue = 400) {
|
|
38607
39112
|
const { top: top2, bottom: bottom2 } = this.margins();
|
|
38608
39113
|
let h = this.getAttribute("height");
|
|
38609
|
-
if (h == null
|
|
38610
|
-
h = defaultValue;
|
|
39114
|
+
if (h == null) {
|
|
39115
|
+
h = maybeAspectRatio(this, top2, bottom2) || defaultValue;
|
|
38611
39116
|
this.setAttribute("height", h, { silent: true });
|
|
38612
39117
|
}
|
|
38613
39118
|
return h - top2 - bottom2;
|
|
@@ -38711,6 +39216,16 @@ var Plot = class {
|
|
|
38711
39216
|
this.legends.push({ legend: legend2, include });
|
|
38712
39217
|
}
|
|
38713
39218
|
};
|
|
39219
|
+
function maybeAspectRatio(plot2, top2, bottom2) {
|
|
39220
|
+
const ar = plot2.getAttribute("aspectRatio");
|
|
39221
|
+
if (ar == null) return;
|
|
39222
|
+
const x3 = plot2.getAttribute("xDomain");
|
|
39223
|
+
const y3 = plot2.getAttribute("yDomain");
|
|
39224
|
+
if (!x3 || !y3) return;
|
|
39225
|
+
const dx = Math.abs(x3[1] - x3[0]);
|
|
39226
|
+
const dy = Math.abs(y3[1] - y3[0]);
|
|
39227
|
+
return dy * plot2.innerWidth() / (ar * dx) + top2 + bottom2;
|
|
39228
|
+
}
|
|
38714
39229
|
|
|
38715
39230
|
// src/marks/util/is-color.js
|
|
38716
39231
|
function isColor2(value) {
|
|
@@ -38757,7 +39272,8 @@ var constantOptions = /* @__PURE__ */ new Set([
|
|
|
38757
39272
|
"crossOrigin",
|
|
38758
39273
|
"paintOrder",
|
|
38759
39274
|
"pointerEvents",
|
|
38760
|
-
"target"
|
|
39275
|
+
"target",
|
|
39276
|
+
"select"
|
|
38761
39277
|
]);
|
|
38762
39278
|
function isConstantOption(value) {
|
|
38763
39279
|
return constantOptions.has(value);
|
|
@@ -38784,39 +39300,6 @@ function isSymbol2(value) {
|
|
|
38784
39300
|
return symbols2.has(`${value}`.toLowerCase());
|
|
38785
39301
|
}
|
|
38786
39302
|
|
|
38787
|
-
// src/marks/util/to-data-columns.js
|
|
38788
|
-
function toDataColumns(data) {
|
|
38789
|
-
return isArrowTable(data) ? arrowToColumns(data) : arrayToColumns(data);
|
|
38790
|
-
}
|
|
38791
|
-
function arrowToColumns(data) {
|
|
38792
|
-
const { numRows, numCols, schema: { fields } } = data;
|
|
38793
|
-
const columns = {};
|
|
38794
|
-
for (let col = 0; col < numCols; ++col) {
|
|
38795
|
-
const name = fields[col].name;
|
|
38796
|
-
if (columns[name]) {
|
|
38797
|
-
console.warn(`Redundant column name "${name}". Skipping...`);
|
|
38798
|
-
} else {
|
|
38799
|
-
columns[name] = convertArrowColumn(data.getChildAt(col));
|
|
38800
|
-
}
|
|
38801
|
-
}
|
|
38802
|
-
return { numRows, columns };
|
|
38803
|
-
}
|
|
38804
|
-
function arrayToColumns(data) {
|
|
38805
|
-
const numRows = data.length;
|
|
38806
|
-
if (typeof data[0] === "object") {
|
|
38807
|
-
const names = numRows ? Object.keys(data[0]) : [];
|
|
38808
|
-
const columns = {};
|
|
38809
|
-
if (names.length > 0) {
|
|
38810
|
-
names.forEach((name) => {
|
|
38811
|
-
columns[name] = data.map((d) => d[name]);
|
|
38812
|
-
});
|
|
38813
|
-
}
|
|
38814
|
-
return { numRows, columns };
|
|
38815
|
-
} else {
|
|
38816
|
-
return { numRows, values: data };
|
|
38817
|
-
}
|
|
38818
|
-
}
|
|
38819
|
-
|
|
38820
39303
|
// src/marks/Mark.js
|
|
38821
39304
|
var isColorChannel = (channel) => channel === "stroke" || channel === "fill";
|
|
38822
39305
|
var isOpacityChannel = (channel) => /opacity$/i.test(channel);
|
|
@@ -38885,7 +39368,7 @@ var Mark2 = class extends MosaicClient {
|
|
|
38885
39368
|
}
|
|
38886
39369
|
/**
|
|
38887
39370
|
* @param {import('../plot.js').Plot} plot The plot.
|
|
38888
|
-
* @param {number} index
|
|
39371
|
+
* @param {number} index
|
|
38889
39372
|
*/
|
|
38890
39373
|
setPlot(plot2, index2) {
|
|
38891
39374
|
this.plot = plot2;
|
|
@@ -38960,18 +39443,8 @@ var Mark2 = class extends MosaicClient {
|
|
|
38960
39443
|
* @returns {object[]}
|
|
38961
39444
|
*/
|
|
38962
39445
|
plotSpecs() {
|
|
38963
|
-
const { type: type2, detail, channels } = this;
|
|
38964
|
-
|
|
38965
|
-
const options = {};
|
|
38966
|
-
const side = {};
|
|
38967
|
-
for (const c4 of channels) {
|
|
38968
|
-
const obj = detail.has(c4.channel) ? side : options;
|
|
38969
|
-
obj[c4.channel] = channelOption(c4, columns);
|
|
38970
|
-
}
|
|
38971
|
-
if (detail.size) options.channels = side;
|
|
38972
|
-
const data = values2 ?? (this.data ? { length: length4 } : null);
|
|
38973
|
-
const spec = [{ type: type2, data, options }];
|
|
38974
|
-
return spec;
|
|
39446
|
+
const { type: type2, data, detail, channels } = this;
|
|
39447
|
+
return markPlotSpec(type2, detail, channels, data);
|
|
38975
39448
|
}
|
|
38976
39449
|
};
|
|
38977
39450
|
function channelOption(c4, columns) {
|
|
@@ -39002,6 +39475,18 @@ function markQuery(channels, table, skip = []) {
|
|
|
39002
39475
|
}
|
|
39003
39476
|
return q;
|
|
39004
39477
|
}
|
|
39478
|
+
function markPlotSpec(type2, detail, channels, data, options = {}) {
|
|
39479
|
+
const { numRows: length4, values: values2, columns } = data ?? {};
|
|
39480
|
+
const side = {};
|
|
39481
|
+
for (const c4 of channels) {
|
|
39482
|
+
const obj = detail.has(c4.channel) ? side : options;
|
|
39483
|
+
obj[c4.channel] = channelOption(c4, columns);
|
|
39484
|
+
}
|
|
39485
|
+
if (detail.size) options.channels = side;
|
|
39486
|
+
const specData = values2 ?? (data ? { length: length4 } : null);
|
|
39487
|
+
const spec = [{ type: type2, data: specData, options }];
|
|
39488
|
+
return spec;
|
|
39489
|
+
}
|
|
39005
39490
|
|
|
39006
39491
|
// src/marks/util/channel-scale.js
|
|
39007
39492
|
function channelScale(mark, channel) {
|
|
@@ -39428,7 +39913,7 @@ var Grid2DMark = class extends Mark2 {
|
|
|
39428
39913
|
}
|
|
39429
39914
|
/**
|
|
39430
39915
|
* @param {import('../plot.js').Plot} plot The plot.
|
|
39431
|
-
* @param {number} index
|
|
39916
|
+
* @param {number} index
|
|
39432
39917
|
*/
|
|
39433
39918
|
setPlot(plot2, index2) {
|
|
39434
39919
|
const update2 = () => {
|
|
@@ -39676,6 +40161,17 @@ function transform2(geometry, x3, y3) {
|
|
|
39676
40161
|
return geometry;
|
|
39677
40162
|
}
|
|
39678
40163
|
|
|
40164
|
+
// src/marks/util/permute.js
|
|
40165
|
+
function indices(length4) {
|
|
40166
|
+
return Array.from({ length: length4 }, (_, i) => i);
|
|
40167
|
+
}
|
|
40168
|
+
function permute2(data, order) {
|
|
40169
|
+
const ord = order.reduce((acc, val, i) => (acc[val] = i, acc), {});
|
|
40170
|
+
const idx = indices(data.length);
|
|
40171
|
+
idx.sort((a2, b) => ord[data[a2]] - ord[data[b]]);
|
|
40172
|
+
return idx;
|
|
40173
|
+
}
|
|
40174
|
+
|
|
39679
40175
|
// src/marks/util/raster.js
|
|
39680
40176
|
function createCanvas(w, h) {
|
|
39681
40177
|
if (typeof document !== "undefined") {
|
|
@@ -39810,12 +40306,13 @@ var RasterMark = class extends Grid2DMark {
|
|
|
39810
40306
|
const { alpha, alphaProp, color: color3, colorProp } = rasterEncoding(this);
|
|
39811
40307
|
const alphaData = columns[alphaProp] ?? [];
|
|
39812
40308
|
const colorData = columns[colorProp] ?? [];
|
|
40309
|
+
const idx = numRows > 1 && colorProp && this.groupby?.includes(colorProp) ? permute2(colorData, this.plot.getAttribute("colorDomain")) : indices(numRows);
|
|
39813
40310
|
this.data = {
|
|
39814
40311
|
numRows,
|
|
39815
40312
|
columns: {
|
|
39816
40313
|
src: Array.from({ length: numRows }, (_, i) => {
|
|
39817
|
-
color3?.(img.data, w, h, colorData[i]);
|
|
39818
|
-
alpha?.(img.data, w, h, alphaData[i]);
|
|
40314
|
+
color3?.(img.data, w, h, colorData[idx[i]]);
|
|
40315
|
+
alpha?.(img.data, w, h, alphaData[idx[i]]);
|
|
39819
40316
|
ctx.putImageData(img, 0, 0);
|
|
39820
40317
|
return canvas.toDataURL();
|
|
39821
40318
|
})
|
|
@@ -39902,7 +40399,7 @@ function colorScale(mark, prop) {
|
|
|
39902
40399
|
const domainAttr = plot2.getAttribute("colorDomain");
|
|
39903
40400
|
const domainFixed = domainAttr === Fixed;
|
|
39904
40401
|
const domainTransient = domainAttr?.[Transient];
|
|
39905
|
-
const domain = !domainFixed && !domainTransient && domainAttr || (flat ? data.sort(ascending) : discrete ? gridDomainDiscrete(data) : gridDomainContinuous(data));
|
|
40402
|
+
const domain = !domainFixed && !domainTransient && domainAttr || (flat ? data.slice().sort(ascending) : discrete ? gridDomainDiscrete(data) : gridDomainContinuous(data));
|
|
39906
40403
|
if (domainFixed || domainTransient || !domainAttr) {
|
|
39907
40404
|
if (!domainFixed) domain[Transient] = true;
|
|
39908
40405
|
plot2.setAttribute("colorDomain", domain);
|
|
@@ -40025,7 +40522,7 @@ function lineDensity(q, x3, y3, z, xn, yn, groupby = [], normalize4 = true) {
|
|
|
40025
40522
|
sql`(y0 > 0 OR y0 + dy > 0)`
|
|
40026
40523
|
));
|
|
40027
40524
|
const num = Query.select({ x: sql`GREATEST(MAX(ABS(dx)), MAX(ABS(dy)))` }).from("pairs");
|
|
40028
|
-
const
|
|
40525
|
+
const indices2 = Query.select({ i: sql`UNNEST(range((${num})))::INTEGER` });
|
|
40029
40526
|
const raster2 = Query.unionAll(
|
|
40030
40527
|
Query.select(groups2, {
|
|
40031
40528
|
x: sql`x0 + i`,
|
|
@@ -40044,7 +40541,7 @@ function lineDensity(q, x3, y3, z, xn, yn, groupby = [], normalize4 = true) {
|
|
|
40044
40541
|
"y",
|
|
40045
40542
|
normalize4 ? { w: sql`1.0 / COUNT(*) OVER (PARTITION BY ${pointPart})` } : null
|
|
40046
40543
|
).where(and(isBetween("x", [0, xn], true), isBetween("y", [0, yn], true)));
|
|
40047
|
-
return Query.with({ pairs: pairs2, indices, raster: raster2, points: points2 }).from("points").select(groupby, {
|
|
40544
|
+
return Query.with({ pairs: pairs2, indices: indices2, raster: raster2, points: points2 }).from("points").select(groupby, {
|
|
40048
40545
|
index: sql`x + y * ${xn}::INTEGER`,
|
|
40049
40546
|
density: normalize4 ? sum("w") : count()
|
|
40050
40547
|
}).groupby("index", groupby);
|
|
@@ -40209,6 +40706,220 @@ function points(data, bins2, x06, y06, deltaX, deltaY, invertX, invertY, offset2
|
|
|
40209
40706
|
return { numRows, columns };
|
|
40210
40707
|
}
|
|
40211
40708
|
|
|
40709
|
+
// src/marks/util/stats.js
|
|
40710
|
+
function ibetainv2(p, a2, b) {
|
|
40711
|
+
var EPS2 = 1e-8;
|
|
40712
|
+
var a1 = a2 - 1;
|
|
40713
|
+
var b1 = b - 1;
|
|
40714
|
+
var j = 0;
|
|
40715
|
+
var lna, lnb, pp, t, u4, err, x3, al, h, w, afac;
|
|
40716
|
+
if (p <= 0) return 0;
|
|
40717
|
+
if (p >= 1) return 1;
|
|
40718
|
+
if (a2 >= 1 && b >= 1) {
|
|
40719
|
+
pp = p < 0.5 ? p : 1 - p;
|
|
40720
|
+
t = Math.sqrt(-2 * Math.log(pp));
|
|
40721
|
+
x3 = (2.30753 + t * 0.27061) / (1 + t * (0.99229 + t * 0.04481)) - t;
|
|
40722
|
+
if (p < 0.5) x3 = -x3;
|
|
40723
|
+
al = (x3 * x3 - 3) / 6;
|
|
40724
|
+
h = 2 / (1 / (2 * a2 - 1) + 1 / (2 * b - 1));
|
|
40725
|
+
w = x3 * Math.sqrt(al + h) / h - (1 / (2 * b - 1) - 1 / (2 * a2 - 1)) * (al + 5 / 6 - 2 / (3 * h));
|
|
40726
|
+
x3 = a2 / (a2 + b * Math.exp(2 * w));
|
|
40727
|
+
} else {
|
|
40728
|
+
lna = Math.log(a2 / (a2 + b));
|
|
40729
|
+
lnb = Math.log(b / (a2 + b));
|
|
40730
|
+
t = Math.exp(a2 * lna) / a2;
|
|
40731
|
+
u4 = Math.exp(b * lnb) / b;
|
|
40732
|
+
w = t + u4;
|
|
40733
|
+
if (p < t / w) x3 = Math.pow(a2 * w * p, 1 / a2);
|
|
40734
|
+
else x3 = 1 - Math.pow(b * w * (1 - p), 1 / b);
|
|
40735
|
+
}
|
|
40736
|
+
afac = -gammaln2(a2) - gammaln2(b) + gammaln2(a2 + b);
|
|
40737
|
+
for (; j < 10; j++) {
|
|
40738
|
+
if (x3 === 0 || x3 === 1) return x3;
|
|
40739
|
+
err = ibeta2(x3, a2, b) - p;
|
|
40740
|
+
t = Math.exp(a1 * Math.log(x3) + b1 * Math.log(1 - x3) + afac);
|
|
40741
|
+
u4 = err / t;
|
|
40742
|
+
x3 -= t = u4 / (1 - 0.5 * Math.min(1, u4 * (a1 / x3 - b1 / (1 - x3))));
|
|
40743
|
+
if (x3 <= 0) x3 = 0.5 * (x3 + t);
|
|
40744
|
+
if (x3 >= 1) x3 = 0.5 * (x3 + t + 1);
|
|
40745
|
+
if (Math.abs(t) < EPS2 * x3 && j > 0) break;
|
|
40746
|
+
}
|
|
40747
|
+
return x3;
|
|
40748
|
+
}
|
|
40749
|
+
function ibeta2(x3, a2, b) {
|
|
40750
|
+
var bt = x3 === 0 || x3 === 1 ? 0 : Math.exp(gammaln2(a2 + b) - gammaln2(a2) - gammaln2(b) + a2 * Math.log(x3) + b * Math.log(1 - x3));
|
|
40751
|
+
if (x3 < 0 || x3 > 1) return 0;
|
|
40752
|
+
if (x3 < (a2 + 1) / (a2 + b + 2))
|
|
40753
|
+
return bt * betacf2(x3, a2, b) / a2;
|
|
40754
|
+
return 1 - bt * betacf2(1 - x3, b, a2) / b;
|
|
40755
|
+
}
|
|
40756
|
+
function betacf2(x3, a2, b) {
|
|
40757
|
+
var fpmin = 1e-30;
|
|
40758
|
+
var m = 1;
|
|
40759
|
+
var qab = a2 + b;
|
|
40760
|
+
var qap = a2 + 1;
|
|
40761
|
+
var qam = a2 - 1;
|
|
40762
|
+
var c4 = 1;
|
|
40763
|
+
var d = 1 - qab * x3 / qap;
|
|
40764
|
+
var m2, aa2, del, h;
|
|
40765
|
+
if (Math.abs(d) < fpmin) d = fpmin;
|
|
40766
|
+
d = 1 / d;
|
|
40767
|
+
h = d;
|
|
40768
|
+
for (; m <= 100; m++) {
|
|
40769
|
+
m2 = 2 * m;
|
|
40770
|
+
aa2 = m * (b - m) * x3 / ((qam + m2) * (a2 + m2));
|
|
40771
|
+
d = 1 + aa2 * d;
|
|
40772
|
+
if (Math.abs(d) < fpmin) d = fpmin;
|
|
40773
|
+
c4 = 1 + aa2 / c4;
|
|
40774
|
+
if (Math.abs(c4) < fpmin) c4 = fpmin;
|
|
40775
|
+
d = 1 / d;
|
|
40776
|
+
h *= d * c4;
|
|
40777
|
+
aa2 = -(a2 + m) * (qab + m) * x3 / ((a2 + m2) * (qap + m2));
|
|
40778
|
+
d = 1 + aa2 * d;
|
|
40779
|
+
if (Math.abs(d) < fpmin) d = fpmin;
|
|
40780
|
+
c4 = 1 + aa2 / c4;
|
|
40781
|
+
if (Math.abs(c4) < fpmin) c4 = fpmin;
|
|
40782
|
+
d = 1 / d;
|
|
40783
|
+
del = d * c4;
|
|
40784
|
+
h *= del;
|
|
40785
|
+
if (Math.abs(del - 1) < 3e-7) break;
|
|
40786
|
+
}
|
|
40787
|
+
return h;
|
|
40788
|
+
}
|
|
40789
|
+
function gammaln2(x3) {
|
|
40790
|
+
var j = 0;
|
|
40791
|
+
var cof = [
|
|
40792
|
+
76.18009172947146,
|
|
40793
|
+
-86.5053203294167,
|
|
40794
|
+
24.01409824083091,
|
|
40795
|
+
-1.231739572450155,
|
|
40796
|
+
0.001208650973866179,
|
|
40797
|
+
-5395239384953e-18
|
|
40798
|
+
];
|
|
40799
|
+
var ser = 1.000000000190015;
|
|
40800
|
+
var xx, y3, tmp2;
|
|
40801
|
+
tmp2 = (y3 = xx = x3) + 5.5;
|
|
40802
|
+
tmp2 -= (xx + 0.5) * Math.log(tmp2);
|
|
40803
|
+
for (; j < 6; j++) ser += cof[j] / ++y3;
|
|
40804
|
+
return Math.log(2.506628274631 * ser / xx) - tmp2;
|
|
40805
|
+
}
|
|
40806
|
+
function qt2(p, dof) {
|
|
40807
|
+
var x3 = ibetainv2(2 * Math.min(p, 1 - p), 0.5 * dof, 0.5);
|
|
40808
|
+
x3 = Math.sqrt(dof * (1 - x3) / x3);
|
|
40809
|
+
return p > 0.5 ? x3 : -x3;
|
|
40810
|
+
}
|
|
40811
|
+
function erfinv(x3) {
|
|
40812
|
+
let w = -Math.log((1 - x3) * (1 + x3));
|
|
40813
|
+
let p;
|
|
40814
|
+
if (w < 6.25) {
|
|
40815
|
+
w -= 3.125;
|
|
40816
|
+
p = -364441206401782e-35;
|
|
40817
|
+
p = -16850591381820166e-35 + p * w;
|
|
40818
|
+
p = 128584807152564e-32 + p * w;
|
|
40819
|
+
p = 11157877678025181e-33 + p * w;
|
|
40820
|
+
p = -1333171662854621e-31 + p * w;
|
|
40821
|
+
p = 20972767875968562e-33 + p * w;
|
|
40822
|
+
p = 6637638134358324e-30 + p * w;
|
|
40823
|
+
p = -4054566272975207e-29 + p * w;
|
|
40824
|
+
p = -8151934197605472e-29 + p * w;
|
|
40825
|
+
p = 26335093153082323e-28 + p * w;
|
|
40826
|
+
p = -12975133253453532e-27 + p * w;
|
|
40827
|
+
p = -5415412054294628e-26 + p * w;
|
|
40828
|
+
p = 10512122733215323e-25 + p * w;
|
|
40829
|
+
p = -4112633980346984e-24 + p * w;
|
|
40830
|
+
p = -29070369957882005e-24 + p * w;
|
|
40831
|
+
p = 42347877827932404e-23 + p * w;
|
|
40832
|
+
p = -13654692000834679e-22 + p * w;
|
|
40833
|
+
p = -13882523362786469e-21 + p * w;
|
|
40834
|
+
p = 18673420803405714e-20 + p * w;
|
|
40835
|
+
p = -740702534166267e-18 + p * w;
|
|
40836
|
+
p = -0.006033670871430149 + p * w;
|
|
40837
|
+
p = 0.24015818242558962 + p * w;
|
|
40838
|
+
p = 1.6536545626831027 + p * w;
|
|
40839
|
+
} else if (w < 16) {
|
|
40840
|
+
w = Math.sqrt(w) - 3.25;
|
|
40841
|
+
p = 22137376921775787e-25;
|
|
40842
|
+
p = 9075656193888539e-23 + p * w;
|
|
40843
|
+
p = -27517406297064545e-23 + p * w;
|
|
40844
|
+
p = 18239629214389228e-24 + p * w;
|
|
40845
|
+
p = 15027403968909828e-22 + p * w;
|
|
40846
|
+
p = -4013867526981546e-21 + p * w;
|
|
40847
|
+
p = 29234449089955446e-22 + p * w;
|
|
40848
|
+
p = 12475304481671779e-21 + p * w;
|
|
40849
|
+
p = -47318229009055734e-21 + p * w;
|
|
40850
|
+
p = 6828485145957318e-20 + p * w;
|
|
40851
|
+
p = 24031110387097894e-21 + p * w;
|
|
40852
|
+
p = -3550375203628475e-19 + p * w;
|
|
40853
|
+
p = 9532893797373805e-19 + p * w;
|
|
40854
|
+
p = -0.0016882755560235047 + p * w;
|
|
40855
|
+
p = 0.002491442096107851 + p * w;
|
|
40856
|
+
p = -0.003751208507569241 + p * w;
|
|
40857
|
+
p = 0.005370914553590064 + p * w;
|
|
40858
|
+
p = 1.0052589676941592 + p * w;
|
|
40859
|
+
p = 3.0838856104922208 + p * w;
|
|
40860
|
+
} else if (Number.isFinite(w)) {
|
|
40861
|
+
w = Math.sqrt(w) - 5;
|
|
40862
|
+
p = -27109920616438573e-27;
|
|
40863
|
+
p = -2555641816996525e-25 + p * w;
|
|
40864
|
+
p = 15076572693500548e-25 + p * w;
|
|
40865
|
+
p = -3789465440126737e-24 + p * w;
|
|
40866
|
+
p = 761570120807834e-23 + p * w;
|
|
40867
|
+
p = -1496002662714924e-23 + p * w;
|
|
40868
|
+
p = 2914795345090108e-23 + p * w;
|
|
40869
|
+
p = -6771199775845234e-23 + p * w;
|
|
40870
|
+
p = 22900482228026655e-23 + p * w;
|
|
40871
|
+
p = -99298272942317e-20 + p * w;
|
|
40872
|
+
p = 4526062597223154e-21 + p * w;
|
|
40873
|
+
p = -1968177810553167e-20 + p * w;
|
|
40874
|
+
p = 7599527703001776e-20 + p * w;
|
|
40875
|
+
p = -21503011930044477e-20 + p * w;
|
|
40876
|
+
p = -13871931833623122e-20 + p * w;
|
|
40877
|
+
p = 1.0103004648645344 + p * w;
|
|
40878
|
+
p = 4.849906401408584 + p * w;
|
|
40879
|
+
} else {
|
|
40880
|
+
p = Infinity;
|
|
40881
|
+
}
|
|
40882
|
+
return p * x3;
|
|
40883
|
+
}
|
|
40884
|
+
|
|
40885
|
+
// src/marks/ErrorBarMark.js
|
|
40886
|
+
var ErrorBarMark = class extends Mark2 {
|
|
40887
|
+
constructor(type2, source, options) {
|
|
40888
|
+
const dim = type2.endsWith("X") ? "y" : "x";
|
|
40889
|
+
const { ci = 0.95, ...channels } = options;
|
|
40890
|
+
super(type2, source, channels);
|
|
40891
|
+
this.dim = dim;
|
|
40892
|
+
this.field = this.channelField(dim).field;
|
|
40893
|
+
this.channels = this.channels.filter((c4) => c4.channel !== dim);
|
|
40894
|
+
this.ci = handleParam(ci, (value) => {
|
|
40895
|
+
return this.ci = value, this.update();
|
|
40896
|
+
});
|
|
40897
|
+
}
|
|
40898
|
+
query(filter3 = []) {
|
|
40899
|
+
const { channels, field: field2, source: { table } } = this;
|
|
40900
|
+
const fields = channels.concat([
|
|
40901
|
+
{ field: avg(field2), as: "__avg__" },
|
|
40902
|
+
{ field: count(field2), as: "__n__" },
|
|
40903
|
+
{ field: stddev(field2), as: "__sd__" }
|
|
40904
|
+
]);
|
|
40905
|
+
return markQuery(fields, table).where(filter3);
|
|
40906
|
+
}
|
|
40907
|
+
queryResult(data) {
|
|
40908
|
+
this.data = toDataColumns(data);
|
|
40909
|
+
return this;
|
|
40910
|
+
}
|
|
40911
|
+
plotSpecs() {
|
|
40912
|
+
const { type: type2, dim, detail, data, ci, channels } = this;
|
|
40913
|
+
const p = Math.SQRT2 * erfinv(ci);
|
|
40914
|
+
const { columns: { __avg__: u4, __sd__: s2, __n__: n } } = data;
|
|
40915
|
+
const options = {
|
|
40916
|
+
[`${dim}1`]: u4.map((u5, i) => u5 - p * s2[i] / Math.sqrt(n[i])),
|
|
40917
|
+
[`${dim}2`]: u4.map((u5, i) => u5 + p * s2[i] / Math.sqrt(n[i]))
|
|
40918
|
+
};
|
|
40919
|
+
return markPlotSpec(type2, detail, channels, data, options);
|
|
40920
|
+
}
|
|
40921
|
+
};
|
|
40922
|
+
|
|
40212
40923
|
// src/marks/GeoMark.js
|
|
40213
40924
|
var DEFAULT_GEOMETRY_COLUMN = "geom";
|
|
40214
40925
|
var GeoMark = class extends Mark2 {
|
|
@@ -40248,50 +40959,48 @@ var HexbinMark = class extends Mark2 {
|
|
|
40248
40959
|
query(filter3 = []) {
|
|
40249
40960
|
if (this.hasOwnData()) return null;
|
|
40250
40961
|
const { plot: plot2, binWidth, channels, source } = this;
|
|
40251
|
-
const [x12, x22] = extentX(this, filter3);
|
|
40252
|
-
const [y12, y22] = extentY(this, filter3);
|
|
40253
|
-
const ox2 = 0.5 - plot2.getAttribute("marginLeft");
|
|
40254
|
-
const oy2 = 0 - plot2.getAttribute("marginTop");
|
|
40255
|
-
const dx = `${binWidth}::DOUBLE`;
|
|
40256
|
-
const dy = `${binWidth * (1.5 / Math.sqrt(3))}::DOUBLE`;
|
|
40257
|
-
const xr = `${plot2.innerWidth() / (x22 - x12)}::DOUBLE`;
|
|
40258
|
-
const yr = `${plot2.innerHeight() / (y22 - y12)}::DOUBLE`;
|
|
40259
40962
|
let x3, y3;
|
|
40260
|
-
const
|
|
40963
|
+
const dims = /* @__PURE__ */ new Set();
|
|
40261
40964
|
const cols = {};
|
|
40262
|
-
let orderby;
|
|
40263
40965
|
for (const c4 of channels) {
|
|
40264
40966
|
if (c4.channel === "orderby") {
|
|
40265
|
-
orderby = c4.value;
|
|
40266
40967
|
} else if (c4.channel === "x") {
|
|
40267
40968
|
x3 = c4;
|
|
40268
40969
|
} else if (c4.channel === "y") {
|
|
40269
40970
|
y3 = c4;
|
|
40270
40971
|
} else if (Object.hasOwn(c4, "field")) {
|
|
40271
|
-
|
|
40272
|
-
|
|
40273
|
-
|
|
40972
|
+
const { as, field: field2 } = c4;
|
|
40973
|
+
cols[as] = field2;
|
|
40974
|
+
if (!field2.aggregate) {
|
|
40975
|
+
dims.add(as);
|
|
40274
40976
|
}
|
|
40275
40977
|
}
|
|
40276
40978
|
}
|
|
40277
|
-
const
|
|
40278
|
-
|
|
40279
|
-
|
|
40979
|
+
const [x12, x22] = extentX(this, filter3);
|
|
40980
|
+
const [y12, y22] = extentY(this, filter3);
|
|
40981
|
+
const ox2 = 0.5 - plot2.getAttribute("marginLeft");
|
|
40982
|
+
const oy2 = 0 - plot2.getAttribute("marginTop");
|
|
40983
|
+
const dx = `${binWidth}::DOUBLE`;
|
|
40984
|
+
const dy = `${binWidth * (1.5 / Math.sqrt(3))}::DOUBLE`;
|
|
40985
|
+
const xr = `${plot2.innerWidth() / (x22 - x12)}::DOUBLE`;
|
|
40986
|
+
const yr = `${plot2.innerHeight() / (y22 - y12)}::DOUBLE`;
|
|
40987
|
+
return Query.select({
|
|
40988
|
+
[x3.as]: sql`${x12}::DOUBLE + ((_x + 0.5 * (_y & 1)) * ${dx} + ${ox2})::DOUBLE / ${xr}`,
|
|
40989
|
+
[y3.as]: sql`${y22}::DOUBLE - (_y * ${dy} + ${oy2})::DOUBLE / ${yr}`,
|
|
40280
40990
|
...cols
|
|
40281
|
-
}).groupby("
|
|
40282
|
-
|
|
40283
|
-
|
|
40284
|
-
|
|
40285
|
-
|
|
40286
|
-
|
|
40287
|
-
|
|
40288
|
-
|
|
40289
|
-
|
|
40290
|
-
|
|
40291
|
-
|
|
40292
|
-
|
|
40293
|
-
|
|
40294
|
-
return q.from(hex2);
|
|
40991
|
+
}).groupby("_x", "_y", ...dims).from(
|
|
40992
|
+
// Subquery performs hex binning in screen space and also passes
|
|
40993
|
+
// original columns through (the DB should optimize this).
|
|
40994
|
+
Query.select({
|
|
40995
|
+
_py: sql`(${yr} * (${y22}::DOUBLE - ${y3.field}) - ${oy2}) / ${dy}`,
|
|
40996
|
+
_pj: sql`ROUND(_py)::INTEGER`,
|
|
40997
|
+
_px: sql`(${xr} * (${x3.field} - ${x12}::DOUBLE) - ${ox2}) / ${dx} - 0.5 * (_pj & 1)`,
|
|
40998
|
+
_pi: sql`ROUND(_px)::INTEGER`,
|
|
40999
|
+
_tt: sql`ABS(_py-_pj) * 3 > 1 AND (_px-_pi)**2 + (_py-_pj)**2 > (_px - _pi - 0.5 * CASE WHEN _px < _pi THEN -1 ELSE 1 END)**2 + (_py - _pj - CASE WHEN _py < _pj THEN -1 ELSE 1 END)**2`,
|
|
41000
|
+
_x: sql`CASE WHEN _tt THEN (_pi + (CASE WHEN _px < _pi THEN -0.5 ELSE 0.5 END) + (CASE WHEN _pj & 1 <> 0 THEN 0.5 ELSE -0.5 END))::INTEGER ELSE _pi END`,
|
|
41001
|
+
_y: sql`CASE WHEN _tt THEN (_pj + CASE WHEN _py < _pj THEN -1 ELSE 1 END)::INTEGER ELSE _pj END`
|
|
41002
|
+
}, "*").from(source.table).where(isNotNull(x3.field), isNotNull(y3.field), filter3)
|
|
41003
|
+
);
|
|
40295
41004
|
}
|
|
40296
41005
|
};
|
|
40297
41006
|
|
|
@@ -40428,12 +41137,13 @@ var RasterTileMark = class extends Grid2DMark {
|
|
|
40428
41137
|
const { alpha, alphaProp, color: color3, colorProp } = rasterEncoding(this);
|
|
40429
41138
|
const alphaData = columns[alphaProp] ?? [];
|
|
40430
41139
|
const colorData = columns[colorProp] ?? [];
|
|
41140
|
+
const idx = numRows > 1 && colorProp && this.groupby?.includes(colorProp) ? permute2(colorData, this.plot.getAttribute("colorDomain")) : indices(numRows);
|
|
40431
41141
|
this.data = {
|
|
40432
41142
|
numRows,
|
|
40433
41143
|
columns: {
|
|
40434
41144
|
src: Array.from({ length: numRows }, (_, i) => {
|
|
40435
|
-
color3?.(img.data, w, h, colorData[i]);
|
|
40436
|
-
alpha?.(img.data, w, h, alphaData[i]);
|
|
41145
|
+
color3?.(img.data, w, h, colorData[idx[i]]);
|
|
41146
|
+
alpha?.(img.data, w, h, alphaData[idx[i]]);
|
|
40437
41147
|
ctx.putImageData(img, 0, 0);
|
|
40438
41148
|
return canvas.toDataURL();
|
|
40439
41149
|
})
|
|
@@ -40519,109 +41229,6 @@ function tileFloor(value) {
|
|
|
40519
41229
|
return floored === value ? floored - 1 : floored;
|
|
40520
41230
|
}
|
|
40521
41231
|
|
|
40522
|
-
// src/marks/util/stats.js
|
|
40523
|
-
function ibetainv2(p, a2, b) {
|
|
40524
|
-
var EPS2 = 1e-8;
|
|
40525
|
-
var a1 = a2 - 1;
|
|
40526
|
-
var b1 = b - 1;
|
|
40527
|
-
var j = 0;
|
|
40528
|
-
var lna, lnb, pp, t, u4, err, x3, al, h, w, afac;
|
|
40529
|
-
if (p <= 0) return 0;
|
|
40530
|
-
if (p >= 1) return 1;
|
|
40531
|
-
if (a2 >= 1 && b >= 1) {
|
|
40532
|
-
pp = p < 0.5 ? p : 1 - p;
|
|
40533
|
-
t = Math.sqrt(-2 * Math.log(pp));
|
|
40534
|
-
x3 = (2.30753 + t * 0.27061) / (1 + t * (0.99229 + t * 0.04481)) - t;
|
|
40535
|
-
if (p < 0.5) x3 = -x3;
|
|
40536
|
-
al = (x3 * x3 - 3) / 6;
|
|
40537
|
-
h = 2 / (1 / (2 * a2 - 1) + 1 / (2 * b - 1));
|
|
40538
|
-
w = x3 * Math.sqrt(al + h) / h - (1 / (2 * b - 1) - 1 / (2 * a2 - 1)) * (al + 5 / 6 - 2 / (3 * h));
|
|
40539
|
-
x3 = a2 / (a2 + b * Math.exp(2 * w));
|
|
40540
|
-
} else {
|
|
40541
|
-
lna = Math.log(a2 / (a2 + b));
|
|
40542
|
-
lnb = Math.log(b / (a2 + b));
|
|
40543
|
-
t = Math.exp(a2 * lna) / a2;
|
|
40544
|
-
u4 = Math.exp(b * lnb) / b;
|
|
40545
|
-
w = t + u4;
|
|
40546
|
-
if (p < t / w) x3 = Math.pow(a2 * w * p, 1 / a2);
|
|
40547
|
-
else x3 = 1 - Math.pow(b * w * (1 - p), 1 / b);
|
|
40548
|
-
}
|
|
40549
|
-
afac = -gammaln2(a2) - gammaln2(b) + gammaln2(a2 + b);
|
|
40550
|
-
for (; j < 10; j++) {
|
|
40551
|
-
if (x3 === 0 || x3 === 1) return x3;
|
|
40552
|
-
err = ibeta2(x3, a2, b) - p;
|
|
40553
|
-
t = Math.exp(a1 * Math.log(x3) + b1 * Math.log(1 - x3) + afac);
|
|
40554
|
-
u4 = err / t;
|
|
40555
|
-
x3 -= t = u4 / (1 - 0.5 * Math.min(1, u4 * (a1 / x3 - b1 / (1 - x3))));
|
|
40556
|
-
if (x3 <= 0) x3 = 0.5 * (x3 + t);
|
|
40557
|
-
if (x3 >= 1) x3 = 0.5 * (x3 + t + 1);
|
|
40558
|
-
if (Math.abs(t) < EPS2 * x3 && j > 0) break;
|
|
40559
|
-
}
|
|
40560
|
-
return x3;
|
|
40561
|
-
}
|
|
40562
|
-
function ibeta2(x3, a2, b) {
|
|
40563
|
-
var bt = x3 === 0 || x3 === 1 ? 0 : Math.exp(gammaln2(a2 + b) - gammaln2(a2) - gammaln2(b) + a2 * Math.log(x3) + b * Math.log(1 - x3));
|
|
40564
|
-
if (x3 < 0 || x3 > 1) return 0;
|
|
40565
|
-
if (x3 < (a2 + 1) / (a2 + b + 2))
|
|
40566
|
-
return bt * betacf2(x3, a2, b) / a2;
|
|
40567
|
-
return 1 - bt * betacf2(1 - x3, b, a2) / b;
|
|
40568
|
-
}
|
|
40569
|
-
function betacf2(x3, a2, b) {
|
|
40570
|
-
var fpmin = 1e-30;
|
|
40571
|
-
var m = 1;
|
|
40572
|
-
var qab = a2 + b;
|
|
40573
|
-
var qap = a2 + 1;
|
|
40574
|
-
var qam = a2 - 1;
|
|
40575
|
-
var c4 = 1;
|
|
40576
|
-
var d = 1 - qab * x3 / qap;
|
|
40577
|
-
var m2, aa2, del, h;
|
|
40578
|
-
if (Math.abs(d) < fpmin) d = fpmin;
|
|
40579
|
-
d = 1 / d;
|
|
40580
|
-
h = d;
|
|
40581
|
-
for (; m <= 100; m++) {
|
|
40582
|
-
m2 = 2 * m;
|
|
40583
|
-
aa2 = m * (b - m) * x3 / ((qam + m2) * (a2 + m2));
|
|
40584
|
-
d = 1 + aa2 * d;
|
|
40585
|
-
if (Math.abs(d) < fpmin) d = fpmin;
|
|
40586
|
-
c4 = 1 + aa2 / c4;
|
|
40587
|
-
if (Math.abs(c4) < fpmin) c4 = fpmin;
|
|
40588
|
-
d = 1 / d;
|
|
40589
|
-
h *= d * c4;
|
|
40590
|
-
aa2 = -(a2 + m) * (qab + m) * x3 / ((a2 + m2) * (qap + m2));
|
|
40591
|
-
d = 1 + aa2 * d;
|
|
40592
|
-
if (Math.abs(d) < fpmin) d = fpmin;
|
|
40593
|
-
c4 = 1 + aa2 / c4;
|
|
40594
|
-
if (Math.abs(c4) < fpmin) c4 = fpmin;
|
|
40595
|
-
d = 1 / d;
|
|
40596
|
-
del = d * c4;
|
|
40597
|
-
h *= del;
|
|
40598
|
-
if (Math.abs(del - 1) < 3e-7) break;
|
|
40599
|
-
}
|
|
40600
|
-
return h;
|
|
40601
|
-
}
|
|
40602
|
-
function gammaln2(x3) {
|
|
40603
|
-
var j = 0;
|
|
40604
|
-
var cof = [
|
|
40605
|
-
76.18009172947146,
|
|
40606
|
-
-86.5053203294167,
|
|
40607
|
-
24.01409824083091,
|
|
40608
|
-
-1.231739572450155,
|
|
40609
|
-
0.001208650973866179,
|
|
40610
|
-
-5395239384953e-18
|
|
40611
|
-
];
|
|
40612
|
-
var ser = 1.000000000190015;
|
|
40613
|
-
var xx, y3, tmp2;
|
|
40614
|
-
tmp2 = (y3 = xx = x3) + 5.5;
|
|
40615
|
-
tmp2 -= (xx + 0.5) * Math.log(tmp2);
|
|
40616
|
-
for (; j < 6; j++) ser += cof[j] / ++y3;
|
|
40617
|
-
return Math.log(2.506628274631 * ser / xx) - tmp2;
|
|
40618
|
-
}
|
|
40619
|
-
function qt2(p, dof) {
|
|
40620
|
-
var x3 = ibetainv2(2 * Math.min(p, 1 - p), 0.5 * dof, 0.5);
|
|
40621
|
-
x3 = Math.sqrt(dof * (1 - x3) / x3);
|
|
40622
|
-
return p > 0.5 ? x3 : -x3;
|
|
40623
|
-
}
|
|
40624
|
-
|
|
40625
41232
|
// src/marks/RegressionMark.js
|
|
40626
41233
|
var RegressionMark = class extends Mark2 {
|
|
40627
41234
|
constructor(source, options) {
|
|
@@ -40708,7 +41315,7 @@ function concat(a2, b) {
|
|
|
40708
41315
|
return array4;
|
|
40709
41316
|
}
|
|
40710
41317
|
function linePoints(fit2) {
|
|
40711
|
-
const { x0: x06, x1: x12, xm, intercept, slope, n, ssx, ssy, ...rest } = fit2.columns;
|
|
41318
|
+
const { x0: x06 = [], x1: x12 = [], xm, intercept, slope, n, ssx, ssy, ...rest } = fit2.columns;
|
|
40712
41319
|
const predict = (x4, i) => intercept[i] + x4 * slope[i];
|
|
40713
41320
|
const x3 = concat(x06, x12);
|
|
40714
41321
|
const y3 = concat(x06.map(predict), x12.map(predict));
|
|
@@ -40812,7 +41419,8 @@ var Highlight = class {
|
|
|
40812
41419
|
for (let i = 0; i < nodes.length; ++i) {
|
|
40813
41420
|
const node = nodes[i];
|
|
40814
41421
|
const base = values2[i];
|
|
40815
|
-
const
|
|
41422
|
+
const data = node.__data__;
|
|
41423
|
+
const t = test(Array.isArray(data) ? data[0] : data);
|
|
40816
41424
|
for (let j = 0; j < channels.length; ++j) {
|
|
40817
41425
|
const [attr, value] = channels[j];
|
|
40818
41426
|
node.setAttribute(attr, t ? base[j] : value);
|
|
@@ -40828,8 +41436,10 @@ async function predicateFunction(mark, selection2) {
|
|
|
40828
41436
|
const filter3 = mark.filterBy?.predicate(mark, true);
|
|
40829
41437
|
const s2 = { __: and(pred) };
|
|
40830
41438
|
const q = mark.query(filter3);
|
|
40831
|
-
|
|
40832
|
-
|
|
41439
|
+
(q.queries || [q]).forEach((q2) => {
|
|
41440
|
+
q2.groupby().length ? q2.select(s2) : q2.$select(s2);
|
|
41441
|
+
});
|
|
41442
|
+
const data = await mark.coordinator.query(q);
|
|
40833
41443
|
const v2 = data.getChild?.("__");
|
|
40834
41444
|
return !(data.numRows || data.length) ? () => false : v2 ? (i) => v2.get(i) : (i) => data[i].__;
|
|
40835
41445
|
}
|
|
@@ -40935,13 +41545,12 @@ var Interval1D = class {
|
|
|
40935
41545
|
}
|
|
40936
41546
|
clause(value) {
|
|
40937
41547
|
const { mark, pixelSize, field: field2, scale: scale3 } = this;
|
|
40938
|
-
return {
|
|
41548
|
+
return clauseInterval(field2, value, {
|
|
40939
41549
|
source: this,
|
|
40940
|
-
schema: { type: "interval", pixelSize, scales: [scale3] },
|
|
40941
41550
|
clients: this.peers ? mark.plot.markSet : (/* @__PURE__ */ new Set()).add(mark),
|
|
40942
|
-
|
|
40943
|
-
|
|
40944
|
-
};
|
|
41551
|
+
scale: scale3,
|
|
41552
|
+
pixelSize
|
|
41553
|
+
});
|
|
40945
41554
|
}
|
|
40946
41555
|
init(svg, root2) {
|
|
40947
41556
|
const { brush: brush3, channel, style } = this;
|
|
@@ -40949,9 +41558,10 @@ var Interval1D = class {
|
|
|
40949
41558
|
const rx = svg.scale("x").range;
|
|
40950
41559
|
const ry = svg.scale("y").range;
|
|
40951
41560
|
brush3.extent([[min2(rx), min2(ry)], [max2(rx), max2(ry)]]);
|
|
41561
|
+
const range3 = this.value?.map(this.scale.apply).sort(ascending);
|
|
40952
41562
|
const facets = select_default2(svg).selectAll('g[aria-label="facet"]');
|
|
40953
41563
|
root2 = facets.size() ? facets : select_default2(root2 ?? svg);
|
|
40954
|
-
this.g = root2.append("g").attr("class", `interval-${channel}`).each(patchScreenCTM).call(brush3).call(brush3.moveSilent,
|
|
41564
|
+
this.g = root2.append("g").attr("class", `interval-${channel}`).each(patchScreenCTM).call(brush3).call(brush3.moveSilent, range3);
|
|
40955
41565
|
if (style) {
|
|
40956
41566
|
const brushes = this.g.selectAll("rect.selection");
|
|
40957
41567
|
for (const name in style) {
|
|
@@ -40965,7 +41575,6 @@ var Interval1D = class {
|
|
|
40965
41575
|
};
|
|
40966
41576
|
|
|
40967
41577
|
// src/interactors/Interval2D.js
|
|
40968
|
-
var asc = (a2, b) => a2 - b;
|
|
40969
41578
|
var Interval2D = class {
|
|
40970
41579
|
constructor(mark, {
|
|
40971
41580
|
selection: selection2,
|
|
@@ -40998,8 +41607,8 @@ var Interval2D = class {
|
|
|
40998
41607
|
let yr = void 0;
|
|
40999
41608
|
if (extent4) {
|
|
41000
41609
|
const [a2, b] = extent4;
|
|
41001
|
-
xr = [a2[0], b[0]].map((v2) => invert(v2, xscale, pixelSize)).sort(
|
|
41002
|
-
yr = [a2[1], b[1]].map((v2) => invert(v2, yscale, pixelSize)).sort(
|
|
41610
|
+
xr = [a2[0], b[0]].map((v2) => invert(v2, xscale, pixelSize)).sort(ascending);
|
|
41611
|
+
yr = [a2[1], b[1]].map((v2) => invert(v2, yscale, pixelSize)).sort(ascending);
|
|
41003
41612
|
}
|
|
41004
41613
|
if (!closeTo(xr, value?.[0]) || !closeTo(yr, value?.[1])) {
|
|
41005
41614
|
this.value = extent4 ? [xr, yr] : void 0;
|
|
@@ -41009,13 +41618,12 @@ var Interval2D = class {
|
|
|
41009
41618
|
}
|
|
41010
41619
|
clause(value) {
|
|
41011
41620
|
const { mark, pixelSize, xfield, yfield, xscale, yscale } = this;
|
|
41012
|
-
return {
|
|
41621
|
+
return clauseIntervals([xfield, yfield], value, {
|
|
41013
41622
|
source: this,
|
|
41014
|
-
schema: { type: "interval", pixelSize, scales: [xscale, yscale] },
|
|
41015
41623
|
clients: this.peers ? mark.plot.markSet : (/* @__PURE__ */ new Set()).add(mark),
|
|
41016
|
-
|
|
41017
|
-
|
|
41018
|
-
};
|
|
41624
|
+
scales: [xscale, yscale],
|
|
41625
|
+
pixelSize
|
|
41626
|
+
});
|
|
41019
41627
|
}
|
|
41020
41628
|
init(svg) {
|
|
41021
41629
|
const { brush: brush3, style } = this;
|
|
@@ -41034,8 +41642,8 @@ var Interval2D = class {
|
|
|
41034
41642
|
}
|
|
41035
41643
|
}
|
|
41036
41644
|
if (this.value) {
|
|
41037
|
-
const [x12, x22] = this.value[0].map(xscale.apply).sort(
|
|
41038
|
-
const [y12, y22] = this.value[1].map(yscale.apply).sort(
|
|
41645
|
+
const [x12, x22] = this.value[0].map(xscale.apply).sort(ascending);
|
|
41646
|
+
const [y12, y22] = this.value[1].map(yscale.apply).sort(ascending);
|
|
41039
41647
|
this.g.call(brush3.moveSilent, [[x12, y12], [x22, y22]]);
|
|
41040
41648
|
}
|
|
41041
41649
|
svg.addEventListener("pointerenter", (evt) => {
|
|
@@ -41048,61 +41656,83 @@ var Interval2D = class {
|
|
|
41048
41656
|
var Nearest = class {
|
|
41049
41657
|
constructor(mark, {
|
|
41050
41658
|
selection: selection2,
|
|
41051
|
-
|
|
41052
|
-
|
|
41659
|
+
pointer: pointer2,
|
|
41660
|
+
channels,
|
|
41661
|
+
fields,
|
|
41662
|
+
maxRadius = 40
|
|
41053
41663
|
}) {
|
|
41054
41664
|
this.mark = mark;
|
|
41055
41665
|
this.selection = selection2;
|
|
41056
41666
|
this.clients = (/* @__PURE__ */ new Set()).add(mark);
|
|
41057
|
-
this.
|
|
41058
|
-
this.
|
|
41667
|
+
this.pointer = pointer2;
|
|
41668
|
+
this.channels = channels || (pointer2 === "x" ? ["x"] : pointer2 === "y" ? ["y"] : ["x", "y"]);
|
|
41669
|
+
this.fields = fields || this.channels.map((c4) => getField(mark, [c4]));
|
|
41670
|
+
this.maxRadius = maxRadius;
|
|
41671
|
+
this.valueIndex = -1;
|
|
41059
41672
|
}
|
|
41060
41673
|
clause(value) {
|
|
41061
|
-
const { clients,
|
|
41062
|
-
|
|
41063
|
-
return {
|
|
41674
|
+
const { clients, fields } = this;
|
|
41675
|
+
return clausePoints(fields, value ? [value] : value, {
|
|
41064
41676
|
source: this,
|
|
41065
|
-
|
|
41066
|
-
|
|
41067
|
-
value,
|
|
41068
|
-
predicate
|
|
41069
|
-
};
|
|
41677
|
+
clients
|
|
41678
|
+
});
|
|
41070
41679
|
}
|
|
41071
41680
|
init(svg) {
|
|
41072
41681
|
const that = this;
|
|
41073
|
-
const { mark,
|
|
41074
|
-
const { data } = mark;
|
|
41075
|
-
const
|
|
41682
|
+
const { mark, channels, selection: selection2, maxRadius } = this;
|
|
41683
|
+
const { data: { columns } } = mark;
|
|
41684
|
+
const keys = channels.map((c4) => mark.channelField(c4).as);
|
|
41685
|
+
const param = !isSelection(selection2);
|
|
41076
41686
|
const facets = select_default2(svg).selectAll('g[aria-label="facet"]');
|
|
41077
41687
|
const root2 = facets.size() ? facets : select_default2(svg);
|
|
41078
|
-
const
|
|
41079
|
-
const
|
|
41080
|
-
|
|
41081
|
-
|
|
41082
|
-
|
|
41083
|
-
|
|
41688
|
+
const xscale = svg.scale("x").apply;
|
|
41689
|
+
const yscale = svg.scale("y").apply;
|
|
41690
|
+
const X3 = Array.from(columns[mark.channelField("x").as], xscale);
|
|
41691
|
+
const Y3 = Array.from(columns[mark.channelField("y").as], yscale);
|
|
41692
|
+
const sx = this.pointer === "y" ? 0.01 : 1;
|
|
41693
|
+
const sy = this.pointer === "x" ? 0.01 : 1;
|
|
41694
|
+
root2.on("pointerenter pointerdown pointermove", function(evt) {
|
|
41695
|
+
const [px, py] = pointer_default(evt, this);
|
|
41696
|
+
const i = findNearest(X3, Y3, px, py, sx, sy, maxRadius);
|
|
41697
|
+
if (i !== this.valueIndex) {
|
|
41698
|
+
this.valueIndex = i;
|
|
41699
|
+
const v2 = i < 0 ? void 0 : keys.map((k2) => columns[k2][i]);
|
|
41700
|
+
if (param) {
|
|
41701
|
+
if (i > -1) selection2.update(v2.length > 1 ? v2 : v2[0]);
|
|
41702
|
+
} else {
|
|
41703
|
+
selection2.update(that.clause(v2));
|
|
41704
|
+
}
|
|
41705
|
+
}
|
|
41084
41706
|
});
|
|
41085
41707
|
if (param) return;
|
|
41708
|
+
root2.on("pointerleave", () => {
|
|
41709
|
+
selection2.update(that.clause(void 0));
|
|
41710
|
+
});
|
|
41086
41711
|
svg.addEventListener("pointerenter", (evt) => {
|
|
41087
|
-
if (!evt.buttons)
|
|
41712
|
+
if (!evt.buttons) {
|
|
41713
|
+
const v2 = this.channels.map(() => 0);
|
|
41714
|
+
selection2.activate(this.clause(v2));
|
|
41715
|
+
}
|
|
41088
41716
|
});
|
|
41089
41717
|
}
|
|
41090
41718
|
};
|
|
41091
|
-
function findNearest(
|
|
41092
|
-
let dist2 =
|
|
41093
|
-
let nearest;
|
|
41094
|
-
for (let i = 0; i <
|
|
41095
|
-
const
|
|
41096
|
-
|
|
41097
|
-
|
|
41098
|
-
|
|
41719
|
+
function findNearest(x3, y3, px, py, sx, sy, maxRadius) {
|
|
41720
|
+
let dist2 = maxRadius * maxRadius;
|
|
41721
|
+
let nearest = -1;
|
|
41722
|
+
for (let i = 0; i < x3.length; ++i) {
|
|
41723
|
+
const dx = sx * (x3[i] - px);
|
|
41724
|
+
const dy = sy * (y3[i] - py);
|
|
41725
|
+
const dd = dx * dx + dy * dy;
|
|
41726
|
+
if (dd <= dist2) {
|
|
41727
|
+
dist2 = dd;
|
|
41728
|
+
nearest = i;
|
|
41099
41729
|
}
|
|
41100
41730
|
}
|
|
41101
41731
|
return nearest;
|
|
41102
41732
|
}
|
|
41103
41733
|
|
|
41104
41734
|
// src/interactors/PanZoom.js
|
|
41105
|
-
var
|
|
41735
|
+
var asc = (a2, b) => a2 - b;
|
|
41106
41736
|
var PanZoom = class {
|
|
41107
41737
|
constructor(mark, {
|
|
41108
41738
|
x: x3 = new Selection(),
|
|
@@ -41144,13 +41774,11 @@ var PanZoom = class {
|
|
|
41144
41774
|
}
|
|
41145
41775
|
}
|
|
41146
41776
|
clause(value, field2, scale3) {
|
|
41147
|
-
return {
|
|
41777
|
+
return clauseInterval(field2, value, {
|
|
41148
41778
|
source: this,
|
|
41149
|
-
schema: { type: "interval", scales: [scale3] },
|
|
41150
41779
|
clients: this.mark.plot.markSet,
|
|
41151
|
-
|
|
41152
|
-
|
|
41153
|
-
};
|
|
41780
|
+
scale: scale3
|
|
41781
|
+
});
|
|
41154
41782
|
}
|
|
41155
41783
|
init(svg) {
|
|
41156
41784
|
this.svg = svg;
|
|
@@ -41159,8 +41787,8 @@ var PanZoom = class {
|
|
|
41159
41787
|
const { panx, pany, mark: { plot: { element } }, xsel, ysel } = this;
|
|
41160
41788
|
this.xscale = svg.scale("x");
|
|
41161
41789
|
this.yscale = svg.scale("y");
|
|
41162
|
-
const rx = this.xscale.range.slice().sort(
|
|
41163
|
-
const ry = this.yscale.range.slice().sort(
|
|
41790
|
+
const rx = this.xscale.range.slice().sort(asc);
|
|
41791
|
+
const ry = this.yscale.range.slice().sort(asc);
|
|
41164
41792
|
const tx = extent3(panx, [-Infinity, Infinity], rx);
|
|
41165
41793
|
const ty = extent3(pany, [-Infinity, Infinity], ry);
|
|
41166
41794
|
const z = zoom_default2().extent([[rx[0], ry[0]], [rx[1], ry[1]]]).scaleExtent(this.zoom).translateExtent([[tx[0], ty[0]], [tx[1], ty[1]]]).on("start", () => {
|
|
@@ -41212,42 +41840,35 @@ var Toggle = class {
|
|
|
41212
41840
|
this.mark = mark;
|
|
41213
41841
|
this.selection = selection2;
|
|
41214
41842
|
this.peers = peers;
|
|
41215
|
-
|
|
41843
|
+
const fields = this.fields = [];
|
|
41844
|
+
const as = this.as = [];
|
|
41845
|
+
channels.forEach((c4) => {
|
|
41216
41846
|
const q = c4 === "color" ? ["color", "fill", "stroke"] : c4 === "x" ? ["x", "x1", "x2"] : c4 === "y" ? ["y", "y1", "y2"] : [c4];
|
|
41217
41847
|
for (let i = 0; i < q.length; ++i) {
|
|
41218
41848
|
const f = mark.channelField(q[i], { exact: true });
|
|
41219
|
-
if (f)
|
|
41220
|
-
|
|
41221
|
-
as
|
|
41222
|
-
|
|
41849
|
+
if (f) {
|
|
41850
|
+
fields.push(f.field?.basis || f.field);
|
|
41851
|
+
as.push(f.as);
|
|
41852
|
+
return;
|
|
41853
|
+
}
|
|
41223
41854
|
}
|
|
41224
41855
|
throw new Error(`Missing channel: ${c4}`);
|
|
41225
41856
|
});
|
|
41226
41857
|
}
|
|
41227
41858
|
clause(value) {
|
|
41228
|
-
const {
|
|
41229
|
-
|
|
41230
|
-
if (value) {
|
|
41231
|
-
const clauses = value.map((vals) => {
|
|
41232
|
-
const list = vals.map((v2, i) => {
|
|
41233
|
-
return isNotDistinct(channels[i].field, literal(v2));
|
|
41234
|
-
});
|
|
41235
|
-
return list.length > 1 ? and(list) : list[0];
|
|
41236
|
-
});
|
|
41237
|
-
predicate = clauses.length > 1 ? or(clauses) : clauses[0];
|
|
41238
|
-
}
|
|
41239
|
-
return {
|
|
41859
|
+
const { fields, mark } = this;
|
|
41860
|
+
return clausePoints(fields, value, {
|
|
41240
41861
|
source: this,
|
|
41241
|
-
|
|
41242
|
-
|
|
41243
|
-
value,
|
|
41244
|
-
predicate
|
|
41245
|
-
};
|
|
41862
|
+
clients: this.peers ? mark.plot.markSet : (/* @__PURE__ */ new Set()).add(mark)
|
|
41863
|
+
});
|
|
41246
41864
|
}
|
|
41247
41865
|
init(svg, selector, accessor) {
|
|
41248
|
-
const { mark,
|
|
41866
|
+
const { mark, as, selection: selection2 } = this;
|
|
41249
41867
|
const { data: { columns = {} } = {} } = mark;
|
|
41250
|
-
accessor ??= (target) =>
|
|
41868
|
+
accessor ??= (target) => as.map((name) => {
|
|
41869
|
+
const data = target.__data__;
|
|
41870
|
+
return columns[name][Array.isArray(data) ? data[0] : data];
|
|
41871
|
+
});
|
|
41251
41872
|
selector ??= `[data-index="${mark.index}"]`;
|
|
41252
41873
|
const groups2 = new Set(svg.querySelectorAll(selector));
|
|
41253
41874
|
svg.addEventListener("pointerdown", (evt) => {
|
|
@@ -41272,7 +41893,7 @@ var Toggle = class {
|
|
|
41272
41893
|
});
|
|
41273
41894
|
svg.addEventListener("pointerenter", (evt) => {
|
|
41274
41895
|
if (evt.buttons) return;
|
|
41275
|
-
this.selection.activate(this.clause([this.
|
|
41896
|
+
this.selection.activate(this.clause([this.fields.map(() => 0)]));
|
|
41276
41897
|
});
|
|
41277
41898
|
}
|
|
41278
41899
|
};
|
|
@@ -41299,7 +41920,7 @@ var Legend = class {
|
|
|
41299
41920
|
constructor(channel, options) {
|
|
41300
41921
|
const { as, field: field2, ...rest } = options;
|
|
41301
41922
|
this.channel = channel;
|
|
41302
|
-
this.options =
|
|
41923
|
+
this.options = rest;
|
|
41303
41924
|
this.type = null;
|
|
41304
41925
|
this.handler = null;
|
|
41305
41926
|
this.selection = as;
|
|
@@ -41307,7 +41928,7 @@ var Legend = class {
|
|
|
41307
41928
|
this.legend = null;
|
|
41308
41929
|
this.element = document.createElement("div");
|
|
41309
41930
|
this.element.setAttribute("class", "legend");
|
|
41310
|
-
Object.
|
|
41931
|
+
Object.defineProperty(this.element, "value", { value: this });
|
|
41311
41932
|
}
|
|
41312
41933
|
setPlot(plot2) {
|
|
41313
41934
|
this.plot = plot2;
|
|
@@ -41319,8 +41940,10 @@ var Legend = class {
|
|
|
41319
41940
|
}
|
|
41320
41941
|
update() {
|
|
41321
41942
|
if (!this.legend) return;
|
|
41322
|
-
const {
|
|
41323
|
-
const
|
|
41943
|
+
const { selection: selection2, handler } = this;
|
|
41944
|
+
const { single, value } = selection2;
|
|
41945
|
+
const vals = single ? value : selection2.valueFor(handler);
|
|
41946
|
+
const curr = vals && vals.length ? new Set(vals.map((v2) => v2[0])) : null;
|
|
41324
41947
|
const nodes = this.legend.querySelectorAll(TOGGLE_SELECTOR);
|
|
41325
41948
|
for (const node of nodes) {
|
|
41326
41949
|
const selected = curr ? curr.has(node.__data__) : true;
|
|
@@ -41329,9 +41952,13 @@ var Legend = class {
|
|
|
41329
41952
|
}
|
|
41330
41953
|
};
|
|
41331
41954
|
function createLegend(legend2, svg) {
|
|
41332
|
-
const { channel,
|
|
41955
|
+
const { channel, plot: plot2, selection: selection2 } = legend2;
|
|
41333
41956
|
const scale3 = svg.scale(channel);
|
|
41334
41957
|
const type2 = scale3.type === "ordinal" ? SWATCH : RAMP;
|
|
41958
|
+
const options = {
|
|
41959
|
+
label: plot2.getAttribute(`${channel}Label`) ?? null,
|
|
41960
|
+
...legend2.options
|
|
41961
|
+
};
|
|
41335
41962
|
const opt = type2 === SWATCH ? options : options.label ? { tickSize: 2, ...options } : { tickSize: 2, marginTop: 1, height: 29, ...options };
|
|
41336
41963
|
const el = svg.legend(channel, opt);
|
|
41337
41964
|
legend2.legend = el;
|
|
@@ -41363,11 +41990,19 @@ function getInteractor(legend2, type2) {
|
|
|
41363
41990
|
if (handler) return handler;
|
|
41364
41991
|
const mark = interactorMark(legend2);
|
|
41365
41992
|
if (type2 === SWATCH) {
|
|
41366
|
-
legend2.handler = new Toggle(mark, {
|
|
41993
|
+
legend2.handler = new Toggle(mark, {
|
|
41994
|
+
selection: selection2,
|
|
41995
|
+
channels: [channel],
|
|
41996
|
+
peers: false
|
|
41997
|
+
});
|
|
41367
41998
|
selection2.addEventListener("value", () => legend2.update());
|
|
41368
41999
|
} else {
|
|
41369
|
-
|
|
41370
|
-
|
|
42000
|
+
legend2.handler = new Interval1D(mark, {
|
|
42001
|
+
selection: selection2,
|
|
42002
|
+
channel,
|
|
42003
|
+
brush: { fill: "none", stroke: "currentColor" },
|
|
42004
|
+
peers: false
|
|
42005
|
+
});
|
|
41371
42006
|
}
|
|
41372
42007
|
return legend2.handler;
|
|
41373
42008
|
}
|
|
@@ -41413,11 +42048,104 @@ function spatialScale(sourceScale, width) {
|
|
|
41413
42048
|
return scale2({ x: { ...rest, type: type2, range: [0, width] } });
|
|
41414
42049
|
}
|
|
41415
42050
|
|
|
42051
|
+
// src/transforms/bin-step.js
|
|
42052
|
+
function binStep(span, steps, minstep = 0, logb = Math.LN10) {
|
|
42053
|
+
let v2;
|
|
42054
|
+
const level = Math.ceil(Math.log(steps) / logb);
|
|
42055
|
+
let step = Math.max(
|
|
42056
|
+
minstep,
|
|
42057
|
+
Math.pow(10, Math.round(Math.log(span) / logb) - level)
|
|
42058
|
+
);
|
|
42059
|
+
while (Math.ceil(span / step) > steps) {
|
|
42060
|
+
step *= 10;
|
|
42061
|
+
}
|
|
42062
|
+
const div = [5, 2];
|
|
42063
|
+
for (let i = 0, n = div.length; i < n; ++i) {
|
|
42064
|
+
v2 = step / div[i];
|
|
42065
|
+
if (v2 >= minstep && span / v2 <= steps) step = v2;
|
|
42066
|
+
}
|
|
42067
|
+
return step;
|
|
42068
|
+
}
|
|
42069
|
+
function bins(min5, max4, options) {
|
|
42070
|
+
let { step, steps, minstep = 0, nice: nice3 = true } = options;
|
|
42071
|
+
if (nice3 !== false) {
|
|
42072
|
+
const span = max4 - min5;
|
|
42073
|
+
const logb = Math.LN10;
|
|
42074
|
+
step = step || binStep(span, steps || 25, minstep, logb);
|
|
42075
|
+
let v2 = Math.log(step);
|
|
42076
|
+
const precision = v2 >= 0 ? 0 : ~~(-v2 / logb) + 1;
|
|
42077
|
+
const eps2 = Math.pow(10, -precision - 1);
|
|
42078
|
+
v2 = Math.floor(min5 / step + eps2) * step;
|
|
42079
|
+
min5 = min5 < v2 ? v2 - step : v2;
|
|
42080
|
+
max4 = Math.ceil(max4 / step) * step;
|
|
42081
|
+
steps = Math.round((max4 - min5) / step);
|
|
42082
|
+
}
|
|
42083
|
+
return { min: min5, max: max4, steps };
|
|
42084
|
+
}
|
|
42085
|
+
|
|
42086
|
+
// src/transforms/time-interval.js
|
|
42087
|
+
var YEAR = "year";
|
|
42088
|
+
var MONTH = "month";
|
|
42089
|
+
var DAY = "day";
|
|
42090
|
+
var HOUR = "hour";
|
|
42091
|
+
var MINUTE = "minute";
|
|
42092
|
+
var SECOND = "second";
|
|
42093
|
+
var MILLISECOND = "millisecond";
|
|
42094
|
+
var durationSecond3 = 1e3;
|
|
42095
|
+
var durationMinute3 = durationSecond3 * 60;
|
|
42096
|
+
var durationHour3 = durationMinute3 * 60;
|
|
42097
|
+
var durationDay3 = durationHour3 * 24;
|
|
42098
|
+
var durationWeek3 = durationDay3 * 7;
|
|
42099
|
+
var durationMonth3 = durationDay3 * 30;
|
|
42100
|
+
var durationYear3 = durationDay3 * 365;
|
|
42101
|
+
var intervals = [
|
|
42102
|
+
[SECOND, 1, durationSecond3],
|
|
42103
|
+
[SECOND, 5, 5 * durationSecond3],
|
|
42104
|
+
[SECOND, 15, 15 * durationSecond3],
|
|
42105
|
+
[SECOND, 30, 30 * durationSecond3],
|
|
42106
|
+
[MINUTE, 1, durationMinute3],
|
|
42107
|
+
[MINUTE, 5, 5 * durationMinute3],
|
|
42108
|
+
[MINUTE, 15, 15 * durationMinute3],
|
|
42109
|
+
[MINUTE, 30, 30 * durationMinute3],
|
|
42110
|
+
[HOUR, 1, durationHour3],
|
|
42111
|
+
[HOUR, 3, 3 * durationHour3],
|
|
42112
|
+
[HOUR, 6, 6 * durationHour3],
|
|
42113
|
+
[HOUR, 12, 12 * durationHour3],
|
|
42114
|
+
[DAY, 1, durationDay3],
|
|
42115
|
+
[DAY, 7, durationWeek3],
|
|
42116
|
+
[MONTH, 1, durationMonth3],
|
|
42117
|
+
[MONTH, 3, 3 * durationMonth3],
|
|
42118
|
+
[YEAR, 1, durationYear3]
|
|
42119
|
+
];
|
|
42120
|
+
function timeInterval3(min5, max4, steps) {
|
|
42121
|
+
const span = max4 - min5;
|
|
42122
|
+
const target = span / steps;
|
|
42123
|
+
let i = bisector((i2) => i2[2]).right(intervals, target);
|
|
42124
|
+
if (i === intervals.length) {
|
|
42125
|
+
return { interval: YEAR, step: binStep(span, steps) };
|
|
42126
|
+
} else if (i) {
|
|
42127
|
+
i = intervals[target / intervals[i - 1][2] < intervals[i][2] / target ? i - 1 : i];
|
|
42128
|
+
return { interval: i[0], step: i[1] };
|
|
42129
|
+
} else {
|
|
42130
|
+
return { interval: MILLISECOND, step: binStep(span, steps, 1) };
|
|
42131
|
+
}
|
|
42132
|
+
}
|
|
42133
|
+
|
|
41416
42134
|
// src/transforms/bin.js
|
|
41417
|
-
var EXTENT = /* @__PURE__ */ new Set([
|
|
41418
|
-
|
|
42135
|
+
var EXTENT = /* @__PURE__ */ new Set([
|
|
42136
|
+
"rectY-x",
|
|
42137
|
+
"rectX-y",
|
|
42138
|
+
"rect-x",
|
|
42139
|
+
"rect-y",
|
|
42140
|
+
"ruleY-x",
|
|
42141
|
+
"ruleX-y"
|
|
42142
|
+
]);
|
|
42143
|
+
function hasExtent(mark, channel) {
|
|
42144
|
+
return EXTENT.has(`${mark.type}-${channel}`);
|
|
42145
|
+
}
|
|
42146
|
+
function bin2(field2, options = {}) {
|
|
41419
42147
|
const fn = (mark, channel) => {
|
|
41420
|
-
if (
|
|
42148
|
+
if (hasExtent(mark, channel)) {
|
|
41421
42149
|
return {
|
|
41422
42150
|
[`${channel}1`]: binField(mark, channel, field2, options),
|
|
41423
42151
|
[`${channel}2`]: binField(mark, channel, field2, { ...options, offset: 1 })
|
|
@@ -41435,57 +42163,39 @@ function binField(mark, channel, column3, options) {
|
|
|
41435
42163
|
return {
|
|
41436
42164
|
column: column3,
|
|
41437
42165
|
label: column3,
|
|
41438
|
-
get stats() {
|
|
41439
|
-
return { column: column3, stats: ["min", "max"] };
|
|
41440
|
-
},
|
|
41441
42166
|
get columns() {
|
|
41442
42167
|
return [column3];
|
|
41443
42168
|
},
|
|
41444
42169
|
get basis() {
|
|
41445
42170
|
return column3;
|
|
41446
42171
|
},
|
|
42172
|
+
get stats() {
|
|
42173
|
+
return { column: column3, stats: ["min", "max"] };
|
|
42174
|
+
},
|
|
41447
42175
|
toString() {
|
|
41448
|
-
const {
|
|
41449
|
-
const {
|
|
41450
|
-
const
|
|
41451
|
-
|
|
41452
|
-
|
|
41453
|
-
|
|
41454
|
-
|
|
41455
|
-
|
|
41456
|
-
|
|
42176
|
+
const { type: type2, min: min5, max: max4 } = mark.channelField(channel);
|
|
42177
|
+
const { interval: i, steps, offset: offset2 = 0 } = options;
|
|
42178
|
+
const interval2 = i ?? (type2 === "date" || hasTimeScale(mark, channel) ? "date" : "number");
|
|
42179
|
+
if (interval2 === "number") {
|
|
42180
|
+
const { apply: apply2, sqlApply, sqlInvert } = channelScale(mark, channel);
|
|
42181
|
+
const b = bins(apply2(min5), apply2(max4), options);
|
|
42182
|
+
const col = sqlApply(column3);
|
|
42183
|
+
const base = b.min === 0 ? col : `(${col} - ${b.min})`;
|
|
42184
|
+
const alpha = `${(b.max - b.min) / b.steps}::DOUBLE`;
|
|
42185
|
+
const off = offset2 ? `${offset2} + ` : "";
|
|
42186
|
+
const expr = `${b.min} + ${alpha} * (${off}FLOOR(${base} / ${alpha}))`;
|
|
42187
|
+
return `${sqlInvert(expr)}`;
|
|
42188
|
+
} else {
|
|
42189
|
+
const { interval: unit3, step = 1 } = interval2 === "date" ? timeInterval3(min5, max4, steps || 40) : options;
|
|
42190
|
+
const off = offset2 ? ` + INTERVAL ${offset2 * step} ${unit3}` : "";
|
|
42191
|
+
return `(${dateBin(column3, unit3, step)}${off})`;
|
|
42192
|
+
}
|
|
41457
42193
|
}
|
|
41458
42194
|
};
|
|
41459
42195
|
}
|
|
41460
|
-
function
|
|
41461
|
-
|
|
41462
|
-
|
|
41463
|
-
const span = max4 - min5;
|
|
41464
|
-
const maxb = steps;
|
|
41465
|
-
const logb = Math.LN10;
|
|
41466
|
-
const level = Math.ceil(Math.log(maxb) / logb);
|
|
41467
|
-
let step = Math.max(
|
|
41468
|
-
minstep,
|
|
41469
|
-
Math.pow(10, Math.round(Math.log(span) / logb) - level)
|
|
41470
|
-
);
|
|
41471
|
-
while (Math.ceil(span / step) > maxb) {
|
|
41472
|
-
step *= 10;
|
|
41473
|
-
}
|
|
41474
|
-
const div = [5, 2];
|
|
41475
|
-
let v2;
|
|
41476
|
-
for (let i = 0, n = div.length; i < n; ++i) {
|
|
41477
|
-
v2 = step / div[i];
|
|
41478
|
-
if (v2 >= minstep && span / v2 <= maxb) step = v2;
|
|
41479
|
-
}
|
|
41480
|
-
v2 = Math.log(step);
|
|
41481
|
-
const precision = v2 >= 0 ? 0 : ~~(-v2 / logb) + 1;
|
|
41482
|
-
const eps2 = Math.pow(10, -precision - 1);
|
|
41483
|
-
v2 = Math.floor(min5 / step + eps2) * step;
|
|
41484
|
-
min5 = min5 < v2 ? v2 - step : v2;
|
|
41485
|
-
max4 = Math.ceil(max4 / step) * step;
|
|
41486
|
-
steps = Math.round((max4 - min5) / step);
|
|
41487
|
-
}
|
|
41488
|
-
return { min: min5, max: max4, steps };
|
|
42196
|
+
function hasTimeScale(mark, channel) {
|
|
42197
|
+
const scale3 = mark.plot.getAttribute(`${channel}Scale`);
|
|
42198
|
+
return scale3 === "utc" || scale3 === "time";
|
|
41489
42199
|
}
|
|
41490
42200
|
export {
|
|
41491
42201
|
ConnectedMark,
|
|
@@ -41493,6 +42203,7 @@ export {
|
|
|
41493
42203
|
DenseLineMark,
|
|
41494
42204
|
Density1DMark,
|
|
41495
42205
|
Density2DMark,
|
|
42206
|
+
ErrorBarMark,
|
|
41496
42207
|
Fixed,
|
|
41497
42208
|
GeoMark,
|
|
41498
42209
|
Grid2DMark,
|