@opendata-ai/openchart-vanilla 2.1.0 → 2.2.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/src/mount.ts CHANGED
@@ -26,7 +26,7 @@ import type {
26
26
  TooltipContent,
27
27
  } from '@opendata-ai/openchart-core';
28
28
  import { compileChart } from '@opendata-ai/openchart-engine';
29
- import { exportCSV, exportPNG, exportSVG, type PNGExportOptions } from './export';
29
+ import { exportCSV, exportJPG, exportPNG, exportSVG, type JPGExportOptions } from './export';
30
30
  import { observeResize } from './resize-observer';
31
31
  import { renderChartSVG } from './svg-renderer';
32
32
  import { createTooltipManager, type TooltipManager } from './tooltip';
@@ -46,8 +46,8 @@ export interface MountOptions extends ChartEventHandlers {
46
46
  responsive?: boolean;
47
47
  }
48
48
 
49
- export interface ExportOptions extends PNGExportOptions {
50
- // Extensible for future formats
49
+ export interface ExportOptions extends JPGExportOptions {
50
+ // Extensible for future formats (extends JPGExportOptions which extends PNGExportOptions)
51
51
  }
52
52
 
53
53
  export interface ChartInstance {
@@ -58,8 +58,9 @@ export interface ChartInstance {
58
58
  /** Export the chart. */
59
59
  export(format: 'svg'): string;
60
60
  export(format: 'png', options?: ExportOptions): Promise<Blob>;
61
+ export(format: 'jpg', options?: ExportOptions): Promise<Blob>;
61
62
  export(format: 'csv'): string;
62
- export(format: 'svg' | 'png' | 'csv', options?: ExportOptions): string | Promise<Blob>;
63
+ export(format: 'svg' | 'png' | 'jpg' | 'csv', options?: ExportOptions): string | Promise<Blob>;
63
64
  /** Remove all DOM elements and disconnect observers. */
64
65
  destroy(): void;
65
66
  /** The current compiled layout (for hooks / debugging). */
@@ -1096,13 +1097,16 @@ function wireSeriesLabelDrag(
1096
1097
 
1097
1098
  /**
1098
1099
  * Wire click handlers on legend entries to toggle series visibility.
1099
- * Optionally calls onLegendToggle when a series is toggled.
1100
+ * Fires onEdit with { type: 'legend-toggle', series, hidden } for each toggle,
1101
+ * and optionally calls the legacy onLegendToggle callback.
1102
+ * Legend entries for hidden series stay visible but dimmed (opacity 0.3).
1100
1103
  * Returns a cleanup function.
1101
1104
  */
1102
1105
  function wireLegendInteraction(
1103
1106
  svg: SVGElement,
1104
1107
  _layout: ChartLayout,
1105
1108
  onLegendToggle?: (series: string, visible: boolean) => void,
1109
+ onEdit?: (edit: ElementEdit) => void,
1106
1110
  ): () => void {
1107
1111
  const legendEntries = svg.querySelectorAll('[data-legend-index]');
1108
1112
  const cleanups: Array<() => void> = [];
@@ -1120,11 +1124,13 @@ function wireLegendInteraction(
1120
1124
  entry.setAttribute('opacity', '1');
1121
1125
  entry.setAttribute('aria-label', `${label}: visible`);
1122
1126
  onLegendToggle?.(label, true);
1127
+ onEdit?.({ type: 'legend-toggle', series: label, hidden: false });
1123
1128
  } else {
1124
1129
  hiddenSeries.add(label);
1125
1130
  entry.setAttribute('opacity', '0.3');
1126
1131
  entry.setAttribute('aria-label', `${label}: hidden`);
1127
1132
  onLegendToggle?.(label, false);
1133
+ onEdit?.({ type: 'legend-toggle', series: label, hidden: true });
1128
1134
  }
1129
1135
 
1130
1136
  // Toggle visibility of marks with matching series.
@@ -1448,7 +1454,12 @@ export function createChart(
1448
1454
  );
1449
1455
 
1450
1456
  // Wire legend interactivity
1451
- cleanupLegend = wireLegendInteraction(svgElement, currentLayout, options?.onLegendToggle);
1457
+ cleanupLegend = wireLegendInteraction(
1458
+ svgElement,
1459
+ currentLayout,
1460
+ options?.onLegendToggle,
1461
+ options?.onEdit,
1462
+ );
1452
1463
 
1453
1464
  // Wire chart event handlers (mark click/hover/leave, annotation click)
1454
1465
  if (
@@ -1546,9 +1557,10 @@ export function createChart(
1546
1557
 
1547
1558
  function doExport(format: 'svg'): string;
1548
1559
  function doExport(format: 'png', exportOptions?: ExportOptions): Promise<Blob>;
1560
+ function doExport(format: 'jpg', exportOptions?: ExportOptions): Promise<Blob>;
1549
1561
  function doExport(format: 'csv'): string;
1550
1562
  function doExport(
1551
- format: 'svg' | 'png' | 'csv',
1563
+ format: 'svg' | 'png' | 'jpg' | 'csv',
1552
1564
  exportOptions?: ExportOptions,
1553
1565
  ): string | Promise<Blob> {
1554
1566
  if (!svgElement) {
@@ -1560,6 +1572,8 @@ export function createChart(
1560
1572
  return exportSVG(svgElement);
1561
1573
  case 'png':
1562
1574
  return exportPNG(svgElement, exportOptions);
1575
+ case 'jpg':
1576
+ return exportJPG(svgElement, exportOptions);
1563
1577
  case 'csv':
1564
1578
  return exportCSV(
1565
1579
  'data' in currentSpec && Array.isArray(currentSpec.data) ? currentSpec.data : [],