@opendata-ai/openchart-vue 8.4.1 → 8.5.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
@@ -61,6 +61,49 @@ const props = defineProps<{ spec: VizSpec }>();
61
61
 
62
62
  If you need event handlers or component-specific props, use the specific component directly instead.
63
63
 
64
+ ## 3D graphs
65
+
66
+ `dimensions: 3` on a graph spec renders with WebGL instead of canvas. The 3D
67
+ renderer ships on its own subpath so three.js never lands in the default bundle,
68
+ and its libraries are optional peers you install yourself:
69
+
70
+ ```bash
71
+ npm install three 3d-force-graph three-spritetext
72
+ ```
73
+
74
+ The subpath registers the renderer as an import side effect, so it has to be
75
+ imported before the graph mounts. Import this package's own subpath rather than
76
+ reaching past it into vanilla:
77
+
78
+ ```vue
79
+ <script setup lang="ts">
80
+ import type { GraphSpec } from '@opendata-ai/openchart-core';
81
+ import { Graph } from '@opendata-ai/openchart-vue';
82
+ import { onMounted, ref } from 'vue';
83
+
84
+ const spec: GraphSpec = {
85
+ type: 'graph',
86
+ nodes: [{ id: 'a' }, { id: 'b' }],
87
+ edges: [{ source: 'a', target: 'b' }],
88
+ };
89
+
90
+ const ready = ref(false);
91
+ // Client-side only: 3d-force-graph touches `window` at import time.
92
+ onMounted(async () => {
93
+ await import('@opendata-ai/openchart-vue/graph-3d');
94
+ ready.value = true;
95
+ });
96
+ </script>
97
+
98
+ <template>
99
+ <Graph v-if="ready" :spec="{ ...spec, dimensions: 3 }" />
100
+ </template>
101
+ ```
102
+
103
+ The subpath import is required only when compilation actually resolves to 3D: a
104
+ spec above the 2000-node gate falls back to 2D and renders without it. See the
105
+ [vanilla README](../vanilla/README.md#3d-graphs) for how 3D differs from 2D.
106
+
64
107
  ## Dark mode and theming
65
108
 
66
109
  Wrap components with `VizThemeProvider` to set theme and dark mode for all child visualizations. It uses Vue's `provide`/`inject` under the hood, so all `Chart`, `DataTable`, and `Graph` components inside the provider inherit its values.
@@ -0,0 +1 @@
1
+ export * from '@opendata-ai/openchart-vanilla/graph-3d';
@@ -0,0 +1,3 @@
1
+ // src/graph-3d.ts
2
+ export * from "@opendata-ai/openchart-vanilla/graph-3d";
3
+ //# sourceMappingURL=graph-3d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/graph-3d.ts"],"sourcesContent":["/**\n * Vue subpath for the 3D graph renderer.\n *\n * Importing this module registers the WebGL renderer with the vanilla graph\n * registry, so a `<Graph />` whose spec sets `dimensions: 3` can mount. It is a\n * side-effect import: there is nothing Vue-specific here beyond the re-export,\n * and it exists so Vue hosts never have to reach past\n * `@opendata-ai/openchart-vue` for a peer (vanilla is a transitive dependency,\n * which strict resolvers refuse to resolve a deep import against).\n *\n * Import it client-side only (three.js touches `window` at module scope):\n *\n * ```ts\n * onMounted(() => {\n * import('@opendata-ai/openchart-vue/graph-3d');\n * });\n * ```\n */\n\nexport * from '@opendata-ai/openchart-vanilla/graph-3d';\n"],"mappings":";AAmBA,cAAc;","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { BarListSpec, ThemeConfig, DarkMode, ChartSpec, LayerSpec, GraphSpec, ElementRef, MarkEvent, Annotation, TextAnnotation, AnnotationOffset, ElementEdit, GeoMapSpec, ChartLayout, TableSpec, SortState, SankeySpec, TileMapSpec, VizSpec } from '@opendata-ai/openchart-core';
2
2
  export * from '@opendata-ai/openchart-core';
3
- import { MountOptions, ChartInstance, CameraFlightOptions, GraphHighlightTarget, GraphLegendData, GraphInstance, TableInstance, TableState, TableMountOptions, GeoMapMarkEvent, GraphTooltipFormatter } from '@opendata-ai/openchart-vanilla';
3
+ import { MountOptions, ChartInstance, CameraFlightOptions, GraphFlyTarget, GraphCamera, GraphHighlightTarget, GraphLegendData, GraphInstance, TableInstance, TableState, TableMountOptions, GeoMapMarkEvent, GraphTooltipFormatter } from '@opendata-ai/openchart-vanilla';
4
4
  export { JPGExportOptions, PNGExportOptions, SVGExportOptions, SpecSequenceOptions, exportCSV, exportJPG, exportPNG, exportSVG, exportSVGWithFonts, exportSpecSequence } from '@opendata-ai/openchart-vanilla';
5
5
  export { ChartRenderer, CompileResult, CompiledGraphEdge, CompiledGraphNode, GraphCompilation, NormalizedBarListSpec, NormalizedChartSpec, NormalizedChrome, NormalizedGeoMapSpec, NormalizedGraphSpec, NormalizedSankeySpec, NormalizedSpec, NormalizedTableSpec, NormalizedTileMapSpec, SimulationConfig, ValidationError, ValidationErrorCode, ValidationResult, clearRenderers, compile, compileBarList, compileChart, compileGeoMap, compileGraph, compileSankey, compileTable, compileTileMap, getChartRenderer, normalizeSpec, registerChartRenderer, validateSpec } from '@opendata-ai/openchart-engine';
6
6
  import * as vue from 'vue';
@@ -334,12 +334,6 @@ declare function useDarkMode(mode: Ref<DarkMode | undefined>): Ref<boolean>;
334
334
  * graph instance. The full vanilla GraphInstance API is threaded through.
335
335
  */
336
336
 
337
- /** Camera transform components (graph-space). */
338
- type GraphCamera = {
339
- x: number;
340
- y: number;
341
- k: number;
342
- };
343
337
  /** Handle exposed by Graph component via expose(). */
344
338
  interface GraphHandle {
345
339
  search: (query: string) => void;
@@ -351,11 +345,7 @@ interface GraphHandle {
351
345
  zoomToNode: (nodeId: string, opts?: CameraFlightOptions & {
352
346
  scale?: number;
353
347
  }) => void;
354
- flyTo: (target: {
355
- x: number;
356
- y: number;
357
- k?: number;
358
- }, opts?: CameraFlightOptions) => void;
348
+ flyTo: (target: GraphFlyTarget, opts?: CameraFlightOptions) => void;
359
349
  centerAt: (x: number, y: number, opts?: CameraFlightOptions) => void;
360
350
  getCamera: () => GraphCamera;
361
351
  selectNode: (nodeId: string, opts?: {
@@ -393,11 +383,7 @@ interface UseGraphReturn {
393
383
  scale?: number;
394
384
  }) => void;
395
385
  /** Fly the camera to a graph-space target. */
396
- flyTo: (target: {
397
- x: number;
398
- y: number;
399
- k?: number;
400
- }, opts?: CameraFlightOptions) => void;
386
+ flyTo: (target: GraphFlyTarget, opts?: CameraFlightOptions) => void;
401
387
  /** Center the camera on a graph-space point (keeps current zoom). */
402
388
  centerAt: (x: number, y: number, opts?: CameraFlightOptions) => void;
403
389
  /** Current camera transform. */
@@ -761,11 +747,7 @@ declare const Graph: vue.DefineComponent<vue.ExtractPropTypes<{
761
747
  } | null) => true;
762
748
  'legend-toggle': (_activeValues: string[]) => true;
763
749
  'highlight-change': (_nodeIds: string[] | null) => true;
764
- 'camera-change': (_camera: {
765
- x: number;
766
- y: number;
767
- k: number;
768
- }) => true;
750
+ 'camera-change': (_camera: GraphCamera) => true;
769
751
  }, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
770
752
  spec: {
771
753
  type: PropType<GraphSpec>;
@@ -811,11 +793,7 @@ declare const Graph: vue.DefineComponent<vue.ExtractPropTypes<{
811
793
  value: string;
812
794
  } | null) => any) | undefined;
813
795
  "onHighlight-change"?: ((_nodeIds: string[] | null) => any) | undefined;
814
- "onCamera-change"?: ((_camera: {
815
- x: number;
816
- y: number;
817
- k: number;
818
- }) => any) | undefined;
796
+ "onCamera-change"?: ((_camera: GraphCamera) => any) | undefined;
819
797
  }>, {
820
798
  theme: ThemeConfig;
821
799
  darkMode: DarkMode;
package/dist/index.js CHANGED
@@ -1087,7 +1087,7 @@ var Graph = defineComponent6({
1087
1087
  const fn = t && typeof t === "object" ? t.formatter : void 0;
1088
1088
  return fn ? fn(item, defaults) : defaults;
1089
1089
  };
1090
- function mountGraph() {
1090
+ function mountGraph(playEntrance = false) {
1091
1091
  const container = containerRef.value;
1092
1092
  if (!container) return;
1093
1093
  const tooltipOption = tooltipOn(props.tooltip) ? { formatter: stableTooltipFormatter } : false;
@@ -1107,7 +1107,7 @@ var Graph = defineComponent6({
1107
1107
  onHighlightChange: (nodeIds) => emit("highlight-change", nodeIds),
1108
1108
  onCameraChange: (camera) => emit("camera-change", camera),
1109
1109
  responsive: true,
1110
- suppressEntrance: mountedOnce
1110
+ suppressEntrance: mountedOnce && !playEntrance
1111
1111
  };
1112
1112
  instance = createGraph(container, props.spec, options);
1113
1113
  prevSpec = JSON.stringify(props.spec);
@@ -1180,6 +1180,14 @@ var Graph = defineComponent6({
1180
1180
  onUnmounted9(() => {
1181
1181
  destroyGraph();
1182
1182
  });
1183
+ watch9(
1184
+ () => props.spec.dimensions ?? 2,
1185
+ () => {
1186
+ if (!containerRef.value) return;
1187
+ destroyGraph();
1188
+ mountGraph(true);
1189
+ }
1190
+ );
1183
1191
  watch9(
1184
1192
  () => JSON.stringify(props.spec),
1185
1193
  (newVal) => {