@internetstiftelsen/charts 0.10.0 → 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.
package/README.md CHANGED
@@ -10,7 +10,7 @@ A framework-agnostic, composable charting library built on D3.js with TypeScript
10
10
  - **Combined Chart Layouts** - `ChartGroup` composes existing charts into shared dashboards with one coordinated legend
11
11
  - **Divergent Bar Support** - Bar charts automatically render from zero and diverge around `0` for mixed positive/negative values
12
12
  - **Mirrored Bar Sides** - Horizontal bars can mirror a series to the left for population-pyramid style charts without changing source data
13
- - **Radial Value Labels** - Pie and donut charts support optional on-chart labels with custom formatters
13
+ - **Custom Value Labels** - XY, pie, and donut charts support optional on-chart labels with custom formatters
14
14
  - **Optional Gauge Animation** - Animate gauge value transitions with `gauge.animate`
15
15
  - **Stacking Control** - Bar stacking modes with optional reversed visual series order
16
16
  - **Axis Direction Control** - Use `scales.x.reverse` / `scales.y.reverse` to flip an axis when needed
package/dist/area.d.ts CHANGED
@@ -21,5 +21,7 @@ export declare class Area implements ChartComponent<AreaConfigBase> {
21
21
  createExportComponent(override?: Partial<AreaConfigBase>): ChartComponent<AreaConfigBase>;
22
22
  private getStackValues;
23
23
  render(plotGroup: Selection<SVGGElement, undefined, null, undefined>, data: DataItem[], xKey: string, x: D3Scale, y: D3Scale, parseValue: (value: unknown) => number, xScaleType: ScaleType | undefined, theme: ChartTheme, stackingContext?: AreaStackingContext, valueLabelLayer?: Selection<SVGGElement, undefined, null, undefined>): void;
24
+ private renderLinePath;
25
+ private renderPoints;
24
26
  private renderValueLabels;
25
27
  }
package/dist/area.js CHANGED
@@ -199,43 +199,49 @@ export class Area {
199
199
  .attr('stroke', 'none')
200
200
  .attr('d', areaGenerator);
201
201
  if (this.showLine) {
202
- const lineGenerator = line()
203
- .defined((d) => d.valid)
204
- .curve(curveFactory)
205
- .x(getXPosition)
206
- .y((d) => y(d.y1) || 0);
207
- const lineStrokeWidth = this.strokeWidth ?? theme.line.strokeWidth;
208
- plotGroup
209
- .append('path')
210
- .datum(areaData)
211
- .attr('class', `area-line-${sanitizedKey}`)
212
- .attr('fill', 'none')
213
- .attr('stroke', this.stroke)
214
- .attr('stroke-width', lineStrokeWidth)
215
- .attr('d', lineGenerator);
202
+ this.renderLinePath(plotGroup, areaData, curveFactory, getXPosition, y, theme, sanitizedKey);
216
203
  }
217
204
  if (this.showPoints) {
218
- const validData = areaData.filter((d) => d.valid);
219
- const pointSize = this.pointSize ?? theme.line.point.size;
220
- const pointStrokeWidth = theme.line.point.strokeWidth;
221
- const pointStrokeColor = theme.line.point.strokeColor || this.stroke;
222
- const pointColor = theme.line.point.color || this.stroke;
223
- plotGroup
224
- .selectAll(`.area-point-${sanitizedKey}`)
225
- .data(validData)
226
- .join('circle')
227
- .attr('class', `area-point-${sanitizedKey}`)
228
- .attr('cx', getXPosition)
229
- .attr('cy', (d) => y(d.y1) || 0)
230
- .attr('r', pointSize)
231
- .attr('fill', pointColor)
232
- .attr('stroke', pointStrokeColor)
233
- .attr('stroke-width', pointStrokeWidth);
205
+ this.renderPoints(plotGroup, areaData, getXPosition, y, theme, sanitizedKey);
234
206
  }
235
207
  if (this.valueLabel?.show) {
236
208
  this.renderValueLabels(valueLabelLayer ?? plotGroup, areaData.filter((d) => d.valid), y, parseValue, theme, getXPosition);
237
209
  }
238
210
  }
