@opendata-ai/openchart-vanilla 6.12.0 → 6.15.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
@@ -299,8 +299,6 @@ var GraphCanvasRenderer = class {
299
299
  this.cssHeight = height;
300
300
  this.canvas.width = width * this.dpr;
301
301
  this.canvas.height = height * this.dpr;
302
- this.canvas.style.width = `${width}px`;
303
- this.canvas.style.height = `${height}px`;
304
302
  }
305
303
  /** Clear canvas and render the full graph state. */
306
304
  render(state) {
@@ -796,20 +794,32 @@ var ZoomTransform = class _ZoomTransform {
796
794
  if (n.x + r > maxX) maxX = n.x + r;
797
795
  if (n.y + r > maxY) maxY = n.y + r;
798
796
  }
799
- const graphW = maxX - minX;
800
- const graphH = maxY - minY;
797
+ let graphW = maxX - minX;
798
+ let graphH = maxY - minY;
801
799
  if (graphW === 0 && graphH === 0) {
802
800
  return {
803
801
  transform: new _ZoomTransform(canvasW / 2 - minX, canvasH / 2 - minY, 1),
804
802
  contentHeight: padding * 2
805
803
  };
806
804
  }
805
+ if (nodes.length > 50) {
806
+ const spread = 1 + Math.sqrt(nodes.length) / 120;
807
+ const cx2 = (minX + maxX) / 2;
808
+ const cy2 = (minY + maxY) / 2;
809
+ graphW *= spread;
810
+ graphH *= spread;
811
+ minX = cx2 - graphW / 2;
812
+ maxX = cx2 + graphW / 2;
813
+ minY = cy2 - graphH / 2;
814
+ maxY = cy2 + graphH / 2;
815
+ }
807
816
  const availW = canvasW - padding * 2;
808
817
  const availH = canvasH - padding * 2;
809
- const k = Math.min(availW / graphW, availH / graphH);
818
+ const k = Math.min(1, availW / graphW, availH / graphH);
810
819
  const cx = (minX + maxX) / 2;
820
+ const cy = (minY + maxY) / 2;
811
821
  const tx = canvasW / 2 - cx * k;
812
- const ty = padding - minY * k;
822
+ const ty = canvasH / 2 - cy * k;
813
823
  const contentHeight = graphH * k + padding * 2;
814
824
  return {
815
825
  transform: new _ZoomTransform(tx, ty, k),
@@ -2811,8 +2821,7 @@ function createGraph(container, spec, options) {
2811
2821
  wrapper.appendChild(legendEl);
2812
2822
  }
2813
2823
  container.appendChild(wrapper);
2814
- const chromeHeight = chromeEl.getBoundingClientRect().height || 0;
2815
- const canvasHeight = Math.max(height - chromeHeight, 200);
2824
+ const canvasHeight = Math.max(height, 200);
2816
2825
  renderer = new GraphCanvasRenderer(canvas);
2817
2826
  renderer.resize(width, canvasHeight);
2818
2827
  }
@@ -3118,8 +3127,7 @@ function createGraph(container, spec, options) {
3118
3127
  function doResize() {
3119
3128
  if (destroyed || !canvas || !renderer || !wrapper) return;
3120
3129
  const { width, height } = getContainerDimensions();
3121
- const chromeHeight = chromeEl?.getBoundingClientRect().height || 0;
3122
- const canvasHeight = Math.max(height - chromeHeight, 200);
3130
+ const canvasHeight = Math.max(height, 200);
3123
3131
  renderer.resize(width, canvasHeight);
3124
3132
  needsRender = true;
3125
3133
  scheduleRender();
@@ -3447,14 +3455,33 @@ function applyTextStyle(el, style) {
3447
3455
  el.setAttribute("font-variant", style.fontVariant);
3448
3456
  }
3449
3457
  }
3450
- function wrapText(text, fontSize, fontWeight, maxWidth) {
3458
+ function wrapText(text, fontSize, fontWeight, maxWidth, measureText) {
3451
3459
  if (maxWidth <= 0) return [text];
3452
3460
  const segments = text.split("\n");
3453
3461
  if (segments.length > 1) {
3454
3462
  return segments.flatMap(
3455
- (segment) => segment.length === 0 ? [""] : wrapText(segment, fontSize, fontWeight, maxWidth)
3463
+ (segment) => segment.length === 0 ? [""] : wrapText(segment, fontSize, fontWeight, maxWidth, measureText)
3456
3464
  );
3457
3465
  }
3466
+ if (measureText) {
3467
+ const textWidth = measureText(text, fontSize, fontWeight).width;
3468
+ if (textWidth <= maxWidth) return [text];
3469
+ const words2 = text.split(" ");
3470
+ const lines2 = [];
3471
+ let current2 = "";
3472
+ for (const word of words2) {
3473
+ const candidate = current2 ? `${current2} ${word}` : word;
3474
+ const candidateWidth = measureText(candidate, fontSize, fontWeight).width;
3475
+ if (candidateWidth > maxWidth && current2) {
3476
+ lines2.push(current2);
3477
+ current2 = word;
3478
+ } else {
3479
+ current2 = candidate;
3480
+ }
3481
+ }
3482
+ if (current2) lines2.push(current2);
3483
+ return lines2;
3484
+ }
3458
3485
  const AVG_CHAR_WIDTH = 0.55;
3459
3486
  const WEIGHT_FACTORS = {
3460
3487
  100: 0.9,
@@ -3486,7 +3513,7 @@ function wrapText(text, fontSize, fontWeight, maxWidth) {
3486
3513
  if (current) lines.push(current);
3487
3514
  return lines;
3488
3515
  }
3489
- function renderChromeElement(parent, element, className, chromeKey) {
3516
+ function renderChromeElement(parent, element, className, chromeKey, measureText) {
3490
3517
  const text = createSVGElement("text");
3491
3518
  setAttrs(text, { x: element.x, y: element.y });
3492
3519
  applyTextStyle(text, element.style);
@@ -3496,7 +3523,8 @@ function renderChromeElement(parent, element, className, chromeKey) {
3496
3523
  element.text,
3497
3524
  element.style.fontSize,
3498
3525
  element.style.fontWeight,
3499
- element.maxWidth
3526
+ element.maxWidth,
3527
+ measureText
3500
3528
  );
3501
3529
  if (lines.length === 1) {
3502
3530
  text.textContent = element.text;
@@ -3514,12 +3542,12 @@ function renderChromeElement(parent, element, className, chromeKey) {
3514
3542
  function renderChrome(parent, layout) {
3515
3543
  const g = createSVGElement("g");
3516
3544
  g.setAttribute("class", "oc-chrome");
3517
- const { chrome } = layout;
3545
+ const { chrome, measureText } = layout;
3518
3546
  if (chrome.title) {
3519
- renderChromeElement(g, chrome.title, "oc-title", "title");
3547
+ renderChromeElement(g, chrome.title, "oc-title", "title", measureText);
3520
3548
  }
3521
3549
  if (chrome.subtitle) {
3522
- renderChromeElement(g, chrome.subtitle, "oc-subtitle", "subtitle");
3550
+ renderChromeElement(g, chrome.subtitle, "oc-subtitle", "subtitle", measureText);
3523
3551
  }
3524
3552
  const xAxisExtent = computeXAxisExtent(layout);
3525
3553
  const bottomOffset = layout.area.y + layout.area.height + xAxisExtent;
@@ -3528,7 +3556,8 @@ function renderChrome(parent, layout) {
3528
3556
  g,
3529
3557
  { ...chrome.source, y: bottomOffset + chrome.source.y },
3530
3558
  "oc-source",
3531
- "source"
3559
+ "source",
3560
+ measureText
3532
3561
  );
3533
3562
  }
3534
3563
  if (chrome.byline) {
@@ -3536,7 +3565,8 @@ function renderChrome(parent, layout) {
3536
3565
  g,
3537
3566
  { ...chrome.byline, y: bottomOffset + chrome.byline.y },
3538
3567
  "oc-byline",
3539
- "byline"
3568
+ "byline",
3569
+ measureText
3540
3570
  );
3541
3571
  }
3542
3572
  if (chrome.footer) {
@@ -3544,7 +3574,8 @@ function renderChrome(parent, layout) {
3544
3574
  g,
3545
3575
  { ...chrome.footer, y: bottomOffset + chrome.footer.y },
3546
3576
  "oc-footer",
3547
- "footer"
3577
+ "footer",
3578
+ measureText
3548
3579
  );
3549
3580
  }
3550
3581
  parent.appendChild(g);
@@ -3967,8 +3998,9 @@ function renderAnnotations(parent, layout) {
3967
3998
  if (layout.annotations.length === 0) return;
3968
3999
  const g = createSVGElement("g");
3969
4000
  g.setAttribute("class", "oc-annotations");
4001
+ const bgColor = layout.theme.colors.background;
3970
4002
  for (let i = 0; i < layout.annotations.length; i++) {
3971
- renderAnnotation(g, layout.annotations[i], i);
4003
+ renderAnnotation(g, layout.annotations[i], i, bgColor);
3972
4004
  }
3973
4005
  parent.appendChild(g);
3974
4006
  }
@@ -4014,7 +4046,7 @@ function renderCurvedArrow(parent, from, to, stroke) {
4014
4046
  });
4015
4047
  parent.appendChild(arrow);
4016
4048
  }
4017
- function renderAnnotation(parent, annotation, index2) {
4049
+ function renderAnnotation(parent, annotation, index2, bgColor) {
4018
4050
  const g = createSVGElement("g");
4019
4051
  g.setAttribute("class", `oc-annotation oc-annotation-${annotation.type}`);
4020
4052
  g.setAttribute("data-annotation-index", String(index2));
@@ -4108,6 +4140,11 @@ function renderAnnotation(parent, annotation, index2) {
4108
4140
  rx: 2
4109
4141
  });
4110
4142
  g.appendChild(bgRect);
4143
+ } else if (bgColor) {
4144
+ text.style.paintOrder = "stroke";
4145
+ text.style.stroke = bgColor;
4146
+ text.style.strokeWidth = `${Math.round(fontSize * 0.3)}px`;
4147
+ text.style.strokeLinejoin = "round";
4111
4148
  }
4112
4149
  g.appendChild(text);
4113
4150
  }