@opendata-ai/openchart-engine 2.6.0 → 2.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.js CHANGED
@@ -589,8 +589,11 @@ function computeSimpleBars(data, valueField, categoryField, xScale, yScale, band
589
589
  }
590
590
 
591
591
  // src/charts/bar/labels.ts
592
- import { estimateTextWidth as estimateTextWidth2, resolveCollisions } from "@opendata-ai/openchart-core";
593
- import { format as d3Format } from "d3-format";
592
+ import {
593
+ buildD3Formatter,
594
+ estimateTextWidth as estimateTextWidth2,
595
+ resolveCollisions
596
+ } from "@opendata-ai/openchart-core";
594
597
  var LABEL_FONT_SIZE = 11;
595
598
  var LABEL_FONT_WEIGHT = 600;
596
599
  var LABEL_PADDING = 6;
@@ -599,22 +602,7 @@ function computeBarLabels(marks, _chartArea, density = "auto", labelFormat) {
599
602
  if (density === "none") return [];
600
603
  const targetMarks = density === "endpoints" && marks.length > 1 ? [marks[0], marks[marks.length - 1]] : marks;
601
604
  const candidates = [];
602
- let formatter = null;
603
- if (labelFormat) {
604
- try {
605
- formatter = d3Format(labelFormat);
606
- } catch {
607
- const suffixMatch = labelFormat.match(/^(.+[a-z])([^a-z]+)$/i);
608
- if (suffixMatch) {
609
- try {
610
- const d3Fmt = d3Format(suffixMatch[1]);
611
- const suffix = suffixMatch[2];
612
- formatter = (v) => d3Fmt(v) + suffix;
613
- } catch {
614
- }
615
- }
616
- }
617
- }
605
+ const formatter = buildD3Formatter(labelFormat);
618
606
  for (const mark of targetMarks) {
619
607
  const ariaLabel = mark.aria.label;
620
608
  const lastColon = ariaLabel.lastIndexOf(":");
@@ -845,24 +833,34 @@ function computeStackedColumns(data, categoryField, valueField, colorField, xSca
845
833
  }
846
834
 
847
835
  // src/charts/column/labels.ts
848
- import { estimateTextWidth as estimateTextWidth3, resolveCollisions as resolveCollisions2 } from "@opendata-ai/openchart-core";
836
+ import {
837
+ buildD3Formatter as buildD3Formatter2,
838
+ estimateTextWidth as estimateTextWidth3,
839
+ resolveCollisions as resolveCollisions2
840
+ } from "@opendata-ai/openchart-core";
849
841
  var LABEL_FONT_SIZE2 = 10;
850
842
  var LABEL_FONT_WEIGHT2 = 600;
851
843
  var LABEL_OFFSET_Y = 6;
852
- function computeColumnLabels(marks, _chartArea, density = "auto") {
844
+ function computeColumnLabels(marks, _chartArea, density = "auto", labelFormat) {
853
845
  if (density === "none") return [];
854
846
  const targetMarks = density === "endpoints" && marks.length > 1 ? [marks[0], marks[marks.length - 1]] : marks;
847
+ const formatter = buildD3Formatter2(labelFormat);
855
848
  const candidates = [];
856
849
  for (const mark of targetMarks) {
857
850
  const ariaLabel = mark.aria.label;
858
851
  const lastColon = ariaLabel.lastIndexOf(":");
859
- const valuePart = lastColon >= 0 ? ariaLabel.slice(lastColon + 1).trim() : "";
860
- if (!valuePart) continue;
852
+ const rawValue = lastColon >= 0 ? ariaLabel.slice(lastColon + 1).trim() : "";
853
+ if (!rawValue) continue;
854
+ let valuePart = rawValue;
855
+ if (formatter) {
856
+ const num = Number(rawValue.replace(/[^0-9.-]/g, ""));
857
+ if (!Number.isNaN(num)) valuePart = formatter(num);
858
+ }
861
859
  const numericValue = parseFloat(valuePart);
862
860
  const isNegative = Number.isFinite(numericValue) && numericValue < 0;
863
861
  const textWidth = estimateTextWidth3(valuePart, LABEL_FONT_SIZE2, LABEL_FONT_WEIGHT2);
864
862
  const textHeight = LABEL_FONT_SIZE2 * 1.2;
865
- const anchorX = mark.x + mark.width / 2 - textWidth / 2;
863
+ const anchorX = mark.x + mark.width / 2;
866
864
  const anchorY = isNegative ? mark.y + mark.height + LABEL_OFFSET_Y : mark.y - LABEL_OFFSET_Y - textHeight;
867
865
  candidates.push({
868
866
  text: valuePart,
@@ -898,7 +896,7 @@ function computeColumnLabels(marks, _chartArea, density = "auto") {
898
896
  // src/charts/column/index.ts
899
897
  var columnRenderer = (spec, scales, chartArea, strategy, _theme) => {
900
898
  const marks = computeColumnMarks(spec, scales, chartArea, strategy);
901
- const labels = computeColumnLabels(marks, chartArea, spec.labels.density);
899
+ const labels = computeColumnLabels(marks, chartArea, spec.labels.density, spec.labels.format);
902
900
  for (let i = 0; i < marks.length && i < labels.length; i++) {
903
901
  marks[i].label = labels[i];
904
902
  }
@@ -2836,8 +2834,12 @@ function compileGraph(spec, options) {
2836
2834
  var DEFAULT_COLLISION_PADDING = 5;
2837
2835
 
2838
2836
  // src/layout/axes.ts
2839
- import { abbreviateNumber as abbreviateNumber3, formatDate, formatNumber as formatNumber3 } from "@opendata-ai/openchart-core";
2840
- import { format as d3Format2 } from "d3-format";
2837
+ import {
2838
+ abbreviateNumber as abbreviateNumber3,
2839
+ buildD3Formatter as buildD3Formatter3,
2840
+ formatDate,
2841
+ formatNumber as formatNumber3
2842
+ } from "@opendata-ai/openchart-core";
2841
2843
  var TICK_COUNTS = {
2842
2844
  full: 8,
2843
2845
  reduced: 5,
@@ -2898,17 +2900,8 @@ function formatTickLabel(value, resolvedScale) {
2898
2900
  if (resolvedScale.type === "linear" || resolvedScale.type === "log") {
2899
2901
  const num = value;
2900
2902
  if (formatStr) {
2901
- try {
2902
- return d3Format2(formatStr)(num);
2903
- } catch {
2904
- const suffixMatch = formatStr.match(/^(.+[a-z])([^a-z]+)$/i);
2905
- if (suffixMatch) {
2906
- try {
2907
- return d3Format2(suffixMatch[1])(num) + suffixMatch[2];
2908
- } catch {
2909
- }
2910
- }
2911
- }
2903
+ const fmt = buildD3Formatter3(formatStr);
2904
+ if (fmt) return fmt(num);
2912
2905
  }
2913
2906
  if (Math.abs(num) >= 1e3) return abbreviateNumber3(num);
2914
2907
  return formatNumber3(num);
@@ -3563,7 +3556,7 @@ function computeCategoryColors(data, column, theme, darkMode) {
3563
3556
 
3564
3557
  // src/tables/format-cells.ts
3565
3558
  import { formatDate as formatDate2, formatNumber as formatNumber4 } from "@opendata-ai/openchart-core";
3566
- import { format as d3Format3 } from "d3-format";
3559
+ import { format as d3Format } from "d3-format";
3567
3560
  function isNumericValue(value) {
3568
3561
  if (typeof value === "number") return Number.isFinite(value);
3569
3562
  return false;
@@ -3583,7 +3576,7 @@ function formatCell(value, column) {
3583
3576
  }
3584
3577
  if (column.format && isNumericValue(value)) {
3585
3578
  try {
3586
- const formatter = d3Format3(column.format);
3579
+ const formatter = d3Format(column.format);
3587
3580
  return {
3588
3581
  value,
3589
3582
  formattedValue: formatter(value),
@@ -3616,7 +3609,7 @@ function formatValueForSearch(value, column) {
3616
3609
  if (value == null) return "";
3617
3610
  if (column.format && isNumericValue(value)) {
3618
3611
  try {
3619
- return d3Format3(column.format)(value);
3612
+ return d3Format(column.format)(value);
3620
3613
  } catch {
3621
3614
  }
3622
3615
  }
@@ -4090,7 +4083,7 @@ function compileTableLayout(spec, options, theme) {
4090
4083
 
4091
4084
  // src/tooltips/compute.ts
4092
4085
  import { formatDate as formatDate3, formatNumber as formatNumber5 } from "@opendata-ai/openchart-core";
4093
- import { format as d3Format4 } from "d3-format";
4086
+ import { format as d3Format2 } from "d3-format";
4094
4087
  function formatValue(value, fieldType, format) {
4095
4088
  if (value == null) return "";
4096
4089
  if (fieldType === "temporal" || value instanceof Date) {
@@ -4099,7 +4092,7 @@ function formatValue(value, fieldType, format) {
4099
4092
  if (typeof value === "number") {
4100
4093
  if (format) {
4101
4094
  try {
4102
- return d3Format4(format)(value);
4095
+ return d3Format2(format)(value);
4103
4096
  } catch {
4104
4097
  return formatNumber5(value);
4105
4098
  }