@opendata-ai/openchart-vanilla 8.0.0-rc.2 → 8.0.0-rc.21

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 (145) hide show
  1. package/dist/{chunk-W34KN7FD.js → chunk-2NAQRP66.js} +2 -2
  2. package/dist/chunk-DCODCLWI.js +234 -0
  3. package/dist/chunk-DCODCLWI.js.map +1 -0
  4. package/dist/{chunk-5EOV5JQZ.js → chunk-EKAUQAAX.js} +50 -46
  5. package/dist/chunk-EKAUQAAX.js.map +1 -0
  6. package/dist/{chunk-ENXSUXC5.js → chunk-KNT5AZ2O.js} +7309 -5490
  7. package/dist/chunk-KNT5AZ2O.js.map +1 -0
  8. package/dist/chunk-RM5XS6NR.js +113 -0
  9. package/dist/chunk-RM5XS6NR.js.map +1 -0
  10. package/dist/chunk-T32UHMZA.js +282 -0
  11. package/dist/chunk-T32UHMZA.js.map +1 -0
  12. package/dist/export-gif.d.ts +113 -0
  13. package/dist/export-gif.js +21 -0
  14. package/dist/export-gif.js.map +1 -0
  15. package/dist/index.d.ts +283 -24
  16. package/dist/index.js +2012 -763
  17. package/dist/index.js.map +1 -1
  18. package/dist/{mount-CUKQLeqD.d.ts → mount-Dvv8NYIv.d.ts} +117 -3
  19. package/dist/simulation-worker.js +83 -2
  20. package/dist/static.js +7 -69
  21. package/dist/static.js.map +1 -1
  22. package/dist/story/index.d.ts +3 -2
  23. package/dist/story/index.js +5 -3
  24. package/dist/story/index.js.map +1 -1
  25. package/dist/styles.css +1 -1
  26. package/dist/styles.css.map +1 -1
  27. package/package.json +14 -6
  28. package/dist/chunk-5EOV5JQZ.js.map +0 -1
  29. package/dist/chunk-ENXSUXC5.js.map +0 -1
  30. package/src/__test-fixtures__/dom.ts +0 -70
  31. package/src/__test-fixtures__/specs.ts +0 -214
  32. package/src/__tests__/animation.test.ts +0 -358
  33. package/src/__tests__/annotations-render.test.ts +0 -201
  34. package/src/__tests__/compound-labels.test.ts +0 -122
  35. package/src/__tests__/continuous-legend.test.ts +0 -91
  36. package/src/__tests__/crosshair.test.ts +0 -130
  37. package/src/__tests__/edit-events.test.ts +0 -902
  38. package/src/__tests__/events.test.ts +0 -387
  39. package/src/__tests__/export.test.ts +0 -241
  40. package/src/__tests__/font-race.test.ts +0 -199
  41. package/src/__tests__/gradient-ids.test.ts +0 -159
  42. package/src/__tests__/gradient-utils.test.ts +0 -125
  43. package/src/__tests__/known-bugs-render.test.ts +0 -183
  44. package/src/__tests__/map.test.ts +0 -293
  45. package/src/__tests__/mount.test.ts +0 -357
  46. package/src/__tests__/pattern-fills.test.ts +0 -105
  47. package/src/__tests__/resize-timing.test.ts +0 -218
  48. package/src/__tests__/sankey.test.ts +0 -133
  49. package/src/__tests__/selection-events.test.ts +0 -869
  50. package/src/__tests__/series-search.test.ts +0 -311
  51. package/src/__tests__/static.test.ts +0 -141
  52. package/src/__tests__/svg-renderer.test.ts +0 -895
  53. package/src/__tests__/table-keyboard.test.ts +0 -361
  54. package/src/__tests__/table-mount.test.ts +0 -639
  55. package/src/__tests__/tilemap.test.ts +0 -158
  56. package/src/__tests__/tooltip.test.ts +0 -337
  57. package/src/__tests__/transition.test.ts +0 -1777
  58. package/src/__tests__/you-draw-it.test.ts +0 -273
  59. package/src/animation-vars.ts +0 -42
  60. package/src/animation.ts +0 -76
  61. package/src/barlist-mount.ts +0 -383
  62. package/src/barlist-renderer.ts +0 -267
  63. package/src/dom-helpers.ts +0 -17
  64. package/src/export.ts +0 -482
  65. package/src/gradient-utils.ts +0 -138
  66. package/src/graph/__tests__/canvas-renderer.test.ts +0 -713
  67. package/src/graph/__tests__/graph-mount.test.ts +0 -213
  68. package/src/graph/__tests__/interaction.test.ts +0 -205
  69. package/src/graph/__tests__/keyboard.test.ts +0 -653
  70. package/src/graph/__tests__/search.test.ts +0 -88
  71. package/src/graph/__tests__/simulation.test.ts +0 -233
  72. package/src/graph/__tests__/spatial-index.test.ts +0 -142
  73. package/src/graph/__tests__/zoom.test.ts +0 -203
  74. package/src/graph/canvas-renderer.ts +0 -747
  75. package/src/graph/interaction.ts +0 -367
  76. package/src/graph/keyboard.ts +0 -208
  77. package/src/graph/search.ts +0 -50
  78. package/src/graph/simulation-worker-url.ts +0 -12
  79. package/src/graph/simulation-worker.ts +0 -278
  80. package/src/graph/simulation.ts +0 -422
  81. package/src/graph/spatial-index.ts +0 -121
  82. package/src/graph/types.ts +0 -47
  83. package/src/graph/worker-protocol.ts +0 -70
  84. package/src/graph/zoom.ts +0 -134
  85. package/src/graph-mount.ts +0 -888
  86. package/src/index.ts +0 -76
  87. package/src/interactions/chart-events.ts +0 -139
  88. package/src/interactions/crosshair.ts +0 -233
  89. package/src/interactions/drag-handler.ts +0 -175
  90. package/src/interactions/editing-drags.ts +0 -515
  91. package/src/interactions/index.ts +0 -25
  92. package/src/interactions/keyboard-nav.ts +0 -111
  93. package/src/interactions/legend-interaction.ts +0 -46
  94. package/src/interactions/selection.ts +0 -280
  95. package/src/interactions/tooltip-events.ts +0 -72
  96. package/src/map-camera.ts +0 -88
  97. package/src/map-mount.ts +0 -701
  98. package/src/map-renderer.ts +0 -338
  99. package/src/map-transition.ts +0 -83
  100. package/src/measure-text.ts +0 -134
  101. package/src/mount.ts +0 -1382
  102. package/src/pattern-utils.ts +0 -110
  103. package/src/renderers/annotations.ts +0 -388
  104. package/src/renderers/axes.ts +0 -351
  105. package/src/renderers/brand.ts +0 -87
  106. package/src/renderers/chrome.ts +0 -196
  107. package/src/renderers/endpoint-labels.ts +0 -150
  108. package/src/renderers/legend.ts +0 -311
  109. package/src/renderers/marks.ts +0 -561
  110. package/src/renderers/metrics.ts +0 -63
  111. package/src/renderers/svg-dom.ts +0 -40
  112. package/src/renderers/table-cells.ts +0 -446
  113. package/src/resize-observer.ts +0 -46
  114. package/src/sankey-mount.ts +0 -622
  115. package/src/sankey-renderer.ts +0 -614
  116. package/src/series-search.ts +0 -392
  117. package/src/static.ts +0 -251
  118. package/src/story/__tests__/camera-math.test.ts +0 -145
  119. package/src/story/__tests__/create-chart-story.test.ts +0 -317
  120. package/src/story/__tests__/progress-math.test.ts +0 -95
  121. package/src/story/__tests__/scroll-driver.test.ts +0 -130
  122. package/src/story/__tests__/tween.test.ts +0 -159
  123. package/src/story/camera-math.ts +0 -125
  124. package/src/story/create-chart-story.ts +0 -353
  125. package/src/story/crossfade.ts +0 -70
  126. package/src/story/index.ts +0 -39
  127. package/src/story/progress-math.ts +0 -85
  128. package/src/story/resolve-camera-target.ts +0 -119
  129. package/src/story/scroll-driver.ts +0 -206
  130. package/src/story/story-camera.ts +0 -49
  131. package/src/story/tween.ts +0 -112
  132. package/src/story/types.ts +0 -76
  133. package/src/svg-ids.ts +0 -23
  134. package/src/svg-renderer.ts +0 -383
  135. package/src/table-keyboard.ts +0 -266
  136. package/src/table-mount.ts +0 -567
  137. package/src/table-renderer.ts +0 -414
  138. package/src/text-edit-overlay.ts +0 -255
  139. package/src/theme-tokens.ts +0 -51
  140. package/src/tilemap-mount.ts +0 -511
  141. package/src/tilemap-renderer.ts +0 -396
  142. package/src/tooltip.ts +0 -177
  143. package/src/transition.ts +0 -2816
  144. package/src/you-draw-it.ts +0 -480
  145. /package/dist/{chunk-W34KN7FD.js.map → chunk-2NAQRP66.js.map} +0 -0
