@opendata-ai/openchart-engine 7.9.2 → 7.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/index.js +109 -76
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/axes.test.ts +271 -35
- package/src/__tests__/rotation.test.ts +83 -0
- package/src/layout/axes/rotation.ts +130 -14
- package/src/layout/axes/ticks.ts +22 -7
- package/src/layout/axes.ts +77 -113
- package/src/layout/plan.ts +18 -3
- package/src/layout/scales.ts +29 -5
package/dist/index.js
CHANGED
|
@@ -10506,12 +10506,41 @@ import {
|
|
|
10506
10506
|
} from "@opendata-ai/openchart-core";
|
|
10507
10507
|
|
|
10508
10508
|
// src/layout/axes/rotation.ts
|
|
10509
|
+
import { TICK_LINE_HEIGHT_FACTOR, X_AXIS_ROTATED_EXTENT_CAP } from "@opendata-ai/openchart-core";
|
|
10509
10510
|
var BAND_FIT_FRACTION = 0.85;
|
|
10510
10511
|
var AUTO_ROTATE_ANGLE = -45;
|
|
10511
|
-
|
|
10512
|
+
var STEEP_ROTATE_ANGLE = -90;
|
|
10513
|
+
var LABEL_GAP = 4;
|
|
10514
|
+
function ribbonSeparation(spacing, angleDeg) {
|
|
10515
|
+
return spacing * Math.abs(Math.sin(angleDeg * Math.PI / 180));
|
|
10516
|
+
}
|
|
10517
|
+
function alongTextClearance(spacing, angleDeg) {
|
|
10518
|
+
return spacing * Math.abs(Math.cos(angleDeg * Math.PI / 180));
|
|
10519
|
+
}
|
|
10520
|
+
function rotatedLabelsFit(spacing, angleDeg, fontSize, maxLabelWidth) {
|
|
10521
|
+
return ribbonSeparation(spacing, angleDeg) >= fontSize * TICK_LINE_HEIGHT_FACTOR + LABEL_GAP || alongTextClearance(spacing, angleDeg) >= maxLabelWidth + LABEL_GAP;
|
|
10522
|
+
}
|
|
10523
|
+
function resolveBandTickAngle(explicitAngle, maxLabelWidth, bandwidth, labelCount, spacing, fontSize) {
|
|
10512
10524
|
if (explicitAngle !== void 0) return explicitAngle;
|
|
10513
10525
|
if (labelCount < 2) return void 0;
|
|
10514
|
-
|
|
10526
|
+
if (maxLabelWidth <= bandwidth * BAND_FIT_FRACTION) return void 0;
|
|
10527
|
+
if (rotatedLabelsFit(spacing, AUTO_ROTATE_ANGLE, fontSize, maxLabelWidth)) {
|
|
10528
|
+
return AUTO_ROTATE_ANGLE;
|
|
10529
|
+
}
|
|
10530
|
+
return maxLabelWidth <= X_AXIS_ROTATED_EXTENT_CAP ? STEEP_ROTATE_ANGLE : AUTO_ROTATE_ANGLE;
|
|
10531
|
+
}
|
|
10532
|
+
function bandLabelStride(maxLabelWidth, angleDeg, fontSize, spacing) {
|
|
10533
|
+
if (spacing <= 0) return 1;
|
|
10534
|
+
if (angleDeg === void 0 || angleDeg === 0) {
|
|
10535
|
+
return Math.max(1, Math.ceil((maxLabelWidth + LABEL_GAP) / spacing));
|
|
10536
|
+
}
|
|
10537
|
+
const separation = ribbonSeparation(spacing, angleDeg);
|
|
10538
|
+
const clearance = alongTextClearance(spacing, angleDeg);
|
|
10539
|
+
const required = fontSize * TICK_LINE_HEIGHT_FACTOR + LABEL_GAP;
|
|
10540
|
+
const byRibbon = separation > 0 ? Math.ceil(required / separation) : Number.POSITIVE_INFINITY;
|
|
10541
|
+
const byLength = clearance > 0 ? Math.ceil((maxLabelWidth + LABEL_GAP) / clearance) : Number.POSITIVE_INFINITY;
|
|
10542
|
+
const stride = Math.min(byRibbon, byLength);
|
|
10543
|
+
return Number.isFinite(stride) ? Math.max(1, stride) : 1;
|
|
10515
10544
|
}
|
|
10516
10545
|
|
|
10517
10546
|
// src/layout/axes/thinning.ts
|
|
@@ -10608,7 +10637,7 @@ var NUMERIC_SCALE_TYPES = /* @__PURE__ */ new Set([
|
|
|
10608
10637
|
"threshold"
|
|
10609
10638
|
]);
|
|
10610
10639
|
var TEMPORAL_SCALE_TYPES = /* @__PURE__ */ new Set(["time", "utc"]);
|
|
10611
|
-
function formatTickLabel(value2, resolvedScale) {
|
|
10640
|
+
function formatTickLabel(value2, resolvedScale, compact = false) {
|
|
10612
10641
|
const axisConfig = resolvedScale.channel.axis || void 0;
|
|
10613
10642
|
const formatStr = axisConfig?.format;
|
|
10614
10643
|
const suffix = axisConfig?.labelSuffix ?? "";
|
|
@@ -10616,7 +10645,7 @@ function formatTickLabel(value2, resolvedScale) {
|
|
|
10616
10645
|
const temporalFmt = buildTemporalFormatter(formatStr);
|
|
10617
10646
|
if (temporalFmt) return temporalFmt(value2) + suffix;
|
|
10618
10647
|
const useUtc = resolvedScale.type === "utc";
|
|
10619
|
-
return formatDate(value2, void 0, void 0, useUtc) + suffix;
|
|
10648
|
+
return formatDate(value2, void 0, void 0, useUtc, compact) + suffix;
|
|
10620
10649
|
}
|
|
10621
10650
|
if (NUMERIC_SCALE_TYPES.has(resolvedScale.type)) {
|
|
10622
10651
|
const num = value2;
|
|
@@ -10643,7 +10672,7 @@ function continuousTicks(resolvedScale, density, targetCount) {
|
|
|
10643
10672
|
const count = axCfg?.tickCount ?? targetCount ?? TICK_COUNTS[density];
|
|
10644
10673
|
return buildContinuousTicks(resolvedScale, count);
|
|
10645
10674
|
}
|
|
10646
|
-
function buildContinuousTicks(resolvedScale, count) {
|
|
10675
|
+
function buildContinuousTicks(resolvedScale, count, compact = false) {
|
|
10647
10676
|
const scale = resolvedScale.scale;
|
|
10648
10677
|
if (!("ticks" in scale) || typeof scale.ticks !== "function") {
|
|
10649
10678
|
return continuousTicks(resolvedScale, "full");
|
|
@@ -10666,7 +10695,7 @@ function buildContinuousTicks(resolvedScale, count) {
|
|
|
10666
10695
|
return ticks2.map((value2) => ({
|
|
10667
10696
|
value: value2,
|
|
10668
10697
|
position: scale(value2),
|
|
10669
|
-
label: formatTickLabel(value2, resolvedScale)
|
|
10698
|
+
label: formatTickLabel(value2, resolvedScale, compact)
|
|
10670
10699
|
}));
|
|
10671
10700
|
}
|
|
10672
10701
|
function scaleSupportsTickCount(resolvedScale) {
|
|
@@ -10781,12 +10810,12 @@ function effectiveDensity(baseDensity, axisLength, minimalThreshold, reducedThre
|
|
|
10781
10810
|
var CONTINUOUS_TICK_FLOOR = 4;
|
|
10782
10811
|
var OVERSHOOT_TOLERANCE = 1.5;
|
|
10783
10812
|
var MIN_QUANTITATIVE_TICKS = 2;
|
|
10784
|
-
function ensureMinContinuousTicks(scale, ticks2, requestedCount) {
|
|
10813
|
+
function ensureMinContinuousTicks(scale, ticks2, requestedCount, compact = false) {
|
|
10785
10814
|
if (ticks2.length >= MIN_QUANTITATIVE_TICKS) return ticks2;
|
|
10786
10815
|
if (!scale || !scaleSupportsTickCount(scale)) return ticks2;
|
|
10787
10816
|
let best = ticks2;
|
|
10788
10817
|
for (let n = Math.max(requestedCount, MIN_QUANTITATIVE_TICKS) + 1; n <= 10; n++) {
|
|
10789
|
-
const candidate = buildContinuousTicks(scale, n);
|
|
10818
|
+
const candidate = buildContinuousTicks(scale, n, compact);
|
|
10790
10819
|
if (candidate.length >= MIN_QUANTITATIVE_TICKS) return candidate;
|
|
10791
10820
|
if (candidate.length > best.length) best = candidate;
|
|
10792
10821
|
}
|
|
@@ -10799,66 +10828,36 @@ function fitContinuousTicks(scale, initialTicks, initialCount, fontSize, fontWei
|
|
|
10799
10828
|
const overshoots = flooredTicks.length > tolerance;
|
|
10800
10829
|
const overlaps = ticksOverlap(flooredTicks, fontSize, fontWeight, measureText, orientation);
|
|
10801
10830
|
if (!overshoots && !overlaps) return flooredTicks;
|
|
10831
|
+
const useCompact = (scale.type === "time" || scale.type === "utc") && orientation === "horizontal";
|
|
10832
|
+
const fitsCleanly = (candidate) => candidate.length <= tolerance && !ticksOverlap(candidate, fontSize, fontWeight, measureText, orientation);
|
|
10833
|
+
if (useCompact) {
|
|
10834
|
+
const compactAtInitial = buildContinuousTicks(scale, initialCount, true);
|
|
10835
|
+
if (fitsCleanly(compactAtInitial)) return compactAtInitial;
|
|
10836
|
+
}
|
|
10802
10837
|
const minThreshold = orientation === "vertical" ? HEIGHT_MINIMAL_THRESHOLD : WIDTH_MINIMAL_THRESHOLD;
|
|
10803
10838
|
const floor = axisLength >= minThreshold ? CONTINUOUS_TICK_FLOOR : 2;
|
|
10804
10839
|
let bestWithinFloor;
|
|
10840
|
+
let bestWithinFloorCount;
|
|
10805
10841
|
for (let n = initialCount - 1; n >= 2; n--) {
|
|
10806
10842
|
const candidate = buildContinuousTicks(scale, n);
|
|
10807
|
-
|
|
10808
|
-
|
|
10809
|
-
|
|
10810
|
-
|
|
10811
|
-
|
|
10812
|
-
|
|
10813
|
-
|
|
10814
|
-
|
|
10815
|
-
if (!candidateOvershoots && !candidateOverlaps) {
|
|
10816
|
-
return candidate;
|
|
10843
|
+
if (fitsCleanly(candidate)) return candidate;
|
|
10844
|
+
if (useCompact) {
|
|
10845
|
+
const compact = buildContinuousTicks(scale, n, true);
|
|
10846
|
+
if (fitsCleanly(compact)) return compact;
|
|
10847
|
+
}
|
|
10848
|
+
if (candidate.length >= floor) {
|
|
10849
|
+
bestWithinFloor = candidate;
|
|
10850
|
+
bestWithinFloorCount = n;
|
|
10817
10851
|
}
|
|
10818
|
-
if (candidate.length >= floor) bestWithinFloor = candidate;
|
|
10819
10852
|
}
|
|
10820
|
-
const rawFallback = bestWithinFloor ?? buildContinuousTicks(scale, floor);
|
|
10821
|
-
const fallback = ensureMinContinuousTicks(scale, rawFallback, floor);
|
|
10853
|
+
const rawFallback = useCompact ? buildContinuousTicks(scale, bestWithinFloorCount ?? floor, true) : bestWithinFloor ?? buildContinuousTicks(scale, floor);
|
|
10854
|
+
const fallback = ensureMinContinuousTicks(scale, rawFallback, floor, useCompact);
|
|
10822
10855
|
return thinTicksUntilFit(fallback, fontSize, fontWeight, measureText, orientation);
|
|
10823
10856
|
}
|
|
10824
|
-
function
|
|
10825
|
-
|
|
10826
|
-
const cosA = angleRad > 0 ? Math.abs(Math.cos(angleRad)) : 1;
|
|
10827
|
-
const projected = measureLabel(tick.label, fontSize, fontWeight, measureText) * cosA;
|
|
10828
|
-
if (angleDeg === 0) {
|
|
10829
|
-
return { left: tick.position - projected / 2, right: tick.position + projected / 2 };
|
|
10830
|
-
}
|
|
10831
|
-
if (angleDeg < 0) {
|
|
10832
|
-
return { left: tick.position - projected, right: tick.position };
|
|
10833
|
-
}
|
|
10834
|
-
return { left: tick.position, right: tick.position + projected };
|
|
10835
|
-
}
|
|
10836
|
-
function thinBandTicksIfNeeded(ticks2, angleDeg, fontSize, fontWeight, measureText) {
|
|
10837
|
-
if (ticks2.length < 3) return ticks2;
|
|
10838
|
-
const minGap = fontSize * 0.5;
|
|
10839
|
-
const spans = ticks2.map((t) => labelSpanAtAngle(t, angleDeg, fontSize, fontWeight, measureText));
|
|
10840
|
-
const keep = new Array(ticks2.length).fill(false);
|
|
10841
|
-
keep[0] = true;
|
|
10842
|
-
let lastRight = spans[0].right;
|
|
10843
|
-
for (let i = 1; i < ticks2.length; i++) {
|
|
10844
|
-
if (spans[i].left >= lastRight + minGap) {
|
|
10845
|
-
keep[i] = true;
|
|
10846
|
-
lastRight = spans[i].right;
|
|
10847
|
-
}
|
|
10848
|
-
}
|
|
10857
|
+
function applyBandLabelStride(ticks2, stride) {
|
|
10858
|
+
if (stride <= 1 || ticks2.length < 3) return ticks2;
|
|
10849
10859
|
const lastIdx = ticks2.length - 1;
|
|
10850
|
-
|
|
10851
|
-
keep[lastIdx] = true;
|
|
10852
|
-
for (let i = lastIdx - 1; i > 0; i--) {
|
|
10853
|
-
if (!keep[i]) continue;
|
|
10854
|
-
if (spans[i].right > spans[lastIdx].left) {
|
|
10855
|
-
keep[i] = false;
|
|
10856
|
-
continue;
|
|
10857
|
-
}
|
|
10858
|
-
break;
|
|
10859
|
-
}
|
|
10860
|
-
}
|
|
10861
|
-
return ticks2.filter((_, i) => keep[i]);
|
|
10860
|
+
return ticks2.filter((_, i) => (lastIdx - i) % stride === 0);
|
|
10862
10861
|
}
|
|
10863
10862
|
function computeAxes(scales, chartArea, strategy, theme, measureText, dataContext) {
|
|
10864
10863
|
const result = {};
|
|
@@ -10909,22 +10908,37 @@ function computeAxes(scales, chartArea, strategy, theme, measureText, dataContex
|
|
|
10909
10908
|
major: true
|
|
10910
10909
|
}));
|
|
10911
10910
|
let tickAngle = axisConfig?.labelAngle;
|
|
10912
|
-
|
|
10913
|
-
|
|
10911
|
+
let bandStride = 1;
|
|
10912
|
+
if (scales.x.type === "band" && allTicks.length > 1) {
|
|
10913
|
+
const bandScale = scales.x.scale;
|
|
10914
|
+
const bandwidth = bandScale.bandwidth();
|
|
10915
|
+
let anchorSpacing = Number.POSITIVE_INFINITY;
|
|
10916
|
+
for (let i = 1; i < allTicks.length; i++) {
|
|
10917
|
+
const d = Math.abs(allTicks[i].position - allTicks[i - 1].position);
|
|
10918
|
+
if (d > 0 && d < anchorSpacing) anchorSpacing = d;
|
|
10919
|
+
}
|
|
10920
|
+
if (!Number.isFinite(anchorSpacing)) anchorSpacing = bandScale.step();
|
|
10914
10921
|
let maxLabelWidth = 0;
|
|
10915
10922
|
for (const t of allTicks) {
|
|
10916
10923
|
const w = measureLabel(t.label, fontSize, fontWeight, measureText);
|
|
10917
10924
|
if (w > maxLabelWidth) maxLabelWidth = w;
|
|
10918
10925
|
}
|
|
10919
|
-
tickAngle = resolveBandTickAngle(
|
|
10926
|
+
tickAngle = resolveBandTickAngle(
|
|
10927
|
+
axisConfig?.labelAngle,
|
|
10928
|
+
maxLabelWidth,
|
|
10929
|
+
bandwidth,
|
|
10930
|
+
allTicks.length,
|
|
10931
|
+
anchorSpacing,
|
|
10932
|
+
fontSize
|
|
10933
|
+
);
|
|
10934
|
+
bandStride = bandLabelStride(maxLabelWidth, tickAngle, fontSize, anchorSpacing);
|
|
10920
10935
|
}
|
|
10921
10936
|
const hasExplicitValues = !!axisConfig?.values;
|
|
10922
10937
|
let ticks2;
|
|
10923
10938
|
if (hasExplicitValues) {
|
|
10924
10939
|
ticks2 = allTicks;
|
|
10925
10940
|
} else if (scales.x.type === "band") {
|
|
10926
|
-
|
|
10927
|
-
ticks2 = thinBandTicksIfNeeded(allTicks, effectiveAngle, fontSize, fontWeight, measureText);
|
|
10941
|
+
ticks2 = applyBandLabelStride(allTicks, bandStride);
|
|
10928
10942
|
} else if (isContinuousX) {
|
|
10929
10943
|
ticks2 = fitContinuousTicks(
|
|
10930
10944
|
scales.x,
|
|
@@ -11287,15 +11301,23 @@ function evenRange(start, end, count) {
|
|
|
11287
11301
|
const step = (end - start) / (count - 1);
|
|
11288
11302
|
return Array.from({ length: count }, (_, i) => start + step * i);
|
|
11289
11303
|
}
|
|
11304
|
+
function resolveBandPadding(scaleConfig) {
|
|
11305
|
+
const padding = scaleConfig?.padding ?? 0.35;
|
|
11306
|
+
return {
|
|
11307
|
+
paddingInner: scaleConfig?.paddingInner ?? padding,
|
|
11308
|
+
paddingOuter: scaleConfig?.paddingOuter ?? padding
|
|
11309
|
+
};
|
|
11310
|
+
}
|
|
11290
11311
|
function estimateBandwidth(scaleConfig, plotWidth, n) {
|
|
11312
|
+
const { paddingInner } = resolveBandPadding(scaleConfig);
|
|
11313
|
+
return estimateBandStep(scaleConfig, plotWidth, n) * (1 - paddingInner);
|
|
11314
|
+
}
|
|
11315
|
+
function estimateBandStep(scaleConfig, plotWidth, n) {
|
|
11291
11316
|
if (n <= 0) return 0;
|
|
11292
|
-
const
|
|
11293
|
-
const paddingInner = scaleConfig?.paddingInner ?? padding;
|
|
11294
|
-
const paddingOuter = scaleConfig?.paddingOuter ?? padding;
|
|
11317
|
+
const { paddingInner, paddingOuter } = resolveBandPadding(scaleConfig);
|
|
11295
11318
|
const denom = n - paddingInner + 2 * paddingOuter;
|
|
11296
11319
|
if (denom <= 0) return 0;
|
|
11297
|
-
|
|
11298
|
-
return step * (1 - paddingInner);
|
|
11320
|
+
return plotWidth / denom;
|
|
11299
11321
|
}
|
|
11300
11322
|
function buildBandScale(channel, data, rangeStart, rangeEnd) {
|
|
11301
11323
|
const values = channel.scale?.domain ? channel.scale.domain : applyCategoricalSort(uniqueStrings(fieldValues(data, channel.field)), channel.sort);
|
|
@@ -11754,8 +11776,17 @@ function resolveLayoutPlan(chartSpec, renderSpec, options, theme, strategy, wate
|
|
|
11754
11776
|
const rightMarginEst = hPad + (isRadial ? hPad : axisMargin);
|
|
11755
11777
|
const plotWidth = Math.max(0, width - leftGutter - Math.max(rightMarginEst, hPad));
|
|
11756
11778
|
const bandwidth = estimateBandwidth(encoding.x?.scale, plotWidth, xLabels.length);
|
|
11779
|
+
const step = estimateBandStep(encoding.x?.scale, plotWidth, xLabels.length);
|
|
11780
|
+
const xTickCount = xAxis?.tickCount;
|
|
11781
|
+
let drawnLabels = xLabels;
|
|
11782
|
+
let anchorSpacing = step;
|
|
11783
|
+
if (xTickCount && xLabels.length > xTickCount) {
|
|
11784
|
+
const capStride = Math.ceil(xLabels.length / xTickCount);
|
|
11785
|
+
drawnLabels = xLabels.filter((_, i) => i % capStride === 0);
|
|
11786
|
+
anchorSpacing = step * capStride;
|
|
11787
|
+
}
|
|
11757
11788
|
let maxXLabelWidth = 0;
|
|
11758
|
-
for (const label of
|
|
11789
|
+
for (const label of drawnLabels) {
|
|
11759
11790
|
const w = measure(label, theme.fonts.sizes.axisTick, theme.fonts.weights.normal);
|
|
11760
11791
|
if (w > maxXLabelWidth) maxXLabelWidth = w;
|
|
11761
11792
|
}
|
|
@@ -11763,7 +11794,9 @@ function resolveLayoutPlan(chartSpec, renderSpec, options, theme, strategy, wate
|
|
|
11763
11794
|
void 0,
|
|
11764
11795
|
maxXLabelWidth,
|
|
11765
11796
|
bandwidth,
|
|
11766
|
-
|
|
11797
|
+
drawnLabels.length,
|
|
11798
|
+
anchorSpacing,
|
|
11799
|
+
theme.fonts.sizes.axisTick
|
|
11767
11800
|
);
|
|
11768
11801
|
}
|
|
11769
11802
|
const xAxisExtent = isRadial || xAxisSuppressed ? 0 : computeXAxisExtentFromLabels2({
|
|
@@ -13834,7 +13867,7 @@ function generateLinkPath(link) {
|
|
|
13834
13867
|
}
|
|
13835
13868
|
|
|
13836
13869
|
// src/sankey/compile-sankey.ts
|
|
13837
|
-
var
|
|
13870
|
+
var LABEL_GAP2 = 6;
|
|
13838
13871
|
var LINK_OPACITY_LIGHT = 0.5;
|
|
13839
13872
|
var LINK_OPACITY_DARK = 0.75;
|
|
13840
13873
|
var NODE_CORNER_RADIUS = 2;
|
|
@@ -13906,16 +13939,16 @@ function computeNodeLabel(node, maxDepth, theme, nodeWidth, nodeLabelAlign = "au
|
|
|
13906
13939
|
let maxWidth;
|
|
13907
13940
|
if (containerWidth !== void 0) {
|
|
13908
13941
|
if (placeLeft) {
|
|
13909
|
-
maxWidth = x0 -
|
|
13942
|
+
maxWidth = x0 - LABEL_GAP2 - pad2;
|
|
13910
13943
|
} else {
|
|
13911
|
-
maxWidth = containerWidth - pad2 - (x1 +
|
|
13944
|
+
maxWidth = containerWidth - pad2 - (x1 + LABEL_GAP2);
|
|
13912
13945
|
}
|
|
13913
13946
|
if (maxWidth !== void 0 && maxWidth < 0) maxWidth = 0;
|
|
13914
13947
|
}
|
|
13915
13948
|
if (placeLeft) {
|
|
13916
13949
|
return {
|
|
13917
13950
|
text: node.label ?? node.id,
|
|
13918
|
-
x: x0 -
|
|
13951
|
+
x: x0 - LABEL_GAP2,
|
|
13919
13952
|
y: midY,
|
|
13920
13953
|
style: { ...style, textAnchor: "end", dominantBaseline: "central" },
|
|
13921
13954
|
visible: true,
|
|
@@ -13924,7 +13957,7 @@ function computeNodeLabel(node, maxDepth, theme, nodeWidth, nodeLabelAlign = "au
|
|
|
13924
13957
|
}
|
|
13925
13958
|
return {
|
|
13926
13959
|
text: node.label ?? node.id,
|
|
13927
|
-
x: x1 +
|
|
13960
|
+
x: x1 + LABEL_GAP2,
|
|
13928
13961
|
y: midY,
|
|
13929
13962
|
style: { ...style, textAnchor: "start", dominantBaseline: "central" },
|
|
13930
13963
|
visible: true,
|
|
@@ -14036,7 +14069,7 @@ function compileSankey(spec, options) {
|
|
|
14036
14069
|
const depth = node.depth ?? 0;
|
|
14037
14070
|
const labelsLeft = nodeLabelAlign === "left" || nodeLabelAlign === "auto" && depth === maxDepthFirst;
|
|
14038
14071
|
if (labelsLeft) continue;
|
|
14039
|
-
const labelX = (node.x1 ?? nodeWidth) +
|
|
14072
|
+
const labelX = (node.x1 ?? nodeWidth) + LABEL_GAP2;
|
|
14040
14073
|
const labelText = node.label ?? node.id;
|
|
14041
14074
|
const labelWidth = estimateTextWidth18(labelText, labelFontSize, labelFontWeight);
|
|
14042
14075
|
const overflow = labelX + labelWidth - rightEdge;
|