@opendata-ai/openchart-engine 7.1.3 → 7.1.4
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 +26 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/compile-snapshot.test.ts.snap +3 -3
- package/src/__tests__/dimensions.test.ts +108 -0
- package/src/charts/bar/__tests__/labels.test.ts +72 -0
- package/src/charts/bar/index.ts +2 -1
- package/src/charts/bar/labels.ts +4 -3
- package/src/layout/dimensions.ts +13 -7
- package/src/layout/scales.ts +22 -4
package/dist/index.js
CHANGED
|
@@ -1778,7 +1778,7 @@ var LABEL_FONT_SIZE = 11;
|
|
|
1778
1778
|
var LABEL_FONT_WEIGHT = 600;
|
|
1779
1779
|
var LABEL_PADDING = 6;
|
|
1780
1780
|
var MIN_WIDTH_FOR_INSIDE_LABEL = 40;
|
|
1781
|
-
function computeBarLabels(marks, _chartArea, density = "auto", labelFormat, labelPrefix, valueField, labelColor) {
|
|
1781
|
+
function computeBarLabels(marks, _chartArea, density = "auto", labelFormat, labelPrefix, valueField, labelColor, darkMode = false) {
|
|
1782
1782
|
const targetMarks = filterByDensity(marks, density);
|
|
1783
1783
|
const candidates = [];
|
|
1784
1784
|
const fitsInSegment = [];
|
|
@@ -1815,16 +1815,16 @@ function computeBarLabels(marks, _chartArea, density = "auto", labelFormat, labe
|
|
|
1815
1815
|
let textAnchor;
|
|
1816
1816
|
if (isStacked2 && isInside) {
|
|
1817
1817
|
anchorX = mark.x + mark.width / 2;
|
|
1818
|
-
fill = pickLabelColor(bgColor);
|
|
1818
|
+
fill = pickLabelColor(bgColor, darkMode);
|
|
1819
1819
|
textAnchor = "middle";
|
|
1820
1820
|
} else if (isInside) {
|
|
1821
1821
|
if (isNegative) {
|
|
1822
1822
|
anchorX = mark.x + LABEL_PADDING;
|
|
1823
|
-
fill = pickLabelColor(bgColor);
|
|
1823
|
+
fill = pickLabelColor(bgColor, darkMode);
|
|
1824
1824
|
textAnchor = "start";
|
|
1825
1825
|
} else {
|
|
1826
1826
|
anchorX = mark.x + mark.width - LABEL_PADDING;
|
|
1827
|
-
fill = pickLabelColor(bgColor);
|
|
1827
|
+
fill = pickLabelColor(bgColor, darkMode);
|
|
1828
1828
|
textAnchor = "end";
|
|
1829
1829
|
}
|
|
1830
1830
|
} else {
|
|
@@ -1898,7 +1898,7 @@ function computeBarLabels(marks, _chartArea, density = "auto", labelFormat, labe
|
|
|
1898
1898
|
}
|
|
1899
1899
|
|
|
1900
1900
|
// src/charts/bar/index.ts
|
|
1901
|
-
var barRenderer = (spec, scales, chartArea, strategy,
|
|
1901
|
+
var barRenderer = (spec, scales, chartArea, strategy, theme) => {
|
|
1902
1902
|
const marks = computeBarMarks(spec, scales, chartArea, strategy);
|
|
1903
1903
|
const valueField = spec.encoding?.x && "field" in spec.encoding.x ? spec.encoding.x.field : void 0;
|
|
1904
1904
|
const labels = computeBarLabels(
|
|
@@ -1908,7 +1908,8 @@ var barRenderer = (spec, scales, chartArea, strategy, _theme) => {
|
|
|
1908
1908
|
spec.labels.format,
|
|
1909
1909
|
spec.labels.prefix,
|
|
1910
1910
|
valueField,
|
|
1911
|
-
spec.labels.color
|
|
1911
|
+
spec.labels.color,
|
|
1912
|
+
theme.isDark
|
|
1912
1913
|
);
|
|
1913
1914
|
for (let i = 0; i < marks.length && i < labels.length; i++) {
|
|
1914
1915
|
marks[i].label = labels[i];
|
|
@@ -10145,6 +10146,7 @@ function computeAxes(scales, chartArea, strategy, theme, measureText, dataContex
|
|
|
10145
10146
|
|
|
10146
10147
|
// src/layout/dimensions.ts
|
|
10147
10148
|
import {
|
|
10149
|
+
AXIS_TITLE_GAP,
|
|
10148
10150
|
AXIS_TITLE_TRAILING_PAD as AXIS_TITLE_TRAILING_PAD2,
|
|
10149
10151
|
BREAKPOINT_COMPACT_MAX as BREAKPOINT_COMPACT_MAX2,
|
|
10150
10152
|
computeChrome as computeChrome3,
|
|
@@ -10609,7 +10611,6 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
|
|
|
10609
10611
|
theme.fonts.weights.normal
|
|
10610
10612
|
);
|
|
10611
10613
|
}
|
|
10612
|
-
const AXIS_TITLE_GAP = 8;
|
|
10613
10614
|
const dynamicTitleOffset = TICK_LABEL_OFFSET2 + estTickLabelWidth + AXIS_TITLE_GAP;
|
|
10614
10615
|
const axisTitleOffset = Math.max(dynamicTitleOffset, getAxisTitleOffset2(width));
|
|
10615
10616
|
const halfGlyph = Math.ceil(theme.fonts.sizes.body / 2);
|
|
@@ -10619,6 +10620,7 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
|
|
|
10619
10620
|
if (options.rightAxisReserve && options.rightAxisReserve > 0) {
|
|
10620
10621
|
margins.right = Math.max(margins.right, hPad + options.rightAxisReserve);
|
|
10621
10622
|
}
|
|
10623
|
+
const hasTopLegend = "entries" in legendLayout && legendLayout.entries.length > 0 && legendLayout.position === "top";
|
|
10622
10624
|
if ("entries" in legendLayout && legendLayout.entries.length > 0) {
|
|
10623
10625
|
const gap = legendGap(width);
|
|
10624
10626
|
if (legendLayout.position === "right" || legendLayout.position === "bottom-right") {
|
|
@@ -10627,7 +10629,7 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
|
|
|
10627
10629
|
margins.top += legendLayout.bounds.height + gap;
|
|
10628
10630
|
}
|
|
10629
10631
|
}
|
|
10630
|
-
margins.top += topAxisGap;
|
|
10632
|
+
margins.top += hasTopLegend ? inlineTickOverhang : topAxisGap;
|
|
10631
10633
|
let chartArea = {
|
|
10632
10634
|
x: margins.left,
|
|
10633
10635
|
y: margins.top,
|
|
@@ -10648,13 +10650,14 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
|
|
|
10648
10650
|
bottomLegendReservation
|
|
10649
10651
|
);
|
|
10650
10652
|
const fallbackTopAxisGap = isRadial && fallbackChrome.topHeight === 0 ? 0 : axisMargin + inlineTickOverhang;
|
|
10653
|
+
const fallbackEffectiveAxisGap = hasTopLegend ? inlineTickOverhang : fallbackTopAxisGap;
|
|
10651
10654
|
const newTop = topPad + fallbackChrome.topHeight + tentativeMetricsHeight;
|
|
10652
10655
|
const topDelta = margins.top - newTop;
|
|
10653
10656
|
const newBottom = bottomMargin(fallbackChrome.bottomHeight, padding, xAxisHeight);
|
|
10654
10657
|
const bottomDelta = margins.bottom - newBottom;
|
|
10655
10658
|
if (topDelta > 0 || bottomDelta > 0) {
|
|
10656
10659
|
const gap = legendGap(width);
|
|
10657
|
-
margins.top = newTop + ("entries" in legendLayout && legendLayout.entries.length > 0 && legendLayout.position === "top" ? legendLayout.bounds.height + gap : 0) +
|
|
10660
|
+
margins.top = newTop + ("entries" in legendLayout && legendLayout.entries.length > 0 && legendLayout.position === "top" ? legendLayout.bounds.height + gap : 0) + fallbackEffectiveAxisGap;
|
|
10658
10661
|
margins.bottom = newBottom;
|
|
10659
10662
|
chartArea = {
|
|
10660
10663
|
x: margins.left,
|
|
@@ -11059,7 +11062,13 @@ function computeScales(spec, chartArea, data) {
|
|
|
11059
11062
|
const xStackEnabled = encoding.x.stack === true || encoding.x.stack === "zero" || encoding.x.stack === "normalize" || encoding.x.stack === "center";
|
|
11060
11063
|
if (spec.markType === "bar" && encoding.color && encoding.x.type === "quantitative" && xStackEnabled) {
|
|
11061
11064
|
if (encoding.x.stack === "normalize") {
|
|
11062
|
-
|
|
11065
|
+
const existingAxis = encoding.x.axis;
|
|
11066
|
+
const axis = existingAxis === false || existingAxis?.format ? existingAxis : { ...typeof existingAxis === "object" ? existingAxis : {}, format: ".0%" };
|
|
11067
|
+
xChannel = {
|
|
11068
|
+
...encoding.x,
|
|
11069
|
+
scale: { ...encoding.x.scale, domain: [0, 1], nice: false },
|
|
11070
|
+
axis
|
|
11071
|
+
};
|
|
11063
11072
|
} else if (encoding.x.stack === "center") {
|
|
11064
11073
|
const yField = encoding.y?.field;
|
|
11065
11074
|
const xField = encoding.x.field;
|
|
@@ -11126,7 +11135,13 @@ function computeScales(spec, chartArea, data) {
|
|
|
11126
11135
|
}
|
|
11127
11136
|
if ((isBarStacked || isAreaStacked) && encoding.color && encoding.y.type === "quantitative") {
|
|
11128
11137
|
if (encoding.y.stack === "normalize") {
|
|
11129
|
-
|
|
11138
|
+
const existingAxis = encoding.y.axis;
|
|
11139
|
+
const axis = existingAxis === false || existingAxis?.format ? existingAxis : { ...typeof existingAxis === "object" ? existingAxis : {}, format: ".0%" };
|
|
11140
|
+
yChannel = {
|
|
11141
|
+
...encoding.y,
|
|
11142
|
+
scale: { ...encoding.y.scale, domain: [0, 1], nice: false },
|
|
11143
|
+
axis
|
|
11144
|
+
};
|
|
11130
11145
|
} else if (encoding.y.stack === "center") {
|
|
11131
11146
|
const xField = encoding.x?.field;
|
|
11132
11147
|
const yField = encoding.y.field;
|