@internetstiftelsen/charts 0.10.0 → 0.11.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.
Files changed (57) hide show
  1. package/README.md +65 -1
  2. package/dist/area.d.ts +11 -1
  3. package/dist/area.js +199 -55
  4. package/dist/bar.d.ts +26 -1
  5. package/dist/bar.js +425 -306
  6. package/dist/base-chart.d.ts +5 -0
  7. package/dist/base-chart.js +91 -67
  8. package/dist/chart-group.d.ts +16 -0
  9. package/dist/chart-group.js +201 -143
  10. package/dist/donut-center-content.d.ts +1 -0
  11. package/dist/donut-center-content.js +21 -38
  12. package/dist/donut-chart.js +32 -32
  13. package/dist/gauge-chart.d.ts +23 -4
  14. package/dist/gauge-chart.js +235 -185
  15. package/dist/lazy-mount.d.ts +13 -0
  16. package/dist/lazy-mount.js +90 -0
  17. package/dist/legend.js +10 -9
  18. package/dist/line.d.ts +9 -1
  19. package/dist/line.js +144 -24
  20. package/dist/pie-chart.d.ts +3 -0
  21. package/dist/pie-chart.js +49 -47
  22. package/dist/radial-chart-base.d.ts +4 -3
  23. package/dist/radial-chart-base.js +27 -12
  24. package/dist/scatter.d.ts +5 -1
  25. package/dist/scatter.js +92 -9
  26. package/dist/theme.js +17 -0
  27. package/dist/tooltip.d.ts +55 -3
  28. package/dist/tooltip.js +968 -159
  29. package/dist/types.d.ts +23 -1
  30. package/dist/utils.js +11 -19
  31. package/dist/x-axis.d.ts +10 -0
  32. package/dist/x-axis.js +190 -149
  33. package/dist/xy-animation.d.ts +3 -0
  34. package/dist/xy-animation.js +2 -0
  35. package/dist/xy-chart.d.ts +35 -1
  36. package/dist/xy-chart.js +358 -153
  37. package/dist/xy-motion/config.d.ts +2 -0
  38. package/dist/xy-motion/config.js +177 -0
  39. package/dist/xy-motion/driver.d.ts +9 -0
  40. package/dist/xy-motion/driver.js +10 -0
  41. package/dist/xy-motion/helpers.d.ts +17 -0
  42. package/dist/xy-motion/helpers.js +105 -0
  43. package/dist/xy-motion/live-state.d.ts +8 -0
  44. package/dist/xy-motion/live-state.js +240 -0
  45. package/dist/xy-motion/noop-xy-motion-driver.d.ts +9 -0
  46. package/dist/xy-motion/noop-xy-motion-driver.js +15 -0
  47. package/dist/xy-motion/types.d.ts +85 -0
  48. package/dist/xy-motion/types.js +1 -0
  49. package/dist/xy-motion/xy-motion-driver.d.ts +19 -0
  50. package/dist/xy-motion/xy-motion-driver.js +130 -0
  51. package/dist/y-axis.d.ts +7 -2
  52. package/dist/y-axis.js +99 -10
  53. package/docs/components.md +50 -1
  54. package/docs/getting-started.md +35 -0
  55. package/docs/theming.md +14 -0
  56. package/docs/xy-chart.md +88 -7
  57. package/package.json +5 -4
@@ -62,44 +62,11 @@ export class DonutCenterContent {
62
62
  }
63
63
  render(svg, cx, cy, theme, fontScale = 1) {
64
64
  const defaults = theme.donut.centerContent;
65
- const elements = [];
66
- if (this.mainValue) {
67
- const style = this.config.mainValueStyle;
68
- elements.push({
69
- text: this.mainValue,
70
- fontSize: (style?.fontSize ?? defaults.mainValue.fontSize) *
71
- fontScale,
72
- fontWeight: style?.fontWeight ?? defaults.mainValue.fontWeight,
73
- fontFamily: style?.fontFamily ??
74
- defaults.mainValue.fontFamily ??
75
- theme.fontFamily,
76
- color: style?.color ?? defaults.mainValue.color,
77
- });
78
- }
79
- if (this.title) {
80
- const style = this.config.titleStyle;
81
- elements.push({
82
- text: this.title,
83
- fontSize: (style?.fontSize ?? defaults.title.fontSize) * fontScale,
84
- fontWeight: style?.fontWeight ?? defaults.title.fontWeight,
85
- fontFamily: style?.fontFamily ??
86
- defaults.title.fontFamily ??
87
- theme.fontFamily,
88
- color: style?.color ?? defaults.title.color,
89
- });
90
- }
91
- if (this.subtitle) {
92
- const style = this.config.subtitleStyle;
93
- elements.push({
94
- text: this.subtitle,
95
- fontSize: (style?.fontSize ?? defaults.subtitle.fontSize) * fontScale,
96
- fontWeight: style?.fontWeight ?? defaults.subtitle.fontWeight,
97
- fontFamily: style?.fontFamily ??
98
- defaults.subtitle.fontFamily ??
99
- theme.fontFamily,
100
- color: style?.color ?? defaults.subtitle.color,
101
- });
102
- }
65
+ const elements = [
66
+ this.buildElement(this.mainValue, this.config.mainValueStyle, defaults.mainValue, theme.fontFamily, fontScale),
67
+ this.buildElement(this.title, this.config.titleStyle, defaults.title, theme.fontFamily, fontScale),
68
+ this.buildElement(this.subtitle, this.config.subtitleStyle, defaults.subtitle, theme.fontFamily, fontScale),
69
+ ].filter((element) => element !== null);
103
70
  if (elements.length === 0) {
104
71
  return;
105
72
  }
@@ -122,4 +89,20 @@ export class DonutCenterContent {
122
89
  currentY += el.fontSize + lineSpacing;
123
90
  }
124
91
  }
