@opendata-ai/openchart-engine 8.0.0-rc.6 → 8.0.0-rc.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +122 -34
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/annotation-behavior.test.ts +131 -0
- package/src/annotations/geometry.ts +7 -1
- package/src/annotations/resolve-text.ts +6 -0
- package/src/compiler/__tests__/validate-did-you-mean.test.ts +84 -0
- package/src/compiler/__tests__/validate-near-miss.test.ts +162 -0
- package/src/compiler/validate.ts +155 -27
- package/src/geo/compile-map.ts +12 -5
package/dist/index.js
CHANGED
|
@@ -244,7 +244,10 @@ function refreshConnector(connector, bounds, markerRadius) {
|
|
|
244
244
|
}
|
|
245
245
|
const exit = connectorExit(bounds, endpoint.x, endpoint.y);
|
|
246
246
|
if (!exit) return void 0;
|
|
247
|
-
const from = {
|
|
247
|
+
const from = {
|
|
248
|
+
x: exit.x + (connector.fromOffset?.dx ?? 0),
|
|
249
|
+
y: exit.y + (connector.fromOffset?.dy ?? 0)
|
|
250
|
+
};
|
|
248
251
|
const gap = connectorPullbackGap(markerRadius, connector.arrow);
|
|
249
252
|
const cdx = endpoint.x - from.x;
|
|
250
253
|
const cdy = endpoint.y - from.y;
|
|
@@ -506,6 +509,10 @@ function resolveTextAnnotation(annotation, scales, chartArea, isDark, measure =
|
|
|
506
509
|
from,
|
|
507
510
|
to,
|
|
508
511
|
endpoint,
|
|
512
|
+
fromOffset: annotation.connectorOffset?.from ? {
|
|
513
|
+
dx: annotation.connectorOffset.from.dx ?? 0,
|
|
514
|
+
dy: annotation.connectorOffset.from.dy ?? 0
|
|
515
|
+
} : void 0,
|
|
509
516
|
stroke: connectorStroke,
|
|
510
517
|
style: connectorStyle,
|
|
511
518
|
arrow: connectorArrow,
|
|
@@ -10729,6 +10736,7 @@ import {
|
|
|
10729
10736
|
MARK_ENCODING_RULES,
|
|
10730
10737
|
MARK_TYPES,
|
|
10731
10738
|
resolveSchemeName as resolveSchemeName2,
|
|
10739
|
+
SEQUENTIAL_PALETTES,
|
|
10732
10740
|
SUPPORTED_SCHEME_NAMES
|
|
10733
10741
|
} from "@opendata-ai/openchart-core";
|
|
10734
10742
|
var VALID_FIELD_TYPES = /* @__PURE__ */ new Set(["quantitative", "temporal", "nominal", "ordinal"]);
|
|
@@ -10787,6 +10795,53 @@ function didYouMean(field, columns) {
|
|
|
10787
10795
|
const match = nearestColumn(field, columns);
|
|
10788
10796
|
return match ? ` Did you mean "${match}"?` : "";
|
|
10789
10797
|
}
|
|
10798
|
+
function checkSchemeName(channelObj, channelPath, errors) {
|
|
10799
|
+
const scale = channelObj.scale;
|
|
10800
|
+
if (scale && typeof scale.scheme === "string" && !resolveSchemeName2(scale.scheme)) {
|
|
10801
|
+
errors.push({
|
|
10802
|
+
message: `Spec error: ${channelPath}.scale.scheme "${scale.scheme}" is not a supported scheme name`,
|
|
10803
|
+
path: `${channelPath}.scale.scheme`,
|
|
10804
|
+
code: "INVALID_VALUE",
|
|
10805
|
+
suggestion: `Use one of the supported scheme names: ${[...SUPPORTED_SCHEME_NAMES].join(", ")}. Or provide explicit colors via scale.range.`
|
|
10806
|
+
});
|
|
10807
|
+
}
|
|
10808
|
+
}
|
|
10809
|
+
function checkSchemeUnused(encoding, errors, familyNote, suggestion) {
|
|
10810
|
+
for (const [channel, ch] of Object.entries(encoding)) {
|
|
10811
|
+
if (!ch || typeof ch !== "object" || Array.isArray(ch)) continue;
|
|
10812
|
+
const scale = ch.scale;
|
|
10813
|
+
if (scale && typeof scale.scheme === "string") {
|
|
10814
|
+
errors.push({
|
|
10815
|
+
message: `Spec error: encoding.${channel}.scale.scheme has no effect \u2014 ${familyNote}`,
|
|
10816
|
+
path: `encoding.${channel}.scale.scheme`,
|
|
10817
|
+
code: "INVALID_VALUE",
|
|
10818
|
+
suggestion
|
|
10819
|
+
});
|
|
10820
|
+
}
|
|
10821
|
+
}
|
|
10822
|
+
}
|
|
10823
|
+
var MAP_PALETTE_NAMES = Object.keys(SEQUENTIAL_PALETTES).join(", ");
|
|
10824
|
+
function checkMapSchemeName(channelObj, channelPath, errors) {
|
|
10825
|
+
const scale = channelObj.scale;
|
|
10826
|
+
if (!scale || typeof scale.scheme !== "string") return;
|
|
10827
|
+
if (channelObj.type === "nominal" || channelObj.type === "ordinal") {
|
|
10828
|
+
errors.push({
|
|
10829
|
+
message: `Spec error: ${channelPath}.scale.scheme has no effect \u2014 categorical map colors come from scale.range and scale.domain`,
|
|
10830
|
+
path: `${channelPath}.scale.scheme`,
|
|
10831
|
+
code: "INVALID_VALUE",
|
|
10832
|
+
suggestion: "Remove scale.scheme. To customize categorical map colors, provide explicit colors via scale.range (with scale.domain for category order)."
|
|
10833
|
+
});
|
|
10834
|
+
return;
|
|
10835
|
+
}
|
|
10836
|
+
if (!(scale.scheme in SEQUENTIAL_PALETTES)) {
|
|
10837
|
+
errors.push({
|
|
10838
|
+
message: `Spec error: ${channelPath}.scale.scheme "${scale.scheme}" is not a supported map palette`,
|
|
10839
|
+
path: `${channelPath}.scale.scheme`,
|
|
10840
|
+
code: "INVALID_VALUE",
|
|
10841
|
+
suggestion: `Maps support the sequential palettes: ${MAP_PALETTE_NAMES}. The default is "blue".`
|
|
10842
|
+
});
|
|
10843
|
+
}
|
|
10844
|
+
}
|
|
10790
10845
|
var VALID_RANGE_STYLES = /* @__PURE__ */ new Set(["dumbbell", "arrow", "bar"]);
|
|
10791
10846
|
function validateRangeSpec(spec, errors) {
|
|
10792
10847
|
const encoding = spec.encoding;
|
|
@@ -11148,15 +11203,7 @@ function validateChartSpec(spec, errors) {
|
|
|
11148
11203
|
suggestion: `Use one of: ${[...VALID_FIELD_TYPES].join(", ")}`
|
|
11149
11204
|
});
|
|
11150
11205
|
}
|
|
11151
|
-
|
|
11152
|
-
if (channelScale && typeof channelScale.scheme === "string" && !resolveSchemeName2(channelScale.scheme)) {
|
|
11153
|
-
errors.push({
|
|
11154
|
-
message: `Spec error: encoding.${channel}.scale.scheme "${channelScale.scheme}" is not a supported scheme name`,
|
|
11155
|
-
path: `encoding.${channel}.scale.scheme`,
|
|
11156
|
-
code: "INVALID_VALUE",
|
|
11157
|
-
suggestion: `Use one of the supported scheme names: ${[...SUPPORTED_SCHEME_NAMES].join(", ")}. Or provide explicit colors via scale.range.`
|
|
11158
|
-
});
|
|
11159
|
-
}
|
|
11206
|
+
checkSchemeName(channelObj, `encoding.${channel}`, errors);
|
|
11160
11207
|
if (channelRule && channelObj.type && channelRule.allowedTypes.length > 0) {
|
|
11161
11208
|
if (!channelRule.allowedTypes.includes(channelObj.type)) {
|
|
11162
11209
|
errors.push({
|
|
@@ -11482,7 +11529,7 @@ function validateGraphSpec(spec, errors) {
|
|
|
11482
11529
|
message: `Spec error: edges[${i}].source "${edge.source}" does not reference an existing node id`,
|
|
11483
11530
|
path: `edges[${i}].source`,
|
|
11484
11531
|
code: "DATA_FIELD_MISSING",
|
|
11485
|
-
suggestion: `Use one of the existing node ids: ${[...nodeIds].slice(0, 5).join(", ")}${nodeIds.size > 5 ? "..." : ""}`
|
|
11532
|
+
suggestion: `Use one of the existing node ids: ${[...nodeIds].slice(0, 5).join(", ")}${nodeIds.size > 5 ? "..." : ""}.${didYouMean(edge.source, [...nodeIds])}`
|
|
11486
11533
|
});
|
|
11487
11534
|
}
|
|
11488
11535
|
if (typeof edge.target !== "string" || edge.target === "") {
|
|
@@ -11497,7 +11544,7 @@ function validateGraphSpec(spec, errors) {
|
|
|
11497
11544
|
message: `Spec error: edges[${i}].target "${edge.target}" does not reference an existing node id`,
|
|
11498
11545
|
path: `edges[${i}].target`,
|
|
11499
11546
|
code: "DATA_FIELD_MISSING",
|
|
11500
|
-
suggestion: `Use one of the existing node ids: ${[...nodeIds].slice(0, 5).join(", ")}${nodeIds.size > 5 ? "..." : ""}`
|
|
11547
|
+
suggestion: `Use one of the existing node ids: ${[...nodeIds].slice(0, 5).join(", ")}${nodeIds.size > 5 ? "..." : ""}.${didYouMean(edge.target, [...nodeIds])}`
|
|
11501
11548
|
});
|
|
11502
11549
|
}
|
|
11503
11550
|
}
|
|
@@ -11515,7 +11562,7 @@ function validateGraphSpec(spec, errors) {
|
|
|
11515
11562
|
message: `Spec error: encoding.${channel}.field "${ch.field}" does not exist on nodes. Available fields: ${[...nodeFields].join(", ")}`,
|
|
11516
11563
|
path: `encoding.${channel}.field`,
|
|
11517
11564
|
code: "DATA_FIELD_MISSING",
|
|
11518
|
-
suggestion: `Use one of the node fields: ${[...nodeFields].join(", ")}`
|
|
11565
|
+
suggestion: `Use one of the node fields: ${[...nodeFields].join(", ")}.${didYouMean(ch.field, [...nodeFields])}`
|
|
11519
11566
|
});
|
|
11520
11567
|
}
|
|
11521
11568
|
}
|
|
@@ -11527,10 +11574,16 @@ function validateGraphSpec(spec, errors) {
|
|
|
11527
11574
|
message: `Spec error: encoding.${channel}.field "${ch.field}" does not exist on edges. Available fields: ${[...edgeFields].join(", ")}`,
|
|
11528
11575
|
path: `encoding.${channel}.field`,
|
|
11529
11576
|
code: "DATA_FIELD_MISSING",
|
|
11530
|
-
suggestion: `Use one of the edge fields: ${[...edgeFields].join(", ")}`
|
|
11577
|
+
suggestion: `Use one of the edge fields: ${[...edgeFields].join(", ")}.${didYouMean(ch.field, [...edgeFields])}`
|
|
11531
11578
|
});
|
|
11532
11579
|
}
|
|
11533
11580
|
}
|
|
11581
|
+
checkSchemeUnused(
|
|
11582
|
+
encoding,
|
|
11583
|
+
errors,
|
|
11584
|
+
"graph colors come from scale.range and scale.domain",
|
|
11585
|
+
"Remove scale.scheme. To customize graph colors, provide explicit colors via scale.range."
|
|
11586
|
+
);
|
|
11534
11587
|
}
|
|
11535
11588
|
if (spec.layout && typeof spec.layout === "object") {
|
|
11536
11589
|
const layout = spec.layout;
|
|
@@ -11584,7 +11637,8 @@ function validateSankeySpec(spec, errors) {
|
|
|
11584
11637
|
}
|
|
11585
11638
|
const encoding = spec.encoding;
|
|
11586
11639
|
const dataColumns = new Set(Object.keys(firstRow));
|
|
11587
|
-
const
|
|
11640
|
+
const columnList = [...dataColumns];
|
|
11641
|
+
const availableColumns = columnList.join(", ");
|
|
11588
11642
|
for (const channel of ["source", "target", "value"]) {
|
|
11589
11643
|
const ch = encoding[channel];
|
|
11590
11644
|
if (!ch || typeof ch !== "object") {
|
|
@@ -11592,7 +11646,7 @@ function validateSankeySpec(spec, errors) {
|
|
|
11592
11646
|
message: `Spec error: sankey encoding requires "${channel}" channel`,
|
|
11593
11647
|
path: `encoding.${channel}`,
|
|
11594
11648
|
code: "MISSING_FIELD",
|
|
11595
|
-
suggestion: `Add encoding.${channel} with a field from your data (${availableColumns}). Example: ${channel}: { field: "${[
|
|
11649
|
+
suggestion: `Add encoding.${channel} with a field from your data (${availableColumns}). Example: ${channel}: { field: "${columnList[0] ?? "myField"}", type: "${channel === "value" ? "quantitative" : "nominal"}" }`
|
|
11596
11650
|
});
|
|
11597
11651
|
continue;
|
|
11598
11652
|
}
|
|
@@ -11610,10 +11664,16 @@ function validateSankeySpec(spec, errors) {
|
|
|
11610
11664
|
message: `Spec error: encoding.${channel}.field "${ch.field}" does not exist in data. Available columns: ${availableColumns}`,
|
|
11611
11665
|
path: `encoding.${channel}.field`,
|
|
11612
11666
|
code: "DATA_FIELD_MISSING",
|
|
11613
|
-
suggestion: `Use one of the available data columns: ${availableColumns}`
|
|
11667
|
+
suggestion: `Use one of the available data columns: ${availableColumns}.${didYouMean(ch.field, columnList)}`
|
|
11614
11668
|
});
|
|
11615
11669
|
}
|
|
11616
11670
|
}
|
|
11671
|
+
checkSchemeUnused(
|
|
11672
|
+
encoding,
|
|
11673
|
+
errors,
|
|
11674
|
+
"sankey node colors cycle the theme categorical palette",
|
|
11675
|
+
"Remove scale.scheme. To customize sankey colors, set theme.colors.categorical."
|
|
11676
|
+
);
|
|
11617
11677
|
if (spec.darkMode !== void 0 && !VALID_DARK_MODES.has(spec.darkMode)) {
|
|
11618
11678
|
errors.push({
|
|
11619
11679
|
message: 'Spec error: darkMode must be "auto", "force", or "off"',
|
|
@@ -11673,7 +11733,8 @@ function validateTileMapSpec(spec, errors) {
|
|
|
11673
11733
|
}
|
|
11674
11734
|
const encoding = spec.encoding;
|
|
11675
11735
|
const dataColumns = new Set(Object.keys(firstRow));
|
|
11676
|
-
const
|
|
11736
|
+
const columnList = [...dataColumns];
|
|
11737
|
+
const availableColumns = columnList.join(", ");
|
|
11677
11738
|
for (const channel of ["state", "value"]) {
|
|
11678
11739
|
const ch = encoding[channel];
|
|
11679
11740
|
if (!ch || typeof ch !== "object") {
|
|
@@ -11681,7 +11742,7 @@ function validateTileMapSpec(spec, errors) {
|
|
|
11681
11742
|
message: `Spec error: tilemap encoding requires "${channel}" channel`,
|
|
11682
11743
|
path: `encoding.${channel}`,
|
|
11683
11744
|
code: "MISSING_FIELD",
|
|
11684
|
-
suggestion: `Add encoding.${channel} with a field from your data (${availableColumns}). Example: ${channel}: { field: "${[
|
|
11745
|
+
suggestion: `Add encoding.${channel} with a field from your data (${availableColumns}). Example: ${channel}: { field: "${columnList[0] ?? "myField"}", type: "${channel === "value" ? "quantitative" : "nominal"}" }`
|
|
11685
11746
|
});
|
|
11686
11747
|
continue;
|
|
11687
11748
|
}
|
|
@@ -11699,11 +11760,19 @@ function validateTileMapSpec(spec, errors) {
|
|
|
11699
11760
|
message: `Spec error: encoding.${channel}.field "${ch.field}" does not exist in data. Available columns: ${availableColumns}`,
|
|
11700
11761
|
path: `encoding.${channel}.field`,
|
|
11701
11762
|
code: "DATA_FIELD_MISSING",
|
|
11702
|
-
suggestion: `Use one of the available data columns: ${availableColumns}`
|
|
11763
|
+
suggestion: `Use one of the available data columns: ${availableColumns}.${didYouMean(ch.field, columnList)}`
|
|
11703
11764
|
});
|
|
11704
11765
|
}
|
|
11705
11766
|
}
|
|
11706
11767
|
}
|
|
11768
|
+
if (spec.encoding && typeof spec.encoding === "object") {
|
|
11769
|
+
checkSchemeUnused(
|
|
11770
|
+
spec.encoding,
|
|
11771
|
+
errors,
|
|
11772
|
+
"tilemap fills come from the top-level palette property",
|
|
11773
|
+
`Remove scale.scheme and set the top-level palette property instead, e.g. palette: "green". Supported: ${MAP_PALETTE_NAMES}.`
|
|
11774
|
+
);
|
|
11775
|
+
}
|
|
11707
11776
|
if (spec.darkMode !== void 0 && !VALID_DARK_MODES.has(spec.darkMode)) {
|
|
11708
11777
|
errors.push({
|
|
11709
11778
|
message: 'Spec error: darkMode must be "auto", "force", or "off"',
|
|
@@ -11742,6 +11811,16 @@ function validateMapSpec(spec, errors) {
|
|
|
11742
11811
|
});
|
|
11743
11812
|
return;
|
|
11744
11813
|
}
|
|
11814
|
+
const mapEncoding = spec.encoding;
|
|
11815
|
+
if (mapEncoding.color && typeof mapEncoding.color === "object") {
|
|
11816
|
+
checkMapSchemeName(mapEncoding.color, "encoding.color", errors);
|
|
11817
|
+
}
|
|
11818
|
+
if (spec.points && typeof spec.points === "object") {
|
|
11819
|
+
const pointsLayer = spec.points;
|
|
11820
|
+
if (pointsLayer.color && typeof pointsLayer.color === "object") {
|
|
11821
|
+
checkMapSchemeName(pointsLayer.color, "points.color", errors);
|
|
11822
|
+
}
|
|
11823
|
+
}
|
|
11745
11824
|
if ("focus" in geo && geo.focus !== void 0 && geo.focus !== null) {
|
|
11746
11825
|
const focus = geo.focus;
|
|
11747
11826
|
if (typeof focus === "string" || typeof focus === "number") {
|
|
@@ -11951,7 +12030,8 @@ function validateBarListSpec(spec, errors) {
|
|
|
11951
12030
|
}
|
|
11952
12031
|
const encoding = spec.encoding;
|
|
11953
12032
|
const dataColumns = new Set(Object.keys(firstRow));
|
|
11954
|
-
const
|
|
12033
|
+
const columnList = [...dataColumns];
|
|
12034
|
+
const availableColumns = columnList.join(", ");
|
|
11955
12035
|
for (const channel of ["label", "value"]) {
|
|
11956
12036
|
const ch = encoding[channel];
|
|
11957
12037
|
if (!ch || typeof ch !== "object") {
|
|
@@ -11959,7 +12039,7 @@ function validateBarListSpec(spec, errors) {
|
|
|
11959
12039
|
message: `Spec error: barlist encoding requires "${channel}" channel`,
|
|
11960
12040
|
path: `encoding.${channel}`,
|
|
11961
12041
|
code: "MISSING_FIELD",
|
|
11962
|
-
suggestion: `Add encoding.${channel} with a field from your data (${availableColumns}). Example: ${channel}: { field: "${[
|
|
12042
|
+
suggestion: `Add encoding.${channel} with a field from your data (${availableColumns}). Example: ${channel}: { field: "${columnList[0] ?? "myField"}", type: "${channel === "value" ? "quantitative" : "nominal"}" }`
|
|
11963
12043
|
});
|
|
11964
12044
|
continue;
|
|
11965
12045
|
}
|
|
@@ -11977,7 +12057,7 @@ function validateBarListSpec(spec, errors) {
|
|
|
11977
12057
|
message: `Spec error: encoding.${channel}.field "${ch.field}" does not exist in data. Available columns: ${availableColumns}`,
|
|
11978
12058
|
path: `encoding.${channel}.field`,
|
|
11979
12059
|
code: "DATA_FIELD_MISSING",
|
|
11980
|
-
suggestion: `Use one of the available data columns: ${availableColumns}`
|
|
12060
|
+
suggestion: `Use one of the available data columns: ${availableColumns}.${didYouMean(ch.field, columnList)}`
|
|
11981
12061
|
});
|
|
11982
12062
|
}
|
|
11983
12063
|
}
|
|
@@ -11990,10 +12070,16 @@ function validateBarListSpec(spec, errors) {
|
|
|
11990
12070
|
message: `Spec error: encoding.${channel}.field "${field}" does not exist in data. Available columns: ${availableColumns}`,
|
|
11991
12071
|
path: `encoding.${channel}.field`,
|
|
11992
12072
|
code: "DATA_FIELD_MISSING",
|
|
11993
|
-
suggestion: `Use one of the available data columns: ${availableColumns}`
|
|
12073
|
+
suggestion: `Use one of the available data columns: ${availableColumns}.${didYouMean(field, columnList)}`
|
|
11994
12074
|
});
|
|
11995
12075
|
}
|
|
11996
12076
|
}
|
|
12077
|
+
checkSchemeUnused(
|
|
12078
|
+
encoding,
|
|
12079
|
+
errors,
|
|
12080
|
+
"bar list colors cycle the built-in barlist palette",
|
|
12081
|
+
"Remove scale.scheme. Bar list colors are not configurable via encoding; they cycle the built-in palette."
|
|
12082
|
+
);
|
|
11997
12083
|
if (spec.darkMode !== void 0 && !VALID_DARK_MODES.has(spec.darkMode)) {
|
|
11998
12084
|
errors.push({
|
|
11999
12085
|
message: 'Spec error: darkMode must be "auto", "force", or "off"',
|
|
@@ -15779,7 +15865,7 @@ import {
|
|
|
15779
15865
|
HPAD_COMPACT_FRACTION as HPAD_COMPACT_FRACTION2,
|
|
15780
15866
|
HPAD_COMPACT_MIN as HPAD_COMPACT_MIN2,
|
|
15781
15867
|
resolveTheme as resolveTheme3,
|
|
15782
|
-
SEQUENTIAL_PALETTES
|
|
15868
|
+
SEQUENTIAL_PALETTES as SEQUENTIAL_PALETTES2
|
|
15783
15869
|
} from "@opendata-ai/openchart-core";
|
|
15784
15870
|
|
|
15785
15871
|
// ../../node_modules/.bun/d3-geo@3.1.1/node_modules/d3-geo/src/math.js
|
|
@@ -18064,7 +18150,7 @@ function compileMap(spec, options) {
|
|
|
18064
18150
|
}
|
|
18065
18151
|
if (colorValues.length > 0) {
|
|
18066
18152
|
const palette = pts.color.scale?.scheme ?? "blue";
|
|
18067
|
-
const paletteStops = [...
|
|
18153
|
+
const paletteStops = [...SEQUENTIAL_PALETTES2[palette] ?? SEQUENTIAL_PALETTES2.blue];
|
|
18068
18154
|
const qScale = quantile2().domain(colorValues).range(paletteStops);
|
|
18069
18155
|
pointColorScale = (val) => {
|
|
18070
18156
|
const v = Number(val);
|
|
@@ -18421,7 +18507,7 @@ function buildQuantitativeMarks(opts) {
|
|
|
18421
18507
|
if (!Number.isNaN(v)) values.push(v);
|
|
18422
18508
|
}
|
|
18423
18509
|
}
|
|
18424
|
-
const paletteStops = [...
|
|
18510
|
+
const paletteStops = [...SEQUENTIAL_PALETTES2[palette] ?? SEQUENTIAL_PALETTES2.blue];
|
|
18425
18511
|
const colorScale = quantile2().domain(values).range(paletteStops);
|
|
18426
18512
|
const marks = [];
|
|
18427
18513
|
let animIndex = 0;
|
|
@@ -18625,13 +18711,15 @@ function resolveFocus(focus, features, pointMarks, warnings) {
|
|
|
18625
18711
|
let maxX2 = -Infinity;
|
|
18626
18712
|
let maxY2 = -Infinity;
|
|
18627
18713
|
for (const p of matched) {
|
|
18628
|
-
minX2 = Math.min(minX2, p.cx
|
|
18629
|
-
minY2 = Math.min(minY2, p.cy
|
|
18630
|
-
maxX2 = Math.max(maxX2, p.cx
|
|
18631
|
-
maxY2 = Math.max(maxY2, p.cy
|
|
18714
|
+
minX2 = Math.min(minX2, p.cx);
|
|
18715
|
+
minY2 = Math.min(minY2, p.cy);
|
|
18716
|
+
maxX2 = Math.max(maxX2, p.cx);
|
|
18717
|
+
maxY2 = Math.max(maxY2, p.cy);
|
|
18632
18718
|
}
|
|
18719
|
+
const w = Math.max(maxX2 - minX2, 1);
|
|
18720
|
+
const h = Math.max(maxY2 - minY2, 1);
|
|
18633
18721
|
return {
|
|
18634
|
-
target: { x: minX2, y: minY2, width:
|
|
18722
|
+
target: { x: minX2, y: minY2, width: w, height: h, padding: padding2 },
|
|
18635
18723
|
// No feature ids: focus-dim is a feature concept, so a points focus
|
|
18636
18724
|
// dims no features (there are no "other" features to mute).
|
|
18637
18725
|
ids: []
|
|
@@ -21349,7 +21437,7 @@ import {
|
|
|
21349
21437
|
HPAD_COMPACT_MIN as HPAD_COMPACT_MIN4,
|
|
21350
21438
|
pickLabelColor as pickLabelColor4,
|
|
21351
21439
|
resolveTheme as resolveTheme6,
|
|
21352
|
-
SEQUENTIAL_PALETTES as
|
|
21440
|
+
SEQUENTIAL_PALETTES as SEQUENTIAL_PALETTES3
|
|
21353
21441
|
} from "@opendata-ai/openchart-core";
|
|
21354
21442
|
var TILE_CORNER_RADIUS = 6;
|
|
21355
21443
|
var TILE_STROKE_WIDTH = 1;
|
|
@@ -21427,7 +21515,7 @@ function compileQuantitative(tilemapSpec, options, theme, chrome, fullArea, isDa
|
|
|
21427
21515
|
const values = Array.from(stateValueMap.values());
|
|
21428
21516
|
const min4 = values.length > 0 ? Math.min(...values) : 0;
|
|
21429
21517
|
const max4 = values.length > 0 ? Math.max(...values) : 100;
|
|
21430
|
-
const paletteStops = [...
|
|
21518
|
+
const paletteStops = [...SEQUENTIAL_PALETTES3[tilemapSpec.palette] ?? SEQUENTIAL_PALETTES3.blue];
|
|
21431
21519
|
const baseColor = isDarkMode ? paletteStops[0] : paletteStops[paletteStops.length - 1];
|
|
21432
21520
|
const opacityRange = isDarkMode ? [0.15, 1] : [0.2, 1];
|
|
21433
21521
|
const opacityScale = linear2().domain([min4, max4]).range(opacityRange).clamp(true);
|