@opendata-ai/openchart-engine 6.6.0 → 6.7.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 CHANGED
@@ -205,8 +205,8 @@ interface NormalizedChartSpec {
205
205
  encoding: Encoding;
206
206
  chrome: NormalizedChrome;
207
207
  annotations: Annotation[];
208
- /** Normalized label configuration with defaults applied. density and format are always set; offsets stays optional. */
209
- labels: Required<Pick<LabelConfig, 'density' | 'format'>> & Pick<LabelConfig, 'offsets'>;
208
+ /** Normalized label configuration with defaults applied. density, format, and prefix are always set; offsets stays optional. */
209
+ labels: Required<Pick<LabelConfig, 'density' | 'format' | 'prefix'>> & Pick<LabelConfig, 'offsets'>;
210
210
  /** Legend configuration (position override). */
211
211
  legend?: LegendConfig;
212
212
  responsive: boolean;
package/dist/index.js CHANGED
@@ -844,7 +844,7 @@ var LABEL_FONT_SIZE = 11;
844
844
  var LABEL_FONT_WEIGHT = 600;
845
845
  var LABEL_PADDING = 6;
846
846
  var MIN_WIDTH_FOR_INSIDE_LABEL = 40;
847
- function computeBarLabels(marks, _chartArea, density = "auto", labelFormat) {
847
+ function computeBarLabels(marks, _chartArea, density = "auto", labelFormat, labelPrefix) {
848
848
  if (density === "none") return [];
849
849
  const targetMarks = density === "endpoints" && marks.length > 1 ? [marks[0], marks[marks.length - 1]] : marks;
850
850
  const candidates = [];
@@ -860,6 +860,7 @@ function computeBarLabels(marks, _chartArea, density = "auto", labelFormat) {
860
860
  const num = parseDisplayNumber(rawValue);
861
861
  if (!Number.isNaN(num)) valuePart = formatter(num);
862
862
  }
863
+ if (labelPrefix) valuePart = labelPrefix + valuePart;
863
864
  const textWidth = estimateTextWidth2(valuePart, LABEL_FONT_SIZE, LABEL_FONT_WEIGHT);
864
865
  const textHeight = LABEL_FONT_SIZE * 1.2;
865
866
  const isStacked = mark.cornerRadius === 0;
@@ -942,7 +943,13 @@ function computeBarLabels(marks, _chartArea, density = "auto", labelFormat) {
942
943
  // src/charts/bar/index.ts
943
944
  var barRenderer = (spec, scales, chartArea, strategy, _theme) => {
944
945
  const marks = computeBarMarks(spec, scales, chartArea, strategy);
945
- const labels = computeBarLabels(marks, chartArea, spec.labels.density, spec.labels.format);
946
+ const labels = computeBarLabels(
947
+ marks,
948
+ chartArea,
949
+ spec.labels.density,
950
+ spec.labels.format,
951
+ spec.labels.prefix
952
+ );
946
953
  for (let i = 0; i < marks.length && i < labels.length; i++) {
947
954
  marks[i].label = labels[i];
948
955
  }
@@ -1131,7 +1138,7 @@ import {
1131
1138
  var LABEL_FONT_SIZE2 = 10;
1132
1139
  var LABEL_FONT_WEIGHT2 = 600;
1133
1140
  var LABEL_OFFSET_Y = 6;
1134
- function computeColumnLabels(marks, _chartArea, density = "auto", labelFormat) {
1141
+ function computeColumnLabels(marks, _chartArea, density = "auto", labelFormat, labelPrefix) {
1135
1142
  if (density === "none") return [];
1136
1143
  const targetMarks = density === "endpoints" && marks.length > 1 ? [marks[0], marks[marks.length - 1]] : marks;
1137
1144
  const formatter = buildD3Formatter2(labelFormat);
@@ -1146,6 +1153,7 @@ function computeColumnLabels(marks, _chartArea, density = "auto", labelFormat) {
1146
1153
  const num = Number(rawValue.replace(/[^0-9.-]/g, ""));
1147
1154
  if (!Number.isNaN(num)) valuePart = formatter(num);
1148
1155
  }
1156
+ if (labelPrefix) valuePart = labelPrefix + valuePart;
1149
1157
  const numericValue = parseFloat(valuePart);
1150
1158
  const isNegative = Number.isFinite(numericValue) && numericValue < 0;
1151
1159
  const textWidth = estimateTextWidth3(valuePart, LABEL_FONT_SIZE2, LABEL_FONT_WEIGHT2);
@@ -1186,7 +1194,13 @@ function computeColumnLabels(marks, _chartArea, density = "auto", labelFormat) {
1186
1194
  // src/charts/column/index.ts
1187
1195
  var columnRenderer = (spec, scales, chartArea, strategy, _theme) => {
1188
1196
  const marks = computeColumnMarks(spec, scales, chartArea, strategy);
1189
- const labels = computeColumnLabels(marks, chartArea, spec.labels.density, spec.labels.format);
1197
+ const labels = computeColumnLabels(
1198
+ marks,
1199
+ chartArea,
1200
+ spec.labels.density,
1201
+ spec.labels.format,
1202
+ spec.labels.prefix
1203
+ );
1190
1204
  for (let i = 0; i < marks.length && i < labels.length; i++) {
1191
1205
  marks[i].label = labels[i];
1192
1206
  }
@@ -1346,15 +1360,16 @@ import { estimateTextWidth as estimateTextWidth4, resolveCollisions as resolveCo
1346
1360
  var LABEL_FONT_SIZE3 = 11;
1347
1361
  var LABEL_FONT_WEIGHT3 = 600;
1348
1362
  var LABEL_OFFSET_X = 10;
1349
- function computeDotLabels(marks, _chartArea, density = "auto") {
1363
+ function computeDotLabels(marks, _chartArea, density = "auto", labelPrefix) {
1350
1364
  if (density === "none") return [];
1351
1365
  const targetMarks = density === "endpoints" && marks.length > 1 ? [marks[0], marks[marks.length - 1]] : marks;
1352
1366
  const candidates = [];
1353
1367
  for (const mark of targetMarks) {
1354
1368
  const ariaLabel = mark.aria.label;
1355
1369
  const lastColon = ariaLabel.lastIndexOf(":");
1356
- const valuePart = lastColon >= 0 ? ariaLabel.slice(lastColon + 1).trim() : "";
1370
+ let valuePart = lastColon >= 0 ? ariaLabel.slice(lastColon + 1).trim() : "";
1357
1371
  if (!valuePart) continue;
1372
+ if (labelPrefix) valuePart = labelPrefix + valuePart;
1358
1373
  const textWidth = estimateTextWidth4(valuePart, LABEL_FONT_SIZE3, LABEL_FONT_WEIGHT3);
1359
1374
  const textHeight = LABEL_FONT_SIZE3 * 1.2;
1360
1375
  candidates.push({
@@ -1392,7 +1407,7 @@ function computeDotLabels(marks, _chartArea, density = "auto") {
1392
1407
  var dotRenderer = (spec, scales, chartArea, strategy, _theme) => {
1393
1408
  const marks = computeDotMarks(spec, scales, chartArea, strategy);
1394
1409
  const pointMarks = marks.filter((m) => m.type === "point");
1395
- const labels = computeDotLabels(pointMarks, chartArea, spec.labels.density);
1410
+ const labels = computeDotLabels(pointMarks, chartArea, spec.labels.density, spec.labels.prefix);
1396
1411
  let labelIdx = 0;
1397
1412
  for (const mark of marks) {
1398
1413
  if (mark.type === "point" && labelIdx < labels.length) {
@@ -5971,6 +5986,7 @@ function normalizeChartSpec(spec, warnings) {
5971
5986
  labels: {
5972
5987
  density: spec.labels?.density ?? "auto",
5973
5988
  format: spec.labels?.format ?? "",
5989
+ prefix: spec.labels?.prefix ?? "",
5974
5990
  offsets: spec.labels?.offsets
5975
5991
  },
5976
5992
  legend: spec.legend,