@internetstiftelsen/charts 0.9.2 → 0.10.1

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.
Files changed (46) hide show
  1. package/README.md +137 -3
  2. package/dist/area.d.ts +2 -0
  3. package/dist/area.js +39 -31
  4. package/dist/bar.d.ts +20 -1
  5. package/dist/bar.js +395 -519
  6. package/dist/base-chart.d.ts +21 -1
  7. package/dist/base-chart.js +166 -93
  8. package/dist/chart-group.d.ts +137 -0
  9. package/dist/chart-group.js +1155 -0
  10. package/dist/chart-interface.d.ts +1 -1
  11. package/dist/donut-center-content.d.ts +1 -0
  12. package/dist/donut-center-content.js +21 -38
  13. package/dist/donut-chart.js +30 -15
  14. package/dist/gauge-chart.d.ts +20 -0
  15. package/dist/gauge-chart.js +229 -133
  16. package/dist/legend-state.d.ts +19 -0
  17. package/dist/legend-state.js +81 -0
  18. package/dist/legend.d.ts +5 -2
  19. package/dist/legend.js +45 -38
  20. package/dist/line.js +3 -1
  21. package/dist/pie-chart.d.ts +3 -0
  22. package/dist/pie-chart.js +45 -19
  23. package/dist/scatter.d.ts +16 -0
  24. package/dist/scatter.js +165 -0
  25. package/dist/tooltip.d.ts +2 -1
  26. package/dist/tooltip.js +21 -25
  27. package/dist/types.d.ts +19 -1
  28. package/dist/utils.js +11 -19
  29. package/dist/validation.d.ts +4 -0
  30. package/dist/validation.js +19 -0
  31. package/dist/x-axis.d.ts +10 -0
  32. package/dist/x-axis.js +190 -149
  33. package/dist/xy-chart.d.ts +40 -1
  34. package/dist/xy-chart.js +488 -165
  35. package/dist/y-axis.d.ts +7 -2
  36. package/dist/y-axis.js +99 -10
  37. package/docs/chart-group.md +213 -0
  38. package/docs/components.md +321 -0
  39. package/docs/donut-chart.md +193 -0
  40. package/docs/gauge-chart.md +175 -0
  41. package/docs/getting-started.md +311 -0
  42. package/docs/pie-chart.md +123 -0
  43. package/docs/theming.md +162 -0
  44. package/docs/word-cloud-chart.md +98 -0
  45. package/docs/xy-chart.md +517 -0
  46. package/package.json +6 -4
@@ -1,5 +1,5 @@
1
1
  import { type Selection } from 'd3';
2
- import type { ChartData, DataItem, ChartTheme, ResolvedChartTheme, AxisScaleConfig, ExportFormat, ExportOptions, D3Scale, ExportHookContext, ExportRenderContext, LegendItem, LegendSeries, ResponsiveConfig, ResponsiveRenderContext, DeepPartial } from './types.js';
2
+ import type { ChartData, DataItem, ChartTheme, ResolvedChartTheme, AxisScaleConfig, ExportFormat, ExportOptions, D3Scale, ExportHookContext, ExportRenderContext, LegendItem, LegendMode, LegendSeries, ResponsiveConfig, ResponsiveRenderContext, DeepPartial } from './types.js';
3
3
  import type { ChartComponentBase, LayoutAwareComponentBase } from './chart-interface.js';
4
4
  import type { XAxis } from './x-axis.js';
5
5
  import type { YAxis } from './y-axis.js';
@@ -8,6 +8,7 @@ import type { Tooltip } from './tooltip.js';
8
8
  import type { Legend } from './legend.js';
9
9
  import type { Title } from './title.js';
10
10
  import { LayoutManager, type PlotAreaBounds } from './layout-manager.js';
11
+ import { LegendStateController } from './legend-state.js';
11
12
  type VisualExportFormat = 'svg' | 'png' | 'jpg' | 'pdf';
