@opendata-ai/openchart-engine 7.2.2 → 7.2.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 CHANGED
@@ -900,7 +900,12 @@ function resolveRefLineAnnotation(annotation, scales, chartArea, isDark) {
900
900
  }
901
901
  const labelDelta = applyOffset({ dx: baseDx, dy: baseDy }, annotation.labelOffset);
902
902
  const defaultStroke2 = isDark ? DARK_REFLINE_STROKE : LIGHT_REFLINE_STROKE;
903
- const style = makeAnnotationLabelStyle(11, 400, annotation.stroke ?? defaultStroke2, isDark);
903
+ const style = makeAnnotationLabelStyle(
904
+ annotation.fontSize ?? 11,
905
+ annotation.fontWeight ?? 400,
906
+ annotation.stroke ?? defaultStroke2,
907
+ isDark
908
+ );
904
909
  style.textAnchor = textAnchor;
905
910
  label = {
906
911
  text: annotation.label,
@@ -1477,7 +1482,9 @@ function computeBarMarks(spec, scales, _chartArea, _strategy) {
1477
1482
  return [];
1478
1483
  }
1479
1484
  const bandwidth = yScale.bandwidth();
1480
- const baseline = xScale(0);
1485
+ const xDomain = xScale.domain();
1486
+ const xIncludesZero = xDomain[0] <= 0 && xDomain[1] >= 0;
1487
+ const baseline = xIncludesZero ? xScale(0) : xScale(xDomain[0]);
1481
1488
  const colorEnc = encoding.color && "field" in encoding.color ? encoding.color : void 0;
1482
1489
  const conditionalColor = encoding.color && isConditionalValueDef(encoding.color) ? encoding.color : void 0;
1483
1490
  const colorField = colorEnc?.field;
@@ -10304,19 +10311,23 @@ function measureLegendWrap(entries, maxWidth, labelStyle, maxRows, entryGap = EN
10304
10311
 
10305
10312
  // src/layout/metrics.ts
10306
10313
  import { estimateTextWidth as estimateTextWidth14 } from "@opendata-ai/openchart-core";
10307
- var LABEL_FONT_SIZE7 = 10;
10308
- var VALUE_FONT_SIZE2 = 22;
10314
+ var DEFAULT_LABEL_FONT_SIZE = 10;
10315
+ var DEFAULT_VALUE_FONT_SIZE = 22;
10309
10316
  var LABEL_LINE_HEIGHT_RATIO = 1.4;
10310
10317
  var VALUE_LINE_HEIGHT_RATIO = 1.15;
10311
10318
  var INTER_ROW_GAP = 4;
10312
10319
  var TOP_GAP = 16;
10313
10320
  var BOTTOM_GAP = 20;
10321
+ var DEFAULT_METRIC_FONT_SIZES = {
10322
+ label: DEFAULT_LABEL_FONT_SIZE,
10323
+ value: DEFAULT_VALUE_FONT_SIZE
10324
+ };
10314
10325
  var MIN_BAR_WIDTH2 = 480;
10315
10326
  var MIN_CHART_HEIGHT = 150;
10316
10327
  var CELL_INNER_PAD = 8;
10317
- function metricBarHeight() {
10318
- const labelLine = LABEL_FONT_SIZE7 * LABEL_LINE_HEIGHT_RATIO;
10319
- const valueLine = VALUE_FONT_SIZE2 * VALUE_LINE_HEIGHT_RATIO;
10328
+ function metricBarHeight(fonts = DEFAULT_METRIC_FONT_SIZES) {
10329
+ const labelLine = fonts.label * LABEL_LINE_HEIGHT_RATIO;
10330
+ const valueLine = fonts.value * VALUE_LINE_HEIGHT_RATIO;
10320
10331
  return TOP_GAP + labelLine + INTER_ROW_GAP + valueLine + BOTTOM_GAP;
10321
10332
  }
10322
10333
  function valueRunText(metric) {
@@ -10325,19 +10336,19 @@ function valueRunText(metric) {
10325
10336
  if (metric.secondary) parts.push(metric.secondary);
10326
10337
  return parts.join(" ");
10327
10338
  }
10328
- function computeMetricBar(metrics, metricsTopY, metricsArea, remainingChartHeight, measureText) {
10339
+ function computeMetricBar(metrics, metricsTopY, metricsArea, remainingChartHeight, measureText, fonts = DEFAULT_METRIC_FONT_SIZES) {
10329
10340
  if (!metrics || metrics.length === 0) return void 0;
10330
10341
  if (metricsArea.width < MIN_BAR_WIDTH2) return void 0;
10331
10342
  if (remainingChartHeight < MIN_CHART_HEIGHT) return void 0;
10332
10343
  const cellWidth = metricsArea.width / metrics.length;
10333
10344
  for (const metric of metrics) {
10334
10345
  const text = valueRunText(metric);
10335
- const measured = measureText ? measureText(text, VALUE_FONT_SIZE2, 510).width : estimateTextWidth14(text, VALUE_FONT_SIZE2, 510);
10346
+ const measured = measureText ? measureText(text, fonts.value, 510).width : estimateTextWidth14(text, fonts.value, 510);
10336
10347
  if (measured > cellWidth - CELL_INNER_PAD) return void 0;
10337
10348
  }
10338
- const labelLine = LABEL_FONT_SIZE7 * LABEL_LINE_HEIGHT_RATIO;
10339
- const labelY = metricsTopY + TOP_GAP + LABEL_FONT_SIZE7;
10340
- const valueY = metricsTopY + TOP_GAP + labelLine + INTER_ROW_GAP + VALUE_FONT_SIZE2;
10349
+ const labelLine = fonts.label * LABEL_LINE_HEIGHT_RATIO;
10350
+ const labelY = metricsTopY + TOP_GAP + fonts.label;
10351
+ const valueY = metricsTopY + TOP_GAP + labelLine + INTER_ROW_GAP + fonts.value;
10341
10352
  const cells = metrics.map((metric, i) => ({
10342
10353
  x: metricsArea.x + i * cellWidth,
10343
10354
  cellWidth,
@@ -10348,12 +10359,15 @@ function computeMetricBar(metrics, metricsTopY, metricsArea, remainingChartHeigh
10348
10359
  }));
10349
10360
  return {
10350
10361
  y: metricsTopY,
10351
- height: metricBarHeight(),
10362
+ height: metricBarHeight(fonts),
10352
10363
  cells
10353
10364
  };
10354
10365
  }
10355
10366
 
10356
10367
  // src/layout/dimensions.ts
10368
+ function metricFonts(theme) {
10369
+ return { label: theme.fonts.sizes.metricLabel, value: theme.fonts.sizes.metricValue };
10370
+ }
10357
10371
  function chromeToInput(chrome) {
10358
10372
  return {
10359
10373
  eyebrow: chrome.eyebrow,
@@ -10485,7 +10499,7 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
10485
10499
  const topAxisGap = isRadial && chrome.topHeight === 0 ? 0 : axisMargin + inlineTickOverhang;
10486
10500
  const topPad = width < NARROW_VIEWPORT_MAX ? padding + TOP_PAD_EXTRA_NARROW : padding;
10487
10501
  const wantsMetrics = !!spec.metrics && spec.metrics.length > 0 && chromeMode !== "hidden";
10488
- const tentativeMetricsHeight = wantsMetrics ? metricBarHeight() : 0;
10502
+ const tentativeMetricsHeight = wantsMetrics ? metricBarHeight(metricFonts(theme)) : 0;
10489
10503
  const margins = {
10490
10504
  top: topPad + chrome.topHeight + tentativeMetricsHeight,
10491
10505
  right: hPad + (isRadial ? hPad : axisMargin),
@@ -10719,7 +10733,8 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
10719
10733
  fallbackMetricsTopY,
10720
10734
  fallbackMetricsArea,
10721
10735
  chartArea.height,
10722
- options.measureText
10736
+ options.measureText,
10737
+ theme
10723
10738
  ) : void 0;
10724
10739
  if (wantsMetrics && !fallbackMetrics) {
10725
10740
  margins.top = Math.max(0, margins.top - tentativeMetricsHeight);
@@ -10742,7 +10757,7 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
10742
10757
  }
10743
10758
  const metricsTopY = topPad + chrome.topHeight;
10744
10759
  const metricsArea = { x: hPad, width: Math.max(0, width - hPad * 2) };
10745
- const resolvedMetrics = wantsMetrics ? resolveMetrics(spec, metricsTopY, metricsArea, chartArea.height, options.measureText) : void 0;
10760
+ const resolvedMetrics = wantsMetrics ? resolveMetrics(spec, metricsTopY, metricsArea, chartArea.height, options.measureText, theme) : void 0;
10746
10761
  if (wantsMetrics && !resolvedMetrics) {
10747
10762
  margins.top = Math.max(0, margins.top - tentativeMetricsHeight);
10748
10763
  chartArea = {
@@ -10761,13 +10776,14 @@ function computeDimensions(spec, options, legendLayout, theme, strategy, waterma
10761
10776
  xAxisHeight
10762
10777
  };
10763
10778
  }
10764
- function resolveMetrics(spec, metricsTopY, metricsArea, remainingChartHeight, measureText) {
10779
+ function resolveMetrics(spec, metricsTopY, metricsArea, remainingChartHeight, measureText, theme) {
10765
10780
  return computeMetricBar(
10766
10781
  spec.metrics,
10767
10782
  metricsTopY,
10768
10783
  metricsArea,
10769
10784
  remainingChartHeight,
10770
- measureText
10785
+ measureText,
10786
+ metricFonts(theme)
10771
10787
  );
10772
10788
  }
10773
10789