@@ -1,105 +0,0 @@
1
- /**
2
- * Fill pattern rendering: <pattern> defs lifecycle and mark fill references.
3
- *
4
- * Mirrors gradient-ids.test.ts for the pattern half of the defs system:
5
- * pattern IDs come from the shared nextSvgId counter, so they are
6
- * deterministic at generation time and globally unique across charts.
7
- */
8
-
9
- import type { ChartSpec } from '@opendata-ai/openchart-core';
10
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
11
- import { createContainer } from '../__test-fixtures__/dom';
12
- import { createChart } from '../mount';
13
-
14
- function stackedSpec(): ChartSpec {
15
- return {
16
- mark: { type: 'bar', fillPattern: 'auto' },
17
- data: [
18
- { quarter: 'Q1', source: 'Solar', twh: 30 },
19
- { quarter: 'Q1', source: 'Wind', twh: 45 },
20
- { quarter: 'Q1', source: 'Hydro', twh: 25 },
21
- { quarter: 'Q1', source: 'Gas', twh: 60 },
22
- { quarter: 'Q2', source: 'Solar', twh: 35 },
23
- { quarter: 'Q2', source: 'Wind', twh: 50 },
24
- { quarter: 'Q2', source: 'Hydro', twh: 22 },
25
- { quarter: 'Q2', source: 'Gas', twh: 55 },
26
- ],
27
- encoding: {
28
- x: { field: 'quarter', type: 'nominal' },
29
- y: { field: 'twh', type: 'quantitative', stack: 'zero' },
30
- color: { field: 'source', type: 'nominal' },
31
- },
32
- };
33
- }
34
-
35
- function collectPatternIds(root: HTMLElement): string[] {
36
- const ids: string[] = [];
37
- for (const el of root.querySelectorAll('pattern')) {
38
- const id = el.getAttribute('id');
39
- if (id) ids.push(id);
40
- }
41
- return ids;
42
- }
43
-
44
- describe('pattern fill rendering', () => {
45
- let a: HTMLDivElement;
46
- let b: HTMLDivElement;
47
-
48
- beforeEach(() => {
49
- a = createContainer();
50
- b = createContainer();
51
- });
52
-
53
- afterEach(() => {
54
- document.body.innerHTML = '';
55
- });
56
-
57
- it('creates one pattern def per series and references them from bar fills', () => {
58
- const chart = createChart(a, stackedSpec());
59
-
60
- const ids = collectPatternIds(a);
61
- expect(ids.length).toBe(4);
62
- for (const id of ids) {
63
- expect(id).toMatch(/^oc-pattern-\d+$/);
64
- }
65
-
66
- // Each pattern tile carries a base rect plus pattern geometry
67
- for (const pattern of a.querySelectorAll('pattern')) {
68
- expect(pattern.querySelector('rect')).not.toBeNull();
69
- expect(pattern.children.length).toBe(2);
70
- }
71
-
72
- // Every large-enough bar segment fills from a pattern url
73
- const rects = a.querySelectorAll('.oc-mark-rect rect, .oc-mark-rect path');
74
- const patternFills = [...rects].filter((el) =>
75
- (el.getAttribute('fill') ?? '').startsWith('url(#oc-pattern-'),
76
- );
77
- expect(patternFills.length).toBeGreaterThan(0);
78
-
79
- chart.destroy();
80
- });
81
-
82
- it('renders solid fills when fillPattern is absent', () => {
83
- const spec = stackedSpec();
84
- spec.mark = { type: 'bar' };
85
- const chart = createChart(a, spec);
86
- expect(collectPatternIds(a)).toEqual([]);
87
- chart.destroy();
88
- });
89
-
90
- it('two charts produce disjoint pattern IDs', () => {
91
- const chartA = createChart(a, stackedSpec());
92
- const chartB = createChart(b, stackedSpec());
93
-
94
- const idsA = collectPatternIds(a);
95
- const idsB = collectPatternIds(b);
96
- expect(idsA.length).toBeGreaterThan(0);
97
- expect(idsB.length).toBeGreaterThan(0);
98
-
99
- const all = [...idsA, ...idsB];
100
- expect(new Set(all).size).toBe(all.length);
101
-
102
- chartA.destroy();
103
- chartB.destroy();
104
- });
105
- });
@@ -1,218 +0,0 @@
1
- /**
2
- * Resize timing behavior.
3
- *
4
- * These tests verify that:
5
- * 1. The inner observer's 16ms debounce coalesces a rapid burst of
6
- * ResizeObserver entries into a single render (no thrash).
7
- * 2. First ResizeObserver fire does not blank-flash (SVG stays mounted).
8
- * 3. Resize events during an entrance animation are deferred and replayed
9
- * on animation end.
10
- *
11
- * happy-dom ships a ResizeObserver stub that does not auto-fire on layout,
12
- * so we override it with a controllable mock that lets us invoke the
13
- * observer callback synchronously.
14
- */
15
-
16
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
17
- import { createAutoHeightContainer, createContainer } from '../__test-fixtures__/dom';
18
- import { lineSpec, longChromeLineSpec } from '../__test-fixtures__/specs';
19
- import { createChart } from '../mount';
20
-
21
- // ---------------------------------------------------------------------------
22
- // Controllable ResizeObserver mock
23
- // ---------------------------------------------------------------------------
24
-
25
- type ObserverCallback = (entries: ResizeObserverEntry[]) => void;
26
-
27
- interface FakeObserver {
28
- element: Element | null;
29
- callback: ObserverCallback;
30
- disconnected: boolean;
31
- }
32
-
33
- const observers: FakeObserver[] = [];
34
-
35
- class MockResizeObserver {
36
- private readonly record: FakeObserver;
37
-
38
- constructor(callback: ObserverCallback) {
39
- this.record = { element: null, callback, disconnected: false };
40
- observers.push(this.record);
41
- }
42
-
43
- observe(element: Element): void {
44
- this.record.element = element;
45
- }
46
-
47
- disconnect(): void {
48
- this.record.disconnected = true;
49
- }
50
-
51
- unobserve(): void {
52
- // no-op
53
- }
54
- }
55
-
56
- /** Fire a ResizeObserver callback for the given element with width/height. */
57
- function fireResize(element: Element, width: number, height: number): void {
58
- for (const o of observers) {
59
- if (o.element === element && !o.disconnected) {
60
- const entry = {
61
- contentRect: { width, height, top: 0, left: 0, right: width, bottom: height, x: 0, y: 0 },
62
- target: element,
63
- } as unknown as ResizeObserverEntry;
64
- o.callback([entry]);
65
- }
66
- }
67
- }
68
-
69
- // ---------------------------------------------------------------------------
70
- // Tests
71
- // ---------------------------------------------------------------------------
72
-
73
- describe('chart resize timing', () => {
74
- let container: HTMLDivElement;
75
- let originalRO: typeof globalThis.ResizeObserver;
76
-
77
- beforeEach(() => {
78
- observers.length = 0;
79
- originalRO = globalThis.ResizeObserver;
80
- // Use MockResizeObserver so tests can drive observer fires deterministically.
81
- // Cast via unknown to satisfy the stricter ResizeObserver type.
82
- globalThis.ResizeObserver = MockResizeObserver as unknown as typeof ResizeObserver;
83
- vi.useFakeTimers();
84
- container = createContainer();
85
- });
86
-
87
- afterEach(() => {
88
- vi.useRealTimers();
89
- globalThis.ResizeObserver = originalRO;
90
- document.body.innerHTML = '';
91
- });
92
-
93
- it('coalesces a rapid burst of resize events into a single render', async () => {
94
- const chart = createChart(container, lineSpec);
95
- const initialSvg = container.querySelector('svg');
96
- expect(initialSvg).not.toBeNull();
97
-
98
- // Track SVG node identity across renders: each render() replaces the SVG,
99
- // so counting how many distinct SVG nodes appear tells us how many renders ran.
100
- let renderCount = 0;
101
- const mo = new MutationObserver((records) => {
102
- for (const r of records) {
103
- for (let i = 0; i < r.addedNodes.length; i++) {
104
- const node = r.addedNodes[i];
105
- if (node instanceof Element && node.tagName.toLowerCase() === 'svg') {
106
- renderCount++;
107
- }
108
- }
109
- }
110
- });
111
- mo.observe(container, { childList: true });
112
-
113
- // Fire 20 resize events within a tight window.
114
- for (let i = 0; i < 20; i++) {
115
- fireResize(container, 600 + i, 400);
116
- }
117
-
118
- // Before the debounce window elapses, no new SVG has been appended.
119
- expect(renderCount).toBe(0);
120
-
121
- // Run all pending timers (16ms inner debounce + any outer delay).
122
- await vi.runAllTimersAsync();
123
-
124
- // MutationObserver records are delivered as microtasks; flush them.
125
- mo.takeRecords().forEach((r) => {
126
- for (let i = 0; i < r.addedNodes.length; i++) {
127
- const node = r.addedNodes[i];
128
- if (node instanceof Element && node.tagName.toLowerCase() === 'svg') {
129
- renderCount++;
130
- }
131
- }
132
- });
133
-
134
- // Exactly one re-render should have run for the whole burst (no thrash).
135
- expect(renderCount).toBe(1);
136
-
137
- mo.disconnect();
138
- chart.destroy();
139
- });
140
-
141
- it('does not blank-flash: SVG remains mounted through first observer fire', async () => {
142
- const chart = createChart(container, lineSpec);
143
-
144
- // SVG is painted immediately on mount, before the observer fires.
145
- const svgBefore = container.querySelector('svg');
146
- expect(svgBefore).not.toBeNull();
147
-
148
- // Fire the observer as it would on first layout.
149
- fireResize(container, 600, 400);
150
-
151
- // Even before the debounce elapses, the SVG must still be in the DOM.
152
- expect(container.querySelector('svg')).not.toBeNull();
153
-
154
- // And after timers flush, the SVG is still there (possibly a new node).
155
- await vi.runAllTimersAsync();
156
- expect(container.querySelector('svg')).not.toBeNull();
157
-
158
- chart.destroy();
159
- });
160
-
161
- it('disconnects the observer on destroy', () => {
162
- const chart = createChart(container, lineSpec);
163
- expect(observers.length).toBe(1);
164
- expect(observers[0].disconnected).toBe(false);
165
-
166
- chart.destroy();
167
-
168
- expect(observers[0].disconnected).toBe(true);
169
- });
170
-
171
- it('clears any pending resize timer on destroy (no callback after teardown)', async () => {
172
- const chart = createChart(container, lineSpec);
173
-
174
- fireResize(container, 700, 500);
175
- // Destroy before the debounce elapses.
176
- chart.destroy();
177
-
178
- await vi.runAllTimersAsync();
179
-
180
- // destroy() removes the SVG; if the timer fired after destroy it would
181
- // try to render a new one. No SVG should be present.
182
- expect(container.querySelector('svg')).toBeNull();
183
- });
184
-
185
- describe('auto-height observer feedback guard', () => {
186
- it('ignores the observer echo from the figure growing itself', async () => {
187
- const autoContainer = createAutoHeightContainer(390);
188
- const chart = createChart(autoContainer, longChromeLineSpec);
189
-
190
- const grownHeight = chart.layout.dimensions.height;
191
- expect(grownHeight).toBeGreaterThan(400);
192
- const genBefore = autoContainer.dataset.ocRenderGen;
193
-
194
- // Growing the SVG grows the container, which fires the observer with
195
- // our own dimensions. That echo must not trigger a re-render (the
196
- // re-render would grow again and loop).
197
- fireResize(autoContainer, 390, grownHeight);
198
- await vi.runAllTimersAsync();
199
- expect(autoContainer.dataset.ocRenderGen).toBe(genBefore);
200
-
201
- chart.destroy();
202
- });
203
-
204
- it('still re-renders when the width changes', async () => {
205
- const autoContainer = createAutoHeightContainer(390);
206
- const chart = createChart(autoContainer, longChromeLineSpec);
207
-
208
- const grownHeight = chart.layout.dimensions.height;
209
- const genBefore = autoContainer.dataset.ocRenderGen;
210
-
211
- fireResize(autoContainer, 340, grownHeight);
212
- await vi.runAllTimersAsync();
213
- expect(autoContainer.dataset.ocRenderGen).not.toBe(genBefore);
214
-
215
- chart.destroy();
216
- });
217
- });
218
- });
@@ -1,133 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
2
- import { createContainer } from '../__test-fixtures__/dom';
3
- import { createSankey } from '../sankey-mount';
4
-
5
- // ---------------------------------------------------------------------------
6
- // Shared fixtures
7
- // ---------------------------------------------------------------------------
8
-
9
- const basicSankeySpec = {
10
- type: 'sankey' as const,
11
- data: [
12
- { from: 'A', to: 'C', amount: 10 },
13
- { from: 'B', to: 'C', amount: 20 },
14
- { from: 'C', to: 'D', amount: 15 },
15
- { from: 'C', to: 'E', amount: 15 },
16
- ],
17
- encoding: {
18
- source: { field: 'from', type: 'nominal' as const },
19
- target: { field: 'to', type: 'nominal' as const },
20
- value: { field: 'amount', type: 'quantitative' as const },
21
- },
22
- };
23
-
24
- // ---------------------------------------------------------------------------
25
- // Tests
26
- // ---------------------------------------------------------------------------
27
-
28
- describe('createSankey', () => {
29
- let container: HTMLDivElement;
30
-
31
- beforeEach(() => {
32
- container = createContainer();
33
- });
34
-
35
- afterEach(() => {
36
- document.body.innerHTML = '';
37
- });
38
-
39
- it('mounts an SVG element into the container', () => {
40
- const instance = createSankey(container, basicSankeySpec, { responsive: false });
41
-
42
- const svg = container.querySelector('svg');
43
- expect(svg).not.toBeNull();
44
- expect(svg?.getAttribute('class')).toContain('oc-chart');
45
-
46
- instance.destroy();
47
- });
48
-
49
- it('renders the correct number of sankey node elements', () => {
50
- const instance = createSankey(container, basicSankeySpec, { responsive: false });
51
-
52
- const nodes = container.querySelectorAll('.oc-sankey-node');
53
- // A, B, C, D, E = 5 nodes
54
- expect(nodes).toHaveLength(5);
55
-
56
- instance.destroy();
57
- });
58
-
59
- it('renders the correct number of sankey link elements', () => {
60
- const instance = createSankey(container, basicSankeySpec, { responsive: false });
61
-
62
- const links = container.querySelectorAll('.oc-sankey-link');
63
- // A->C, B->C, C->D, C->E = 4 links
64
- expect(links).toHaveLength(4);
65
-
66
- instance.destroy();
67
- });
68
-
69
- it('creates gradient defs when linkStyle is gradient', () => {
70
- const spec = { ...basicSankeySpec, linkStyle: 'gradient' as const };
71
- const instance = createSankey(container, spec, { responsive: false });
72
-
73
- const gradients = container.querySelectorAll('linearGradient');
74
- expect(gradients.length).toBeGreaterThan(0);
75
-
76
- instance.destroy();
77
- });
78
-
79
- it('update() replaces the SVG with new content', () => {
80
- const instance = createSankey(container, basicSankeySpec, { responsive: false });
81
-
82
- const svgBefore = container.querySelector('svg');
83
- expect(svgBefore).not.toBeNull();
84
-
85
- // Update with different data
86
- const updatedSpec = {
87
- ...basicSankeySpec,
88
- data: [{ from: 'X', to: 'Y', amount: 50 }],
89
- };
90
- instance.update(updatedSpec);
91
-
92
- const svgAfter = container.querySelector('svg');
93
- expect(svgAfter).not.toBeNull();
94
-
95
- // Should now have 2 nodes (X and Y) instead of 5
96
- const nodes = container.querySelectorAll('.oc-sankey-node');
97
- expect(nodes).toHaveLength(2);
98
-
99
- instance.destroy();
100
- });
101
-
102
- it('destroy() removes the SVG from the container', () => {
103
- const instance = createSankey(container, basicSankeySpec, { responsive: false });
104
-
105
- const svgBefore = container.querySelector('svg');
106
- expect(svgBefore).not.toBeNull();
107
-
108
- instance.destroy();
109
-
110
- const svgAfter = container.querySelector('svg');
111
- expect(svgAfter).toBeNull();
112
- });
113
-
114
- it('has oc-animate class when animation is enabled', () => {
115
- const spec = { ...basicSankeySpec, animation: true };
116
- const instance = createSankey(container, spec, { responsive: false });
117
-
118
- const svg = container.querySelector('svg');
119
- expect(svg?.classList.contains('oc-animate')).toBe(true);
120
-
121
- instance.destroy();
122
- });
123
-
124
- it('layout property returns the compiled layout', () => {
125
- const instance = createSankey(container, basicSankeySpec, { responsive: false });
126
-
127
- expect(instance.layout).toBeDefined();
128
- expect(instance.layout.nodes).toHaveLength(5);
129
- expect(instance.layout.links).toHaveLength(4);
130
-
131
- instance.destroy();
132
- });
133
- });