12
13
  type RenderDimensions = {
13
14
  width: number;
@@ -82,10 +83,13 @@ export declare abstract class BaseChart {
82
83
  protected resizeObserver: ResizeObserver | null;
83
84
  protected layoutManager: LayoutManager;
84
85
  protected plotArea: PlotAreaBounds | null;
86
+ protected readonly legendState: LegendStateController;
85
87
  private readyPromise;
86
88
  private disconnectedLegendContainer;
87
89
  private renderThemeOverride;
88
90
  private renderSizeOverride;
91
+ private readonly renderCallbacks;
92
+ private legendModeOverride;
89
93
  protected constructor(config: BaseChartConfig);
90
94
  /**
91
95
  * Adds a component (axis, grid, tooltip, etc.) to the chart
@@ -101,6 +105,7 @@ export declare abstract class BaseChart {
101
105
  */
102
106
  private performRender;
103
107
  protected resolveRenderDimensions(containerRect: DOMRect): RenderDimensions;
108
+ private pushIfIncluded;
104
109
  private resolveAccessibleLabel;
105
110
  private syncAccessibleLabelFromSvg;
106
111
  protected resolveResponsiveContext(context: {
@@ -112,6 +117,17 @@ export declare abstract class BaseChart {
112
117
  private applyRenderTheme;
113
118
  protected get renderTheme(): ChartTheme;
114
119
  protected get resolvedRenderTheme(): ResolvedChartTheme;
120
+ protected getLegendMode(): LegendMode | null;
121
+ protected hasInlineLegend(): boolean;
122
+ protected hasDisconnectedLegend(): boolean;
123
+ protected shouldIncludeLegendInExport(): boolean;
124
+ getConfiguredSize(): {
125
+ width?: number;
126
+ height?: number;
127
+ };
128
+ setLegendModeOverride(mode: LegendMode | null, rerender?: boolean): this;
129
+ onRender(callback: () => void): () => void;
130
+ private notifyRendered;
115
131
  /**
116
132
  * Get layout-aware components in order
117
133
  * Override in subclasses to provide chart-specific components
@@ -193,6 +209,10 @@ export declare abstract class BaseChart {
193
209
  private exportImage;
194
210
  private exportPDF;
195
211
  protected exportSVG(options?: ExportOptions, formatForHooks?: VisualExportFormat): Promise<string>;
212
+ private requireRenderedSvg;
213
+ private resolveExportContext;
214
+ private createExportSvgClone;
215
+ private populateExportChart;
196
216
  protected exportJSON(): string;
197
217
  }
198
218
  export {};
@@ -7,6 +7,7 @@ import { exportRasterBlob } from './export-image.js';
7
7
  import { exportXLSXBlob } from './export-xlsx.js';
8
8
  import { exportPDFBlob } from './export-pdf.js';
9
9
  import { normalizeChartData } from './grouped-data.js';
10
+ import { LegendStateController } from './legend-state.js';
10
11
  import { mergeDeep } from './utils.js';
11
12
  function normalizeChartDimension(value, name) {
12
13
  if (value === undefined) {
@@ -182,6 +183,12 @@ export class BaseChart {
182
183
  writable: true,
183
184
  value: null
184
185
  });
186
+ Object.defineProperty(this, "legendState", {
187
+ enumerable: true,
188
+ configurable: true,
189
+ writable: true,
190
+ value: void 0
191
+ });
185
192
  Object.defineProperty(this, "readyPromise", {
186
193
  enumerable: true,
187
194
  configurable: true,
@@ -206,6 +213,18 @@ export class BaseChart {
206
213
  writable: true,
207
214
  value: null
208
215
  });
216
+ Object.defineProperty(this, "renderCallbacks", {
217
+ enumerable: true,
218
+ configurable: true,
219
+ writable: true,
220
+ value: new Set()
221
+ });
222
+ Object.defineProperty(this, "legendModeOverride", {
223
+ enumerable: true,
224
+ configurable: true,
225
+ writable: true,
226
+ value: null
227
+ });
209
228
  const normalized = normalizeChartData(config.data);
210
229
  ChartValidator.validateData(normalized.data);
211
230
  this.sourceData = config.data;
@@ -217,6 +236,10 @@ export class BaseChart {
217
236
  this.height = this.configuredHeight ?? DEFAULT_CHART_HEIGHT;
218
237
  this.scaleConfig = config.scales || {};
219
238
  this.responsiveConfig = config.responsive;
239
+ this.legendState = new LegendStateController();
240
+ this.legendState.subscribe(() => {
241
+ this.rerender();
242
+ });
220
243
  this.layoutManager = new LayoutManager(this.resolvedRenderTheme);
221
244
  }
222
245
  /**
@@ -309,6 +332,7 @@ export class BaseChart {
309
332
  plotArea,
310
333
  });
311
334
  this.renderDisconnectedLegend();
335
+ this.notifyRendered();
312
336
  }
313
337
  finally {
314
338
  restoreComponents();
@@ -316,22 +340,34 @@ export class BaseChart {
316
340
  }
317
341
  }
318
342
  resolveRenderDimensions(containerRect) {
319
- const width = this.renderSizeOverride?.width ??
320
- this.configuredWidth ??
321
- (containerRect.width || DEFAULT_CHART_WIDTH);
322
- const height = this.renderSizeOverride?.height ??
323
- this.configuredHeight ??
324
- (containerRect.height || DEFAULT_CHART_HEIGHT);
325
- return {
326
- width,
327
- height,
328
- svgWidthAttr: this.renderSizeOverride?.width ??
329
- this.configuredWidth ??
330
- '100%',
331
- svgHeightAttr: this.renderSizeOverride?.height ??
332
- this.configuredHeight ??
333
- '100%',
343
+ const dimensions = {
344
+ width: containerRect.width || DEFAULT_CHART_WIDTH,
345
+ height: containerRect.height || DEFAULT_CHART_HEIGHT,
346
+ svgWidthAttr: '100%',
347
+ svgHeightAttr: '100%',
334
348
  };
349
+ if (this.configuredWidth !== undefined) {
350
+ dimensions.width = this.configuredWidth;
351
+ dimensions.svgWidthAttr = this.configuredWidth;
352
+ }
353
+ if (this.configuredHeight !== undefined) {
354
+ dimensions.height = this.configuredHeight;
355
+ dimensions.svgHeightAttr = this.configuredHeight;
356
+ }
357
+ if (this.renderSizeOverride?.width !== undefined) {
358
+ dimensions.width = this.renderSizeOverride.width;
359
+ dimensions.svgWidthAttr = this.renderSizeOverride.width;
360
+ }
361
+ if (this.renderSizeOverride?.height !== undefined) {
362
+ dimensions.height = this.renderSizeOverride.height;
363
+ dimensions.svgHeightAttr = this.renderSizeOverride.height;
364
+ }
365
+ return dimensions;
366
+ }
367
+ pushIfIncluded(components, shouldInclude, component) {
368
+ if (shouldInclude && component) {
369
+ components.push(component);
370
+ }
335
371
  }
336
372
  resolveAccessibleLabel() {
337
373
  const titleText = this.title?.text.trim();
@@ -401,6 +437,49 @@ export class BaseChart {
401
437
  height: this.height,
402
438
  };
403
439
  }
440
+ getLegendMode() {
441
+ if (!this.legend) {
442
+ return null;
443
+ }
444
+ return this.legendModeOverride ?? this.legend.mode;
445
+ }
446
+ hasInlineLegend() {
447
+ return this.getLegendMode() === 'inline';
448
+ }
449
+ hasDisconnectedLegend() {
450
+ return this.getLegendMode() === 'disconnected';
451
+ }
452
+ shouldIncludeLegendInExport() {
453
+ const legendMode = this.getLegendMode();
454
+ return !!this.legend && legendMode !== null && legendMode !== 'hidden';
455
+ }
456
+ getConfiguredSize() {
457
+ return {
458
+ width: this.configuredWidth,
459
+ height: this.configuredHeight,
460
+ };
461
+ }
462
+ setLegendModeOverride(mode, rerender = true) {
463
+ if (this.legendModeOverride === mode) {
464
+ return this;
465
+ }
466
+ this.legendModeOverride = mode;
467
+ if (rerender) {
468
+ this.rerender();
469
+ }
470
+ return this;
471
+ }
472
+ onRender(callback) {
473
+ this.renderCallbacks.add(callback);
474
+ return () => {
475
+ this.renderCallbacks.delete(callback);
476
+ };
477
+ }
478
+ notifyRendered() {
479
+ this.renderCallbacks.forEach((callback) => {
480
+ callback();
481
+ });
482
+ }
404
483
  /**
405
484
  * Get layout-aware components in order
406
485
  * Override in subclasses to provide chart-specific components
@@ -424,7 +503,7 @@ export class BaseChart {
424
503
  if (options.yAxis && this.yAxis) {
425
504
  components.push(this.yAxis);
426
505
  }
427
- if (options.inlineLegend && this.legend?.isInlineMode()) {
506
+ if (options.inlineLegend && this.legend && this.hasInlineLegend()) {
428
507
  components.push(this.legend);
429
508
  }
430
509
  return components;
@@ -444,24 +523,12 @@ export class BaseChart {
444
523
  }
445
524
  getBaseExportComponents(options) {
446
525
  const components = [];
447
- if (options.title && this.title) {
448
- components.push(this.title);
449
- }
450
- if (options.grid && this.grid) {
451
- components.push(this.grid);
452
- }
453
- if (options.xAxis && this.xAxis) {
454
- components.push(this.xAxis);
455
- }
456
- if (options.yAxis && this.yAxis) {
457
- components.push(this.yAxis);
458
- }
459
- if (options.tooltip && this.tooltip) {
460
- components.push(this.tooltip);
461
- }
462
- if (options.legend && this.legend) {
463
- components.push(this.legend);
464
- }
526
+ this.pushIfIncluded(components, options.title, this.title);
527
+ this.pushIfIncluded(components, options.grid, this.grid);
528
+ this.pushIfIncluded(components, options.xAxis, this.xAxis);
529
+ this.pushIfIncluded(components, options.yAxis, this.yAxis);
530
+ this.pushIfIncluded(components, options.tooltip, this.tooltip);
531
+ this.pushIfIncluded(components, options.legend && this.shouldIncludeLegendInExport(), this.legend);
465
532
  return components;
466
533
  }
467
534
  registerBaseComponent(component) {
@@ -630,25 +697,25 @@ export class BaseChart {
630
697
  this.title.render(svg, this.renderTheme, this.width, position.x, position.y);
631
698
  }
632
699
  renderInlineLegend(svg) {
633
- if (!this.legend?.isInlineMode()) {
700
+ if (!this.legend || !this.hasInlineLegend()) {
634
701
  return;
635
702
  }
703
+ const series = this.getLegendSeries();
704
+ this.legendState.ensureSeries(series.map((entry) => entry.dataKey), { silent: true });
636
705
  const position = this.layoutManager.getComponentPosition(this.legend);
637
- this.legend.render(svg, this.getLegendSeries(), this.renderTheme, this.width, position.x, position.y);
706
+ this.legend.render(svg, series, this.renderTheme, this.width, position.x, position.y);
638
707
  }
639
708
  measureInlineLegend(svgNode) {
640
- if (!this.legend?.isInlineMode()) {
709
+ if (!this.legend || !this.hasInlineLegend()) {
641
710
  return;
642
711
  }
643
- this.legend.estimateLayoutSpace(this.getLegendSeries(), this.renderTheme, this.width, svgNode);
712
+ const series = this.getLegendSeries();
713
+ this.legendState.ensureSeries(series.map((entry) => entry.dataKey), { silent: true });
714
+ this.legend.estimateLayoutSpace(series, this.renderTheme, this.width, svgNode);
644
715
  }
645
716
  filterVisibleItems(items, getDataKey) {
646
- const { legend } = this;
647
- if (!legend) {
648
- return items;
649
- }
650
717
  return items.filter((item) => {
651
- return legend.isSeriesVisible(getDataKey(item));
718
+ return this.legendState.isSeriesVisible(getDataKey(item));
652
719
  });
653
720
  }
654
721
  validateSourceData(_data) { }
@@ -683,40 +750,31 @@ export class BaseChart {
683
750
  return [];
684
751
  }
685
752
  getLegendItems() {
686
- if (!this.legend) {
687
- return [];
688
- }
689
753
  return this.getLegendSeries().map((series) => {
690
754
  return {
691
755
  dataKey: series.dataKey,
692
756
  color: series.stroke || series.fill || '#8884d8',
693
- visible: this.legend.isSeriesVisible(series.dataKey),
757
+ visible: this.legendState.isSeriesVisible(series.dataKey),
694
758
  };
695
759
  });
696
760
  }
697
761
  isLegendSeriesVisible(dataKey) {
698
- if (!this.legend) {
699
- return true;
700
- }
701
- return this.legend.isSeriesVisible(dataKey);
762
+ return this.legendState.isSeriesVisible(dataKey);
702
763
  }
703
764
  setLegendSeriesVisible(dataKey, visible) {
704
- this.legend?.setSeriesVisible(dataKey, visible);
765
+ this.legendState.setSeriesVisible(dataKey, visible);
705
766
  return this;
706
767
  }
707
768
  toggleLegendSeries(dataKey) {
708
- this.legend?.toggleSeries(dataKey);
769
+ this.legendState.toggleSeries(dataKey);
709
770
  return this;
710
771
  }
711
772
  setLegendVisibility(visibility) {
712
- this.legend?.setVisibilityMap(visibility);
773
+ this.legendState.setVisibilityMap(visibility);
713
774
  return this;
714
775
  }
715
776
  onLegendChange(callback) {
716
- if (!this.legend) {
717
- return () => { };
718
- }
719
- return this.legend.subscribe(callback);
777
+ return this.legendState.subscribe(callback);
720
778
  }
721
779
  /**
722
780
  * Updates the chart with new data
@@ -758,7 +816,7 @@ export class BaseChart {
758
816
  this.cleanupDisconnectedLegendContainer();
759
817
  return;
760
818
  }
761
- if (!this.legend.isDisconnectedMode()) {
819
+ if (!this.hasDisconnectedLegend()) {
762
820
  this.cleanupDisconnectedLegendContainer();
763
821
  return;
764
822
  }
@@ -767,6 +825,7 @@ export class BaseChart {
767
825
  this.cleanupDisconnectedLegendContainer();
768
826
  return;
769
827
  }
828
+ this.legendState.ensureSeries(series.map((entry) => entry.dataKey), { silent: true });
770
829
  const legendHost = this.resolveDisconnectedLegendHost();
771
830
  if (!legendHost) {
772
831
  this.cleanupDisconnectedLegendContainer();
@@ -927,9 +986,7 @@ export class BaseChart {
927
986
  this.legend = component;
928
987
  },
929
988
  onRegister: (component) => {
930
- component.setToggleCallback(() => {
931
- this.rerender();
932
- });
989
+ component.setStateController(this.legendState);
933
990
  },
934
991
  },
935
992
  ];
@@ -1051,27 +1108,10 @@ export class BaseChart {
1051
1108
  });
1052
1109
  }
1053
1110
  async exportSVG(options, formatForHooks = 'svg') {
1054
- if (!this.svg) {
1055
- throw new Error('Chart must be rendered before export');
1056
- }
1111
+ const liveSvg = this.requireRenderedSvg();
1057
1112
  await this.whenReady();
1058
- const liveSvg = this.svg?.node();
1059
- if (!liveSvg) {
1060
- throw new Error('Chart must remain mounted until export completes');
1061
- }
1062
- const exportWidth = options?.width ?? this.width;
1063
- const exportHeight = options?.height ?? this.height;
1064
- const requiresExportRender = exportWidth !== this.width || exportHeight !== this.height;
1065
- const clone = liveSvg.cloneNode(true);
1066
- clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
1067
- clone.setAttribute('width', String(exportWidth));
1068
- clone.setAttribute('height', String(exportHeight));
1069
- const baseContext = {
1070
- format: formatForHooks,
1071
- options,
1072
- width: exportWidth,
1073
- height: exportHeight,
1074
- };
1113
+ const { exportWidth, exportHeight, requiresExportRender, baseContext } = this.resolveExportContext(options, formatForHooks);
1114
+ const clone = this.createExportSvgClone(liveSvg, exportWidth, exportHeight);
1075
1115
  const overrides = this.collectExportOverrides(baseContext);
1076
1116
  if (overrides.size === 0 && !requiresExportRender) {
1077
1117
  this.runExportHooks({
@@ -1086,17 +1126,7 @@ export class BaseChart {
1086
1126
  width: exportWidth,
1087
1127
  height: exportHeight,
1088
1128
  };
1089
- const components = this.getExportComponents();
1090
- components.forEach((component) => {
1091
- const exportable = component;
1092
- const override = overrides.get(component);
1093
- if (exportable.createExportComponent) {
1094
- exportChart.addChild(exportable.createExportComponent(override));
1095
- }
1096
- else {
1097
- exportChart.addChild(component);
1098
- }
1099
- });
1129
+ this.populateExportChart(exportChart, overrides);
1100
1130
  const exportSvg = await this.renderExportChart(exportChart, exportWidth, exportHeight);
1101
1131
  exportSvg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
1102
1132
  exportSvg.setAttribute('width', String(exportWidth));
@@ -1108,6 +1138,49 @@ export class BaseChart {
1108
1138
  this.syncAccessibleLabelFromSvg(exportSvg);
1109
1139
  return exportSvg.outerHTML;
1110
1140
  }
1141
+ requireRenderedSvg() {
1142
+ if (!this.svg) {
1143
+ throw new Error('Chart must be rendered before export');
1144
+ }
1145
+ const liveSvg = this.svg.node();
1146
+ if (!liveSvg) {
1147
+ throw new Error('Chart must remain mounted until export completes');
1148
+ }
1149
+ return liveSvg;
1150
+ }
1151
+ resolveExportContext(options, format) {
1152
+ const exportWidth = options?.width ?? this.width;
1153
+ const exportHeight = options?.height ?? this.height;
1154
+ return {
1155
+ exportWidth,
1156
+ exportHeight,
1157
+ requiresExportRender: exportWidth !== this.width || exportHeight !== this.height,
1158
+ baseContext: {
1159
+ format,
1160
+ options,
1161
+ width: exportWidth,
1162
+ height: exportHeight,
1163
+ },
1164
+ };
1165
+ }
1166
+ createExportSvgClone(liveSvg, width, height) {
1167
+ const clone = liveSvg.cloneNode(true);
1168
+ clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
1169
+ clone.setAttribute('width', String(width));
1170
+ clone.setAttribute('height', String(height));
1171
+ return clone;
1172
+ }
1173
+ populateExportChart(exportChart, overrides) {
1174
+ this.getExportComponents().forEach((component) => {
1175
+ const exportable = component;
1176
+ const override = overrides.get(component);
1177
+ if (exportable.createExportComponent) {
1178
+ exportChart.addChild(exportable.createExportComponent(override));
1179
+ return;
1180
+ }
1181
+ exportChart.addChild(component);
1182
+ });
1183
+ }
1111
1184
  exportJSON() {
1112
1185
  return JSON.stringify(this.sourceData, null, 2);
1113
1186
  }
@@ -0,0 +1,137 @@
1
+ import type { BaseChart } from './base-chart.js';
2
+ import type { ChartTheme, DeepPartial, ExportOptions, LegendItem } from './types.js';
3
+ type BreakpointRange = {
4
+ minWidth?: number;
5
+ maxWidth?: number;
6
+ };
7
+ export type ChartGroupResponsiveBreakpointConfig = BreakpointRange & {
8
+ cols?: number;
9
+ gap?: number;
10
+ };
11
+ export type ChartGroupResponsiveBreakpointDefinition = number | ChartGroupResponsiveBreakpointConfig;
12
+ export type ChartGroupResponsiveBreakpoints = Record<string, ChartGroupResponsiveBreakpointDefinition>;
13
+ export type ChartGroupResponsiveConfig = {
14
+ breakpoints?: ChartGroupResponsiveBreakpoints;
15
+ };
16
+ export type ChartGroupItemResponsiveBreakpointConfig = BreakpointRange & {
17
+ span?: number;
18
+ height?: number;
19
+ hidden?: boolean;
20
+ order?: number;
21
+ };
22
+ export type ChartGroupItemResponsiveBreakpointDefinition = number | ChartGroupItemResponsiveBreakpointConfig;
23
+ export type ChartGroupItemResponsiveBreakpoints = Record<string, ChartGroupItemResponsiveBreakpointDefinition>;
24
+ export type ChartGroupItemResponsiveConfig = {
25
+ breakpoints?: ChartGroupItemResponsiveBreakpoints;
26
+ };
27
+ export type ChartGroupConfig = {
28
+ cols: number;
29
+ gap?: number;
30
+ syncY?: boolean;
31
+ height?: number;
32
+ chartHeight?: number;
33
+ theme?: DeepPartial<ChartTheme>;
34
+ responsive?: ChartGroupResponsiveConfig;
35
+ };
36
+ export type ChartGroupChartOptions = {
37
+ span?: number;
38
+ height?: number;
39
+ hidden?: boolean;
40
+ order?: number;
41
+ responsive?: ChartGroupItemResponsiveConfig;
42
+ };
43
+ export type ChartGroupExportFormat = 'svg' | 'png' | 'jpg' | 'pdf';
44
+ export declare class ChartGroup {
45
+ private readonly cols;
46
+ private readonly gap;
47
+ private readonly syncY;
48
+ private readonly configuredHeight?;
49
+ private readonly chartHeight;
50
+ private readonly theme;
51
+ private readonly responsiveConfig?;
52
+ private readonly charts;
53
+ private readonly legendState;
54
+ private readonly renderCallbacks;
55
+ private readonly warnedWidthCharts;
56
+ private readonly warnedColorConflicts;
57
+ private container;
58
+ private legend;
59
+ private title;
60
+ private resizeObserver;
61
+ private readyPromise;
62
+ private childLegendSnapshot;
63
+ private childYDomainSnapshot;
64
+ private isRendering;
65
+ private isSyncingLegend;
66
+ private hasWarnedIncompatibleYScaleTypes;
67
+ constructor(config: ChartGroupConfig);
68
+ addChart(chart: BaseChart, options?: ChartGroupChartOptions): this;
69
+ addChild(component: {
70
+ type: string;
71
+ }): this;
72
+ render(target: string | HTMLElement): HTMLElement | null;
73
+ refresh(): HTMLElement | null;
74
+ whenReady(): Promise<void>;
75
+ getLegendItems(): LegendItem[];
76
+ private getLegendItemsForWidth;
77
+ isLegendSeriesVisible(dataKey: string): boolean;
78
+ setLegendSeriesVisible(dataKey: string, visible: boolean): this;
79
+ toggleLegendSeries(dataKey: string): this;
80
+ setLegendVisibility(visibility: Record<string, boolean>): this;
81
+ onLegendChange(callback: () => void): () => void;
82
+ export(format: ChartGroupExportFormat, options?: ExportOptions): Promise<string | Blob | void>;
83
+ destroy(): void;
84
+ private bindChartRenderCallback;
85
+ private resolveContainer;
86
+ private resolveContainerWidth;
87
+ private resolveCurrentWidth;
88
+ private resolveTotalHeightConstraint;
89
+ private resolveChartAreaHeightConstraint;
90
+ private resolveSpan;
91
+ private warnOnExplicitChildWidth;
92
+ private getAllVerticalXYCharts;
93
+ private getVerticalXYCharts;
94
+ private resolveSharedYDomain;
95
+ private warnIncompatibleYScaleTypes;
96
+ private applyScaleSyncOverrides;
97
+ private buildRows;
98
+ private resolveDefaultChartHeight;
99
+ private resolveDefaultChartHeightForWidth;
100
+ private calculateLayout;
101
+ private collectMergedLegendEntries;
102
+ private resolveLegendVisibility;
103
+ private syncLegendStateFromChildren;
104
+ private applyLegendStateToChildren;
105
+ private serializeChildLegendState;
106
+ private serializeChildYDomains;
107
+ private renderLegendIntoContainer;
108
+ private renderTitleSvg;
109
+ private renderLegendSvg;
110
+ private setupResizeObserver;
111
+ private exportSVG;
112
+ private resolveChartOptions;
113
+ private refreshIfMounted;
114
+ private prepareRenderState;
115
+ private createRenderHosts;
116
+ private appendRenderedSection;
117
+ private renderLayoutItems;
118
+ private createChartHost;
119
+ private createReadyPromise;
120
+ private requireRenderedContainer;
121
+ private resolveExportContent;
122
+ private createRasterExportOptions;
123
+ private exportPdfContent;
124
+ private resolveExportLayoutState;
125
+ private resolveLiveChartHeightOverride;
126
+ private exportLayoutItems;
127
+ private composeExportSvg;
128
+ private validateResponsiveConfig;
129
+ private validateItemResponsiveConfig;
130
+ private resolveResponsiveConfigForWidth;
131
+ private resolveMatchedGroupBreakpoints;
132
+ private resolveVisibleChartEntries;
133
+ private resolveResponsiveChartEntry;
134
+ private downloadContent;
135
+ private getMimeType;
136
+ }
137
+ export {};