92
+ buildElement(text, style, defaults, themeFontFamily, fontScale) {
93
+ if (!text) {
94
+ return null;
95
+ }
96
+ const resolvedStyle = {
97
+ ...defaults,
98
+ ...style,
99
+ };
100
+ return {
101
+ text,
102
+ fontSize: resolvedStyle.fontSize * fontScale,
103
+ fontWeight: resolvedStyle.fontWeight,
104
+ fontFamily: resolvedStyle.fontFamily || themeFontFamily,
105
+ color: resolvedStyle.color,
106
+ };
107
+ }
125
108
  }
@@ -6,6 +6,15 @@ const HOVER_EXPAND_PX = 8;
6
6
  const ANIMATION_DURATION_MS = 150;
7
7
  const OUTSIDE_LABEL_TEXT_OFFSET_PX = 10;
8
8
  const OUTSIDE_LABEL_LINE_INSET_PX = 4;
9
+ const DEFAULT_DONUT_VALUE_LABEL = {
10
+ show: false,
11
+ position: 'auto',
12
+ outsideOffset: 16,
13
+ minVerticalSpacing: 14,
14
+ formatter: (label, value, _data, _percentage) => {
15
+ return `${label}: ${value}`;
16
+ },
17
+ };
9
18
  export class DonutChart extends RadialChartBase {
10
19
  constructor(config) {
11
20
  super(config);
@@ -57,21 +66,27 @@ export class DonutChart extends RadialChartBase {
57
66
  writable: true,
58
67
  value: null
59
68
  });
60
- const donut = config.donut ?? {};
61
- this.innerRadiusRatio =
62
- donut.innerRadius ?? this.theme.donut.innerRadius;
63
- this.padAngle = donut.padAngle ?? this.theme.donut.padAngle;
64
- this.cornerRadius = donut.cornerRadius ?? this.theme.donut.cornerRadius;
65
- this.valueKey = config.valueKey ?? 'value';
66
- this.labelKey = config.labelKey ?? 'name';
67
- this.valueLabel = {
68
- show: config.valueLabel?.show ?? false,
69
- position: config.valueLabel?.position ?? 'auto',
70
- outsideOffset: config.valueLabel?.outsideOffset ?? 16,
71
- minVerticalSpacing: config.valueLabel?.minVerticalSpacing ?? 14,
72
- formatter: config.valueLabel?.formatter ??
73
- ((label, value, _data, _percentage) => `${label}: ${value}`),
69
+ const donut = {
70
+ innerRadius: this.theme.donut.innerRadius,
71
+ padAngle: this.theme.donut.padAngle,
72
+ cornerRadius: this.theme.donut.cornerRadius,
73
+ ...config.donut,
74
74
  };
75
+ const resolvedConfig = {
76
+ valueKey: 'value',
77
+ labelKey: 'name',
78
+ ...config,
79
+ };
80
+ const valueLabel = {
81
+ ...DEFAULT_DONUT_VALUE_LABEL,
82
+ ...config.valueLabel,
83
+ };
84
+ this.innerRadiusRatio = donut.innerRadius;
85
+ this.padAngle = donut.padAngle;
86
+ this.cornerRadius = donut.cornerRadius;
87
+ this.valueKey = resolvedConfig.valueKey;
88
+ this.labelKey = resolvedConfig.labelKey;
89
+ this.valueLabel = valueLabel;
75
90
  this.initializeDataState();
76
91
  }
77
92
  validateDonutData() {
@@ -220,9 +235,6 @@ export class DonutChart extends RadialChartBase {
220
235
  .append('g')
221
236
  .attr('class', 'donut-segments')
222
237
  .attr('transform', `translate(${cx}, ${cy})`);
223
- const resolveTooltipDiv = () => this.tooltip
224
- ? select(`#${this.tooltip.id}`)
225
- : null;
226
238
  segmentGroup
227
239
  .selectAll('.donut-segment')
228
240
  .data(pieData)
@@ -241,19 +253,10 @@ export class DonutChart extends RadialChartBase {
241
253
  .selectAll('.donut-segment')
242
254
  .filter((_, i, nodes) => nodes[i] !== event.currentTarget)
243
255
  .style('opacity', 0.5);
244
- const tooltipDiv = resolveTooltipDiv();
245
- if (tooltipDiv && !tooltipDiv.empty()) {
246
- tooltipDiv
247
- .style('visibility', 'visible')
248
- .html(this.buildTooltipContent(d, segments));
249
- this.positionTooltipFromPointer(event, tooltipDiv);
250
- }
256
+ this.showTooltipFromPointer(event, this.buildTooltipContent(d, segments));
251
257
  })
252
258
  .on('mousemove', (event) => {
253
- const tooltipDiv = resolveTooltipDiv();
254
- if (tooltipDiv && !tooltipDiv.empty()) {
255
- this.positionTooltipFromPointer(event, tooltipDiv);
256
- }
259
+ this.positionTooltipFromPointer(event);
257
260
  })
258
261
  .on('mouseleave', (event, d) => {
259
262
  select(event.currentTarget)
@@ -261,10 +264,7 @@ export class DonutChart extends RadialChartBase {
261
264
  .duration(ANIMATION_DURATION_MS)
262
265
  .attr('d', arcGenerator(d));
263
266
  segmentGroup.selectAll('.donut-segment').style('opacity', 1);
264
- const tooltipDiv = resolveTooltipDiv();
265
- if (tooltipDiv && !tooltipDiv.empty()) {
266
- tooltipDiv.style('visibility', 'hidden');
267
- }
267
+ this.hideTooltip();
268
268
  });
269
269
  return {
270
270
  segmentGroup,
@@ -1,6 +1,7 @@
1
1
  import type { DataItem, LegendSeries } from './types.js';
2
- import { BaseChart, type BaseChartConfig, type BaseRenderContext } from './base-chart.js';
2
+ import type { BaseChart, BaseChartConfig, BaseRenderContext } from './base-chart.js';
3
3
  import type { ChartComponentBase } from './chart-interface.js';
4
+ import { RadialChartBase } from './radial-chart-base.js';
4
5
  export type GaugeSegment = {
5
6
  from: number;
6
7
  to: number;
@@ -70,7 +71,7 @@ export type GaugeChartConfig = BaseChartConfig & {
70
71
  valueKey?: string;
71
72
  targetValueKey?: string;
72
73
  };
73
- export declare class GaugeChart extends BaseChart {
74
+ export declare class GaugeChart extends RadialChartBase {
74
75
  private readonly configuredValue;
75
76
  private readonly configuredTargetValue;
76
77
  private readonly configuredSegments;
@@ -101,6 +102,7 @@ export declare class GaugeChart extends BaseChart {
101
102
  private targetValue;
102
103
  private lastRenderedValue;
103
104
  constructor(config: GaugeChartConfig);
105
+ private resolveGaugeConstructorValues;
104
106
  private normalizeNeedleConfig;
105
107
  private normalizeMarkerConfig;
106
108
  private getThemePaletteColor;
@@ -108,9 +110,18 @@ export declare class GaugeChart extends BaseChart {
108
110
  private normalizeAnimationConfig;
109
111
  private resolveAnimationEasing;
110
112
  private parseCssLinearEasing;
113
+ private parseLinearEasingStop;
114
+ private resolveLinearEasingPositions;
115
+ private fillMissingLinearEasingPositions;
116
+ private interpolateLinearEasing;
111
117
  private normalizeTickLabelStyle;
112
118
  private normalizeValueLabelStyle;
113
119
  private validateGaugeConfig;
120
+ private validateGaugeRange;
121
+ private validateGaugeGeometry;
122
+ private validateTickSettings;
123
+ private validateIndicatorSettings;
124
+ private validateAnimationSettings;
114
125
  private validateSegments;
115
126
  private refreshResolvedValues;
116
127
  private resolveValue;
@@ -125,6 +136,16 @@ export declare class GaugeChart extends BaseChart {
125
136
  protected createExportChart(): BaseChart;
126
137
  protected syncDerivedState(): void;
127
138
  protected renderChart({ svg, plotGroup, plotArea, }: BaseRenderContext): void;
139
+ private resolveGaugeGeometry;
140
+ private resolveLabelAllowance;
141
+ private resolveHalfCircleGeometry;
142
+ private resolveFullCircleGeometry;
143
+ private resolveInnerRadius;
144
+ private renderSegmentsOrProgress;
145
+ private renderVisibleSegments;
146
+ private renderGaugeLabels;
147
+ private renderGaugeIndicators;
148
+ private attachTooltipIfEnabled;
128
149
  private resolveAnimationStartValue;
129
150
  private shouldAnimateTransition;
130
151
  private buildAriaLabel;
@@ -144,8 +165,6 @@ export declare class GaugeChart extends BaseChart {
144
165
  private renderCurrentValueMarker;
145
166
  private renderValueText;
146
167
  private attachTooltipLayer;
147
- private resolveTooltipDiv;
148
168
  private buildTooltipContent;
149
- private positionTooltip;
150
169
  protected getLegendSeries(): LegendSeries[];
151
170
  }