211
+ renderLinePath(plotGroup, areaData, curveFactory, getXPosition, y, theme, sanitizedKey) {
212
+ const lineGenerator = line()
213
+ .defined((d) => d.valid)
214
+ .curve(curveFactory)
215
+ .x(getXPosition)
216
+ .y((d) => y(d.y1) || 0);
217
+ const lineStrokeWidth = this.strokeWidth ?? theme.line.strokeWidth;
218
+ plotGroup
219
+ .append('path')
220
+ .datum(areaData)
221
+ .attr('class', `area-line-${sanitizedKey}`)
222
+ .attr('fill', 'none')
223
+ .attr('stroke', this.stroke)
224
+ .attr('stroke-width', lineStrokeWidth)
225
+ .attr('d', lineGenerator);
226
+ }
227
+ renderPoints(plotGroup, areaData, getXPosition, y, theme, sanitizedKey) {
228
+ const validData = areaData.filter((d) => d.valid);
229
+ const pointSize = this.pointSize ?? theme.line.point.size;
230
+ const pointStrokeWidth = theme.line.point.strokeWidth;
231
+ const pointStrokeColor = theme.line.point.strokeColor || this.stroke;
232
+ const pointColor = theme.line.point.color || this.stroke;
233
+ plotGroup
234
+ .selectAll(`.area-point-${sanitizedKey}`)
235
+ .data(validData)
236
+ .join('circle')
237
+ .attr('class', `area-point-${sanitizedKey}`)
238
+ .attr('cx', getXPosition)
239
+ .attr('cy', (d) => y(d.y1) || 0)
240
+ .attr('r', pointSize)
241
+ .attr('fill', pointColor)
242
+ .attr('stroke', pointStrokeColor)
243
+ .attr('stroke-width', pointStrokeWidth);
244
+ }
239
245
  renderValueLabels(plotGroup, data, y, parseValue, theme, getXPosition) {
240
246
  const config = this.valueLabel;
241
247
  const fontSize = config.fontSize ?? theme.valueLabel.fontSize;
@@ -260,7 +266,9 @@ export class Area {
260
266
  if (!Number.isFinite(parsedValue)) {
261
267
  return;
262
268
  }
263
- const valueText = String(parsedValue);
269
+ const valueText = config.formatter
270
+ ? config.formatter(this.dataKey, parsedValue, d.data)
271
+ : String(parsedValue);
264
272
  const xPos = getXPosition(d);
265
273
  const yPos = y(d.y1) || 0;
266
274
  const tempText = labelGroup
package/dist/bar.d.ts CHANGED
@@ -17,6 +17,23 @@ export declare class Bar implements ChartComponent<BarConfigBase> {
17
17
  render(plotGroup: Selection<SVGGElement, undefined, null, undefined>, data: DataItem[], xKey: string, x: D3Scale, y: D3Scale, parseValue: (value: unknown) => number, xScaleType?: ScaleType, theme?: ChartTheme, stackingContext?: BarStackingContext, orientation?: 'vertical' | 'horizontal'): void;
18
18
  private renderVertical;
19
19
  private renderHorizontal;
20
+ private resolveValueLabelConfig;
21
+ private resolveValueLabelPlacement;
22
+ private resolveValueLabelStyle;
23
+ private getValueLabelText;
24
+ private getBarColor;
25
+ private measureLabelBox;
26
+ private getLabelColor;
27
+ private appendValueLabel;
28
+ private getVerticalLabelPlacement;
29
+ private getVerticalOutsideLabelPlacement;
30
+ private getVerticalInsideLabelY;
31
+ private getHorizontalLabelPlacement;
32
+ private getHorizontalOutsideLabelPlacement;
33
+ private getHorizontalInsideLabelX;
34
+ private isHorizontalLabelWithinBounds;
35
+ private renderVerticalValueLabel;
36
+ private renderHorizontalValueLabel;
20
37
  private renderVerticalValueLabels;
21
38
  private renderHorizontalValueLabels;
22
39
  }