@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 +35 -42
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/charts/bar/__tests__/compute.test.ts +51 -0
- package/src/charts/bar/labels.ts +6 -23
- package/src/charts/column/__tests__/compute.test.ts +76 -0
- package/src/charts/column/index.ts +1 -1
- package/src/charts/column/labels.ts +18 -4
- package/src/layout/axes.ts +8 -15
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 {
|
|
593
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
|
860
|
-
if (!
|
|
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
|
|
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 {
|
|
2840
|
-
|
|
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
|
-
|
|
2902
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
4095
|
+
return d3Format2(format)(value);
|
|
4103
4096
|
} catch {
|
|
4104
4097
|
return formatNumber5(value);
|
|
4105
4098
|
}
|