@opendata-ai/openchart-engine 6.10.0 → 6.12.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/index.d.ts +9 -10
- package/dist/index.js +148 -59
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__test-fixtures__/specs.ts +3 -0
- package/src/charts/bar/compute.ts +9 -5
- package/src/charts/bar/labels.ts +2 -1
- package/src/charts/column/compute.ts +9 -5
- package/src/charts/column/labels.ts +2 -1
- package/src/charts/dot/labels.ts +6 -2
- package/src/charts/line/area.ts +3 -2
- package/src/charts/line/compute.ts +5 -2
- package/src/charts/pie/compute.ts +24 -3
- package/src/charts/rule/index.ts +6 -3
- package/src/charts/scatter/compute.ts +2 -1
- package/src/charts/text/index.ts +6 -3
- package/src/charts/tick/index.ts +6 -3
- package/src/charts/utils.ts +3 -3
- package/src/compile.ts +27 -14
- package/src/compiler/__tests__/normalize.test.ts +110 -0
- package/src/compiler/normalize.ts +20 -1
- package/src/compiler/types.ts +4 -0
- package/src/graphs/compile-graph.ts +8 -0
- package/src/graphs/types.ts +2 -0
- package/src/layout/dimensions.ts +3 -0
- package/src/layout/scales.ts +2 -2
- package/src/legend/compute.ts +3 -1
- package/src/sankey/compile-sankey.ts +12 -2
- package/src/sankey/types.ts +1 -0
- package/src/tables/compile-table.ts +5 -0
- package/src/tooltips/compute.ts +11 -6
package/dist/index.js
CHANGED
|
@@ -590,7 +590,7 @@ function computeAnnotations(spec, scales, chartArea, strategy, isDark = false, o
|
|
|
590
590
|
}
|
|
591
591
|
|
|
592
592
|
// src/charts/bar/compute.ts
|
|
593
|
-
import { abbreviateNumber, formatNumber } from "@opendata-ai/openchart-core";
|
|
593
|
+
import { abbreviateNumber, formatNumber, isGradientDef } from "@opendata-ai/openchart-core";
|
|
594
594
|
|
|
595
595
|
// src/transforms/predicates.ts
|
|
596
596
|
function isFieldPredicate(pred) {
|
|
@@ -933,9 +933,12 @@ function computeSimpleBars(data, valueField, categoryField, xScale, yScale, band
|
|
|
933
933
|
if (bandY === void 0) continue;
|
|
934
934
|
let color2;
|
|
935
935
|
if (conditionalColor) {
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
936
|
+
const resolved = resolveConditionalValue(row, conditionalColor);
|
|
937
|
+
if (resolved != null) {
|
|
938
|
+
color2 = isGradientDef(resolved) ? resolved : String(resolved);
|
|
939
|
+
} else {
|
|
940
|
+
color2 = getColor(scales, "__default__");
|
|
941
|
+
}
|
|
939
942
|
} else if (sequentialColor) {
|
|
940
943
|
color2 = getSequentialColor(scales, value2);
|
|
941
944
|
} else {
|
|
@@ -966,6 +969,7 @@ function computeSimpleBars(data, valueField, categoryField, xScale, yScale, band
|
|
|
966
969
|
import {
|
|
967
970
|
buildD3Formatter,
|
|
968
971
|
estimateTextWidth as estimateTextWidth2,
|
|
972
|
+
getRepresentativeColor,
|
|
969
973
|
resolveCollisions
|
|
970
974
|
} from "@opendata-ai/openchart-core";
|
|
971
975
|
var SUFFIX_MULTIPLIERS = {
|
|
@@ -1024,7 +1028,7 @@ function computeBarLabels(marks, _chartArea, density = "auto", labelFormat, labe
|
|
|
1024
1028
|
textAnchor = "end";
|
|
1025
1029
|
} else {
|
|
1026
1030
|
anchorX = mark.x + mark.width + LABEL_PADDING;
|
|
1027
|
-
fill = mark.fill;
|
|
1031
|
+
fill = getRepresentativeColor(mark.fill);
|
|
1028
1032
|
textAnchor = "start";
|
|
1029
1033
|
}
|
|
1030
1034
|
const anchorY = mark.y + mark.height / 2;
|
|
@@ -1103,7 +1107,7 @@ var barRenderer = (spec, scales, chartArea, strategy, _theme) => {
|
|
|
1103
1107
|
};
|
|
1104
1108
|
|
|
1105
1109
|
// src/charts/column/compute.ts
|
|
1106
|
-
import { abbreviateNumber as abbreviateNumber2, formatNumber as formatNumber2 } from "@opendata-ai/openchart-core";
|
|
1110
|
+
import { abbreviateNumber as abbreviateNumber2, formatNumber as formatNumber2, isGradientDef as isGradientDef2 } from "@opendata-ai/openchart-core";
|
|
1107
1111
|
var MIN_COLUMN_HEIGHT = 1;
|
|
1108
1112
|
function formatColumnValue(value2) {
|
|
1109
1113
|
if (Math.abs(value2) >= 1e3) return abbreviateNumber2(value2);
|
|
@@ -1192,9 +1196,12 @@ function computeSimpleColumns(data, categoryField, valueField, xScale, yScale, b
|
|
|
1192
1196
|
if (bandX === void 0) continue;
|
|
1193
1197
|
let color2;
|
|
1194
1198
|
if (conditionalColor) {
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1199
|
+
const resolved = resolveConditionalValue(row, conditionalColor);
|
|
1200
|
+
if (resolved != null) {
|
|
1201
|
+
color2 = isGradientDef2(resolved) ? resolved : String(resolved);
|
|
1202
|
+
} else {
|
|
1203
|
+
color2 = getColor(scales, "__default__");
|
|
1204
|
+
}
|
|
1198
1205
|
} else if (sequentialColor) {
|
|
1199
1206
|
color2 = getSequentialColor(scales, value2);
|
|
1200
1207
|
} else {
|
|
@@ -1342,6 +1349,7 @@ function computeStackedColumns(data, categoryField, valueField, colorField, xSca
|
|
|
1342
1349
|
import {
|
|
1343
1350
|
buildD3Formatter as buildD3Formatter2,
|
|
1344
1351
|
estimateTextWidth as estimateTextWidth3,
|
|
1352
|
+
getRepresentativeColor as getRepresentativeColor2,
|
|
1345
1353
|
resolveCollisions as resolveCollisions2
|
|
1346
1354
|
} from "@opendata-ai/openchart-core";
|
|
1347
1355
|
var LABEL_FONT_SIZE2 = 10;
|
|
@@ -1380,7 +1388,7 @@ function computeColumnLabels(marks, _chartArea, density = "auto", labelFormat, l
|
|
|
1380
1388
|
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
1381
1389
|
fontSize: LABEL_FONT_SIZE2,
|
|
1382
1390
|
fontWeight: LABEL_FONT_WEIGHT2,
|
|
1383
|
-
fill: mark.fill,
|
|
1391
|
+
fill: getRepresentativeColor2(mark.fill),
|
|
1384
1392
|
lineHeight: 1.2,
|
|
1385
1393
|
textAnchor: "middle",
|
|
1386
1394
|
dominantBaseline: isNegative ? "hanging" : "auto"
|
|
@@ -1565,7 +1573,11 @@ function computeLollipopMarks(data, valueField, categoryField, xScale, yScale, b
|
|
|
1565
1573
|
}
|
|
1566
1574
|
|
|
1567
1575
|
// src/charts/dot/labels.ts
|
|
1568
|
-
import {
|
|
1576
|
+
import {
|
|
1577
|
+
estimateTextWidth as estimateTextWidth4,
|
|
1578
|
+
getRepresentativeColor as getRepresentativeColor3,
|
|
1579
|
+
resolveCollisions as resolveCollisions3
|
|
1580
|
+
} from "@opendata-ai/openchart-core";
|
|
1569
1581
|
var LABEL_FONT_SIZE3 = 11;
|
|
1570
1582
|
var LABEL_FONT_WEIGHT3 = 600;
|
|
1571
1583
|
var LABEL_OFFSET_X = 10;
|
|
@@ -1592,7 +1604,7 @@ function computeDotLabels(marks, _chartArea, density = "auto", labelPrefix) {
|
|
|
1592
1604
|
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
1593
1605
|
fontSize: LABEL_FONT_SIZE3,
|
|
1594
1606
|
fontWeight: LABEL_FONT_WEIGHT3,
|
|
1595
|
-
fill: mark.fill,
|
|
1607
|
+
fill: getRepresentativeColor3(mark.fill),
|
|
1596
1608
|
lineHeight: 1.2,
|
|
1597
1609
|
textAnchor: "start",
|
|
1598
1610
|
dominantBaseline: "central"
|
|
@@ -1627,6 +1639,9 @@ var dotRenderer = (spec, scales, chartArea, strategy, _theme) => {
|
|
|
1627
1639
|
return marks;
|
|
1628
1640
|
};
|
|
1629
1641
|
|
|
1642
|
+
// src/charts/line/area.ts
|
|
1643
|
+
import { getRepresentativeColor as getRepresentativeColor4 } from "@opendata-ai/openchart-core";
|
|
1644
|
+
|
|
1630
1645
|
// ../../node_modules/.bun/d3-shape@3.2.0/node_modules/d3-shape/src/constant.js
|
|
1631
1646
|
function constant_default(x2) {
|
|
1632
1647
|
return function constant2() {
|
|
@@ -2581,7 +2596,7 @@ function computeSingleArea(spec, scales, _chartArea) {
|
|
|
2581
2596
|
topPath: topPathStr,
|
|
2582
2597
|
fill: color2,
|
|
2583
2598
|
fillOpacity: DEFAULT_FILL_OPACITY,
|
|
2584
|
-
stroke: color2,
|
|
2599
|
+
stroke: getRepresentativeColor4(color2),
|
|
2585
2600
|
strokeWidth: 2,
|
|
2586
2601
|
seriesKey: seriesKey === "__default__" ? void 0 : seriesKey,
|
|
2587
2602
|
data: validPoints.map((p) => p.row),
|
|
@@ -2668,7 +2683,7 @@ function computeStackedArea(spec, scales, chartArea) {
|
|
|
2668
2683
|
fill: color2,
|
|
2669
2684
|
fillOpacity: 0.7,
|
|
2670
2685
|
// Higher opacity for stacked so layers are visible
|
|
2671
|
-
stroke: color2,
|
|
2686
|
+
stroke: getRepresentativeColor4(color2),
|
|
2672
2687
|
strokeWidth: 1,
|
|
2673
2688
|
seriesKey,
|
|
2674
2689
|
data: layer.map((d) => {
|
|
@@ -2695,6 +2710,7 @@ function computeAreaMarks(spec, scales, chartArea) {
|
|
|
2695
2710
|
}
|
|
2696
2711
|
|
|
2697
2712
|
// src/charts/line/compute.ts
|
|
2713
|
+
import { getRepresentativeColor as getRepresentativeColor5 } from "@opendata-ai/openchart-core";
|
|
2698
2714
|
var DEFAULT_STROKE_WIDTH = 2.5;
|
|
2699
2715
|
var DEFAULT_POINT_RADIUS = 3;
|
|
2700
2716
|
function computeLineMarks(spec, scales, _chartArea, _strategy) {
|
|
@@ -2712,6 +2728,7 @@ function computeLineMarks(spec, scales, _chartArea, _strategy) {
|
|
|
2712
2728
|
const marks = [];
|
|
2713
2729
|
for (const [seriesKey, rows] of groups) {
|
|
2714
2730
|
const color2 = isSequentialColor ? getSequentialColor(scales, _getMidValue(rows, sequentialColorField)) : getColor(scales, seriesKey);
|
|
2731
|
+
const strokeColor = getRepresentativeColor5(color2);
|
|
2715
2732
|
const sortedRows = sortByField(rows, xChannel.field);
|
|
2716
2733
|
const pointsWithData = [];
|
|
2717
2734
|
const segments = [];
|
|
@@ -2760,7 +2777,7 @@ function computeLineMarks(spec, scales, _chartArea, _strategy) {
|
|
|
2760
2777
|
type: "line",
|
|
2761
2778
|
points: allPoints,
|
|
2762
2779
|
path: combinedPath,
|
|
2763
|
-
stroke:
|
|
2780
|
+
stroke: strokeColor,
|
|
2764
2781
|
strokeWidth: styleOverride?.strokeWidth ?? DEFAULT_STROKE_WIDTH,
|
|
2765
2782
|
strokeDasharray,
|
|
2766
2783
|
opacity: styleOverride?.opacity,
|
|
@@ -2905,6 +2922,7 @@ var areaRenderer = (spec, scales, chartArea, strategy, _theme) => {
|
|
|
2905
2922
|
};
|
|
2906
2923
|
|
|
2907
2924
|
// src/charts/pie/compute.ts
|
|
2925
|
+
import { isConditionalDef, isGradientDef as isGradientDef3 } from "@opendata-ai/openchart-core";
|
|
2908
2926
|
var SMALL_SLICE_THRESHOLD = 0.03;
|
|
2909
2927
|
var DEFAULT_PALETTE = [
|
|
2910
2928
|
"#1b7fa3",
|
|
@@ -2943,6 +2961,7 @@ function computePieMarks(spec, scales, chartArea, _strategy, isDonut = false) {
|
|
|
2943
2961
|
const encoding = spec.encoding;
|
|
2944
2962
|
const valueChannel = encoding.y ?? encoding.x;
|
|
2945
2963
|
const categoryField = encoding.color && "field" in encoding.color ? encoding.color.field : void 0;
|
|
2964
|
+
const conditionalColor = encoding.color && isConditionalDef(encoding.color) ? encoding.color : void 0;
|
|
2946
2965
|
if (!valueChannel) return [];
|
|
2947
2966
|
let slices = [];
|
|
2948
2967
|
if (categoryField) {
|
|
@@ -2993,7 +3012,20 @@ function computePieMarks(spec, scales, chartArea, _strategy, isDonut = false) {
|
|
|
2993
3012
|
const arcDatum = arcs[i];
|
|
2994
3013
|
const slice2 = arcDatum.data;
|
|
2995
3014
|
let color2;
|
|
2996
|
-
if (
|
|
3015
|
+
if (conditionalColor) {
|
|
3016
|
+
const resolved = resolveConditionalValue(
|
|
3017
|
+
slice2.originalRow,
|
|
3018
|
+
conditionalColor
|
|
3019
|
+
);
|
|
3020
|
+
if (resolved != null) {
|
|
3021
|
+
color2 = isGradientDef3(resolved) ? resolved : String(resolved);
|
|
3022
|
+
} else if (scales.color && categoryField) {
|
|
3023
|
+
const colorScale = scales.color.scale;
|
|
3024
|
+
color2 = colorScale(slice2.label);
|
|
3025
|
+
} else {
|
|
3026
|
+
color2 = DEFAULT_PALETTE[i % DEFAULT_PALETTE.length];
|
|
3027
|
+
}
|
|
3028
|
+
} else if (scales.color && categoryField) {
|
|
2997
3029
|
const colorScale = scales.color.scale;
|
|
2998
3030
|
color2 = colorScale(slice2.label);
|
|
2999
3031
|
} else {
|
|
@@ -3131,6 +3163,7 @@ function clearRenderers() {
|
|
|
3131
3163
|
}
|
|
3132
3164
|
|
|
3133
3165
|
// src/charts/rule/index.ts
|
|
3166
|
+
import { getRepresentativeColor as getRepresentativeColor6 } from "@opendata-ai/openchart-core";
|
|
3134
3167
|
function computeRuleMarks(spec, scales, chartArea) {
|
|
3135
3168
|
const encoding = spec.encoding;
|
|
3136
3169
|
const xChannel = encoding.x;
|
|
@@ -3173,7 +3206,9 @@ function computeRuleMarks(spec, scales, chartArea) {
|
|
|
3173
3206
|
const y2Val = scaleValue(scales.y.scale, scales.y.type, row[y2Channel.field]);
|
|
3174
3207
|
if (y2Val != null) y2 = y2Val;
|
|
3175
3208
|
}
|
|
3176
|
-
const color2 =
|
|
3209
|
+
const color2 = getRepresentativeColor6(
|
|
3210
|
+
colorField ? getColor(scales, String(row[colorField] ?? "__default__")) : getColor(scales, "__default__")
|
|
3211
|
+
);
|
|
3177
3212
|
const strokeDashEncoding = encoding.strokeDash && "field" in encoding.strokeDash ? encoding.strokeDash : void 0;
|
|
3178
3213
|
const strokeDasharray = strokeDashEncoding ? String(row[strokeDashEncoding.field] ?? "") : void 0;
|
|
3179
3214
|
const aria = {
|
|
@@ -5980,6 +6015,7 @@ var scatterRenderer = (spec, scales, chartArea, strategy, _theme) => {
|
|
|
5980
6015
|
};
|
|
5981
6016
|
|
|
5982
6017
|
// src/charts/text/index.ts
|
|
6018
|
+
import { getRepresentativeColor as getRepresentativeColor7 } from "@opendata-ai/openchart-core";
|
|
5983
6019
|
function computeTextMarks(spec, scales) {
|
|
5984
6020
|
const encoding = spec.encoding;
|
|
5985
6021
|
const xChannel = encoding.x;
|
|
@@ -6005,7 +6041,9 @@ function computeTextMarks(spec, scales) {
|
|
|
6005
6041
|
}
|
|
6006
6042
|
const text = String(row[textChannel.field] ?? "");
|
|
6007
6043
|
if (!text) continue;
|
|
6008
|
-
const color2 =
|
|
6044
|
+
const color2 = getRepresentativeColor7(
|
|
6045
|
+
colorField ? getColor(scales, String(row[colorField] ?? "__default__")) : getColor(scales, "__default__")
|
|
6046
|
+
);
|
|
6009
6047
|
const fontSize = sizeEncoding ? Math.max(8, Math.min(48, Number(row[sizeEncoding.field]) || 12)) : 12;
|
|
6010
6048
|
const aria = {
|
|
6011
6049
|
label: text
|
|
@@ -6030,6 +6068,7 @@ var textRenderer = (spec, scales, _chartArea, _strategy, _theme) => {
|
|
|
6030
6068
|
};
|
|
6031
6069
|
|
|
6032
6070
|
// src/charts/tick/index.ts
|
|
6071
|
+
import { getRepresentativeColor as getRepresentativeColor8 } from "@opendata-ai/openchart-core";
|
|
6033
6072
|
var DEFAULT_TICK_LENGTH = 18;
|
|
6034
6073
|
function computeTickMarks(spec, scales, _chartArea) {
|
|
6035
6074
|
const encoding = spec.encoding;
|
|
@@ -6045,7 +6084,9 @@ function computeTickMarks(spec, scales, _chartArea) {
|
|
|
6045
6084
|
const xVal = scaleValue(scales.x.scale, scales.x.type, row[xChannel.field]);
|
|
6046
6085
|
const yVal = scaleValue(scales.y.scale, scales.y.type, row[yChannel.field]);
|
|
6047
6086
|
if (xVal == null || yVal == null) continue;
|
|
6048
|
-
const color2 =
|
|
6087
|
+
const color2 = getRepresentativeColor8(
|
|
6088
|
+
colorField ? getColor(scales, String(row[colorField] ?? "__default__")) : getColor(scales, "__default__")
|
|
6089
|
+
);
|
|
6049
6090
|
const aria = {
|
|
6050
6091
|
label: `${row[xChannel.field]}, ${row[yChannel.field]}`
|
|
6051
6092
|
};
|
|
@@ -6203,7 +6244,8 @@ function normalizeChartSpec(spec, warnings) {
|
|
|
6203
6244
|
theme: spec.theme ?? {},
|
|
6204
6245
|
darkMode: spec.darkMode ?? "off",
|
|
6205
6246
|
hiddenSeries: spec.hiddenSeries ?? [],
|
|
6206
|
-
seriesStyles: spec.seriesStyles ?? {}
|
|
6247
|
+
seriesStyles: spec.seriesStyles ?? {},
|
|
6248
|
+
watermark: spec.watermark ?? true
|
|
6207
6249
|
};
|
|
6208
6250
|
}
|
|
6209
6251
|
function normalizeTableSpec(spec, _warnings) {
|
|
@@ -6220,7 +6262,8 @@ function normalizeTableSpec(spec, _warnings) {
|
|
|
6220
6262
|
stickyFirstColumn: spec.stickyFirstColumn ?? false,
|
|
6221
6263
|
compact: spec.compact ?? false,
|
|
6222
6264
|
responsive: spec.responsive ?? true,
|
|
6223
|
-
animation: spec.animation
|
|
6265
|
+
animation: spec.animation,
|
|
6266
|
+
watermark: spec.watermark ?? true
|
|
6224
6267
|
};
|
|
6225
6268
|
}
|
|
6226
6269
|
function normalizeSankeySpec(spec, _warnings) {
|
|
@@ -6240,7 +6283,8 @@ function normalizeSankeySpec(spec, _warnings) {
|
|
|
6240
6283
|
darkMode: spec.darkMode ?? "off",
|
|
6241
6284
|
animation: spec.animation,
|
|
6242
6285
|
valueFormat: spec.valueFormat,
|
|
6243
|
-
linkOpacity: spec.linkOpacity
|
|
6286
|
+
linkOpacity: spec.linkOpacity,
|
|
6287
|
+
watermark: spec.watermark ?? true
|
|
6244
6288
|
};
|
|
6245
6289
|
}
|
|
6246
6290
|
function normalizeGraphSpec(spec, _warnings) {
|
|
@@ -6263,7 +6307,8 @@ function normalizeGraphSpec(spec, _warnings) {
|
|
|
6263
6307
|
chrome: normalizeChrome(spec.chrome),
|
|
6264
6308
|
annotations: normalizeAnnotations(spec.annotations),
|
|
6265
6309
|
theme: spec.theme ?? {},
|
|
6266
|
-
darkMode: spec.darkMode ?? "off"
|
|
6310
|
+
darkMode: spec.darkMode ?? "off",
|
|
6311
|
+
watermark: spec.watermark ?? true
|
|
6267
6312
|
};
|
|
6268
6313
|
}
|
|
6269
6314
|
function normalizeSpec(spec, warnings = []) {
|
|
@@ -6290,14 +6335,23 @@ function normalizeSpec(spec, warnings = []) {
|
|
|
6290
6335
|
`Unknown spec shape. Expected mark (chart), layer, type: 'table', type: 'graph', or type: 'sankey'.`
|
|
6291
6336
|
);
|
|
6292
6337
|
}
|
|
6293
|
-
function flattenLayers(spec, parentData, parentEncoding, parentTransforms) {
|
|
6338
|
+
function flattenLayers(spec, parentData, parentEncoding, parentTransforms, parentWatermark) {
|
|
6294
6339
|
const resolvedData = spec.data ?? parentData;
|
|
6295
6340
|
const resolvedEncoding = parentEncoding && spec.encoding ? { ...parentEncoding, ...spec.encoding } : spec.encoding ?? parentEncoding;
|
|
6296
6341
|
const resolvedTransforms = [...parentTransforms ?? [], ...spec.transform ?? []];
|
|
6342
|
+
const resolvedWatermark = spec.watermark ?? parentWatermark;
|
|
6297
6343
|
const leaves = [];
|
|
6298
6344
|
for (const child of spec.layer) {
|
|
6299
6345
|
if (isLayerSpec(child)) {
|
|
6300
|
-
leaves.push(
|
|
6346
|
+
leaves.push(
|
|
6347
|
+
...flattenLayers(
|
|
6348
|
+
child,
|
|
6349
|
+
resolvedData,
|
|
6350
|
+
resolvedEncoding,
|
|
6351
|
+
resolvedTransforms,
|
|
6352
|
+
resolvedWatermark
|
|
6353
|
+
)
|
|
6354
|
+
);
|
|
6301
6355
|
} else {
|
|
6302
6356
|
const mergedData = child.data ?? resolvedData ?? [];
|
|
6303
6357
|
const mergedEncoding = resolvedEncoding ? { ...resolvedEncoding, ...child.encoding } : child.encoding;
|
|
@@ -6306,7 +6360,9 @@ function flattenLayers(spec, parentData, parentEncoding, parentTransforms) {
|
|
|
6306
6360
|
...child,
|
|
6307
6361
|
data: mergedData,
|
|
6308
6362
|
encoding: mergedEncoding,
|
|
6309
|
-
transform: mergedTransforms.length > 0 ? mergedTransforms : void 0
|
|
6363
|
+
transform: mergedTransforms.length > 0 ? mergedTransforms : void 0,
|
|
6364
|
+
// Inherit parent watermark if child doesn't explicitly set one
|
|
6365
|
+
...child.watermark === void 0 && resolvedWatermark !== void 0 ? { watermark: resolvedWatermark } : {}
|
|
6310
6366
|
});
|
|
6311
6367
|
}
|
|
6312
6368
|
}
|
|
@@ -7365,6 +7421,8 @@ function compileGraph(spec, options) {
|
|
|
7365
7421
|
);
|
|
7366
7422
|
}
|
|
7367
7423
|
const graphSpec = normalized;
|
|
7424
|
+
const rawWatermark = spec.watermark;
|
|
7425
|
+
const watermark = rawWatermark !== void 0 ? graphSpec.watermark : options.watermark ?? true;
|
|
7368
7426
|
const mergedThemeConfig = options.theme ? { ...graphSpec.theme, ...options.theme } : graphSpec.theme;
|
|
7369
7427
|
let theme = resolveTheme(mergedThemeConfig);
|
|
7370
7428
|
if (options.darkMode) {
|
|
@@ -7432,7 +7490,10 @@ function compileGraph(spec, options) {
|
|
|
7432
7490
|
},
|
|
7433
7491
|
theme,
|
|
7434
7492
|
options.width,
|
|
7435
|
-
options.measureText
|
|
7493
|
+
options.measureText,
|
|
7494
|
+
"full",
|
|
7495
|
+
void 0,
|
|
7496
|
+
watermark
|
|
7436
7497
|
);
|
|
7437
7498
|
return {
|
|
7438
7499
|
nodes: compiledNodes,
|
|
@@ -7446,7 +7507,8 @@ function compileGraph(spec, options) {
|
|
|
7446
7507
|
width: options.width,
|
|
7447
7508
|
height: options.height
|
|
7448
7509
|
},
|
|
7449
|
-
simulationConfig
|
|
7510
|
+
simulationConfig,
|
|
7511
|
+
watermark
|
|
7450
7512
|
};
|
|
7451
7513
|
}
|
|
7452
7514
|
var DEFAULT_COLLISION_PADDING = 5;
|
|
@@ -7745,7 +7807,7 @@ function scalePadding(basePadding, width, height) {
|
|
|
7745
7807
|
}
|
|
7746
7808
|
var MIN_CHART_WIDTH = 60;
|
|
7747
7809
|
var MIN_CHART_HEIGHT = 40;
|
|
7748
|
-
function computeDimensions(spec, options, legendLayout, theme, strategy) {
|
|
7810
|
+
function computeDimensions(spec, options, legendLayout, theme, strategy, watermark = true) {
|
|
7749
7811
|
const { width, height } = options;
|
|
7750
7812
|
const padding = scalePadding(theme.spacing.padding, width, height);
|
|
7751
7813
|
const axisMargin = theme.spacing.axisMargin;
|
|
@@ -7756,7 +7818,8 @@ function computeDimensions(spec, options, legendLayout, theme, strategy) {
|
|
|
7756
7818
|
width,
|
|
7757
7819
|
options.measureText,
|
|
7758
7820
|
chromeMode,
|
|
7759
|
-
padding
|
|
7821
|
+
padding,
|
|
7822
|
+
watermark
|
|
7760
7823
|
);
|
|
7761
7824
|
const total = { x: 0, y: 0, width, height };
|
|
7762
7825
|
const isRadial = spec.markType === "arc";
|
|
@@ -7914,7 +7977,8 @@ function computeDimensions(spec, options, legendLayout, theme, strategy) {
|
|
|
7914
7977
|
width,
|
|
7915
7978
|
options.measureText,
|
|
7916
7979
|
fallbackMode,
|
|
7917
|
-
padding
|
|
7980
|
+
padding,
|
|
7981
|
+
watermark
|
|
7918
7982
|
);
|
|
7919
7983
|
const fallbackTopAxisGap = isRadial && fallbackChrome.topHeight === 0 ? 0 : axisMargin;
|
|
7920
7984
|
const newTop = padding + fallbackChrome.topHeight + fallbackTopAxisGap;
|
|
@@ -8400,7 +8464,7 @@ function truncateEntries(entries, maxCount) {
|
|
|
8400
8464
|
});
|
|
8401
8465
|
return truncated;
|
|
8402
8466
|
}
|
|
8403
|
-
function computeLegend(spec, strategy, theme, chartArea) {
|
|
8467
|
+
function computeLegend(spec, strategy, theme, chartArea, watermark = true) {
|
|
8404
8468
|
if (spec.legend?.show === false || strategy.legendMaxHeight === 0) {
|
|
8405
8469
|
return {
|
|
8406
8470
|
position: "top",
|
|
@@ -8477,7 +8541,7 @@ function computeLegend(spec, strategy, theme, chartArea) {
|
|
|
8477
8541
|
entryGap: 4
|
|
8478
8542
|
};
|
|
8479
8543
|
}
|
|
8480
|
-
const availableWidth = chartArea.width - LEGEND_PADDING * 2 - BRAND_RESERVE_WIDTH;
|
|
8544
|
+
const availableWidth = chartArea.width - LEGEND_PADDING * 2 - (watermark ? BRAND_RESERVE_WIDTH : 0);
|
|
8481
8545
|
if (spec.legend?.symbolLimit != null) {
|
|
8482
8546
|
const limit = Math.max(1, spec.legend.symbolLimit);
|
|
8483
8547
|
if (limit < entries.length) {
|
|
@@ -9096,6 +9160,8 @@ function compileSankey(spec, options) {
|
|
|
9096
9160
|
);
|
|
9097
9161
|
}
|
|
9098
9162
|
const sankeySpec = normalized;
|
|
9163
|
+
const rawWatermark = spec.watermark;
|
|
9164
|
+
const watermark = rawWatermark !== void 0 ? sankeySpec.watermark : options.watermark ?? true;
|
|
9099
9165
|
const mergedThemeConfig = options.theme ? { ...sankeySpec.theme, ...options.theme } : sankeySpec.theme;
|
|
9100
9166
|
const lightTheme = resolveTheme2(mergedThemeConfig);
|
|
9101
9167
|
let theme = lightTheme;
|
|
@@ -9116,7 +9182,10 @@ function compileSankey(spec, options) {
|
|
|
9116
9182
|
},
|
|
9117
9183
|
theme,
|
|
9118
9184
|
options.width,
|
|
9119
|
-
options.measureText
|
|
9185
|
+
options.measureText,
|
|
9186
|
+
"full",
|
|
9187
|
+
void 0,
|
|
9188
|
+
watermark
|
|
9120
9189
|
);
|
|
9121
9190
|
const padding = theme.spacing.padding;
|
|
9122
9191
|
const fullArea = {
|
|
@@ -9126,7 +9195,7 @@ function compileSankey(spec, options) {
|
|
|
9126
9195
|
height: options.height - chrome.topHeight - chrome.bottomHeight - padding * 2
|
|
9127
9196
|
};
|
|
9128
9197
|
if (fullArea.width <= 0 || fullArea.height <= 0) {
|
|
9129
|
-
return emptyLayout(fullArea, chrome, theme, options);
|
|
9198
|
+
return emptyLayout(fullArea, chrome, theme, options, watermark);
|
|
9130
9199
|
}
|
|
9131
9200
|
const sourceField = sankeySpec.encoding.source.field;
|
|
9132
9201
|
const targetField = sankeySpec.encoding.target.field;
|
|
@@ -9162,7 +9231,7 @@ function compileSankey(spec, options) {
|
|
|
9162
9231
|
height: fullArea.height - legend.bounds.height - legendGap
|
|
9163
9232
|
};
|
|
9164
9233
|
if (area.height <= 0) {
|
|
9165
|
-
return emptyLayout(area, chrome, theme, options);
|
|
9234
|
+
return emptyLayout(area, chrome, theme, options, watermark);
|
|
9166
9235
|
}
|
|
9167
9236
|
const labelFontSize = theme.fonts.sizes.small;
|
|
9168
9237
|
const labelFontWeight = theme.fonts.weights.normal;
|
|
@@ -9306,7 +9375,8 @@ function compileSankey(spec, options) {
|
|
|
9306
9375
|
width: options.width,
|
|
9307
9376
|
height: options.height
|
|
9308
9377
|
},
|
|
9309
|
-
animation: resolvedAnimation
|
|
9378
|
+
animation: resolvedAnimation,
|
|
9379
|
+
watermark
|
|
9310
9380
|
};
|
|
9311
9381
|
}
|
|
9312
9382
|
function buildSankeyLegend(nodeColorMap, colorField, data, sourceField, targetField, theme, area) {
|
|
@@ -9413,7 +9483,7 @@ function buildTooltipDescriptors(nodes, links, valueFormat) {
|
|
|
9413
9483
|
}
|
|
9414
9484
|
return descriptors;
|
|
9415
9485
|
}
|
|
9416
|
-
function emptyLayout(area, chrome, theme, options) {
|
|
9486
|
+
function emptyLayout(area, chrome, theme, options, watermark) {
|
|
9417
9487
|
return {
|
|
9418
9488
|
area,
|
|
9419
9489
|
chrome,
|
|
@@ -9445,7 +9515,8 @@ function emptyLayout(area, chrome, theme, options) {
|
|
|
9445
9515
|
dimensions: {
|
|
9446
9516
|
width: options.width,
|
|
9447
9517
|
height: options.height
|
|
9448
|
-
}
|
|
9518
|
+
},
|
|
9519
|
+
watermark
|
|
9449
9520
|
};
|
|
9450
9521
|
}
|
|
9451
9522
|
|
|
@@ -10045,6 +10116,7 @@ function compileTableLayout(spec, options, theme) {
|
|
|
10045
10116
|
});
|
|
10046
10117
|
return { id: rowId, cells, data: row };
|
|
10047
10118
|
});
|
|
10119
|
+
const watermark = spec.watermark;
|
|
10048
10120
|
const chrome = computeChrome4(
|
|
10049
10121
|
{
|
|
10050
10122
|
title: spec.chrome.title,
|
|
@@ -10055,7 +10127,10 @@ function compileTableLayout(spec, options, theme) {
|
|
|
10055
10127
|
},
|
|
10056
10128
|
theme,
|
|
10057
10129
|
options.width,
|
|
10058
|
-
options.measureText
|
|
10130
|
+
options.measureText,
|
|
10131
|
+
"full",
|
|
10132
|
+
void 0,
|
|
10133
|
+
watermark
|
|
10059
10134
|
);
|
|
10060
10135
|
const titleText = spec.chrome.title?.text ?? "";
|
|
10061
10136
|
const caption = titleText ? `Table: ${titleText}` : `Data table with ${data.length} rows`;
|
|
@@ -10077,12 +10152,18 @@ function compileTableLayout(spec, options, theme) {
|
|
|
10077
10152
|
summary: `${resolvedColumns.length} columns, ${totalFiltered} rows`
|
|
10078
10153
|
},
|
|
10079
10154
|
theme,
|
|
10080
|
-
animation: resolveAnimation(spec.animation)
|
|
10155
|
+
animation: resolveAnimation(spec.animation),
|
|
10156
|
+
watermark
|
|
10081
10157
|
};
|
|
10082
10158
|
}
|
|
10083
10159
|
|
|
10084
10160
|
// src/tooltips/compute.ts
|
|
10085
|
-
import {
|
|
10161
|
+
import {
|
|
10162
|
+
buildTemporalFormatter as buildTemporalFormatter2,
|
|
10163
|
+
formatDate as formatDate3,
|
|
10164
|
+
formatNumber as formatNumber6,
|
|
10165
|
+
getRepresentativeColor as getRepresentativeColor9
|
|
10166
|
+
} from "@opendata-ai/openchart-core";
|
|
10086
10167
|
function formatValue(value2, fieldType, format2) {
|
|
10087
10168
|
if (value2 == null) return "";
|
|
10088
10169
|
if (fieldType === "temporal" || value2 instanceof Date) {
|
|
@@ -10166,12 +10247,12 @@ function tooltipsForLine(mark, encoding, _markIndex) {
|
|
|
10166
10247
|
}
|
|
10167
10248
|
function tooltipsForPoint(mark, encoding, markIndex) {
|
|
10168
10249
|
const title = getTooltipTitle(mark.data, encoding);
|
|
10169
|
-
const fields = buildFields(mark.data, encoding, mark.fill);
|
|
10250
|
+
const fields = buildFields(mark.data, encoding, getRepresentativeColor9(mark.fill));
|
|
10170
10251
|
return [[`point-${markIndex}`, { title, fields }]];
|
|
10171
10252
|
}
|
|
10172
10253
|
function tooltipsForRect(mark, encoding, markIndex) {
|
|
10173
10254
|
const title = getTooltipTitle(mark.data, encoding);
|
|
10174
|
-
const fields = buildFields(mark.data, encoding, mark.fill);
|
|
10255
|
+
const fields = buildFields(mark.data, encoding, getRepresentativeColor9(mark.fill));
|
|
10175
10256
|
return [[`rect-${markIndex}`, { title, fields }]];
|
|
10176
10257
|
}
|
|
10177
10258
|
function tooltipsForArc(mark, encoding, markIndex) {
|
|
@@ -10184,14 +10265,14 @@ function tooltipsForArc(mark, encoding, markIndex) {
|
|
|
10184
10265
|
fields.push({
|
|
10185
10266
|
label: categoryName,
|
|
10186
10267
|
value: formatValue(row[encoding.y.field], encoding.y.type, encoding.y.axis?.format),
|
|
10187
|
-
color: mark.fill
|
|
10268
|
+
color: getRepresentativeColor9(mark.fill)
|
|
10188
10269
|
});
|
|
10189
10270
|
}
|
|
10190
10271
|
} else if (encoding.y) {
|
|
10191
10272
|
fields.push({
|
|
10192
10273
|
label: encoding.y.field,
|
|
10193
10274
|
value: formatValue(row[encoding.y.field], encoding.y.type, encoding.y.axis?.format),
|
|
10194
|
-
color: mark.fill
|
|
10275
|
+
color: getRepresentativeColor9(mark.fill)
|
|
10195
10276
|
});
|
|
10196
10277
|
}
|
|
10197
10278
|
const title = colorEnc ? String(row[colorEnc.field] ?? "") : void 0;
|
|
@@ -10202,7 +10283,7 @@ function tooltipsForArea(mark, encoding, _markIndex) {
|
|
|
10202
10283
|
for (const dp of mark.dataPoints) {
|
|
10203
10284
|
dp.tooltip = {
|
|
10204
10285
|
title: getTooltipTitle(dp.datum, encoding),
|
|
10205
|
-
fields: buildFields(dp.datum, encoding, mark.fill)
|
|
10286
|
+
fields: buildFields(dp.datum, encoding, getRepresentativeColor9(mark.fill))
|
|
10206
10287
|
};
|
|
10207
10288
|
}
|
|
10208
10289
|
}
|
|
@@ -10518,6 +10599,8 @@ function compileChart(spec, options) {
|
|
|
10518
10599
|
throw new Error("compileChart received a sankey spec. Use compileSankey instead.");
|
|
10519
10600
|
}
|
|
10520
10601
|
let chartSpec = normalized;
|
|
10602
|
+
const rawWatermark = spec.watermark;
|
|
10603
|
+
const watermark = rawWatermark !== void 0 ? chartSpec.watermark : options.watermark ?? true;
|
|
10521
10604
|
const rawTransforms = spec.transform;
|
|
10522
10605
|
if (rawTransforms && rawTransforms.length > 0) {
|
|
10523
10606
|
chartSpec = { ...chartSpec, data: runTransforms(chartSpec.data, rawTransforms) };
|
|
@@ -10576,8 +10659,8 @@ function compileChart(spec, options) {
|
|
|
10576
10659
|
width: options.width,
|
|
10577
10660
|
height: options.height
|
|
10578
10661
|
};
|
|
10579
|
-
const legendLayout = computeLegend(chartSpec, strategy, theme, preliminaryArea);
|
|
10580
|
-
const dims = computeDimensions(chartSpec, options, legendLayout, theme, strategy);
|
|
10662
|
+
const legendLayout = computeLegend(chartSpec, strategy, theme, preliminaryArea, watermark);
|
|
10663
|
+
const dims = computeDimensions(chartSpec, options, legendLayout, theme, strategy, watermark);
|
|
10581
10664
|
const chartArea = dims.chartArea;
|
|
10582
10665
|
const legendArea = { ...chartArea };
|
|
10583
10666
|
if (legendLayout.entries.length > 0) {
|
|
@@ -10595,7 +10678,7 @@ function compileChart(spec, options) {
|
|
|
10595
10678
|
break;
|
|
10596
10679
|
}
|
|
10597
10680
|
}
|
|
10598
|
-
const finalLegend = computeLegend(chartSpec, strategy, theme, legendArea);
|
|
10681
|
+
const finalLegend = computeLegend(chartSpec, strategy, theme, legendArea, watermark);
|
|
10599
10682
|
let renderData = chartSpec.data;
|
|
10600
10683
|
if (chartSpec.hiddenSeries.length > 0 && chartSpec.encoding.color && "field" in chartSpec.encoding.color) {
|
|
10601
10684
|
const colorField = chartSpec.encoding.color.field;
|
|
@@ -10630,7 +10713,7 @@ function compileChart(spec, options) {
|
|
|
10630
10713
|
);
|
|
10631
10714
|
}
|
|
10632
10715
|
}
|
|
10633
|
-
scales.defaultColor = theme.colors.categorical[0];
|
|
10716
|
+
scales.defaultColor = chartSpec.markDef.fill ?? theme.colors.categorical[0];
|
|
10634
10717
|
const isRadial = chartSpec.markType === "arc";
|
|
10635
10718
|
const axes = isRadial ? { x: void 0, y: void 0 } : computeAxes(scales, chartArea, strategy, theme, options.measureText);
|
|
10636
10719
|
if (!isRadial) {
|
|
@@ -10662,12 +10745,14 @@ function compileChart(spec, options) {
|
|
|
10662
10745
|
obstacles.push(computeLabelBounds(mark.label));
|
|
10663
10746
|
}
|
|
10664
10747
|
}
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
10668
|
-
|
|
10669
|
-
|
|
10670
|
-
|
|
10748
|
+
if (watermark) {
|
|
10749
|
+
const brandPadding = theme.spacing.padding;
|
|
10750
|
+
const brandX = dims.total.width - brandPadding - BRAND_RESERVE_WIDTH2;
|
|
10751
|
+
const xAxisExtent = axes.x?.label ? 48 : axes.x ? 26 : 0;
|
|
10752
|
+
const firstBottomChrome = dims.chrome.source ?? dims.chrome.byline ?? dims.chrome.footer;
|
|
10753
|
+
const brandY = firstBottomChrome ? chartArea.y + chartArea.height + xAxisExtent + firstBottomChrome.y : chartArea.y + chartArea.height + xAxisExtent + theme.spacing.chartToFooter;
|
|
10754
|
+
obstacles.push({ x: brandX, y: brandY, width: BRAND_RESERVE_WIDTH2, height: 30 });
|
|
10755
|
+
}
|
|
10671
10756
|
const annotations = computeAnnotations(
|
|
10672
10757
|
chartSpec,
|
|
10673
10758
|
scales,
|
|
@@ -10748,7 +10833,8 @@ function compileChart(spec, options) {
|
|
|
10748
10833
|
width: options.width,
|
|
10749
10834
|
height: options.height
|
|
10750
10835
|
},
|
|
10751
|
-
animation: resolvedAnimation
|
|
10836
|
+
animation: resolvedAnimation,
|
|
10837
|
+
watermark
|
|
10752
10838
|
};
|
|
10753
10839
|
}
|
|
10754
10840
|
function getMarkPrimaryValue(mark) {
|
|
@@ -10818,6 +10904,7 @@ function buildPrimarySpec(leaves, layerSpec) {
|
|
|
10818
10904
|
responsive: layerSpec.responsive ?? leaves[0].responsive,
|
|
10819
10905
|
theme: layerSpec.theme ?? leaves[0].theme,
|
|
10820
10906
|
darkMode: layerSpec.darkMode ?? leaves[0].darkMode,
|
|
10907
|
+
watermark: layerSpec.watermark ?? leaves[0].watermark,
|
|
10821
10908
|
hiddenSeries: layerSpec.hiddenSeries ?? leaves[0].hiddenSeries
|
|
10822
10909
|
};
|
|
10823
10910
|
return primary;
|
|
@@ -10834,7 +10921,9 @@ function compileTable(spec, options) {
|
|
|
10834
10921
|
if (options.darkMode) {
|
|
10835
10922
|
theme = adaptTheme3(theme);
|
|
10836
10923
|
}
|
|
10837
|
-
|
|
10924
|
+
const rawWatermark = spec.watermark;
|
|
10925
|
+
const watermark = rawWatermark !== void 0 ? tableSpec.watermark : options.watermark ?? true;
|
|
10926
|
+
return compileTableLayout({ ...tableSpec, watermark }, options, theme);
|
|
10838
10927
|
}
|
|
10839
10928
|
function compileGraph2(spec, options) {
|
|
10840
10929
|
return compileGraph(spec, options);
|