@opendata-ai/openchart-engine 6.19.2 → 6.20.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.js +105 -123
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/axes.test.ts +68 -0
- package/src/__tests__/legend.test.ts +39 -0
- package/src/charts/_shared/format-label-value.ts +15 -0
- package/src/charts/bar/__tests__/gradient-orient.test.ts +127 -0
- package/src/charts/bar/compute.ts +6 -11
- package/src/charts/bar/labels.ts +2 -9
- package/src/charts/column/compute.ts +6 -11
- package/src/charts/column/labels.ts +2 -13
- package/src/charts/dot/labels.ts +2 -13
- package/src/layout/axes.ts +21 -4
- package/src/legend/compute.ts +6 -51
- package/src/legend/wrap.ts +94 -0
- package/src/sankey/__tests__/node-label-wrap.test.ts +114 -0
- package/src/sankey/__tests__/node-sort.test.ts +45 -0
- package/src/sankey/compile-sankey.ts +5 -20
package/dist/index.js
CHANGED
|
@@ -583,7 +583,7 @@ function computeAnnotations(spec, scales, chartArea, strategy, isDark = false, o
|
|
|
583
583
|
}
|
|
584
584
|
|
|
585
585
|
// src/charts/bar/compute.ts
|
|
586
|
-
import {
|
|
586
|
+
import { isGradientDef } from "@opendata-ai/openchart-core";
|
|
587
587
|
|
|
588
588
|
// src/transforms/predicates.ts
|
|
589
589
|
function isFieldPredicate(pred) {
|
|
@@ -653,6 +653,13 @@ function isConditionalValueDef(def) {
|
|
|
653
653
|
return def !== null && typeof def === "object" && "condition" in def;
|
|
654
654
|
}
|
|
655
655
|
|
|
656
|
+
// src/charts/_shared/format-label-value.ts
|
|
657
|
+
import { abbreviateNumber, formatNumber } from "@opendata-ai/openchart-core";
|
|
658
|
+
function formatLabelValue(value2) {
|
|
659
|
+
if (Math.abs(value2) >= 1e3) return abbreviateNumber(value2);
|
|
660
|
+
return formatNumber(value2);
|
|
661
|
+
}
|
|
662
|
+
|
|
656
663
|
// src/charts/utils.ts
|
|
657
664
|
var DEFAULT_COLOR = "#1b7fa3";
|
|
658
665
|
function scaleValue(scale, scaleType, value2) {
|
|
@@ -735,10 +742,6 @@ function orientGradientForHorizontalBar(grad) {
|
|
|
735
742
|
return { ...lg, x1: 0, y1: 0, x2: 1, y2: 0 };
|
|
736
743
|
}
|
|
737
744
|
var MIN_BAR_WIDTH = 1;
|
|
738
|
-
function formatBarValue(value2) {
|
|
739
|
-
if (Math.abs(value2) >= 1e3) return abbreviateNumber(value2);
|
|
740
|
-
return formatNumber(value2);
|
|
741
|
-
}
|
|
742
745
|
function computeBarMarks(spec, scales, _chartArea, _strategy) {
|
|
743
746
|
const encoding = spec.encoding;
|
|
744
747
|
const xChannel = encoding.x;
|
|
@@ -836,7 +839,7 @@ function computeStackedBars(data, valueField, categoryField, colorField, xScale,
|
|
|
836
839
|
const xRight = xScale(cumulativeValue + value2);
|
|
837
840
|
const barWidth = Math.max(Math.abs(xRight - xLeft), MIN_BAR_WIDTH);
|
|
838
841
|
const aria = {
|
|
839
|
-
label: `${category}, ${groupKey2}: ${
|
|
842
|
+
label: `${category}, ${groupKey2}: ${formatLabelValue(rawValue)}`
|
|
840
843
|
};
|
|
841
844
|
marks.push({
|
|
842
845
|
type: "rect",
|
|
@@ -883,7 +886,7 @@ function computeGroupedBars(data, valueField, categoryField, colorField, xScale,
|
|
|
883
886
|
const barWidth = Math.max(Math.abs(xScale(value2) - baseline), MIN_BAR_WIDTH);
|
|
884
887
|
const subY = bandY + groupIndex * (subBandHeight + gap);
|
|
885
888
|
const aria = {
|
|
886
|
-
label: `${category}, ${groupKey2}: ${
|
|
889
|
+
label: `${category}, ${groupKey2}: ${formatLabelValue(value2)}`
|
|
887
890
|
};
|
|
888
891
|
marks.push({
|
|
889
892
|
type: "rect",
|
|
@@ -914,7 +917,7 @@ function computeColoredBars(data, valueField, categoryField, colorField, xScale,
|
|
|
914
917
|
const xPos = value2 >= 0 ? baseline : xScale(value2);
|
|
915
918
|
const barWidth = Math.max(Math.abs(xScale(value2) - baseline), MIN_BAR_WIDTH);
|
|
916
919
|
const aria = {
|
|
917
|
-
label: `${category}, ${groupKey2}: ${
|
|
920
|
+
label: `${category}, ${groupKey2}: ${formatLabelValue(value2)}`
|
|
918
921
|
};
|
|
919
922
|
marks.push({
|
|
920
923
|
type: "rect",
|
|
@@ -955,7 +958,7 @@ function computeSimpleBars(data, valueField, categoryField, xScale, yScale, band
|
|
|
955
958
|
const xPos = value2 >= 0 ? baseline : xScale(value2);
|
|
956
959
|
const barWidth = Math.max(Math.abs(xScale(value2) - baseline), MIN_BAR_WIDTH);
|
|
957
960
|
const aria = {
|
|
958
|
-
label: `${category}: ${
|
|
961
|
+
label: `${category}: ${formatLabelValue(value2)}`
|
|
959
962
|
};
|
|
960
963
|
marks.push({
|
|
961
964
|
type: "rect",
|
|
@@ -975,17 +978,11 @@ function computeSimpleBars(data, valueField, categoryField, xScale, yScale, band
|
|
|
975
978
|
|
|
976
979
|
// src/charts/bar/labels.ts
|
|
977
980
|
import {
|
|
978
|
-
abbreviateNumber as abbreviateNumber2,
|
|
979
981
|
buildD3Formatter,
|
|
980
982
|
estimateTextWidth as estimateTextWidth2,
|
|
981
|
-
formatNumber as formatNumber2,
|
|
982
983
|
getRepresentativeColor,
|
|
983
984
|
resolveCollisions
|
|
984
985
|
} from "@opendata-ai/openchart-core";
|
|
985
|
-
function formatBarValue2(value2) {
|
|
986
|
-
if (Math.abs(value2) >= 1e3) return abbreviateNumber2(value2);
|
|
987
|
-
return formatNumber2(value2);
|
|
988
|
-
}
|
|
989
986
|
var SUFFIX_MULTIPLIERS = {
|
|
990
987
|
K: 1e3,
|
|
991
988
|
M: 1e6,
|
|
@@ -1023,7 +1020,7 @@ function computeBarLabels(marks, _chartArea, density = "auto", labelFormat, labe
|
|
|
1023
1020
|
if (formatter && Number.isFinite(rawNum)) {
|
|
1024
1021
|
valuePart = formatter(rawNum);
|
|
1025
1022
|
} else if (Number.isFinite(rawNum)) {
|
|
1026
|
-
valuePart =
|
|
1023
|
+
valuePart = formatLabelValue(rawNum);
|
|
1027
1024
|
} else {
|
|
1028
1025
|
const ariaLabel = mark.aria.label;
|
|
1029
1026
|
const lastColon = ariaLabel.lastIndexOf(":");
|
|
@@ -1135,12 +1132,8 @@ var barRenderer = (spec, scales, chartArea, strategy, _theme) => {
|
|
|
1135
1132
|
};
|
|
1136
1133
|
|
|
1137
1134
|
// src/charts/column/compute.ts
|
|
1138
|
-
import {
|
|
1135
|
+
import { isGradientDef as isGradientDef2 } from "@opendata-ai/openchart-core";
|
|
1139
1136
|
var MIN_COLUMN_HEIGHT = 1;
|
|
1140
|
-
function formatColumnValue(value2) {
|
|
1141
|
-
if (Math.abs(value2) >= 1e3) return abbreviateNumber3(value2);
|
|
1142
|
-
return formatNumber3(value2);
|
|
1143
|
-
}
|
|
1144
1137
|
function computeColumnMarks(spec, scales, _chartArea, _strategy) {
|
|
1145
1138
|
const encoding = spec.encoding;
|
|
1146
1139
|
const xChannel = encoding.x;
|
|
@@ -1241,7 +1234,7 @@ function computeSimpleColumns(data, categoryField, valueField, xScale, yScale, b
|
|
|
1241
1234
|
const columnHeight = Math.max(Math.abs(baseline - yPos), MIN_COLUMN_HEIGHT);
|
|
1242
1235
|
const y2 = value2 >= 0 ? yPos : baseline;
|
|
1243
1236
|
const aria = {
|
|
1244
|
-
label: `${category}: ${
|
|
1237
|
+
label: `${category}: ${formatLabelValue(value2)}`
|
|
1245
1238
|
};
|
|
1246
1239
|
marks.push({
|
|
1247
1240
|
type: "rect",
|
|
@@ -1272,7 +1265,7 @@ function computeColoredColumns(data, categoryField, valueField, colorField, xSca
|
|
|
1272
1265
|
const columnHeight = Math.max(Math.abs(baseline - yPos), MIN_COLUMN_HEIGHT);
|
|
1273
1266
|
const y2 = value2 >= 0 ? yPos : baseline;
|
|
1274
1267
|
const aria = {
|
|
1275
|
-
label: `${category}, ${groupKey2}: ${
|
|
1268
|
+
label: `${category}, ${groupKey2}: ${formatLabelValue(value2)}`
|
|
1276
1269
|
};
|
|
1277
1270
|
marks.push({
|
|
1278
1271
|
type: "rect",
|
|
@@ -1320,7 +1313,7 @@ function computeGroupedColumns(data, categoryField, valueField, colorField, xSca
|
|
|
1320
1313
|
const y2 = value2 >= 0 ? yPos : baseline;
|
|
1321
1314
|
const subX = bandX + groupIndex * (subBandWidth + gap);
|
|
1322
1315
|
const aria = {
|
|
1323
|
-
label: `${category}, ${groupKey2}: ${
|
|
1316
|
+
label: `${category}, ${groupKey2}: ${formatLabelValue(value2)}`
|
|
1324
1317
|
};
|
|
1325
1318
|
marks.push({
|
|
1326
1319
|
type: "rect",
|
|
@@ -1360,7 +1353,7 @@ function computeStackedColumns(data, categoryField, valueField, colorField, xSca
|
|
|
1360
1353
|
const yBottom = yScale(cumulativeValue);
|
|
1361
1354
|
const columnHeight = Math.max(Math.abs(yBottom - yTop), MIN_COLUMN_HEIGHT);
|
|
1362
1355
|
const aria = {
|
|
1363
|
-
label: `${category}, ${groupKey2}: ${
|
|
1356
|
+
label: `${category}, ${groupKey2}: ${formatLabelValue(rawValue)}`
|
|
1364
1357
|
};
|
|
1365
1358
|
marks.push({
|
|
1366
1359
|
type: "rect",
|
|
@@ -1383,17 +1376,11 @@ function computeStackedColumns(data, categoryField, valueField, colorField, xSca
|
|
|
1383
1376
|
|
|
1384
1377
|
// src/charts/column/labels.ts
|
|
1385
1378
|
import {
|
|
1386
|
-
abbreviateNumber as abbreviateNumber4,
|
|
1387
1379
|
buildD3Formatter as buildD3Formatter2,
|
|
1388
1380
|
estimateTextWidth as estimateTextWidth3,
|
|
1389
|
-
formatNumber as formatNumber4,
|
|
1390
1381
|
getRepresentativeColor as getRepresentativeColor2,
|
|
1391
1382
|
resolveCollisions as resolveCollisions2
|
|
1392
1383
|
} from "@opendata-ai/openchart-core";
|
|
1393
|
-
function formatColumnValue2(value2) {
|
|
1394
|
-
if (Math.abs(value2) >= 1e3) return abbreviateNumber4(value2);
|
|
1395
|
-
return formatNumber4(value2);
|
|
1396
|
-
}
|
|
1397
1384
|
var LABEL_FONT_SIZE2 = 10;
|
|
1398
1385
|
var LABEL_FONT_WEIGHT2 = 600;
|
|
1399
1386
|
var LABEL_OFFSET_Y = 6;
|
|
@@ -1408,7 +1395,7 @@ function computeColumnLabels(marks, _chartArea, density = "auto", labelFormat, l
|
|
|
1408
1395
|
if (formatter && Number.isFinite(rawNum)) {
|
|
1409
1396
|
valuePart = formatter(rawNum);
|
|
1410
1397
|
} else if (Number.isFinite(rawNum)) {
|
|
1411
|
-
valuePart =
|
|
1398
|
+
valuePart = formatLabelValue(rawNum);
|
|
1412
1399
|
} else {
|
|
1413
1400
|
const ariaLabel = mark.aria.label;
|
|
1414
1401
|
const lastColon = ariaLabel.lastIndexOf(":");
|
|
@@ -1627,17 +1614,11 @@ function computeLollipopMarks(data, valueField, categoryField, xScale, yScale, b
|
|
|
1627
1614
|
|
|
1628
1615
|
// src/charts/dot/labels.ts
|
|
1629
1616
|
import {
|
|
1630
|
-
abbreviateNumber as abbreviateNumber5,
|
|
1631
1617
|
buildD3Formatter as buildD3Formatter3,
|
|
1632
1618
|
estimateTextWidth as estimateTextWidth4,
|
|
1633
|
-
formatNumber as formatNumber5,
|
|
1634
1619
|
getRepresentativeColor as getRepresentativeColor3,
|
|
1635
1620
|
resolveCollisions as resolveCollisions3
|
|
1636
1621
|
} from "@opendata-ai/openchart-core";
|
|
1637
|
-
function formatDotValue(value2) {
|
|
1638
|
-
if (Math.abs(value2) >= 1e3) return abbreviateNumber5(value2);
|
|
1639
|
-
return formatNumber5(value2);
|
|
1640
|
-
}
|
|
1641
1622
|
var LABEL_FONT_SIZE3 = 11;
|
|
1642
1623
|
var LABEL_FONT_WEIGHT3 = 600;
|
|
1643
1624
|
var LABEL_OFFSET_X = 10;
|
|
@@ -1652,7 +1633,7 @@ function computeDotLabels(marks, _chartArea, density = "auto", labelPrefix, labe
|
|
|
1652
1633
|
if (formatter && Number.isFinite(rawNum)) {
|
|
1653
1634
|
valuePart = formatter(rawNum);
|
|
1654
1635
|
} else if (Number.isFinite(rawNum)) {
|
|
1655
|
-
valuePart =
|
|
1636
|
+
valuePart = formatLabelValue(rawNum);
|
|
1656
1637
|
} else {
|
|
1657
1638
|
const ariaLabel = mark.aria.label;
|
|
1658
1639
|
const lastColon = ariaLabel.lastIndexOf(":");
|
|
@@ -7769,12 +7750,12 @@ var DEFAULT_COLLISION_PADDING = 5;
|
|
|
7769
7750
|
|
|
7770
7751
|
// src/layout/axes.ts
|
|
7771
7752
|
import {
|
|
7772
|
-
abbreviateNumber as
|
|
7753
|
+
abbreviateNumber as abbreviateNumber2,
|
|
7773
7754
|
buildD3Formatter as buildD3Formatter4,
|
|
7774
7755
|
buildTemporalFormatter,
|
|
7775
7756
|
estimateTextWidth as estimateTextWidth7,
|
|
7776
7757
|
formatDate,
|
|
7777
|
-
formatNumber as
|
|
7758
|
+
formatNumber as formatNumber2
|
|
7778
7759
|
} from "@opendata-ai/openchart-core";
|
|
7779
7760
|
var TICK_COUNTS = {
|
|
7780
7761
|
full: 12,
|
|
@@ -7802,9 +7783,19 @@ function effectiveDensity(baseDensity, axisLength, minimalThreshold, reducedThre
|
|
|
7802
7783
|
function measureLabel(text, fontSize, fontWeight, measureText) {
|
|
7803
7784
|
return measureText ? measureText(text, fontSize, fontWeight).width : estimateTextWidth7(text, fontSize, fontWeight);
|
|
7804
7785
|
}
|
|
7805
|
-
function ticksOverlap(ticks2, fontSize, fontWeight, measureText) {
|
|
7786
|
+
function ticksOverlap(ticks2, fontSize, fontWeight, measureText, orientation = "horizontal") {
|
|
7806
7787
|
if (ticks2.length < 2) return false;
|
|
7807
7788
|
const minGap = fontSize * MIN_TICK_GAP_FACTOR;
|
|
7789
|
+
if (orientation === "vertical") {
|
|
7790
|
+
const sorted = [...ticks2].sort((a, b) => a.position - b.position);
|
|
7791
|
+
const labelHeight = fontSize * 1.2;
|
|
7792
|
+
for (let i = 0; i < sorted.length - 1; i++) {
|
|
7793
|
+
const aBottom = sorted[i].position + labelHeight / 2;
|
|
7794
|
+
const bTop = sorted[i + 1].position - labelHeight / 2;
|
|
7795
|
+
if (aBottom + minGap > bTop) return true;
|
|
7796
|
+
}
|
|
7797
|
+
return false;
|
|
7798
|
+
}
|
|
7808
7799
|
for (let i = 0; i < ticks2.length - 1; i++) {
|
|
7809
7800
|
const aWidth = measureLabel(ticks2[i].label, fontSize, fontWeight, measureText);
|
|
7810
7801
|
const bWidth = measureLabel(ticks2[i + 1].label, fontSize, fontWeight, measureText);
|
|
@@ -7814,8 +7805,8 @@ function ticksOverlap(ticks2, fontSize, fontWeight, measureText) {
|
|
|
7814
7805
|
}
|
|
7815
7806
|
return false;
|
|
7816
7807
|
}
|
|
7817
|
-
function thinTicksUntilFit(ticks2, fontSize, fontWeight, measureText) {
|
|
7818
|
-
if (!ticksOverlap(ticks2, fontSize, fontWeight, measureText)) return ticks2;
|
|
7808
|
+
function thinTicksUntilFit(ticks2, fontSize, fontWeight, measureText, orientation = "horizontal") {
|
|
7809
|
+
if (!ticksOverlap(ticks2, fontSize, fontWeight, measureText, orientation)) return ticks2;
|
|
7819
7810
|
let current = ticks2;
|
|
7820
7811
|
while (current.length > MIN_TICK_COUNT) {
|
|
7821
7812
|
const thinned = [current[0]];
|
|
@@ -7824,7 +7815,7 @@ function thinTicksUntilFit(ticks2, fontSize, fontWeight, measureText) {
|
|
|
7824
7815
|
}
|
|
7825
7816
|
if (current.length > 1) thinned.push(current[current.length - 1]);
|
|
7826
7817
|
current = thinned;
|
|
7827
|
-
if (!ticksOverlap(current, fontSize, fontWeight, measureText)) break;
|
|
7818
|
+
if (!ticksOverlap(current, fontSize, fontWeight, measureText, orientation)) break;
|
|
7828
7819
|
}
|
|
7829
7820
|
return current;
|
|
7830
7821
|
}
|
|
@@ -7894,8 +7885,8 @@ function formatTickLabel(value2, resolvedScale) {
|
|
|
7894
7885
|
const fmt = buildD3Formatter4(formatStr);
|
|
7895
7886
|
if (fmt) return fmt(num);
|
|
7896
7887
|
}
|
|
7897
|
-
if (Math.abs(num) >= 1e3) return
|
|
7898
|
-
return
|
|
7888
|
+
if (Math.abs(num) >= 1e3) return abbreviateNumber2(num);
|
|
7889
|
+
return formatNumber2(num);
|
|
7899
7890
|
}
|
|
7900
7891
|
return String(value2);
|
|
7901
7892
|
}
|
|
@@ -8011,7 +8002,7 @@ function computeAxes(scales, chartArea, strategy, theme, measureText) {
|
|
|
8011
8002
|
allTicks = continuousTicks(scales.y, yDensity);
|
|
8012
8003
|
}
|
|
8013
8004
|
const shouldThin = scales.y.type !== "band" && !axisConfig?.tickCount && !axisConfig?.values;
|
|
8014
|
-
const ticks2 = shouldThin ? thinTicksUntilFit(allTicks, fontSize, fontWeight, measureText) : allTicks;
|
|
8005
|
+
const ticks2 = shouldThin ? thinTicksUntilFit(allTicks, fontSize, fontWeight, measureText, "vertical") : allTicks;
|
|
8015
8006
|
const gridlines = ticks2.map((t) => ({
|
|
8016
8007
|
position: t.position,
|
|
8017
8008
|
major: true
|
|
@@ -8709,10 +8700,46 @@ function computeScales(spec, chartArea, data) {
|
|
|
8709
8700
|
}
|
|
8710
8701
|
|
|
8711
8702
|
// src/legend/compute.ts
|
|
8712
|
-
import { BRAND_RESERVE_WIDTH, estimateTextWidth as
|
|
8703
|
+
import { BRAND_RESERVE_WIDTH, estimateTextWidth as estimateTextWidth10 } from "@opendata-ai/openchart-core";
|
|
8704
|
+
|
|
8705
|
+
// src/legend/wrap.ts
|
|
8706
|
+
import { estimateTextWidth as estimateTextWidth9 } from "@opendata-ai/openchart-core";
|
|
8713
8707
|
var SWATCH_SIZE2 = 12;
|
|
8714
8708
|
var SWATCH_GAP2 = 6;
|
|
8715
8709
|
var ENTRY_GAP2 = 16;
|
|
8710
|
+
function measureLegendWrap(entries, maxWidth, labelStyle, maxRows) {
|
|
8711
|
+
if (entries.length === 0) {
|
|
8712
|
+
return { rowCount: 0, fittingCount: 0, rowWidths: [] };
|
|
8713
|
+
}
|
|
8714
|
+
let rowCount = 1;
|
|
8715
|
+
let rowWidth = 0;
|
|
8716
|
+
const rowWidths = [];
|
|
8717
|
+
let fittingCount = entries.length;
|
|
8718
|
+
let fittingCountLocked = false;
|
|
8719
|
+
for (let i = 0; i < entries.length; i++) {
|
|
8720
|
+
const labelWidth = estimateTextWidth9(
|
|
8721
|
+
entries[i].label,
|
|
8722
|
+
labelStyle.fontSize,
|
|
8723
|
+
labelStyle.fontWeight
|
|
8724
|
+
);
|
|
8725
|
+
const entryWidth = SWATCH_SIZE2 + SWATCH_GAP2 + labelWidth + ENTRY_GAP2;
|
|
8726
|
+
if (rowWidth + entryWidth > maxWidth && rowWidth > 0) {
|
|
8727
|
+
rowWidths.push(rowWidth);
|
|
8728
|
+
rowCount++;
|
|
8729
|
+
rowWidth = entryWidth;
|
|
8730
|
+
if (!fittingCountLocked && maxRows != null && rowCount > maxRows) {
|
|
8731
|
+
fittingCount = i;
|
|
8732
|
+
fittingCountLocked = true;
|
|
8733
|
+
}
|
|
8734
|
+
} else {
|
|
8735
|
+
rowWidth += entryWidth;
|
|
8736
|
+
}
|
|
8737
|
+
}
|
|
8738
|
+
rowWidths.push(rowWidth);
|
|
8739
|
+
return { rowCount, fittingCount, rowWidths };
|
|
8740
|
+
}
|
|
8741
|
+
|
|
8742
|
+
// src/legend/compute.ts
|
|
8716
8743
|
var LEGEND_PADDING = 8;
|
|
8717
8744
|
var LEGEND_RIGHT_WIDTH = 120;
|
|
8718
8745
|
var RIGHT_LEGEND_MAX_HEIGHT_RATIO = 0.4;
|
|
@@ -8753,26 +8780,6 @@ function extractColorEntries(spec, theme) {
|
|
|
8753
8780
|
};
|
|
8754
8781
|
});
|
|
8755
8782
|
}
|
|
8756
|
-
function entriesThatFit(entries, maxWidth, maxRows, labelStyle) {
|
|
8757
|
-
let row = 1;
|
|
8758
|
-
let rowWidth = 0;
|
|
8759
|
-
for (let i = 0; i < entries.length; i++) {
|
|
8760
|
-
const labelWidth = estimateTextWidth9(
|
|
8761
|
-
entries[i].label,
|
|
8762
|
-
labelStyle.fontSize,
|
|
8763
|
-
labelStyle.fontWeight
|
|
8764
|
-
);
|
|
8765
|
-
const entryWidth = SWATCH_SIZE2 + SWATCH_GAP2 + labelWidth + ENTRY_GAP2;
|
|
8766
|
-
if (rowWidth + entryWidth > maxWidth && rowWidth > 0) {
|
|
8767
|
-
row++;
|
|
8768
|
-
rowWidth = entryWidth;
|
|
8769
|
-
if (row > maxRows) return i;
|
|
8770
|
-
} else {
|
|
8771
|
-
rowWidth += entryWidth;
|
|
8772
|
-
}
|
|
8773
|
-
}
|
|
8774
|
-
return entries.length;
|
|
8775
|
-
}
|
|
8776
8783
|
function truncateEntries(entries, maxCount) {
|
|
8777
8784
|
if (maxCount >= entries.length || maxCount <= 0) return entries;
|
|
8778
8785
|
const truncated = entries.slice(0, maxCount);
|
|
@@ -8840,7 +8847,7 @@ function computeLegend(spec, strategy, theme, chartArea, watermark = true) {
|
|
|
8840
8847
|
}
|
|
8841
8848
|
if (resolvedPosition === "right" || resolvedPosition === "bottom-right") {
|
|
8842
8849
|
const maxLabelWidth = Math.max(
|
|
8843
|
-
...entries.map((e) =>
|
|
8850
|
+
...entries.map((e) => estimateTextWidth10(e.label, labelStyle.fontSize, labelStyle.fontWeight))
|
|
8844
8851
|
);
|
|
8845
8852
|
const legendWidth = Math.min(
|
|
8846
8853
|
LEGEND_RIGHT_WIDTH,
|
|
@@ -8886,26 +8893,15 @@ function computeLegend(spec, strategy, theme, chartArea, watermark = true) {
|
|
|
8886
8893
|
}
|
|
8887
8894
|
}
|
|
8888
8895
|
const maxRows = spec.legend?.maxRows != null ? Math.max(1, spec.legend.maxRows) : spec.legend?.columns != null ? Math.ceil(entries.length / spec.legend.columns) : TOP_LEGEND_MAX_ROWS;
|
|
8889
|
-
const
|
|
8890
|
-
if (
|
|
8891
|
-
entries = truncateEntries(entries,
|
|
8896
|
+
const { fittingCount } = measureLegendWrap(entries, availableWidth, labelStyle, maxRows);
|
|
8897
|
+
if (fittingCount < entries.length) {
|
|
8898
|
+
entries = truncateEntries(entries, fittingCount);
|
|
8892
8899
|
}
|
|
8893
8900
|
const totalWidth = entries.reduce((sum2, entry) => {
|
|
8894
|
-
const labelWidth =
|
|
8901
|
+
const labelWidth = estimateTextWidth10(entry.label, labelStyle.fontSize, labelStyle.fontWeight);
|
|
8895
8902
|
return sum2 + SWATCH_SIZE2 + SWATCH_GAP2 + labelWidth + ENTRY_GAP2;
|
|
8896
8903
|
}, 0);
|
|
8897
|
-
|
|
8898
|
-
let rowWidth = 0;
|
|
8899
|
-
for (const entry of entries) {
|
|
8900
|
-
const labelWidth = estimateTextWidth9(entry.label, labelStyle.fontSize, labelStyle.fontWeight);
|
|
8901
|
-
const entryWidth = SWATCH_SIZE2 + SWATCH_GAP2 + labelWidth + ENTRY_GAP2;
|
|
8902
|
-
if (rowWidth + entryWidth > availableWidth && rowWidth > 0) {
|
|
8903
|
-
rowCount++;
|
|
8904
|
-
rowWidth = entryWidth;
|
|
8905
|
-
} else {
|
|
8906
|
-
rowWidth += entryWidth;
|
|
8907
|
-
}
|
|
8908
|
-
}
|
|
8904
|
+
const { rowCount } = measureLegendWrap(entries, availableWidth, labelStyle);
|
|
8909
8905
|
const rowHeight = SWATCH_SIZE2 + 4;
|
|
8910
8906
|
const legendHeight = rowCount * rowHeight + LEGEND_PADDING * 2;
|
|
8911
8907
|
const offsetDx = spec.legend?.offset?.dx ?? 0;
|
|
@@ -8931,8 +8927,8 @@ import {
|
|
|
8931
8927
|
adaptTheme as adaptTheme2,
|
|
8932
8928
|
buildD3Formatter as buildD3Formatter5,
|
|
8933
8929
|
computeChrome as computeChrome3,
|
|
8934
|
-
estimateTextWidth as
|
|
8935
|
-
formatNumber as
|
|
8930
|
+
estimateTextWidth as estimateTextWidth11,
|
|
8931
|
+
formatNumber as formatNumber3,
|
|
8936
8932
|
resolveTheme as resolveTheme2
|
|
8937
8933
|
} from "@opendata-ai/openchart-core";
|
|
8938
8934
|
|
|
@@ -9408,9 +9404,6 @@ function generateLinkPath(link) {
|
|
|
9408
9404
|
}
|
|
9409
9405
|
|
|
9410
9406
|
// src/sankey/compile-sankey.ts
|
|
9411
|
-
var SWATCH_SIZE3 = 12;
|
|
9412
|
-
var SWATCH_GAP3 = 6;
|
|
9413
|
-
var ENTRY_GAP3 = 16;
|
|
9414
9407
|
var LABEL_GAP = 6;
|
|
9415
9408
|
var LINK_OPACITY_LIGHT = 0.5;
|
|
9416
9409
|
var LINK_OPACITY_DARK = 0.75;
|
|
@@ -9615,7 +9608,7 @@ function compileSankey(spec, options) {
|
|
|
9615
9608
|
if (labelsLeft) continue;
|
|
9616
9609
|
const labelX = (node.x1 ?? nodeWidth) + LABEL_GAP;
|
|
9617
9610
|
const labelText = node.label ?? node.id;
|
|
9618
|
-
const labelWidth =
|
|
9611
|
+
const labelWidth = estimateTextWidth11(labelText, labelFontSize, labelFontWeight);
|
|
9619
9612
|
const overflow = labelX + labelWidth - rightEdge;
|
|
9620
9613
|
if (overflow > maxOverflow) maxOverflow = overflow;
|
|
9621
9614
|
}
|
|
@@ -9780,22 +9773,11 @@ function buildSankeyLegend(nodeColorMap, colorField, data, sourceField, targetFi
|
|
|
9780
9773
|
}
|
|
9781
9774
|
let bounds = { x: 0, y: 0, width: 0, height: 0 };
|
|
9782
9775
|
if (entries.length > 0) {
|
|
9783
|
-
const ROW_HEIGHT =
|
|
9776
|
+
const ROW_HEIGHT = SWATCH_SIZE2 + 4;
|
|
9784
9777
|
const availableWidth = area.width;
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
const labelWidth = estimateTextWidth10(entry.label, labelStyle.fontSize, labelStyle.fontWeight);
|
|
9789
|
-
const entryWidth = SWATCH_SIZE3 + SWATCH_GAP3 + labelWidth + ENTRY_GAP3;
|
|
9790
|
-
if (rowX > 0 && rowX + entryWidth > availableWidth) {
|
|
9791
|
-
rowCount++;
|
|
9792
|
-
rowX = entryWidth;
|
|
9793
|
-
} else {
|
|
9794
|
-
rowX += entryWidth;
|
|
9795
|
-
}
|
|
9796
|
-
}
|
|
9797
|
-
rowCount = Math.min(rowCount, 2);
|
|
9798
|
-
const legendHeight = rowCount * ROW_HEIGHT;
|
|
9778
|
+
const { rowCount } = measureLegendWrap(entries, availableWidth, labelStyle);
|
|
9779
|
+
const cappedRowCount = Math.min(rowCount, 2);
|
|
9780
|
+
const legendHeight = cappedRowCount * ROW_HEIGHT;
|
|
9799
9781
|
bounds = {
|
|
9800
9782
|
x: area.x,
|
|
9801
9783
|
y: area.y,
|
|
@@ -9808,9 +9790,9 @@ function buildSankeyLegend(nodeColorMap, colorField, data, sourceField, targetFi
|
|
|
9808
9790
|
entries,
|
|
9809
9791
|
bounds,
|
|
9810
9792
|
labelStyle,
|
|
9811
|
-
swatchSize:
|
|
9812
|
-
swatchGap:
|
|
9813
|
-
entryGap:
|
|
9793
|
+
swatchSize: SWATCH_SIZE2,
|
|
9794
|
+
swatchGap: SWATCH_GAP2,
|
|
9795
|
+
entryGap: ENTRY_GAP2
|
|
9814
9796
|
};
|
|
9815
9797
|
}
|
|
9816
9798
|
function formatFlowValue(value2, valueFormat) {
|
|
@@ -9818,7 +9800,7 @@ function formatFlowValue(value2, valueFormat) {
|
|
|
9818
9800
|
const fmt = buildD3Formatter5(valueFormat);
|
|
9819
9801
|
if (fmt) return fmt(value2);
|
|
9820
9802
|
}
|
|
9821
|
-
return
|
|
9803
|
+
return formatNumber3(value2);
|
|
9822
9804
|
}
|
|
9823
9805
|
function buildTooltipDescriptors(nodes, links, valueFormat) {
|
|
9824
9806
|
const descriptors = /* @__PURE__ */ new Map();
|
|
@@ -9866,9 +9848,9 @@ function emptyLayout(area, chrome, theme, options, watermark) {
|
|
|
9866
9848
|
fill: theme.colors.text,
|
|
9867
9849
|
lineHeight: 1.3
|
|
9868
9850
|
},
|
|
9869
|
-
swatchSize:
|
|
9870
|
-
swatchGap:
|
|
9871
|
-
entryGap:
|
|
9851
|
+
swatchSize: SWATCH_SIZE2,
|
|
9852
|
+
swatchGap: SWATCH_GAP2,
|
|
9853
|
+
entryGap: ENTRY_GAP2
|
|
9872
9854
|
},
|
|
9873
9855
|
tooltipDescriptors: /* @__PURE__ */ new Map(),
|
|
9874
9856
|
a11y: {
|
|
@@ -9887,7 +9869,7 @@ function emptyLayout(area, chrome, theme, options, watermark) {
|
|
|
9887
9869
|
}
|
|
9888
9870
|
|
|
9889
9871
|
// src/tables/compile-table.ts
|
|
9890
|
-
import { computeChrome as computeChrome4, estimateTextWidth as
|
|
9872
|
+
import { computeChrome as computeChrome4, estimateTextWidth as estimateTextWidth12 } from "@opendata-ai/openchart-core";
|
|
9891
9873
|
|
|
9892
9874
|
// src/tables/bar-column.ts
|
|
9893
9875
|
var NEGATIVE_BAR_COLOR = "#c44e52";
|
|
@@ -10004,7 +9986,7 @@ function computeCategoryColors(data, column, theme, darkMode) {
|
|
|
10004
9986
|
}
|
|
10005
9987
|
|
|
10006
9988
|
// src/tables/format-cells.ts
|
|
10007
|
-
import { buildD3Formatter as buildD3Formatter6, formatDate as formatDate2, formatNumber as
|
|
9989
|
+
import { buildD3Formatter as buildD3Formatter6, formatDate as formatDate2, formatNumber as formatNumber4 } from "@opendata-ai/openchart-core";
|
|
10008
9990
|
function isNumericValue(value2) {
|
|
10009
9991
|
if (typeof value2 === "number") return Number.isFinite(value2);
|
|
10010
9992
|
return false;
|
|
@@ -10035,7 +10017,7 @@ function formatCell(value2, column) {
|
|
|
10035
10017
|
if (isNumericValue(value2)) {
|
|
10036
10018
|
return {
|
|
10037
10019
|
value: value2,
|
|
10038
|
-
formattedValue:
|
|
10020
|
+
formattedValue: formatNumber4(value2),
|
|
10039
10021
|
style
|
|
10040
10022
|
};
|
|
10041
10023
|
}
|
|
@@ -10061,7 +10043,7 @@ function formatValueForSearch(value2, column) {
|
|
|
10061
10043
|
}
|
|
10062
10044
|
}
|
|
10063
10045
|
if (isNumericValue(value2)) {
|
|
10064
|
-
return
|
|
10046
|
+
return formatNumber4(value2);
|
|
10065
10047
|
}
|
|
10066
10048
|
return String(value2);
|
|
10067
10049
|
}
|
|
@@ -10302,13 +10284,13 @@ function estimateColumnWidth(col, data, fontSize) {
|
|
|
10302
10284
|
if (col.image) return (col.image.width ?? 24) + PADDING;
|
|
10303
10285
|
if (col.flag) return 60;
|
|
10304
10286
|
const label = col.label ?? col.key;
|
|
10305
|
-
const headerWidth =
|
|
10287
|
+
const headerWidth = estimateTextWidth12(label, fontSize, 600) + PADDING;
|
|
10306
10288
|
const sampleSize = Math.min(100, data.length);
|
|
10307
10289
|
let maxDataWidth = 0;
|
|
10308
10290
|
for (let i = 0; i < sampleSize; i++) {
|
|
10309
10291
|
const val = data[i][col.key];
|
|
10310
10292
|
const text = val == null ? "" : String(val);
|
|
10311
|
-
const width =
|
|
10293
|
+
const width = estimateTextWidth12(text, fontSize, 400) + PADDING;
|
|
10312
10294
|
if (width > maxDataWidth) maxDataWidth = width;
|
|
10313
10295
|
}
|
|
10314
10296
|
return Math.max(MIN_WIDTH, headerWidth, maxDataWidth);
|
|
@@ -10536,7 +10518,7 @@ function compileTableLayout(spec, options, theme) {
|
|
|
10536
10518
|
import {
|
|
10537
10519
|
buildTemporalFormatter as buildTemporalFormatter2,
|
|
10538
10520
|
formatDate as formatDate3,
|
|
10539
|
-
formatNumber as
|
|
10521
|
+
formatNumber as formatNumber5,
|
|
10540
10522
|
getRepresentativeColor as getRepresentativeColor10
|
|
10541
10523
|
} from "@opendata-ai/openchart-core";
|
|
10542
10524
|
function formatValue(value2, fieldType, format2) {
|
|
@@ -10551,10 +10533,10 @@ function formatValue(value2, fieldType, format2) {
|
|
|
10551
10533
|
try {
|
|
10552
10534
|
return format(format2)(value2);
|
|
10553
10535
|
} catch {
|
|
10554
|
-
return
|
|
10536
|
+
return formatNumber5(value2);
|
|
10555
10537
|
}
|
|
10556
10538
|
}
|
|
10557
|
-
return
|
|
10539
|
+
return formatNumber5(value2);
|
|
10558
10540
|
}
|
|
10559
10541
|
return String(value2);
|
|
10560
10542
|
}
|