@opendata-ai/openchart-vanilla 7.0.0 → 7.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opendata-ai/openchart-vanilla",
3
- "version": "7.0.0",
3
+ "version": "7.0.3",
4
4
  "description": "Vanilla JS renderer for openchart: SVG charts, HTML tables, force-directed graphs",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Riley Hilliard",
@@ -50,8 +50,8 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@floating-ui/dom": "^1.7.6",
53
- "@opendata-ai/openchart-core": "7.0.0",
54
- "@opendata-ai/openchart-engine": "7.0.0",
53
+ "@opendata-ai/openchart-core": "7.0.3",
54
+ "@opendata-ai/openchart-engine": "7.0.3",
55
55
  "d3-force": "^3.0.0",
56
56
  "d3-quadtree": "^3.0.1"
57
57
  },
@@ -111,7 +111,21 @@ export function createBarList(
111
111
  measureText,
112
112
  };
113
113
 
114
- return compileBarList(currentSpec, compileOpts);
114
+ const layout = compileBarList(currentSpec, compileOpts);
115
+
116
+ // Auto-size height to content so few-row lists don't leave empty space.
117
+ if (layout.rows.length > 0) {
118
+ const lastRow = layout.rows[layout.rows.length - 1];
119
+ const contentBottom =
120
+ lastRow.y + lastRow.height + layout.chrome.bottomHeight + layout.theme.spacing.padding;
121
+ if (contentBottom < layout.height) {
122
+ layout.height = contentBottom;
123
+ layout.area.height =
124
+ contentBottom - layout.area.y - layout.chrome.bottomHeight - layout.theme.spacing.padding;
125
+ }
126
+ }
127
+
128
+ return layout;
115
129
  }
116
130
 
117
131
  function wireTooltipAndInteraction(svg: SVGSVGElement, layout: BarListLayout): () => void {
@@ -20,23 +20,28 @@ function snapKey(x: number): number {
20
20
  }
21
21
 
22
22
  function collectSeriesGroups(layout: ChartLayout): SeriesGroup[] {
23
- const groups: SeriesGroup[] = [];
23
+ // Dedupe by seriesKey: area charts emit BOTH an AreaMark and a derived
24
+ // LineMark per series. Without dedupe, single-series area charts show
25
+ // "line-0" / "area-1" in the tooltip instead of the actual data fields.
26
+ // Prefer the line mark (same logic as endpoint-labels).
27
+ const byKey = new Map<string, SeriesGroup>();
28
+ const markTypeByKey = new Map<string, 'line' | 'area'>();
24
29
  for (let i = 0; i < layout.marks.length; i++) {
25
30
  const mark = layout.marks[i];
26
31
  if ((mark.type === 'line' || mark.type === 'area') && mark.dataPoints?.length) {
32
+ const key = mark.seriesKey ?? '__default__';
33
+ const existingType = markTypeByKey.get(key);
34
+ if (existingType === 'line' && mark.type === 'area') continue;
27
35
  const color = mark.type === 'line' ? mark.stroke : getRepresentativeColor(mark.fill);
28
36
  const pointsByX = new Map<number, SeriesPoint>();
29
37
  for (const dp of mark.dataPoints) {
30
38
  pointsByX.set(snapKey(dp.x), { ...dp });
31
39
  }
32
- groups.push({
33
- seriesKey: mark.seriesKey ?? `${mark.type}-${i}`,
34
- color,
35
- pointsByX,
36
- });
40
+ byKey.set(key, { seriesKey: key, color, pointsByX });
41
+ markTypeByKey.set(key, mark.type);
37
42
  }
38
43
  }
39
- return groups;
44
+ return Array.from(byKey.values());
40
45
  }
41
46
 
42
47
  function collectSnapXs(groups: SeriesGroup[]): number[] {