@opendata-ai/openchart-vue 6.5.2 → 6.7.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.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { ChartSpec, LayerSpec, GraphSpec, ThemeConfig, DarkMode, ElementRef, MarkEvent, Annotation, TextAnnotation, AnnotationOffset, ElementEdit, ChartLayout, TableSpec, SortState, VizSpec } from '@opendata-ai/openchart-core';
1
+ import { ChartSpec, LayerSpec, GraphSpec, ThemeConfig, DarkMode, ElementRef, MarkEvent, Annotation, TextAnnotation, AnnotationOffset, ElementEdit, ChartLayout, TableSpec, SortState, SankeySpec, VizSpec } from '@opendata-ai/openchart-core';
2
2
  export * from '@opendata-ai/openchart-core';
3
3
  import { MountOptions, ChartInstance, GraphInstance, TableInstance, TableState, TableMountOptions } from '@opendata-ai/openchart-vanilla';
4
4
  export { JPGExportOptions, PNGExportOptions, exportCSV, exportJPG, exportPNG, exportSVG } from '@opendata-ai/openchart-vanilla';
5
- export { ChartRenderer, CompileResult, CompiledGraphEdge, CompiledGraphNode, GraphCompilation, NormalizedChartSpec, NormalizedChrome, NormalizedGraphSpec, NormalizedSpec, NormalizedTableSpec, SimulationConfig, ValidationError, ValidationErrorCode, ValidationResult, clearRenderers, compile, compileChart, compileGraph, compileTable, getChartRenderer, normalizeSpec, registerChartRenderer, validateSpec } from '@opendata-ai/openchart-engine';
5
+ export { ChartRenderer, CompileResult, CompiledGraphEdge, CompiledGraphNode, GraphCompilation, NormalizedChartSpec, NormalizedChrome, NormalizedGraphSpec, NormalizedSankeySpec, NormalizedSpec, NormalizedTableSpec, SimulationConfig, ValidationError, ValidationErrorCode, ValidationResult, clearRenderers, compile, compileChart, compileGraph, compileSankey, compileTable, getChartRenderer, normalizeSpec, registerChartRenderer, validateSpec } from '@opendata-ai/openchart-engine';
6
6
  import * as vue from 'vue';
7
7
  import { PropType, CSSProperties, Ref, ShallowRef, InjectionKey, ComputedRef } from 'vue';
8
8
 
@@ -448,6 +448,74 @@ declare const Graph: vue.DefineComponent<vue.ExtractPropTypes<{
448
448
  style: string | CSSProperties;
449
449
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
450
450
 
451
+ interface SankeyProps {
452
+ spec: SankeySpec;
453
+ theme?: ThemeConfig;
454
+ darkMode?: DarkMode;
455
+ class?: string;
456
+ style?: string | CSSProperties;
457
+ }
458
+ declare const Sankey: vue.DefineComponent<vue.ExtractPropTypes<{
459
+ spec: {
460
+ type: PropType<SankeySpec>;
461
+ required: true;
462
+ };
463
+ theme: {
464
+ type: PropType<ThemeConfig>;
465
+ default: undefined;
466
+ };
467
+ darkMode: {
468
+ type: PropType<DarkMode>;
469
+ default: undefined;
470
+ };
471
+ class: {
472
+ type: StringConstructor;
473
+ default: undefined;
474
+ };
475
+ style: {
476
+ type: PropType<string | CSSProperties>;
477
+ default: undefined;
478
+ };
479
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
480
+ [key: string]: any;
481
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
482
+ 'node-click': (_node: Record<string, unknown>) => true;
483
+ 'link-click': (_link: Record<string, unknown>) => true;
484
+ 'node-hover': (_node: Record<string, unknown> | null) => true;
485
+ 'link-hover': (_link: Record<string, unknown> | null) => true;
486
+ }, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
487
+ spec: {
488
+ type: PropType<SankeySpec>;
489
+ required: true;
490
+ };
491
+ theme: {
492
+ type: PropType<ThemeConfig>;
493
+ default: undefined;
494
+ };
495
+ darkMode: {
496
+ type: PropType<DarkMode>;
497
+ default: undefined;
498
+ };
499
+ class: {
500
+ type: StringConstructor;
501
+ default: undefined;
502
+ };
503
+ style: {
504
+ type: PropType<string | CSSProperties>;
505
+ default: undefined;
506
+ };
507
+ }>> & Readonly<{
508
+ "onNode-click"?: ((_node: Record<string, unknown>) => any) | undefined;
509
+ "onLink-click"?: ((_link: Record<string, unknown>) => any) | undefined;
510
+ "onNode-hover"?: ((_node: Record<string, unknown> | null) => any) | undefined;
511
+ "onLink-hover"?: ((_link: Record<string, unknown> | null) => any) | undefined;
512
+ }>, {
513
+ theme: ThemeConfig;
514
+ darkMode: DarkMode;
515
+ class: string;
516
+ style: string | CSSProperties;
517
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
518
+
451
519
  interface VizThemeProviderProps {
452
520
  theme: ThemeConfig | undefined;
453
521
  darkMode?: DarkMode;
@@ -535,4 +603,4 @@ declare const Visualization: vue.DefineComponent<vue.ExtractPropTypes<{
535
603
  style: string | CSSProperties;
536
604
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
537
605
 
538
- export { Chart, type ChartProps, DataTable, type DataTableProps, Graph, type GraphHandle, type GraphProps, type UseChartOptions, type UseChartReturn, type UseGraphReturn, type UseTableReturn, type UseTableStateOptions, type UseTableStateReturn, Visualization, type VisualizationProps, VizDarkModeKey, VizThemeKey, VizThemeProvider, type VizThemeProviderProps, useChart, useDarkMode, useGraph, useTable, useTableState, useVizDarkMode, useVizTheme };
606
+ export { Chart, type ChartProps, DataTable, type DataTableProps, Graph, type GraphHandle, type GraphProps, Sankey, type SankeyProps, type UseChartOptions, type UseChartReturn, type UseGraphReturn, type UseTableReturn, type UseTableStateOptions, type UseTableStateReturn, Visualization, type VisualizationProps, VizDarkModeKey, VizThemeKey, VizThemeProvider, type VizThemeProviderProps, useChart, useDarkMode, useGraph, useTable, useTableState, useVizDarkMode, useVizTheme };
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  compile,
7
7
  compileChart,
8
8
  compileGraph,
9
+ compileSankey,
9
10
  compileTable,
10
11
  getChartRenderer,
11
12
  normalizeSpec,
@@ -688,9 +689,130 @@ var Graph = defineComponent3({
688
689
  }
689
690
  });
690
691
 
692
+ // src/Sankey.ts
693
+ import {
694
+ createSankey
695
+ } from "@opendata-ai/openchart-vanilla";
696
+ import {
697
+ defineComponent as defineComponent4,
698
+ h as h4,
699
+ inject as inject5,
700
+ onMounted as onMounted6,
701
+ onUnmounted as onUnmounted7,
702
+ ref as ref9,
703
+ watch as watch7
704
+ } from "vue";
705
+ var Sankey = defineComponent4({
706
+ name: "Sankey",
707
+ props: {
708
+ spec: {
709
+ type: Object,
710
+ required: true
711
+ },
712
+ theme: {
713
+ type: Object,
714
+ default: void 0
715
+ },
716
+ darkMode: {
717
+ type: String,
718
+ default: void 0
719
+ },
720
+ class: {
721
+ type: String,
722
+ default: void 0
723
+ },
724
+ style: {
725
+ type: [String, Object],
726
+ default: void 0
727
+ }
728
+ },
729
+ emits: {
730
+ "node-click": (_node) => true,
731
+ "link-click": (_link) => true,
732
+ "node-hover": (_node) => true,
733
+ "link-hover": (_link) => true
734
+ },
735
+ setup(props, { emit, expose }) {
736
+ const containerRef = ref9(null);
737
+ let instance = null;
738
+ let prevSpec = "";
739
+ const contextTheme = inject5(VizThemeKey, void 0);
740
+ const contextDarkMode = inject5(VizDarkModeKey, void 0);
741
+ function resolveTheme() {
742
+ return props.theme ?? contextTheme?.value;
743
+ }
744
+ function resolveDarkMode() {
745
+ return props.darkMode ?? contextDarkMode?.value;
746
+ }
747
+ function mountSankey() {
748
+ const container = containerRef.value;
749
+ if (!container) return;
750
+ const options = {
751
+ theme: resolveTheme(),
752
+ darkMode: resolveDarkMode(),
753
+ onNodeClick: (node) => emit("node-click", node),
754
+ onLinkClick: (link) => emit("link-click", link),
755
+ onNodeHover: (node) => emit("node-hover", node),
756
+ onLinkHover: (link) => emit("link-hover", link),
757
+ responsive: true
758
+ };
759
+ instance = createSankey(container, props.spec, options);
760
+ prevSpec = JSON.stringify(props.spec);
761
+ }
762
+ function destroySankey() {
763
+ instance?.destroy();
764
+ instance = null;
765
+ prevSpec = "";
766
+ }
767
+ expose({
768
+ get instance() {
769
+ return instance;
770
+ }
771
+ });
772
+ onMounted6(() => {
773
+ mountSankey();
774
+ });
775
+ onUnmounted7(() => {
776
+ destroySankey();
777
+ });
778
+ watch7(
779
+ () => JSON.stringify(props.spec),
780
+ (newVal) => {
781
+ if (!instance) return;
782
+ if (newVal !== prevSpec) {
783
+ prevSpec = newVal;
784
+ instance.update(props.spec);
785
+ }
786
+ }
787
+ );
788
+ watch7(
789
+ [
790
+ () => props.theme,
791
+ () => props.darkMode,
792
+ () => contextTheme?.value,
793
+ () => contextDarkMode?.value
794
+ ],
795
+ () => {
796
+ if (!containerRef.value) return;
797
+ destroySankey();
798
+ mountSankey();
799
+ }
800
+ );
801
+ const rootClass = () => {
802
+ const base = "oc-sankey-root";
803
+ return props.class ? `${base} ${props.class}` : base;
804
+ };
805
+ return () => h4("div", {
806
+ ref: containerRef,
807
+ class: rootClass(),
808
+ style: props.style
809
+ });
810
+ }
811
+ });
812
+
691
813
  // src/ThemeProvider.ts
692
- import { computed as computed2, defineComponent as defineComponent4, provide } from "vue";
693
- var VizThemeProvider = defineComponent4({
814
+ import { computed as computed2, defineComponent as defineComponent5, provide } from "vue";
815
+ var VizThemeProvider = defineComponent5({
694
816
  name: "VizThemeProvider",
695
817
  props: {
696
818
  theme: {
@@ -712,9 +834,9 @@ var VizThemeProvider = defineComponent4({
712
834
  });
713
835
 
714
836
  // src/Visualization.ts
715
- import { isGraphSpec, isTableSpec } from "@opendata-ai/openchart-core";
716
- import { defineComponent as defineComponent5, h as h4 } from "vue";
717
- var Visualization = defineComponent5({
837
+ import { isGraphSpec, isSankeySpec, isTableSpec } from "@opendata-ai/openchart-core";
838
+ import { defineComponent as defineComponent6, h as h5 } from "vue";
839
+ var Visualization = defineComponent6({
718
840
  name: "Visualization",
719
841
  props: {
720
842
  spec: {
@@ -743,12 +865,15 @@ var Visualization = defineComponent5({
743
865
  const { spec, theme, darkMode, class: className, style } = props;
744
866
  const sharedProps = { theme, darkMode, class: className, style };
745
867
  if (isTableSpec(spec)) {
746
- return h4(DataTable, { ...sharedProps, spec });
868
+ return h5(DataTable, { ...sharedProps, spec });
747
869
  }
748
870
  if (isGraphSpec(spec)) {
749
- return h4(Graph, { ...sharedProps, spec });
871
+ return h5(Graph, { ...sharedProps, spec });
872
+ }
873
+ if (isSankeySpec(spec)) {
874
+ return h5(Sankey, { ...sharedProps, spec });
750
875
  }
751
- return h4(Chart, { ...sharedProps, spec });
876
+ return h5(Chart, { ...sharedProps, spec });
752
877
  };
753
878
  }
754
879
  });
@@ -756,6 +881,7 @@ export {
756
881
  Chart,
757
882
  DataTable,
758
883
  Graph,
884
+ Sankey,
759
885
  Visualization,
760
886
  VizDarkModeKey,
761
887
  VizThemeKey,
@@ -764,6 +890,7 @@ export {
764
890
  compile,
765
891
  compileChart,
766
892
  compileGraph,
893
+ compileSankey,
767
894
  compileTable,
768
895
  exportCSV,
769
896
  exportJPG,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/Chart.ts","../src/context.ts","../src/composables/useChart.ts","../src/composables/useDarkMode.ts","../src/composables/useGraph.ts","../src/composables/useTable.ts","../src/composables/useTableState.ts","../src/DataTable.ts","../src/Graph.ts","../src/ThemeProvider.ts","../src/Visualization.ts"],"sourcesContent":["/**\n * @opendata-ai/openchart-vue\n *\n * Vue 3 adapter for openchart. Provides <Chart />, <DataTable />, <Graph />,\n * and <VizThemeProvider /> components that wrap the vanilla adapter with\n * Vue lifecycle management.\n *\n * Re-exports the full core type system and utilities so Vue consumers\n * only need a single @opendata-ai/openchart-vue dependency.\n */\n\n// ---------------------------------------------------------------------------\n// Core: full type system, theme, colors, locale, accessibility, helpers\n// ---------------------------------------------------------------------------\n\nexport * from '@opendata-ai/openchart-core';\n\n// ---------------------------------------------------------------------------\n// Vanilla: export utilities (SVG/PNG/JPG/CSV)\n// ---------------------------------------------------------------------------\n\nexport type { JPGExportOptions, PNGExportOptions } from '@opendata-ai/openchart-vanilla';\nexport { exportCSV, exportJPG, exportPNG, exportSVG } from '@opendata-ai/openchart-vanilla';\n\n// ---------------------------------------------------------------------------\n// Engine: compile API and types not covered by core\n// ---------------------------------------------------------------------------\n\nexport type {\n ChartRenderer,\n CompiledGraphEdge,\n CompiledGraphNode,\n CompileResult,\n GraphCompilation,\n NormalizedChartSpec,\n NormalizedChrome,\n NormalizedGraphSpec,\n NormalizedSpec,\n NormalizedTableSpec,\n SimulationConfig,\n ValidationError,\n ValidationErrorCode,\n ValidationResult,\n} from '@opendata-ai/openchart-engine';\nexport {\n clearRenderers,\n compile,\n compileChart,\n compileGraph,\n compileTable,\n getChartRenderer,\n normalizeSpec,\n registerChartRenderer,\n validateSpec,\n} from '@opendata-ai/openchart-engine';\n\n// Components\nexport type { ChartProps } from './Chart';\nexport { Chart } from './Chart';\n// Composables\nexport type { UseChartOptions, UseChartReturn } from './composables/useChart';\nexport { useChart } from './composables/useChart';\nexport { useDarkMode } from './composables/useDarkMode';\nexport type { GraphHandle, UseGraphReturn } from './composables/useGraph';\nexport { useGraph } from './composables/useGraph';\nexport type { UseTableReturn } from './composables/useTable';\nexport { useTable } from './composables/useTable';\nexport type { UseTableStateOptions, UseTableStateReturn } from './composables/useTableState';\nexport { useTableState } from './composables/useTableState';\n// Context (injection keys and composables)\nexport { useVizDarkMode, useVizTheme, VizDarkModeKey, VizThemeKey } from './context';\nexport type { DataTableProps } from './DataTable';\nexport { DataTable } from './DataTable';\nexport type { GraphProps } from './Graph';\nexport { Graph } from './Graph';\nexport type { VizThemeProviderProps } from './ThemeProvider';\nexport { VizThemeProvider } from './ThemeProvider';\nexport type { VisualizationProps } from './Visualization';\nexport { Visualization } from './Visualization';\n","/**\n * Vue Chart component: thin wrapper around the vanilla adapter.\n *\n * Mounts a chart instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createChart() function.\n */\n\nimport type {\n Annotation,\n AnnotationOffset,\n ChartSpec,\n DarkMode,\n ElementEdit,\n ElementRef,\n GraphSpec,\n LayerSpec,\n MarkEvent,\n TextAnnotation,\n ThemeConfig,\n} from '@opendata-ai/openchart-core';\nimport { type ChartInstance, createChart, type MountOptions } from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n getCurrentInstance,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface ChartProps {\n spec: ChartSpec | LayerSpec | GraphSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Chart = defineComponent({\n name: 'Chart',\n props: {\n spec: {\n type: Object as PropType<ChartSpec | LayerSpec | GraphSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n selectedElement: {\n type: Object as PropType<ElementRef>,\n default: undefined,\n },\n },\n emits: {\n 'mark-click': (_event: MarkEvent) => true,\n 'mark-hover': (_event: MarkEvent) => true,\n 'mark-leave': () => true,\n 'legend-toggle': (_series: string, _visible: boolean) => true,\n 'annotation-click': (_annotation: Annotation, _event: MouseEvent) => true,\n 'annotation-edit': (_annotation: TextAnnotation, _updatedOffset: AnnotationOffset) => true,\n edit: (_edit: ElementEdit) => true,\n select: (_element: ElementRef) => true,\n deselect: (_element: ElementRef) => true,\n 'text-edit': (_element: ElementRef, _oldText: string, _newText: string) => true,\n 'data-point-click': (_data: Record<string, unknown>) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: ChartInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n // Check which event listeners are bound by the parent.\n // Vue 3 passes listeners as onXxx props on the component vnode.\n // We cache this at setup time since it won't change.\n const vm = getCurrentInstance();\n const vnodeProps = vm?.vnode.props ?? {};\n const hasAnnotationEditListener =\n 'onAnnotation-edit' in vnodeProps || 'onAnnotationEdit' in vnodeProps;\n const hasEditListener = 'onEdit' in vnodeProps;\n const hasSelectListener = 'onSelect' in vnodeProps;\n const hasDeselectListener = 'onDeselect' in vnodeProps;\n const hasTextEditListener = 'onText-edit' in vnodeProps || 'onTextEdit' in vnodeProps;\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountChart() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: MountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onDataPointClick: (data: Record<string, unknown>) => emit('data-point-click', data),\n onMarkClick: (event: MarkEvent) => emit('mark-click', event),\n onMarkHover: (event: MarkEvent) => emit('mark-hover', event),\n onMarkLeave: () => emit('mark-leave'),\n onLegendToggle: (series: string, visible: boolean) =>\n emit('legend-toggle', series, visible),\n onAnnotationClick: (annotation: Annotation, event: MouseEvent) =>\n emit('annotation-click', annotation, event),\n // Only include editing callbacks when the parent binds a listener.\n // Without this gate, every chart gets drag editing wired up.\n ...(hasAnnotationEditListener\n ? {\n onAnnotationEdit: (annotation: TextAnnotation, updatedOffset: AnnotationOffset) =>\n emit('annotation-edit', annotation, updatedOffset),\n }\n : {}),\n ...(hasEditListener ? { onEdit: (edit: ElementEdit) => emit('edit', edit) } : {}),\n ...(hasSelectListener\n ? { onSelect: (element: ElementRef) => emit('select', element) }\n : {}),\n ...(hasDeselectListener\n ? { onDeselect: (element: ElementRef) => emit('deselect', element) }\n : {}),\n ...(hasTextEditListener\n ? {\n onTextEdit: (element: ElementRef, oldText: string, newText: string) =>\n emit('text-edit', element, oldText, newText),\n }\n : {}),\n ...(props.selectedElement ? { selectedElement: props.selectedElement } : {}),\n responsive: true,\n };\n\n instance = createChart(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyChart() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative methods for parent ref access\n expose({\n getSelectedElement(): ElementRef | null {\n return instance?.getSelectedElement() ?? null;\n },\n select(elementRef: ElementRef): void {\n instance?.select(elementRef);\n },\n deselect(): void {\n instance?.deselect();\n },\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountChart();\n });\n\n onUnmounted(() => {\n destroyChart();\n });\n\n // Watch spec changes: update if only spec changed, recreate if theme/darkMode changed\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec, { selectedElement: props.selectedElement });\n }\n },\n );\n\n // Watch selectedElement prop changes\n watch(\n () => props.selectedElement,\n (newVal) => {\n if (!instance) return;\n if (newVal) {\n instance.select(newVal);\n } else {\n instance.deselect();\n }\n },\n );\n\n // Recreate chart when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyChart();\n mountChart();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-chart-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Theme injection context for Vue.\n *\n * Provides typed injection keys and composables for accessing theme\n * and dark mode from any descendant component within a VizThemeProvider.\n */\n\nimport type { DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';\nimport { type ComputedRef, computed, type InjectionKey, inject, type Ref } from 'vue';\n\n/** Injection key for the theme config ref. */\nexport const VizThemeKey: InjectionKey<Ref<ThemeConfig | undefined>> = Symbol('VizTheme');\n\n/** Injection key for the dark mode ref. */\nexport const VizDarkModeKey: InjectionKey<Ref<DarkMode | undefined>> = Symbol('VizDarkMode');\n\n/**\n * Read the current theme from the nearest VizThemeProvider.\n * Returns a computed ref that stays reactive to provider changes.\n */\nexport function useVizTheme(): ComputedRef<ThemeConfig | undefined> {\n const theme = inject(VizThemeKey, undefined);\n return computed(() => theme?.value);\n}\n\n/**\n * Read the current dark mode preference from the nearest VizThemeProvider.\n * Returns a computed ref that stays reactive to provider changes.\n */\nexport function useVizDarkMode(): ComputedRef<DarkMode | undefined> {\n const darkMode = inject(VizDarkModeKey, undefined);\n return computed(() => darkMode?.value);\n}\n","/**\n * useChart: composable for manual chart lifecycle control.\n *\n * Provides a template ref to attach to a container div. The chart\n * mounts automatically and updates when the spec changes.\n */\n\nimport type {\n ChartLayout,\n ChartSpec,\n DarkMode,\n GraphSpec,\n LayerSpec,\n ThemeConfig,\n} from '@opendata-ai/openchart-core';\nimport { type ChartInstance, createChart, type MountOptions } from '@opendata-ai/openchart-vanilla';\nimport { onMounted, onUnmounted, type Ref, ref, type ShallowRef, shallowRef, watch } from 'vue';\n\nexport interface UseChartOptions {\n /** Theme overrides. */\n theme?: ThemeConfig;\n /** Dark mode setting. */\n darkMode?: DarkMode;\n /** Data point click handler. */\n onDataPointClick?: MountOptions['onDataPointClick'];\n /** Enable responsive resizing. Defaults to true. */\n responsive?: boolean;\n}\n\nexport interface UseChartReturn {\n /** Template ref to attach to the container div. */\n containerRef: Ref<HTMLDivElement | null>;\n /** The chart instance (null until mounted). */\n chart: ShallowRef<ChartInstance | null>;\n /** The current compiled layout (null until mounted). */\n layout: ShallowRef<ChartLayout | null>;\n}\n\n/**\n * Composable for manual chart lifecycle control.\n *\n * Attach the returned containerRef to a container div via `ref=\"containerRef\"`.\n * The chart mounts automatically and updates when the spec changes.\n */\nexport function useChart(\n spec: Ref<ChartSpec | LayerSpec | GraphSpec>,\n options?: UseChartOptions,\n): UseChartReturn {\n const containerRef = ref<HTMLDivElement | null>(null);\n const chart = shallowRef<ChartInstance | null>(null);\n const layout = shallowRef<ChartLayout | null>(null);\n\n function mount() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOpts: MountOptions = {\n theme: options?.theme,\n darkMode: options?.darkMode,\n onDataPointClick: options?.onDataPointClick,\n responsive: options?.responsive,\n };\n\n const instance = createChart(container, spec.value, mountOpts);\n chart.value = instance;\n layout.value = instance.layout;\n }\n\n function destroy() {\n chart.value?.destroy();\n chart.value = null;\n layout.value = null;\n }\n\n onMounted(() => {\n mount();\n });\n\n onUnmounted(() => {\n destroy();\n });\n\n // Update on spec change\n watch(spec, (newSpec) => {\n const instance = chart.value;\n if (!instance) return;\n instance.update(newSpec);\n layout.value = instance.layout;\n });\n\n return {\n containerRef,\n chart,\n layout,\n };\n}\n","/**\n * useDarkMode: composable that resolves a DarkMode preference to a boolean.\n *\n * - \"force\" -> true\n * - \"off\" -> false\n * - \"auto\" -> matches system preference (reactive to changes)\n */\n\nimport type { DarkMode } from '@opendata-ai/openchart-core';\nimport { onUnmounted, type Ref, ref, watch } from 'vue';\n\n/**\n * Resolve a DarkMode preference to a reactive boolean.\n *\n * For \"auto\" mode, watches the system `prefers-color-scheme` media query\n * and updates reactively when the user changes their OS theme.\n */\nexport function useDarkMode(mode: Ref<DarkMode | undefined>): Ref<boolean> {\n const isDark = ref(resolveInitial(mode.value));\n let cleanup: (() => void) | null = null;\n\n function setup(currentMode: DarkMode | undefined) {\n // Clean up previous listener\n cleanup?.();\n cleanup = null;\n\n if (currentMode !== 'auto') {\n isDark.value = currentMode === 'force';\n return;\n }\n\n if (typeof window === 'undefined' || !window.matchMedia) {\n isDark.value = false;\n return;\n }\n\n const mq = window.matchMedia('(prefers-color-scheme: dark)');\n isDark.value = mq.matches;\n\n const handler = (e: MediaQueryListEvent) => {\n isDark.value = e.matches;\n };\n mq.addEventListener('change', handler);\n cleanup = () => mq.removeEventListener('change', handler);\n }\n\n // Run setup for initial value\n setup(mode.value);\n\n // React to mode changes\n watch(mode, (newMode) => {\n setup(newMode);\n });\n\n onUnmounted(() => {\n cleanup?.();\n cleanup = null;\n });\n\n return isDark;\n}\n\nfunction resolveInitial(mode?: DarkMode): boolean {\n if (mode === 'force') return true;\n if (mode === 'off' || mode === undefined) return false;\n // \"auto\"\n if (typeof window !== 'undefined' && window.matchMedia) {\n return window.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n return false;\n}\n","/**\n * useGraph: composable for imperative graph control.\n *\n * Provides a template ref to pass to <Graph /> and exposes graph methods\n * (search, zoom, select) for programmatic control of the graph instance.\n */\n\nimport type { GraphInstance } from '@opendata-ai/openchart-vanilla';\nimport { type Ref, ref } from 'vue';\n\n/** Handle exposed by Graph component via expose(). */\nexport interface GraphHandle {\n search: (query: string) => void;\n clearSearch: () => void;\n zoomToFit: () => void;\n zoomToNode: (nodeId: string) => void;\n selectNode: (nodeId: string) => void;\n getSelectedNodes: () => string[];\n /** The underlying GraphInstance from the vanilla adapter. */\n instance: GraphInstance | null;\n}\n\nexport interface UseGraphReturn {\n /** Template ref to pass to <Graph ref={graphRef} />. */\n graphRef: Ref<GraphHandle | null>;\n /** Search for nodes matching a query string. */\n search: (query: string) => void;\n /** Clear the current search. */\n clearSearch: () => void;\n /** Zoom to fit all nodes in view. */\n zoomToFit: () => void;\n /** Zoom and center on a specific node. */\n zoomToNode: (nodeId: string) => void;\n /** Select a node by id. */\n selectNode: (nodeId: string) => void;\n /** Get the currently selected node ids. */\n getSelectedNodes: () => string[];\n}\n\n/**\n * Composable for imperative graph control.\n *\n * Usage:\n * ```vue\n * <script setup>\n * const { graphRef, search, zoomToFit } = useGraph();\n * </script>\n * <template>\n * <Graph ref=\"graphRef\" :spec=\"spec\" />\n * </template>\n * ```\n */\nexport function useGraph(): UseGraphReturn {\n const graphRef = ref<GraphHandle | null>(null);\n\n function search(query: string) {\n graphRef.value?.search(query);\n }\n\n function clearSearch() {\n graphRef.value?.clearSearch();\n }\n\n function zoomToFit() {\n graphRef.value?.zoomToFit();\n }\n\n function zoomToNode(nodeId: string) {\n graphRef.value?.zoomToNode(nodeId);\n }\n\n function selectNode(nodeId: string) {\n graphRef.value?.selectNode(nodeId);\n }\n\n function getSelectedNodes(): string[] {\n return graphRef.value?.getSelectedNodes() ?? [];\n }\n\n return {\n graphRef,\n search,\n clearSearch,\n zoomToFit,\n zoomToNode,\n selectNode,\n getSelectedNodes,\n };\n}\n","/**\n * useTable: composable for manual table lifecycle control.\n *\n * Attaches to a container ref, mounts a vanilla table instance,\n * and exposes the instance and current state.\n */\n\nimport type { TableSpec } from '@opendata-ai/openchart-core';\nimport {\n createTable,\n type TableInstance,\n type TableMountOptions,\n type TableState,\n} from '@opendata-ai/openchart-vanilla';\nimport { onMounted, onUnmounted, type Ref, ref, type ShallowRef, shallowRef, watch } from 'vue';\n\nexport interface UseTableReturn {\n /** Template ref to attach to the container div. */\n containerRef: Ref<HTMLDivElement | null>;\n /** The table instance (null until mounted). */\n table: ShallowRef<TableInstance | null>;\n /** The current table state (sort, search, page). */\n state: Ref<TableState>;\n}\n\n/**\n * Composable for manual table lifecycle control.\n *\n * Attach the returned containerRef to a container div via `ref=\"containerRef\"`.\n * The table mounts automatically and updates when the spec changes.\n */\nexport function useTable(spec: Ref<TableSpec>, options?: TableMountOptions): UseTableReturn {\n const containerRef = ref<HTMLDivElement | null>(null);\n const table = shallowRef<TableInstance | null>(null);\n const state = ref<TableState>({\n sort: null,\n search: '',\n page: 0,\n });\n\n const originalOnStateChange = options?.onStateChange;\n\n function handleStateChange(newState: TableState) {\n state.value = newState;\n originalOnStateChange?.(newState);\n }\n\n function mount() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOpts: TableMountOptions = {\n ...options,\n onStateChange: handleStateChange,\n };\n\n const instance = createTable(container, spec.value, mountOpts);\n table.value = instance;\n state.value = instance.getState();\n }\n\n function destroy() {\n table.value?.destroy();\n table.value = null;\n }\n\n onMounted(() => {\n mount();\n });\n\n onUnmounted(() => {\n destroy();\n });\n\n // Update on spec change\n watch(spec, (newSpec) => {\n const instance = table.value;\n if (!instance) return;\n instance.update(newSpec);\n state.value = instance.getState();\n });\n\n return {\n containerRef,\n table,\n state,\n };\n}\n","/**\n * useTableState: managed state composable for controlled table usage.\n *\n * Provides individual sort/search/page state with setters and a\n * resetState function to return to initial values.\n */\n\nimport type { SortState } from '@opendata-ai/openchart-core';\nimport { type Ref, ref } from 'vue';\n\nexport interface UseTableStateReturn {\n sort: Ref<SortState | null>;\n setSort: (sort: SortState | null) => void;\n search: Ref<string>;\n setSearch: (query: string) => void;\n page: Ref<number>;\n setPage: (page: number) => void;\n resetState: () => void;\n}\n\nexport interface UseTableStateOptions {\n sort?: SortState | null;\n search?: string;\n page?: number;\n}\n\n/**\n * Composable for managing table state (sort, search, page).\n *\n * Use with the DataTable component's controlled props:\n * ```vue\n * <script setup>\n * const { sort, search, page, setSort, setSearch, setPage } = useTableState();\n * </script>\n * <template>\n * <DataTable\n * :spec=\"spec\"\n * :sort=\"sort\"\n * :search=\"search\"\n * :page=\"page\"\n * @update:sort=\"setSort\"\n * @update:search=\"setSearch\"\n * @update:page=\"setPage\"\n * />\n * </template>\n * ```\n */\nexport function useTableState(initialState?: UseTableStateOptions): UseTableStateReturn {\n const sort = ref<SortState | null>(initialState?.sort ?? null);\n const search = ref(initialState?.search ?? '');\n const page = ref(initialState?.page ?? 0);\n\n function setSort(newSort: SortState | null) {\n sort.value = newSort;\n }\n\n function setSearch(query: string) {\n search.value = query;\n }\n\n function setPage(newPage: number) {\n page.value = newPage;\n }\n\n function resetState() {\n sort.value = initialState?.sort ?? null;\n search.value = initialState?.search ?? '';\n page.value = initialState?.page ?? 0;\n }\n\n return {\n sort,\n setSort,\n search,\n setSearch,\n page,\n setPage,\n resetState,\n };\n}\n","/**\n * DataTable component: Vue wrapper around the vanilla table adapter.\n *\n * Mounts a table instance on render, updates when spec changes,\n * and cleans up on unmount. Supports both controlled and uncontrolled modes\n * for sort, search, and pagination state.\n */\n\nimport type { DarkMode, SortState, TableSpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createTable,\n type TableInstance,\n type TableMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface DataTableProps {\n spec: TableSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n sort?: SortState | null;\n search?: string;\n page?: number;\n}\n\nexport const DataTable = defineComponent({\n name: 'DataTable',\n props: {\n spec: {\n type: Object as PropType<TableSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n sort: {\n type: [Object, null] as PropType<SortState | null>,\n default: undefined,\n },\n search: {\n type: String,\n default: undefined,\n },\n page: {\n type: Number,\n default: undefined,\n },\n },\n emits: {\n 'row-click': (_row: Record<string, unknown>) => true,\n 'update:sort': (_sort: SortState | null) => true,\n 'update:search': (_query: string) => true,\n 'update:page': (_page: number) => true,\n },\n setup(props, { emit }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: TableInstance | null = null;\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function isControlled(): boolean {\n return props.sort !== undefined || props.search !== undefined || props.page !== undefined;\n }\n\n let prevSpec = '';\n\n function mountTable() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOptions: TableMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onRowClick: (row: Record<string, unknown>) => emit('row-click', row),\n responsive: true,\n onStateChange: (state) => {\n if (state.sort !== undefined) emit('update:sort', state.sort);\n if (state.search !== undefined) emit('update:search', state.search);\n if (state.page !== undefined) emit('update:page', state.page);\n },\n };\n\n if (isControlled()) {\n mountOptions.externalState = {\n sort: props.sort ?? null,\n search: props.search ?? '',\n page: props.page ?? 0,\n };\n }\n\n instance = createTable(container, props.spec, mountOptions);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyTable() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n onMounted(() => {\n mountTable();\n });\n\n onUnmounted(() => {\n destroyTable();\n });\n\n // Watch spec changes via JSON.stringify comparison (consistent with Chart/Graph)\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyTable();\n mountTable();\n },\n );\n\n // Sync controlled state without remounting\n watch([() => props.sort, () => props.search, () => props.page], () => {\n if (!instance || !isControlled()) return;\n instance.setState({\n sort: props.sort ?? null,\n search: props.search ?? '',\n page: props.page ?? 0,\n });\n });\n\n const rootClass = () => {\n const base = 'oc-table-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Vue Graph component: thin wrapper around the vanilla adapter.\n *\n * Mounts a graph instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createGraph() function.\n *\n * Exposes imperative methods via defineExpose for use with useGraph().\n */\n\nimport type { DarkMode, GraphSpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createGraph,\n type GraphInstance,\n type GraphMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface GraphProps {\n spec: GraphSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Graph = defineComponent({\n name: 'Graph',\n props: {\n spec: {\n type: Object as PropType<GraphSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'node-click': (_node: Record<string, unknown>) => true,\n 'node-double-click': (_node: Record<string, unknown>) => true,\n 'selection-change': (_nodeIds: string[]) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: GraphInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountGraph() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: GraphMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onNodeClick: (node: Record<string, unknown>) => emit('node-click', node),\n onNodeDoubleClick: (node: Record<string, unknown>) => emit('node-double-click', node),\n onSelectionChange: (nodeIds: string[]) => emit('selection-change', nodeIds),\n responsive: true,\n };\n\n instance = createGraph(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyGraph() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative methods for useGraph() composable\n expose({\n search(query: string) {\n instance?.search(query);\n },\n clearSearch() {\n instance?.clearSearch();\n },\n zoomToFit() {\n instance?.zoomToFit();\n },\n zoomToNode(nodeId: string) {\n instance?.zoomToNode(nodeId);\n },\n selectNode(nodeId: string) {\n instance?.selectNode(nodeId);\n },\n getSelectedNodes(): string[] {\n return instance?.getSelectedNodes() ?? [];\n },\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountGraph();\n });\n\n onUnmounted(() => {\n destroyGraph();\n });\n\n // Watch spec changes\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate graph when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyGraph();\n mountGraph();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-graph-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * VizThemeProvider: provides a theme and dark mode preference to all\n * descendant Chart, DataTable, and Graph components without prop drilling.\n *\n * Components use the context values as fallbacks when no explicit\n * `theme` or `darkMode` prop is passed.\n */\n\nimport type { DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';\nimport { computed, defineComponent, type PropType, provide } from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface VizThemeProviderProps {\n theme: ThemeConfig | undefined;\n darkMode?: DarkMode;\n}\n\nexport const VizThemeProvider = defineComponent({\n name: 'VizThemeProvider',\n props: {\n theme: {\n type: Object as PropType<ThemeConfig | undefined>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n },\n setup(props, { slots }) {\n // Wrap in computed() so changes to props propagate reactively\n // through the injection system.\n const themeRef = computed(() => props.theme);\n const darkModeRef = computed(() => props.darkMode);\n\n provide(VizThemeKey, themeRef);\n provide(VizDarkModeKey, darkModeRef);\n\n return () => slots.default?.();\n },\n});\n","/**\n * Visualization routing component: renders Chart, DataTable, or Graph\n * based on the spec type. Use this when rendering arbitrary VizSpec values.\n *\n * For event handlers, use the specific component (Chart, DataTable, Graph) directly.\n */\n\nimport type { DarkMode, ThemeConfig, VizSpec } from '@opendata-ai/openchart-core';\nimport { isGraphSpec, isTableSpec } from '@opendata-ai/openchart-core';\nimport { type CSSProperties, defineComponent, h, type PropType } from 'vue';\nimport { Chart } from './Chart';\nimport { DataTable } from './DataTable';\nimport { Graph } from './Graph';\n\nexport interface VisualizationProps {\n spec: VizSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Visualization = defineComponent({\n name: 'Visualization',\n props: {\n spec: {\n type: Object as PropType<VizSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n setup(props) {\n return () => {\n const { spec, theme, darkMode, class: className, style } = props;\n const sharedProps = { theme, darkMode, class: className, style };\n\n if (isTableSpec(spec)) {\n return h(DataTable, { ...sharedProps, spec });\n }\n if (isGraphSpec(spec)) {\n return h(Graph, { ...sharedProps, spec });\n }\n return h(Chart, { ...sharedProps, spec });\n };\n },\n});\n"],"mappings":"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","names":["inject","inject","createChart","onMounted","onUnmounted","ref","watch","onUnmounted","ref","watch","ref","onMounted","onUnmounted","ref","shallowRef","watch","ref","createTable","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","createTable","onMounted","onUnmounted","watch","h","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","computed","defineComponent","defineComponent","computed","defineComponent","h","defineComponent","h"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/Chart.ts","../src/context.ts","../src/composables/useChart.ts","../src/composables/useDarkMode.ts","../src/composables/useGraph.ts","../src/composables/useTable.ts","../src/composables/useTableState.ts","../src/DataTable.ts","../src/Graph.ts","../src/Sankey.ts","../src/ThemeProvider.ts","../src/Visualization.ts"],"sourcesContent":["/**\n * @opendata-ai/openchart-vue\n *\n * Vue 3 adapter for openchart. Provides <Chart />, <DataTable />, <Graph />,\n * and <VizThemeProvider /> components that wrap the vanilla adapter with\n * Vue lifecycle management.\n *\n * Re-exports the full core type system and utilities so Vue consumers\n * only need a single @opendata-ai/openchart-vue dependency.\n */\n\n// ---------------------------------------------------------------------------\n// Core: full type system, theme, colors, locale, accessibility, helpers\n// ---------------------------------------------------------------------------\n\nexport * from '@opendata-ai/openchart-core';\n\n// ---------------------------------------------------------------------------\n// Vanilla: export utilities (SVG/PNG/JPG/CSV)\n// ---------------------------------------------------------------------------\n\nexport type { JPGExportOptions, PNGExportOptions } from '@opendata-ai/openchart-vanilla';\nexport { exportCSV, exportJPG, exportPNG, exportSVG } from '@opendata-ai/openchart-vanilla';\n\n// ---------------------------------------------------------------------------\n// Engine: compile API and types not covered by core\n// ---------------------------------------------------------------------------\n\nexport type {\n ChartRenderer,\n CompiledGraphEdge,\n CompiledGraphNode,\n CompileResult,\n GraphCompilation,\n NormalizedChartSpec,\n NormalizedChrome,\n NormalizedGraphSpec,\n NormalizedSankeySpec,\n NormalizedSpec,\n NormalizedTableSpec,\n SimulationConfig,\n ValidationError,\n ValidationErrorCode,\n ValidationResult,\n} from '@opendata-ai/openchart-engine';\nexport {\n clearRenderers,\n compile,\n compileChart,\n compileGraph,\n compileSankey,\n compileTable,\n getChartRenderer,\n normalizeSpec,\n registerChartRenderer,\n validateSpec,\n} from '@opendata-ai/openchart-engine';\n\n// Components\nexport type { ChartProps } from './Chart';\nexport { Chart } from './Chart';\n// Composables\nexport type { UseChartOptions, UseChartReturn } from './composables/useChart';\nexport { useChart } from './composables/useChart';\nexport { useDarkMode } from './composables/useDarkMode';\nexport type { GraphHandle, UseGraphReturn } from './composables/useGraph';\nexport { useGraph } from './composables/useGraph';\nexport type { UseTableReturn } from './composables/useTable';\nexport { useTable } from './composables/useTable';\nexport type { UseTableStateOptions, UseTableStateReturn } from './composables/useTableState';\nexport { useTableState } from './composables/useTableState';\n// Context (injection keys and composables)\nexport { useVizDarkMode, useVizTheme, VizDarkModeKey, VizThemeKey } from './context';\nexport type { DataTableProps } from './DataTable';\nexport { DataTable } from './DataTable';\nexport type { GraphProps } from './Graph';\nexport { Graph } from './Graph';\nexport type { SankeyProps } from './Sankey';\nexport { Sankey } from './Sankey';\nexport type { VizThemeProviderProps } from './ThemeProvider';\nexport { VizThemeProvider } from './ThemeProvider';\nexport type { VisualizationProps } from './Visualization';\nexport { Visualization } from './Visualization';\n","/**\n * Vue Chart component: thin wrapper around the vanilla adapter.\n *\n * Mounts a chart instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createChart() function.\n */\n\nimport type {\n Annotation,\n AnnotationOffset,\n ChartSpec,\n DarkMode,\n ElementEdit,\n ElementRef,\n GraphSpec,\n LayerSpec,\n MarkEvent,\n TextAnnotation,\n ThemeConfig,\n} from '@opendata-ai/openchart-core';\nimport { type ChartInstance, createChart, type MountOptions } from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n getCurrentInstance,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface ChartProps {\n spec: ChartSpec | LayerSpec | GraphSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Chart = defineComponent({\n name: 'Chart',\n props: {\n spec: {\n type: Object as PropType<ChartSpec | LayerSpec | GraphSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n selectedElement: {\n type: Object as PropType<ElementRef>,\n default: undefined,\n },\n },\n emits: {\n 'mark-click': (_event: MarkEvent) => true,\n 'mark-hover': (_event: MarkEvent) => true,\n 'mark-leave': () => true,\n 'legend-toggle': (_series: string, _visible: boolean) => true,\n 'annotation-click': (_annotation: Annotation, _event: MouseEvent) => true,\n 'annotation-edit': (_annotation: TextAnnotation, _updatedOffset: AnnotationOffset) => true,\n edit: (_edit: ElementEdit) => true,\n select: (_element: ElementRef) => true,\n deselect: (_element: ElementRef) => true,\n 'text-edit': (_element: ElementRef, _oldText: string, _newText: string) => true,\n 'data-point-click': (_data: Record<string, unknown>) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: ChartInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n // Check which event listeners are bound by the parent.\n // Vue 3 passes listeners as onXxx props on the component vnode.\n // We cache this at setup time since it won't change.\n const vm = getCurrentInstance();\n const vnodeProps = vm?.vnode.props ?? {};\n const hasAnnotationEditListener =\n 'onAnnotation-edit' in vnodeProps || 'onAnnotationEdit' in vnodeProps;\n const hasEditListener = 'onEdit' in vnodeProps;\n const hasSelectListener = 'onSelect' in vnodeProps;\n const hasDeselectListener = 'onDeselect' in vnodeProps;\n const hasTextEditListener = 'onText-edit' in vnodeProps || 'onTextEdit' in vnodeProps;\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountChart() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: MountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onDataPointClick: (data: Record<string, unknown>) => emit('data-point-click', data),\n onMarkClick: (event: MarkEvent) => emit('mark-click', event),\n onMarkHover: (event: MarkEvent) => emit('mark-hover', event),\n onMarkLeave: () => emit('mark-leave'),\n onLegendToggle: (series: string, visible: boolean) =>\n emit('legend-toggle', series, visible),\n onAnnotationClick: (annotation: Annotation, event: MouseEvent) =>\n emit('annotation-click', annotation, event),\n // Only include editing callbacks when the parent binds a listener.\n // Without this gate, every chart gets drag editing wired up.\n ...(hasAnnotationEditListener\n ? {\n onAnnotationEdit: (annotation: TextAnnotation, updatedOffset: AnnotationOffset) =>\n emit('annotation-edit', annotation, updatedOffset),\n }\n : {}),\n ...(hasEditListener ? { onEdit: (edit: ElementEdit) => emit('edit', edit) } : {}),\n ...(hasSelectListener\n ? { onSelect: (element: ElementRef) => emit('select', element) }\n : {}),\n ...(hasDeselectListener\n ? { onDeselect: (element: ElementRef) => emit('deselect', element) }\n : {}),\n ...(hasTextEditListener\n ? {\n onTextEdit: (element: ElementRef, oldText: string, newText: string) =>\n emit('text-edit', element, oldText, newText),\n }\n : {}),\n ...(props.selectedElement ? { selectedElement: props.selectedElement } : {}),\n responsive: true,\n };\n\n instance = createChart(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyChart() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative methods for parent ref access\n expose({\n getSelectedElement(): ElementRef | null {\n return instance?.getSelectedElement() ?? null;\n },\n select(elementRef: ElementRef): void {\n instance?.select(elementRef);\n },\n deselect(): void {\n instance?.deselect();\n },\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountChart();\n });\n\n onUnmounted(() => {\n destroyChart();\n });\n\n // Watch spec changes: update if only spec changed, recreate if theme/darkMode changed\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec, { selectedElement: props.selectedElement });\n }\n },\n );\n\n // Watch selectedElement prop changes\n watch(\n () => props.selectedElement,\n (newVal) => {\n if (!instance) return;\n if (newVal) {\n instance.select(newVal);\n } else {\n instance.deselect();\n }\n },\n );\n\n // Recreate chart when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyChart();\n mountChart();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-chart-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Theme injection context for Vue.\n *\n * Provides typed injection keys and composables for accessing theme\n * and dark mode from any descendant component within a VizThemeProvider.\n */\n\nimport type { DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';\nimport { type ComputedRef, computed, type InjectionKey, inject, type Ref } from 'vue';\n\n/** Injection key for the theme config ref. */\nexport const VizThemeKey: InjectionKey<Ref<ThemeConfig | undefined>> = Symbol('VizTheme');\n\n/** Injection key for the dark mode ref. */\nexport const VizDarkModeKey: InjectionKey<Ref<DarkMode | undefined>> = Symbol('VizDarkMode');\n\n/**\n * Read the current theme from the nearest VizThemeProvider.\n * Returns a computed ref that stays reactive to provider changes.\n */\nexport function useVizTheme(): ComputedRef<ThemeConfig | undefined> {\n const theme = inject(VizThemeKey, undefined);\n return computed(() => theme?.value);\n}\n\n/**\n * Read the current dark mode preference from the nearest VizThemeProvider.\n * Returns a computed ref that stays reactive to provider changes.\n */\nexport function useVizDarkMode(): ComputedRef<DarkMode | undefined> {\n const darkMode = inject(VizDarkModeKey, undefined);\n return computed(() => darkMode?.value);\n}\n","/**\n * useChart: composable for manual chart lifecycle control.\n *\n * Provides a template ref to attach to a container div. The chart\n * mounts automatically and updates when the spec changes.\n */\n\nimport type {\n ChartLayout,\n ChartSpec,\n DarkMode,\n GraphSpec,\n LayerSpec,\n ThemeConfig,\n} from '@opendata-ai/openchart-core';\nimport { type ChartInstance, createChart, type MountOptions } from '@opendata-ai/openchart-vanilla';\nimport { onMounted, onUnmounted, type Ref, ref, type ShallowRef, shallowRef, watch } from 'vue';\n\nexport interface UseChartOptions {\n /** Theme overrides. */\n theme?: ThemeConfig;\n /** Dark mode setting. */\n darkMode?: DarkMode;\n /** Data point click handler. */\n onDataPointClick?: MountOptions['onDataPointClick'];\n /** Enable responsive resizing. Defaults to true. */\n responsive?: boolean;\n}\n\nexport interface UseChartReturn {\n /** Template ref to attach to the container div. */\n containerRef: Ref<HTMLDivElement | null>;\n /** The chart instance (null until mounted). */\n chart: ShallowRef<ChartInstance | null>;\n /** The current compiled layout (null until mounted). */\n layout: ShallowRef<ChartLayout | null>;\n}\n\n/**\n * Composable for manual chart lifecycle control.\n *\n * Attach the returned containerRef to a container div via `ref=\"containerRef\"`.\n * The chart mounts automatically and updates when the spec changes.\n */\nexport function useChart(\n spec: Ref<ChartSpec | LayerSpec | GraphSpec>,\n options?: UseChartOptions,\n): UseChartReturn {\n const containerRef = ref<HTMLDivElement | null>(null);\n const chart = shallowRef<ChartInstance | null>(null);\n const layout = shallowRef<ChartLayout | null>(null);\n\n function mount() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOpts: MountOptions = {\n theme: options?.theme,\n darkMode: options?.darkMode,\n onDataPointClick: options?.onDataPointClick,\n responsive: options?.responsive,\n };\n\n const instance = createChart(container, spec.value, mountOpts);\n chart.value = instance;\n layout.value = instance.layout;\n }\n\n function destroy() {\n chart.value?.destroy();\n chart.value = null;\n layout.value = null;\n }\n\n onMounted(() => {\n mount();\n });\n\n onUnmounted(() => {\n destroy();\n });\n\n // Update on spec change\n watch(spec, (newSpec) => {\n const instance = chart.value;\n if (!instance) return;\n instance.update(newSpec);\n layout.value = instance.layout;\n });\n\n return {\n containerRef,\n chart,\n layout,\n };\n}\n","/**\n * useDarkMode: composable that resolves a DarkMode preference to a boolean.\n *\n * - \"force\" -> true\n * - \"off\" -> false\n * - \"auto\" -> matches system preference (reactive to changes)\n */\n\nimport type { DarkMode } from '@opendata-ai/openchart-core';\nimport { onUnmounted, type Ref, ref, watch } from 'vue';\n\n/**\n * Resolve a DarkMode preference to a reactive boolean.\n *\n * For \"auto\" mode, watches the system `prefers-color-scheme` media query\n * and updates reactively when the user changes their OS theme.\n */\nexport function useDarkMode(mode: Ref<DarkMode | undefined>): Ref<boolean> {\n const isDark = ref(resolveInitial(mode.value));\n let cleanup: (() => void) | null = null;\n\n function setup(currentMode: DarkMode | undefined) {\n // Clean up previous listener\n cleanup?.();\n cleanup = null;\n\n if (currentMode !== 'auto') {\n isDark.value = currentMode === 'force';\n return;\n }\n\n if (typeof window === 'undefined' || !window.matchMedia) {\n isDark.value = false;\n return;\n }\n\n const mq = window.matchMedia('(prefers-color-scheme: dark)');\n isDark.value = mq.matches;\n\n const handler = (e: MediaQueryListEvent) => {\n isDark.value = e.matches;\n };\n mq.addEventListener('change', handler);\n cleanup = () => mq.removeEventListener('change', handler);\n }\n\n // Run setup for initial value\n setup(mode.value);\n\n // React to mode changes\n watch(mode, (newMode) => {\n setup(newMode);\n });\n\n onUnmounted(() => {\n cleanup?.();\n cleanup = null;\n });\n\n return isDark;\n}\n\nfunction resolveInitial(mode?: DarkMode): boolean {\n if (mode === 'force') return true;\n if (mode === 'off' || mode === undefined) return false;\n // \"auto\"\n if (typeof window !== 'undefined' && window.matchMedia) {\n return window.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n return false;\n}\n","/**\n * useGraph: composable for imperative graph control.\n *\n * Provides a template ref to pass to <Graph /> and exposes graph methods\n * (search, zoom, select) for programmatic control of the graph instance.\n */\n\nimport type { GraphInstance } from '@opendata-ai/openchart-vanilla';\nimport { type Ref, ref } from 'vue';\n\n/** Handle exposed by Graph component via expose(). */\nexport interface GraphHandle {\n search: (query: string) => void;\n clearSearch: () => void;\n zoomToFit: () => void;\n zoomToNode: (nodeId: string) => void;\n selectNode: (nodeId: string) => void;\n getSelectedNodes: () => string[];\n /** The underlying GraphInstance from the vanilla adapter. */\n instance: GraphInstance | null;\n}\n\nexport interface UseGraphReturn {\n /** Template ref to pass to <Graph ref={graphRef} />. */\n graphRef: Ref<GraphHandle | null>;\n /** Search for nodes matching a query string. */\n search: (query: string) => void;\n /** Clear the current search. */\n clearSearch: () => void;\n /** Zoom to fit all nodes in view. */\n zoomToFit: () => void;\n /** Zoom and center on a specific node. */\n zoomToNode: (nodeId: string) => void;\n /** Select a node by id. */\n selectNode: (nodeId: string) => void;\n /** Get the currently selected node ids. */\n getSelectedNodes: () => string[];\n}\n\n/**\n * Composable for imperative graph control.\n *\n * Usage:\n * ```vue\n * <script setup>\n * const { graphRef, search, zoomToFit } = useGraph();\n * </script>\n * <template>\n * <Graph ref=\"graphRef\" :spec=\"spec\" />\n * </template>\n * ```\n */\nexport function useGraph(): UseGraphReturn {\n const graphRef = ref<GraphHandle | null>(null);\n\n function search(query: string) {\n graphRef.value?.search(query);\n }\n\n function clearSearch() {\n graphRef.value?.clearSearch();\n }\n\n function zoomToFit() {\n graphRef.value?.zoomToFit();\n }\n\n function zoomToNode(nodeId: string) {\n graphRef.value?.zoomToNode(nodeId);\n }\n\n function selectNode(nodeId: string) {\n graphRef.value?.selectNode(nodeId);\n }\n\n function getSelectedNodes(): string[] {\n return graphRef.value?.getSelectedNodes() ?? [];\n }\n\n return {\n graphRef,\n search,\n clearSearch,\n zoomToFit,\n zoomToNode,\n selectNode,\n getSelectedNodes,\n };\n}\n","/**\n * useTable: composable for manual table lifecycle control.\n *\n * Attaches to a container ref, mounts a vanilla table instance,\n * and exposes the instance and current state.\n */\n\nimport type { TableSpec } from '@opendata-ai/openchart-core';\nimport {\n createTable,\n type TableInstance,\n type TableMountOptions,\n type TableState,\n} from '@opendata-ai/openchart-vanilla';\nimport { onMounted, onUnmounted, type Ref, ref, type ShallowRef, shallowRef, watch } from 'vue';\n\nexport interface UseTableReturn {\n /** Template ref to attach to the container div. */\n containerRef: Ref<HTMLDivElement | null>;\n /** The table instance (null until mounted). */\n table: ShallowRef<TableInstance | null>;\n /** The current table state (sort, search, page). */\n state: Ref<TableState>;\n}\n\n/**\n * Composable for manual table lifecycle control.\n *\n * Attach the returned containerRef to a container div via `ref=\"containerRef\"`.\n * The table mounts automatically and updates when the spec changes.\n */\nexport function useTable(spec: Ref<TableSpec>, options?: TableMountOptions): UseTableReturn {\n const containerRef = ref<HTMLDivElement | null>(null);\n const table = shallowRef<TableInstance | null>(null);\n const state = ref<TableState>({\n sort: null,\n search: '',\n page: 0,\n });\n\n const originalOnStateChange = options?.onStateChange;\n\n function handleStateChange(newState: TableState) {\n state.value = newState;\n originalOnStateChange?.(newState);\n }\n\n function mount() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOpts: TableMountOptions = {\n ...options,\n onStateChange: handleStateChange,\n };\n\n const instance = createTable(container, spec.value, mountOpts);\n table.value = instance;\n state.value = instance.getState();\n }\n\n function destroy() {\n table.value?.destroy();\n table.value = null;\n }\n\n onMounted(() => {\n mount();\n });\n\n onUnmounted(() => {\n destroy();\n });\n\n // Update on spec change\n watch(spec, (newSpec) => {\n const instance = table.value;\n if (!instance) return;\n instance.update(newSpec);\n state.value = instance.getState();\n });\n\n return {\n containerRef,\n table,\n state,\n };\n}\n","/**\n * useTableState: managed state composable for controlled table usage.\n *\n * Provides individual sort/search/page state with setters and a\n * resetState function to return to initial values.\n */\n\nimport type { SortState } from '@opendata-ai/openchart-core';\nimport { type Ref, ref } from 'vue';\n\nexport interface UseTableStateReturn {\n sort: Ref<SortState | null>;\n setSort: (sort: SortState | null) => void;\n search: Ref<string>;\n setSearch: (query: string) => void;\n page: Ref<number>;\n setPage: (page: number) => void;\n resetState: () => void;\n}\n\nexport interface UseTableStateOptions {\n sort?: SortState | null;\n search?: string;\n page?: number;\n}\n\n/**\n * Composable for managing table state (sort, search, page).\n *\n * Use with the DataTable component's controlled props:\n * ```vue\n * <script setup>\n * const { sort, search, page, setSort, setSearch, setPage } = useTableState();\n * </script>\n * <template>\n * <DataTable\n * :spec=\"spec\"\n * :sort=\"sort\"\n * :search=\"search\"\n * :page=\"page\"\n * @update:sort=\"setSort\"\n * @update:search=\"setSearch\"\n * @update:page=\"setPage\"\n * />\n * </template>\n * ```\n */\nexport function useTableState(initialState?: UseTableStateOptions): UseTableStateReturn {\n const sort = ref<SortState | null>(initialState?.sort ?? null);\n const search = ref(initialState?.search ?? '');\n const page = ref(initialState?.page ?? 0);\n\n function setSort(newSort: SortState | null) {\n sort.value = newSort;\n }\n\n function setSearch(query: string) {\n search.value = query;\n }\n\n function setPage(newPage: number) {\n page.value = newPage;\n }\n\n function resetState() {\n sort.value = initialState?.sort ?? null;\n search.value = initialState?.search ?? '';\n page.value = initialState?.page ?? 0;\n }\n\n return {\n sort,\n setSort,\n search,\n setSearch,\n page,\n setPage,\n resetState,\n };\n}\n","/**\n * DataTable component: Vue wrapper around the vanilla table adapter.\n *\n * Mounts a table instance on render, updates when spec changes,\n * and cleans up on unmount. Supports both controlled and uncontrolled modes\n * for sort, search, and pagination state.\n */\n\nimport type { DarkMode, SortState, TableSpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createTable,\n type TableInstance,\n type TableMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface DataTableProps {\n spec: TableSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n sort?: SortState | null;\n search?: string;\n page?: number;\n}\n\nexport const DataTable = defineComponent({\n name: 'DataTable',\n props: {\n spec: {\n type: Object as PropType<TableSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n sort: {\n type: [Object, null] as PropType<SortState | null>,\n default: undefined,\n },\n search: {\n type: String,\n default: undefined,\n },\n page: {\n type: Number,\n default: undefined,\n },\n },\n emits: {\n 'row-click': (_row: Record<string, unknown>) => true,\n 'update:sort': (_sort: SortState | null) => true,\n 'update:search': (_query: string) => true,\n 'update:page': (_page: number) => true,\n },\n setup(props, { emit }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: TableInstance | null = null;\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function isControlled(): boolean {\n return props.sort !== undefined || props.search !== undefined || props.page !== undefined;\n }\n\n let prevSpec = '';\n\n function mountTable() {\n const container = containerRef.value;\n if (!container) return;\n\n const mountOptions: TableMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onRowClick: (row: Record<string, unknown>) => emit('row-click', row),\n responsive: true,\n onStateChange: (state) => {\n if (state.sort !== undefined) emit('update:sort', state.sort);\n if (state.search !== undefined) emit('update:search', state.search);\n if (state.page !== undefined) emit('update:page', state.page);\n },\n };\n\n if (isControlled()) {\n mountOptions.externalState = {\n sort: props.sort ?? null,\n search: props.search ?? '',\n page: props.page ?? 0,\n };\n }\n\n instance = createTable(container, props.spec, mountOptions);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyTable() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n onMounted(() => {\n mountTable();\n });\n\n onUnmounted(() => {\n destroyTable();\n });\n\n // Watch spec changes via JSON.stringify comparison (consistent with Chart/Graph)\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyTable();\n mountTable();\n },\n );\n\n // Sync controlled state without remounting\n watch([() => props.sort, () => props.search, () => props.page], () => {\n if (!instance || !isControlled()) return;\n instance.setState({\n sort: props.sort ?? null,\n search: props.search ?? '',\n page: props.page ?? 0,\n });\n });\n\n const rootClass = () => {\n const base = 'oc-table-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Vue Graph component: thin wrapper around the vanilla adapter.\n *\n * Mounts a graph instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createGraph() function.\n *\n * Exposes imperative methods via defineExpose for use with useGraph().\n */\n\nimport type { DarkMode, GraphSpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createGraph,\n type GraphInstance,\n type GraphMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface GraphProps {\n spec: GraphSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Graph = defineComponent({\n name: 'Graph',\n props: {\n spec: {\n type: Object as PropType<GraphSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'node-click': (_node: Record<string, unknown>) => true,\n 'node-double-click': (_node: Record<string, unknown>) => true,\n 'selection-change': (_nodeIds: string[]) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: GraphInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountGraph() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: GraphMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onNodeClick: (node: Record<string, unknown>) => emit('node-click', node),\n onNodeDoubleClick: (node: Record<string, unknown>) => emit('node-double-click', node),\n onSelectionChange: (nodeIds: string[]) => emit('selection-change', nodeIds),\n responsive: true,\n };\n\n instance = createGraph(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroyGraph() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative methods for useGraph() composable\n expose({\n search(query: string) {\n instance?.search(query);\n },\n clearSearch() {\n instance?.clearSearch();\n },\n zoomToFit() {\n instance?.zoomToFit();\n },\n zoomToNode(nodeId: string) {\n instance?.zoomToNode(nodeId);\n },\n selectNode(nodeId: string) {\n instance?.selectNode(nodeId);\n },\n getSelectedNodes(): string[] {\n return instance?.getSelectedNodes() ?? [];\n },\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountGraph();\n });\n\n onUnmounted(() => {\n destroyGraph();\n });\n\n // Watch spec changes\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate graph when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroyGraph();\n mountGraph();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-graph-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * Vue Sankey component: thin wrapper around the vanilla adapter.\n *\n * Mounts a sankey instance on render, updates when spec changes,\n * and cleans up on unmount. All heavy lifting is done by the vanilla\n * createSankey() function.\n */\n\nimport type { DarkMode, SankeySpec, ThemeConfig } from '@opendata-ai/openchart-core';\nimport {\n createSankey,\n type SankeyInstance,\n type SankeyMountOptions,\n} from '@opendata-ai/openchart-vanilla';\nimport {\n type CSSProperties,\n defineComponent,\n h,\n inject,\n onMounted,\n onUnmounted,\n type PropType,\n ref,\n watch,\n} from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface SankeyProps {\n spec: SankeySpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Sankey = defineComponent({\n name: 'Sankey',\n props: {\n spec: {\n type: Object as PropType<SankeySpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n emits: {\n 'node-click': (_node: Record<string, unknown>) => true,\n 'link-click': (_link: Record<string, unknown>) => true,\n 'node-hover': (_node: Record<string, unknown> | null) => true,\n 'link-hover': (_link: Record<string, unknown> | null) => true,\n },\n setup(props, { emit, expose }) {\n const containerRef = ref<HTMLDivElement | null>(null);\n let instance: SankeyInstance | null = null;\n let prevSpec = '';\n\n // Inject theme/darkMode from provider as fallbacks\n const contextTheme = inject(VizThemeKey, undefined);\n const contextDarkMode = inject(VizDarkModeKey, undefined);\n\n function resolveTheme(): ThemeConfig | undefined {\n return props.theme ?? contextTheme?.value;\n }\n\n function resolveDarkMode(): DarkMode | undefined {\n return props.darkMode ?? contextDarkMode?.value;\n }\n\n function mountSankey() {\n const container = containerRef.value;\n if (!container) return;\n\n const options: SankeyMountOptions = {\n theme: resolveTheme(),\n darkMode: resolveDarkMode(),\n onNodeClick: (node: Record<string, unknown>) => emit('node-click', node),\n onLinkClick: (link: Record<string, unknown>) => emit('link-click', link),\n onNodeHover: (node: Record<string, unknown> | null) => emit('node-hover', node),\n onLinkHover: (link: Record<string, unknown> | null) => emit('link-hover', link),\n responsive: true,\n };\n\n instance = createSankey(container, props.spec, options);\n prevSpec = JSON.stringify(props.spec);\n }\n\n function destroySankey() {\n instance?.destroy();\n instance = null;\n prevSpec = '';\n }\n\n // Expose imperative access to the instance\n expose({\n get instance() {\n return instance;\n },\n });\n\n onMounted(() => {\n mountSankey();\n });\n\n onUnmounted(() => {\n destroySankey();\n });\n\n // Watch spec changes\n watch(\n () => JSON.stringify(props.spec),\n (newVal) => {\n if (!instance) return;\n if (newVal !== prevSpec) {\n prevSpec = newVal;\n instance.update(props.spec);\n }\n },\n );\n\n // Recreate sankey when theme or darkMode change\n watch(\n [\n () => props.theme,\n () => props.darkMode,\n () => contextTheme?.value,\n () => contextDarkMode?.value,\n ],\n () => {\n if (!containerRef.value) return;\n destroySankey();\n mountSankey();\n },\n );\n\n const rootClass = () => {\n const base = 'oc-sankey-root';\n return props.class ? `${base} ${props.class}` : base;\n };\n\n return () =>\n h('div', {\n ref: containerRef,\n class: rootClass(),\n style: props.style,\n });\n },\n});\n","/**\n * VizThemeProvider: provides a theme and dark mode preference to all\n * descendant Chart, DataTable, and Graph components without prop drilling.\n *\n * Components use the context values as fallbacks when no explicit\n * `theme` or `darkMode` prop is passed.\n */\n\nimport type { DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';\nimport { computed, defineComponent, type PropType, provide } from 'vue';\nimport { VizDarkModeKey, VizThemeKey } from './context';\n\nexport interface VizThemeProviderProps {\n theme: ThemeConfig | undefined;\n darkMode?: DarkMode;\n}\n\nexport const VizThemeProvider = defineComponent({\n name: 'VizThemeProvider',\n props: {\n theme: {\n type: Object as PropType<ThemeConfig | undefined>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n },\n setup(props, { slots }) {\n // Wrap in computed() so changes to props propagate reactively\n // through the injection system.\n const themeRef = computed(() => props.theme);\n const darkModeRef = computed(() => props.darkMode);\n\n provide(VizThemeKey, themeRef);\n provide(VizDarkModeKey, darkModeRef);\n\n return () => slots.default?.();\n },\n});\n","/**\n * Visualization routing component: renders Chart, DataTable, or Graph\n * based on the spec type. Use this when rendering arbitrary VizSpec values.\n *\n * For event handlers, use the specific component (Chart, DataTable, Graph) directly.\n */\n\nimport type { DarkMode, ThemeConfig, VizSpec } from '@opendata-ai/openchart-core';\nimport { isGraphSpec, isSankeySpec, isTableSpec } from '@opendata-ai/openchart-core';\nimport { type CSSProperties, defineComponent, h, type PropType } from 'vue';\nimport { Chart } from './Chart';\nimport { DataTable } from './DataTable';\nimport { Graph } from './Graph';\nimport { Sankey } from './Sankey';\n\nexport interface VisualizationProps {\n spec: VizSpec;\n theme?: ThemeConfig;\n darkMode?: DarkMode;\n class?: string;\n style?: string | CSSProperties;\n}\n\nexport const Visualization = defineComponent({\n name: 'Visualization',\n props: {\n spec: {\n type: Object as PropType<VizSpec>,\n required: true,\n },\n theme: {\n type: Object as PropType<ThemeConfig>,\n default: undefined,\n },\n darkMode: {\n type: String as PropType<DarkMode>,\n default: undefined,\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: [String, Object] as PropType<string | CSSProperties>,\n default: undefined,\n },\n },\n setup(props) {\n return () => {\n const { spec, theme, darkMode, class: className, style } = props;\n const sharedProps = { theme, darkMode, class: className, style };\n\n if (isTableSpec(spec)) {\n return h(DataTable, { ...sharedProps, spec });\n }\n if (isGraphSpec(spec)) {\n return h(Graph, { ...sharedProps, spec });\n }\n if (isSankeySpec(spec)) {\n return h(Sankey, { ...sharedProps, spec });\n }\n return h(Chart, { ...sharedProps, spec });\n };\n },\n});\n"],"mappings":"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","names":["inject","inject","createChart","onMounted","onUnmounted","ref","watch","onUnmounted","ref","watch","ref","onMounted","onUnmounted","ref","shallowRef","watch","ref","createTable","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","createTable","onMounted","onUnmounted","watch","h","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","defineComponent","h","inject","onMounted","onUnmounted","ref","watch","defineComponent","ref","inject","onMounted","onUnmounted","watch","h","computed","defineComponent","defineComponent","computed","defineComponent","h","defineComponent","h"]}
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- .oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root{--oc-font-family:Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--oc-font-mono:"JetBrains Mono", "Fira Code", "Cascadia Code", monospace;--oc-ease-smooth:linear(0, .157, .438, .64, .766, .85, .906, .941, .964, .978, .988, .994, .998, 1);--oc-ease-snappy:linear(0, .012, .048, .108, .194, .302, .426, .559, .69, .808, .905, .973, 1.013, 1.028, 1.023, 1.006, .984, .966, .957, .957, .964, .975, .986, .995, 1, 1.003, 1.002, 1, .998, .998, .999, 1);--oc-animation-duration:.5s;--oc-animation-stagger:80ms;--oc-annotation-delay:.2s;--oc-title-size:22px;--oc-title-weight:700;--oc-title-tracking:-.02em;--oc-subtitle-size:14px;--oc-subtitle-weight:400;--oc-source-size:12px;--oc-source-weight:400;--oc-body-size:13px;--oc-bg:#fff;--oc-text:#1d1d1d;--oc-text-secondary:#5c5c5c;--oc-text-muted:#999;--oc-gridline:#e8e8e8;--oc-axis:#888;--oc-border:#e2e2e2;--oc-border-radius:4px;--oc-focus:#3b82f6;--oc-hover-bg:rgba(0,0,0,.024);--oc-tooltip-bg:rgba(255,255,255,.88);--oc-tooltip-border:rgba(0,0,0,.08);--oc-tooltip-shadow:0 2px 8px rgba(0,0,0,.08), 0 0 1px rgba(0,0,0,.12);--oc-tooltip-text:#1d1d1d;--oc-legend-text:#555}.oc-dark{--oc-bg:#1a1a2e;--oc-text:#e0e0e0;--oc-text-secondary:#b0b0b0;--oc-text-muted:gray;--oc-gridline:#335;--oc-axis:#999;--oc-border:#446;--oc-focus:#60a5fa;--oc-hover-bg:rgba(255,255,255,.05);--oc-tooltip-bg:rgba(30,30,50,.85);--oc-tooltip-border:rgba(255,255,255,.08);--oc-tooltip-shadow:0 2px 8px rgba(0,0,0,.3), 0 0 1px rgba(0,0,0,.4);--oc-tooltip-text:#e0e0e0;--oc-legend-text:#b0b0b0}.oc-chart-root{width:100%}.oc-table-root,.oc-graph-root{width:100%;height:100%}.oc-table-root{overflow:auto}.oc-chart{font-family:var(--oc-font-family);width:100%;display:block}.oc-sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.oc-editable-hover{outline-offset:2px;border-radius:2px;outline:1.5px solid rgba(79,70,229,.35)}.oc-chrome{font-family:var(--oc-font-family)}.oc-title{font-size:var(--oc-title-size);font-weight:var(--oc-title-weight);letter-spacing:var(--oc-title-tracking);fill:var(--oc-text)}.oc-subtitle{font-size:var(--oc-subtitle-size);font-weight:var(--oc-subtitle-weight);fill:var(--oc-text-secondary)}.oc-source,.oc-byline,.oc-footer{font-size:var(--oc-source-size);font-weight:var(--oc-source-weight);fill:var(--oc-text-muted)}.oc-chrome-footer{padding-top:16px}.oc-tooltip{pointer-events:none;z-index:1000;background:var(--oc-tooltip-bg);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid var(--oc-tooltip-border);box-shadow:var(--oc-tooltip-shadow);color:var(--oc-tooltip-text);font-family:var(--oc-font-family);border-radius:8px;min-width:140px;max-width:260px;padding:0;font-size:12px;line-height:1.4;animation:.12s ease-out oc-tooltip-in;display:none;position:absolute}.oc-tooltip .oc-tooltip-header{align-items:center;gap:6px;padding:8px 12px 6px;display:flex}.oc-tooltip .oc-tooltip-dot{border-radius:50%;flex-shrink:0;width:8px;height:8px}.oc-tooltip .oc-tooltip-title{letter-spacing:-.01em;color:var(--oc-tooltip-text);white-space:nowrap;text-overflow:ellipsis;font-size:12px;font-weight:600;overflow:hidden}.oc-tooltip .oc-tooltip-body{border-top:1px solid var(--oc-tooltip-border);padding:4px 12px 8px}.oc-tooltip .oc-tooltip-header+.oc-tooltip-body{padding-top:6px}.oc-tooltip .oc-tooltip-body:first-child{border-top:none;padding-top:8px}.oc-tooltip .oc-tooltip-row{justify-content:space-between;align-items:baseline;gap:12px;padding:1px 0;display:flex}.oc-tooltip .oc-tooltip-label{color:var(--oc-text-muted);white-space:nowrap;flex-shrink:0;font-size:11px}.oc-tooltip .oc-tooltip-value{font-variant-numeric:tabular-nums;text-align:right;text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:500;overflow:hidden}.oc-legend{font-family:var(--oc-font-family);font-size:var(--oc-body-size)}.oc-legend-entry{cursor:default}.oc-legend text{fill:var(--oc-legend-text)}.oc-table-wrapper{font-family:var(--oc-font-family);color:var(--oc-text);background:var(--oc-bg)}.oc-table-wrapper>.oc-chrome{margin-bottom:16px}.oc-table-wrapper table{border-collapse:collapse;width:100%}.oc-table-wrapper th{text-align:left;border-bottom:1px solid var(--oc-border);padding:10px 16px}.oc-table-wrapper td{text-align:left;border-bottom:1px solid var(--oc-border);padding:10px 16px}.oc-table-wrapper th{text-transform:uppercase;letter-spacing:.05em;color:var(--oc-text-secondary);white-space:nowrap;font-size:12px;font-weight:600}.oc-table-wrapper thead{z-index:2;background:var(--oc-bg);position:sticky;top:0}.oc-table-wrapper thead th{border-bottom-width:2px}.oc-table-wrapper td{font-variant-numeric:tabular-nums;font-size:14px}.oc-table-wrapper th:focus{outline:2px solid var(--oc-focus);outline-offset:-2px}.oc-table-wrapper tbody:focus{outline:none}.oc-table-title{font-size:var(--oc-title-computed-size,var(--oc-title-size));font-weight:var(--oc-title-computed-weight,var(--oc-title-weight));color:var(--oc-title-computed-color,var(--oc-text));margin-bottom:4px}.oc-table-subtitle{font-size:var(--oc-subtitle-computed-size,var(--oc-subtitle-size));font-weight:var(--oc-subtitle-computed-weight,var(--oc-subtitle-weight));color:var(--oc-subtitle-computed-color,var(--oc-text-secondary));margin-bottom:8px}.oc-table-source{font-size:var(--oc-source-computed-size,var(--oc-source-size));color:var(--oc-source-computed-color,var(--oc-text-muted))}.oc-table-footer-text{font-size:var(--oc-footer-computed-size,var(--oc-source-size));color:var(--oc-footer-computed-color,var(--oc-text-muted))}.oc-table-scroll{overflow-x:auto}.oc-table--sticky th:first-child{z-index:1;background:var(--oc-bg);position:sticky;left:0}.oc-table--sticky td:first-child{z-index:1;background:var(--oc-bg);position:sticky;left:0}.oc-table-sort-btn{cursor:pointer;vertical-align:middle;background:0 0;border:none;flex-direction:column;align-items:center;gap:2px;margin-left:6px;padding:2px;display:inline-flex}.oc-table-sort-btn:before{content:"";border-left:5px solid transparent;border-right:5px solid transparent;width:0;height:0;transition:opacity .15s,border-color .15s;display:block}.oc-table-sort-btn:after{content:"";border-left:5px solid transparent;border-right:5px solid transparent;width:0;height:0;transition:opacity .15s,border-color .15s;display:block}.oc-table-sort-btn:before{border-bottom:4.5px solid var(--oc-text-secondary);opacity:.45}.oc-table-sort-btn:after{border-top:4.5px solid var(--oc-text-secondary);opacity:.45}.oc-table-sort-btn:hover:before{opacity:.75}.oc-table-sort-btn:hover:after{opacity:.75}th[aria-sort=ascending] .oc-table-sort-btn:before{opacity:1;border-bottom-color:var(--oc-text)}th[aria-sort=ascending] .oc-table-sort-btn:after{opacity:.15}th[aria-sort=descending] .oc-table-sort-btn:after{opacity:1;border-top-color:var(--oc-text)}th[aria-sort=descending] .oc-table-sort-btn:before{opacity:.15}.oc-table-search{padding:8px 0}.oc-table-search input{border:1px solid var(--oc-border);background:var(--oc-bg);width:100%;color:var(--oc-text);box-sizing:border-box;border-radius:6px;padding:8px 12px;font-family:inherit;font-size:13px;transition:border-color .15s}.oc-table-search input::-ms-input-placeholder{color:var(--oc-text-muted);font-size:13px}.oc-table-search input::placeholder{color:var(--oc-text-muted);font-size:13px}.oc-table-search input:focus{border-color:var(--oc-focus);outline:none;box-shadow:0 0 0 3px rgba(59,130,246,.1)}.oc-table-pagination{color:var(--oc-text-secondary);justify-content:space-between;align-items:center;padding:12px 0 4px;font-size:13px;display:flex}.oc-table-pagination button{border:1px solid var(--oc-border);background:var(--oc-bg);color:var(--oc-text);cursor:pointer;border-radius:6px;padding:6px 14px;font-family:inherit;font-size:13px;transition:background .15s,border-color .15s}.oc-table-pagination button:disabled{opacity:.35;cursor:not-allowed}.oc-table-pagination button:hover:not(:disabled){background:var(--oc-hover-bg);border-color:var(--oc-axis)}.oc-table-pagination button:focus-visible{outline:2px solid var(--oc-focus);outline-offset:1px}.oc-table-pagination-info{font-variant-numeric:tabular-nums}.oc-table-pagination-btns{gap:8px;display:flex}.oc-table-bar{position:relative}.oc-table-bar-fill{opacity:.15;pointer-events:none;border-radius:2px;position:absolute;top:6px;bottom:6px;left:0}.oc-table-bar-value{z-index:1;position:relative}.oc-table-sparkline{width:100%;display:block;position:relative}.oc-table-sparkline svg{width:100%;display:block;overflow:visible}.oc-table-sparkline-dot{border-radius:50%;width:5px;height:5px;position:absolute}.oc-table-sparkline-labels{justify-content:space-between;font-size:11px;line-height:1;display:flex}.oc-table-image{vertical-align:middle;display:inline-block}.oc-table-image img{object-fit:cover}.oc-table-image-rounded img{border-radius:50%}.oc-table-flag{font-size:1.2em}.oc-table--compact th{padding:4px 8px;font-size:13px}.oc-table--compact td{padding:4px 8px;font-size:13px}.oc-table--compact th{font-size:11px}.oc-table--clickable tbody tr{cursor:pointer}.oc-table--clickable tbody tr:hover{background:var(--oc-hover-bg)}.oc-table-cell-focus{outline:2px solid var(--oc-focus);outline-offset:-2px}.oc-table-empty{text-align:center;color:var(--oc-text-secondary);padding:32px 16px;font-size:14px;font-style:italic}.oc-table-wrapper.oc-animate>.oc-chrome{animation:oc-enter-fade calc(var(--oc-animation-duration) * .6) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate thead{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate tbody tr{animation:oc-table-enter-row var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0))}.oc-table-wrapper.oc-animate tbody td{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0))}.oc-table-wrapper.oc-animate td.oc-table-heatmap{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .7) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate td.oc-table-category{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .7) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate .oc-table-bar-fill{animation:oc-table-enter-bar-fill calc(var(--oc-animation-duration) * .8) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate .oc-table-sparkline>svg{animation:oc-enter-line calc(var(--oc-animation-duration) * .8) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .4)}.oc-table-wrapper.oc-animate .oc-table-sparkline-dot{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .3) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .8)}.oc-table-wrapper.oc-animate .oc-table-sparkline-labels{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .3) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .8)}.oc-table-wrapper.oc-animate .oc-table-search{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate .oc-table-pagination{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-graph-wrapper{background:var(--oc-bg);font-family:var(--oc-font-family);width:100%;height:100%;position:relative;overflow:hidden}.oc-graph-canvas{cursor:grab;display:block}.oc-graph-canvas--dragging{cursor:grabbing}.oc-graph-chrome{padding:16px 16px 8px}.oc-graph-chrome .oc-title{font-size:var(--oc-title-size);font-weight:var(--oc-title-weight);letter-spacing:var(--oc-title-tracking);color:var(--oc-text);margin:0 0 4px}.oc-graph-chrome .oc-subtitle{font-size:var(--oc-subtitle-size);color:var(--oc-text-secondary);margin:0}.oc-graph-legend{background:var(--oc-bg);border:1px solid var(--oc-border);border-radius:var(--oc-border-radius);color:var(--oc-text-secondary);max-height:200px;padding:8px 12px;font-size:12px;position:absolute;top:8px;right:8px;overflow-y:auto}.oc-graph-legend-item{align-items:center;gap:6px;padding:2px 0;display:flex}.oc-graph-legend-swatch{border-radius:50%;flex-shrink:0;width:10px;height:10px}.oc-graph-search{position:absolute;top:8px;left:8px}.oc-graph-search input{font-family:var(--oc-font-family);font-size:var(--oc-body-size);border:1px solid var(--oc-border);border-radius:var(--oc-border-radius);background:var(--oc-bg);color:var(--oc-text);outline:none;padding:6px 10px}.oc-graph-search input:focus{border-color:var(--oc-focus);box-shadow:0 0 0 2px rgba(59,130,246,.25)}.oc-dark .oc-graph-wrapper,.oc-graph-wrapper.oc-dark{--oc-bg:#0d1117}.oc-dark .oc-graph-legend,.oc-dark.oc-graph-wrapper .oc-graph-legend,.oc-dark .oc-graph-search input{background:rgba(13,17,23,.85);border-color:rgba(255,255,255,.1)}@keyframes oc-enter-bar{0%{clip-path:inset(100% 0 0);opacity:0}75%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-bar-h{0%{clip-path:inset(0 100% 0 0);opacity:0}75%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-line{0%{clip-path:inset(0 100% 0 0);opacity:0}15%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-point{0%{opacity:0;transform:scale(.3)}to{opacity:1;transform:scale(1)}}@keyframes oc-enter-fade-only{0%{opacity:0}to{opacity:1}}@keyframes oc-enter-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes oc-table-enter-row{0%{transform:translateY(6px)}to{transform:translateY(0)}}@keyframes oc-table-enter-bar-fill{0%{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0)}}@keyframes oc-tooltip-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}.oc-animate .oc-mark-rect rect{animation:oc-enter-bar var(--oc-animation-duration) var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-bar rect{animation:oc-enter-bar var(--oc-animation-duration) var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-rect[data-orient=horizontal] rect{animation-name:oc-enter-bar-h}.oc-animate .oc-mark-bar[data-orient=horizontal] rect{animation-name:oc-enter-bar-h}.oc-animate .oc-mark-rect[data-stack-pos] rect{animation-duration:var(--oc-stack-segment-duration,.15s);animation-timing-function:linear;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0) + var(--oc-stack-pos,0) * var(--oc-stack-segment-duration,.15s))}.oc-animate .oc-mark-line{animation:oc-enter-line var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-area{animation:oc-enter-line var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-arc{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate circle.oc-mark-point{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate circle.oc-mark-circle{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-line~circle.oc-mark-point{animation-delay:calc(var(--oc-animation-duration) * .35 + var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-area~circle.oc-mark-point{animation-delay:calc(var(--oc-animation-duration) * .35 + var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-text text{animation:oc-enter-fade calc(var(--oc-animation-duration) * .6) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-rule line{animation:oc-enter-fade calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-tick line{animation:oc-enter-fade calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-label{animation:oc-enter-fade .3s var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0) + var(--oc-animation-duration) * .7)}.oc-animate .oc-annotation{animation:oc-enter-fade .4s var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-duration) + var(--oc-annotation-delay,.2s))}@media (prefers-reduced-motion:reduce){.oc-table-sort-btn:before,.oc-table-sort-btn:after,.oc-table-search input,.oc-table-pagination button{transition:none}.oc-animate .oc-mark-rect rect,.oc-animate .oc-mark-bar rect,.oc-animate .oc-mark-arc,.oc-animate .oc-mark-line,.oc-animate .oc-mark-area,.oc-animate circle.oc-mark-point,.oc-animate circle.oc-mark-circle,.oc-animate .oc-mark-text text,.oc-animate .oc-mark-rule line,.oc-animate .oc-mark-tick line,.oc-animate .oc-mark-label,.oc-animate .oc-annotation,.oc-table-wrapper.oc-animate>.oc-chrome,.oc-table-wrapper.oc-animate thead,.oc-table-wrapper.oc-animate tbody tr,.oc-table-wrapper.oc-animate tbody td,.oc-table-wrapper.oc-animate td.oc-table-heatmap,.oc-table-wrapper.oc-animate td.oc-table-category,.oc-table-wrapper.oc-animate .oc-table-bar-fill,.oc-table-wrapper.oc-animate .oc-table-sparkline>svg,.oc-table-wrapper.oc-animate .oc-table-sparkline-dot,.oc-table-wrapper.oc-animate .oc-table-sparkline-labels,.oc-table-wrapper.oc-animate .oc-table-search,.oc-table-wrapper.oc-animate .oc-table-pagination{animation:none}}
1
+ .oc-root,.oc-chart-root,.oc-table-wrapper,.oc-table-root,.oc-graph-wrapper,.oc-graph-root,.oc-sankey-root{--oc-font-family:Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--oc-font-mono:"JetBrains Mono", "Fira Code", "Cascadia Code", monospace;--oc-ease-smooth:linear(0, .157, .438, .64, .766, .85, .906, .941, .964, .978, .988, .994, .998, 1);--oc-ease-snappy:linear(0, .012, .048, .108, .194, .302, .426, .559, .69, .808, .905, .973, 1.013, 1.028, 1.023, 1.006, .984, .966, .957, .957, .964, .975, .986, .995, 1, 1.003, 1.002, 1, .998, .998, .999, 1);--oc-animation-duration:.5s;--oc-animation-stagger:80ms;--oc-annotation-delay:.2s;--oc-title-size:22px;--oc-title-weight:700;--oc-title-tracking:-.02em;--oc-subtitle-size:14px;--oc-subtitle-weight:400;--oc-source-size:12px;--oc-source-weight:400;--oc-body-size:13px;--oc-bg:#fff;--oc-text:#1d1d1d;--oc-text-secondary:#5c5c5c;--oc-text-muted:#999;--oc-gridline:#e8e8e8;--oc-axis:#888;--oc-border:#e2e2e2;--oc-border-radius:4px;--oc-focus:#3b82f6;--oc-hover-bg:rgba(0,0,0,.024);--oc-tooltip-bg:rgba(255,255,255,.88);--oc-tooltip-border:rgba(0,0,0,.08);--oc-tooltip-shadow:0 2px 8px rgba(0,0,0,.08), 0 0 1px rgba(0,0,0,.12);--oc-tooltip-text:#1d1d1d;--oc-legend-text:#555}.oc-dark{--oc-bg:#1a1a2e;--oc-text:#e0e0e0;--oc-text-secondary:#b0b0b0;--oc-text-muted:gray;--oc-gridline:#335;--oc-axis:#999;--oc-border:#446;--oc-focus:#60a5fa;--oc-hover-bg:rgba(255,255,255,.05);--oc-tooltip-bg:rgba(30,30,50,.85);--oc-tooltip-border:rgba(255,255,255,.08);--oc-tooltip-shadow:0 2px 8px rgba(0,0,0,.3), 0 0 1px rgba(0,0,0,.4);--oc-tooltip-text:#e0e0e0;--oc-legend-text:#b0b0b0}.oc-chart-root{width:100%}.oc-table-root,.oc-graph-root,.oc-sankey-root{width:100%;height:100%}.oc-table-root{overflow:auto}.oc-chart{font-family:var(--oc-font-family);width:100%;display:block}.oc-sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.oc-editable-hover{outline-offset:2px;border-radius:2px;outline:1.5px solid rgba(79,70,229,.35)}.oc-chrome{font-family:var(--oc-font-family)}.oc-title{font-size:var(--oc-title-size);font-weight:var(--oc-title-weight);letter-spacing:var(--oc-title-tracking);fill:var(--oc-text)}.oc-subtitle{font-size:var(--oc-subtitle-size);font-weight:var(--oc-subtitle-weight);fill:var(--oc-text-secondary)}.oc-source,.oc-byline,.oc-footer{font-size:var(--oc-source-size);font-weight:var(--oc-source-weight);fill:var(--oc-text-muted)}.oc-chrome-footer{padding-top:16px}.oc-tooltip{pointer-events:none;z-index:1000;background:var(--oc-tooltip-bg);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid var(--oc-tooltip-border);box-shadow:var(--oc-tooltip-shadow);color:var(--oc-tooltip-text);font-family:var(--oc-font-family);border-radius:8px;min-width:140px;max-width:260px;padding:0;font-size:12px;line-height:1.4;animation:.12s ease-out oc-tooltip-in;display:none;position:absolute}.oc-tooltip .oc-tooltip-header{align-items:center;gap:6px;padding:8px 12px 6px;display:flex}.oc-tooltip .oc-tooltip-dot{border-radius:50%;flex-shrink:0;width:8px;height:8px}.oc-tooltip .oc-tooltip-title{letter-spacing:-.01em;color:var(--oc-tooltip-text);white-space:nowrap;text-overflow:ellipsis;font-size:12px;font-weight:600;overflow:hidden}.oc-tooltip .oc-tooltip-body{border-top:1px solid var(--oc-tooltip-border);padding:4px 12px 8px}.oc-tooltip .oc-tooltip-header+.oc-tooltip-body{padding-top:6px}.oc-tooltip .oc-tooltip-body:first-child{border-top:none;padding-top:8px}.oc-tooltip .oc-tooltip-row{justify-content:space-between;align-items:baseline;gap:12px;padding:1px 0;display:flex}.oc-tooltip .oc-tooltip-label{color:var(--oc-text-muted);white-space:nowrap;flex-shrink:0;font-size:11px}.oc-tooltip .oc-tooltip-value{font-variant-numeric:tabular-nums;text-align:right;text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:500;overflow:hidden}.oc-legend{font-family:var(--oc-font-family);font-size:var(--oc-body-size)}.oc-legend-entry{cursor:default}.oc-legend text{fill:var(--oc-legend-text)}.oc-table-wrapper{font-family:var(--oc-font-family);color:var(--oc-text);background:var(--oc-bg)}.oc-table-wrapper>.oc-chrome{margin-bottom:16px;padding-left:16px;padding-right:16px}.oc-table-wrapper>.oc-chrome:first-child{padding-top:4px}.oc-table-wrapper table{border-collapse:collapse;width:100%}.oc-table-wrapper th{text-align:left;border-bottom:1px solid var(--oc-border);padding:10px 16px}.oc-table-wrapper td{text-align:left;border-bottom:1px solid var(--oc-border);padding:10px 16px}.oc-table-wrapper th{text-transform:uppercase;letter-spacing:.05em;color:var(--oc-text-secondary);white-space:nowrap;font-size:12px;font-weight:600}.oc-table-wrapper thead{z-index:2;background:var(--oc-bg);position:sticky;top:0}.oc-table-wrapper thead th{border-bottom-width:2px}.oc-table-wrapper td{font-variant-numeric:tabular-nums;font-size:14px}.oc-table-wrapper th:focus{outline:2px solid var(--oc-focus);outline-offset:-2px}.oc-table-wrapper tbody:focus{outline:none}.oc-table-title{font-size:var(--oc-title-computed-size,var(--oc-title-size));font-weight:var(--oc-title-computed-weight,var(--oc-title-weight));color:var(--oc-title-computed-color,var(--oc-text));margin-bottom:4px}.oc-table-subtitle{font-size:var(--oc-subtitle-computed-size,var(--oc-subtitle-size));font-weight:var(--oc-subtitle-computed-weight,var(--oc-subtitle-weight));color:var(--oc-subtitle-computed-color,var(--oc-text-secondary));margin-bottom:8px}.oc-table-source{font-size:var(--oc-source-computed-size,var(--oc-source-size));color:var(--oc-source-computed-color,var(--oc-text-muted))}.oc-table-footer-text{font-size:var(--oc-footer-computed-size,var(--oc-source-size));color:var(--oc-footer-computed-color,var(--oc-text-muted))}.oc-table-scroll{overflow-x:auto}.oc-table--sticky th:first-child{z-index:1;background:var(--oc-bg);position:sticky;left:0}.oc-table--sticky td:first-child{z-index:1;background:var(--oc-bg);position:sticky;left:0}.oc-table-sort-btn{cursor:pointer;vertical-align:middle;background:0 0;border:none;flex-direction:column;align-items:center;gap:2px;margin-left:6px;padding:2px;display:inline-flex}.oc-table-sort-btn:before{content:"";border-left:5px solid transparent;border-right:5px solid transparent;width:0;height:0;transition:opacity .15s,border-color .15s;display:block}.oc-table-sort-btn:after{content:"";border-left:5px solid transparent;border-right:5px solid transparent;width:0;height:0;transition:opacity .15s,border-color .15s;display:block}.oc-table-sort-btn:before{border-bottom:4.5px solid var(--oc-text-secondary);opacity:.45}.oc-table-sort-btn:after{border-top:4.5px solid var(--oc-text-secondary);opacity:.45}.oc-table-sort-btn:hover:before{opacity:.75}.oc-table-sort-btn:hover:after{opacity:.75}th[aria-sort=ascending] .oc-table-sort-btn:before{opacity:1;border-bottom-color:var(--oc-text)}th[aria-sort=ascending] .oc-table-sort-btn:after{opacity:.15}th[aria-sort=descending] .oc-table-sort-btn:after{opacity:1;border-top-color:var(--oc-text)}th[aria-sort=descending] .oc-table-sort-btn:before{opacity:.15}.oc-table-search{padding:8px 0}.oc-table-search input{border:1px solid var(--oc-border);background:var(--oc-bg);width:100%;color:var(--oc-text);box-sizing:border-box;border-radius:6px;padding:8px 12px;font-family:inherit;font-size:13px;transition:border-color .15s}.oc-table-search input::-ms-input-placeholder{color:var(--oc-text-muted);font-size:13px}.oc-table-search input::placeholder{color:var(--oc-text-muted);font-size:13px}.oc-table-search input:focus{border-color:var(--oc-focus);outline:none;box-shadow:0 0 0 3px rgba(59,130,246,.1)}.oc-table-pagination{color:var(--oc-text-secondary);justify-content:space-between;align-items:center;padding:12px 0 4px;font-size:13px;display:flex}.oc-table-pagination button{border:1px solid var(--oc-border);background:var(--oc-bg);color:var(--oc-text);cursor:pointer;border-radius:6px;padding:6px 14px;font-family:inherit;font-size:13px;transition:background .15s,border-color .15s}.oc-table-pagination button:disabled{opacity:.35;cursor:not-allowed}.oc-table-pagination button:hover:not(:disabled){background:var(--oc-hover-bg);border-color:var(--oc-axis)}.oc-table-pagination button:focus-visible{outline:2px solid var(--oc-focus);outline-offset:1px}.oc-table-pagination-info{font-variant-numeric:tabular-nums}.oc-table-pagination-btns{gap:8px;display:flex}.oc-table-bar{position:relative}.oc-table-bar-fill{opacity:.15;pointer-events:none;border-radius:2px;position:absolute;top:6px;bottom:6px;left:0}.oc-table-bar-value{z-index:1;position:relative}.oc-table-sparkline{width:100%;display:block;position:relative}.oc-table-sparkline svg{width:100%;display:block;overflow:visible}.oc-table-sparkline-dot{border-radius:50%;width:5px;height:5px;position:absolute}.oc-table-sparkline-labels{justify-content:space-between;font-size:11px;line-height:1;display:flex}.oc-table-image{vertical-align:middle;display:inline-block}.oc-table-image img{object-fit:cover}.oc-table-image-rounded img{border-radius:50%}.oc-table-flag{font-size:1.2em}.oc-table--compact th{padding:4px 8px;font-size:13px}.oc-table--compact td{padding:4px 8px;font-size:13px}.oc-table--compact th{font-size:11px}.oc-table--clickable tbody tr{cursor:pointer}.oc-table--clickable tbody tr:hover{background:var(--oc-hover-bg)}.oc-table-cell-focus{outline:2px solid var(--oc-focus);outline-offset:-2px}.oc-table-empty{text-align:center;color:var(--oc-text-secondary);padding:32px 16px;font-size:14px;font-style:italic}.oc-table-wrapper.oc-animate>.oc-chrome{animation:oc-enter-fade calc(var(--oc-animation-duration) * .6) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate thead{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate tbody tr{animation:oc-table-enter-row var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0))}.oc-table-wrapper.oc-animate tbody td{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0))}.oc-table-wrapper.oc-animate td.oc-table-heatmap{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .7) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate td.oc-table-category{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .7) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate .oc-table-bar-fill{animation:oc-table-enter-bar-fill calc(var(--oc-animation-duration) * .8) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .3)}.oc-table-wrapper.oc-animate .oc-table-sparkline>svg{animation:oc-enter-line calc(var(--oc-animation-duration) * .8) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .4)}.oc-table-wrapper.oc-animate .oc-table-sparkline-dot{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .3) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .8)}.oc-table-wrapper.oc-animate .oc-table-sparkline-labels{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .3) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-row-index,0) + var(--oc-animation-duration) * .8)}.oc-table-wrapper.oc-animate .oc-table-search{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-table-wrapper.oc-animate .oc-table-pagination{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both}.oc-graph-wrapper{background:var(--oc-bg);font-family:var(--oc-font-family);width:100%;height:100%;position:relative;overflow:hidden}.oc-graph-canvas{cursor:grab;display:block}.oc-graph-canvas--dragging{cursor:grabbing}.oc-graph-chrome{padding:16px 16px 8px}.oc-graph-chrome .oc-title{font-size:var(--oc-title-size);font-weight:var(--oc-title-weight);letter-spacing:var(--oc-title-tracking);color:var(--oc-text);margin:0 0 4px}.oc-graph-chrome .oc-subtitle{font-size:var(--oc-subtitle-size);color:var(--oc-text-secondary);margin:0}.oc-graph-legend{background:var(--oc-bg);border:1px solid var(--oc-border);border-radius:var(--oc-border-radius);color:var(--oc-text-secondary);max-height:200px;padding:8px 12px;font-size:12px;position:absolute;top:8px;right:8px;overflow-y:auto}.oc-graph-legend-item{align-items:center;gap:6px;padding:2px 0;display:flex}.oc-graph-legend-swatch{border-radius:50%;flex-shrink:0;width:10px;height:10px}.oc-graph-search{position:absolute;top:8px;left:8px}.oc-graph-search input{font-family:var(--oc-font-family);font-size:var(--oc-body-size);border:1px solid var(--oc-border);border-radius:var(--oc-border-radius);background:var(--oc-bg);color:var(--oc-text);outline:none;padding:6px 10px}.oc-graph-search input:focus{border-color:var(--oc-focus);box-shadow:0 0 0 2px rgba(59,130,246,.25)}.oc-dark .oc-graph-wrapper,.oc-graph-wrapper.oc-dark{--oc-bg:#0d1117}.oc-dark .oc-graph-legend,.oc-dark.oc-graph-wrapper .oc-graph-legend,.oc-dark .oc-graph-search input{background:rgba(13,17,23,.85);border-color:rgba(255,255,255,.1)}@keyframes oc-enter-bar{0%{clip-path:inset(100% 0 0);opacity:0}75%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-bar-h{0%{clip-path:inset(0 100% 0 0);opacity:0}75%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-line{0%{clip-path:inset(0 100% 0 0);opacity:0}15%{opacity:1}to{clip-path:inset(0);opacity:1}}@keyframes oc-enter-point{0%{opacity:0;transform:scale(.3)}to{opacity:1;transform:scale(1)}}@keyframes oc-enter-fade-only{0%{opacity:0}to{opacity:1}}@keyframes oc-enter-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}@keyframes oc-table-enter-row{0%{transform:translateY(6px)}to{transform:translateY(0)}}@keyframes oc-table-enter-bar-fill{0%{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0)}}@keyframes oc-tooltip-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}.oc-animate .oc-mark-rect rect{animation:oc-enter-bar var(--oc-animation-duration) var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-bar rect{animation:oc-enter-bar var(--oc-animation-duration) var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-rect[data-orient=horizontal] rect{animation-name:oc-enter-bar-h}.oc-animate .oc-mark-bar[data-orient=horizontal] rect{animation-name:oc-enter-bar-h}.oc-animate .oc-mark-rect[data-stack-pos] rect{animation-duration:var(--oc-stack-segment-duration,.15s);animation-timing-function:linear;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0) + var(--oc-stack-pos,0) * var(--oc-stack-segment-duration,.15s))}.oc-animate .oc-mark-line{animation:oc-enter-line var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-area{animation:oc-enter-line var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-arc{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate circle.oc-mark-point{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate circle.oc-mark-circle{animation:oc-enter-fade-only calc(var(--oc-animation-duration) * .4) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-line~circle.oc-mark-point{animation-delay:calc(var(--oc-animation-duration) * .35 + var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-area~circle.oc-mark-point{animation-delay:calc(var(--oc-animation-duration) * .35 + var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-text text{animation:oc-enter-fade calc(var(--oc-animation-duration) * .6) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-rule line{animation:oc-enter-fade calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-tick line{animation:oc-enter-fade calc(var(--oc-animation-duration) * .5) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-mark-label{animation:oc-enter-fade .3s var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0) + var(--oc-animation-duration) * .7)}.oc-animate .oc-annotation{animation:oc-enter-fade .4s var(--oc-ease-smooth) both;animation-delay:calc(var(--oc-animation-duration) + var(--oc-annotation-delay,.2s))}.oc-animate .oc-sankey-node rect{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-stagger) * var(--oc-mark-index,0))}.oc-animate .oc-sankey-link path{animation:oc-enter-fade-only var(--oc-animation-duration) var(--oc-animation-ease,var(--oc-ease-smooth)) both;animation-delay:calc(var(--oc-animation-duration) * .3 + var(--oc-animation-stagger) * var(--oc-mark-index,0))}@media (prefers-reduced-motion:reduce){.oc-table-sort-btn:before,.oc-table-sort-btn:after,.oc-table-search input,.oc-table-pagination button{transition:none}.oc-animate .oc-mark-rect rect,.oc-animate .oc-mark-bar rect,.oc-animate .oc-mark-arc,.oc-animate .oc-mark-line,.oc-animate .oc-mark-area,.oc-animate circle.oc-mark-point,.oc-animate circle.oc-mark-circle,.oc-animate .oc-mark-text text,.oc-animate .oc-mark-rule line,.oc-animate .oc-mark-tick line,.oc-animate .oc-mark-label,.oc-animate .oc-annotation,.oc-animate .oc-sankey-node rect,.oc-animate .oc-sankey-link path,.oc-table-wrapper.oc-animate>.oc-chrome,.oc-table-wrapper.oc-animate thead,.oc-table-wrapper.oc-animate tbody tr,.oc-table-wrapper.oc-animate tbody td,.oc-table-wrapper.oc-animate td.oc-table-heatmap,.oc-table-wrapper.oc-animate td.oc-table-category,.oc-table-wrapper.oc-animate .oc-table-bar-fill,.oc-table-wrapper.oc-animate .oc-table-sparkline>svg,.oc-table-wrapper.oc-animate .oc-table-sparkline-dot,.oc-table-wrapper.oc-animate .oc-table-sparkline-labels,.oc-table-wrapper.oc-animate .oc-table-search,.oc-table-wrapper.oc-animate .oc-table-pagination{animation:none}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opendata-ai/openchart-vue",
3
- "version": "6.5.2",
3
+ "version": "6.7.0",
4
4
  "description": "Vue 3 components for openchart: <Chart />, <DataTable />, <Graph />, <VizThemeProvider />",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Riley Hilliard",
@@ -49,9 +49,9 @@
49
49
  "typecheck": "tsc --noEmit"
50
50
  },
51
51
  "dependencies": {
52
- "@opendata-ai/openchart-core": "6.5.2",
53
- "@opendata-ai/openchart-engine": "6.5.2",
54
- "@opendata-ai/openchart-vanilla": "6.5.2"
52
+ "@opendata-ai/openchart-core": "6.7.0",
53
+ "@opendata-ai/openchart-engine": "6.7.0",
54
+ "@opendata-ai/openchart-vanilla": "6.7.0"
55
55
  },
56
56
  "peerDependencies": {
57
57
  "vue": ">=3.3.0"
package/src/Sankey.ts ADDED
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Vue Sankey component: thin wrapper around the vanilla adapter.
3
+ *
4
+ * Mounts a sankey instance on render, updates when spec changes,
5
+ * and cleans up on unmount. All heavy lifting is done by the vanilla
6
+ * createSankey() function.
7
+ */
8
+
9
+ import type { DarkMode, SankeySpec, ThemeConfig } from '@opendata-ai/openchart-core';
10
+ import {
11
+ createSankey,
12
+ type SankeyInstance,
13
+ type SankeyMountOptions,
14
+ } from '@opendata-ai/openchart-vanilla';
15
+ import {
16
+ type CSSProperties,
17
+ defineComponent,
18
+ h,
19
+ inject,
20
+ onMounted,
21
+ onUnmounted,
22
+ type PropType,
23
+ ref,
24
+ watch,
25
+ } from 'vue';
26
+ import { VizDarkModeKey, VizThemeKey } from './context';
27
+
28
+ export interface SankeyProps {
29
+ spec: SankeySpec;
30
+ theme?: ThemeConfig;
31
+ darkMode?: DarkMode;
32
+ class?: string;
33
+ style?: string | CSSProperties;
34
+ }
35
+
36
+ export const Sankey = defineComponent({
37
+ name: 'Sankey',
38
+ props: {
39
+ spec: {
40
+ type: Object as PropType<SankeySpec>,
41
+ required: true,
42
+ },
43
+ theme: {
44
+ type: Object as PropType<ThemeConfig>,
45
+ default: undefined,
46
+ },
47
+ darkMode: {
48
+ type: String as PropType<DarkMode>,
49
+ default: undefined,
50
+ },
51
+ class: {
52
+ type: String,
53
+ default: undefined,
54
+ },
55
+ style: {
56
+ type: [String, Object] as PropType<string | CSSProperties>,
57
+ default: undefined,
58
+ },
59
+ },
60
+ emits: {
61
+ 'node-click': (_node: Record<string, unknown>) => true,
62
+ 'link-click': (_link: Record<string, unknown>) => true,
63
+ 'node-hover': (_node: Record<string, unknown> | null) => true,
64
+ 'link-hover': (_link: Record<string, unknown> | null) => true,
65
+ },
66
+ setup(props, { emit, expose }) {
67
+ const containerRef = ref<HTMLDivElement | null>(null);
68
+ let instance: SankeyInstance | null = null;
69
+ let prevSpec = '';
70
+
71
+ // Inject theme/darkMode from provider as fallbacks
72
+ const contextTheme = inject(VizThemeKey, undefined);
73
+ const contextDarkMode = inject(VizDarkModeKey, undefined);
74
+
75
+ function resolveTheme(): ThemeConfig | undefined {
76
+ return props.theme ?? contextTheme?.value;
77
+ }
78
+
79
+ function resolveDarkMode(): DarkMode | undefined {
80
+ return props.darkMode ?? contextDarkMode?.value;
81
+ }
82
+
83
+ function mountSankey() {
84
+ const container = containerRef.value;
85
+ if (!container) return;
86
+
87
+ const options: SankeyMountOptions = {
88
+ theme: resolveTheme(),
89
+ darkMode: resolveDarkMode(),
90
+ onNodeClick: (node: Record<string, unknown>) => emit('node-click', node),
91
+ onLinkClick: (link: Record<string, unknown>) => emit('link-click', link),
92
+ onNodeHover: (node: Record<string, unknown> | null) => emit('node-hover', node),
93
+ onLinkHover: (link: Record<string, unknown> | null) => emit('link-hover', link),
94
+ responsive: true,
95
+ };
96
+
97
+ instance = createSankey(container, props.spec, options);
98
+ prevSpec = JSON.stringify(props.spec);
99
+ }
100
+
101
+ function destroySankey() {
102
+ instance?.destroy();
103
+ instance = null;
104
+ prevSpec = '';
105
+ }
106
+
107
+ // Expose imperative access to the instance
108
+ expose({
109
+ get instance() {
110
+ return instance;
111
+ },
112
+ });
113
+
114
+ onMounted(() => {
115
+ mountSankey();
116
+ });
117
+
118
+ onUnmounted(() => {
119
+ destroySankey();
120
+ });
121
+
122
+ // Watch spec changes
123
+ watch(
124
+ () => JSON.stringify(props.spec),
125
+ (newVal) => {
126
+ if (!instance) return;
127
+ if (newVal !== prevSpec) {
128
+ prevSpec = newVal;
129
+ instance.update(props.spec);
130
+ }
131
+ },
132
+ );
133
+
134
+ // Recreate sankey when theme or darkMode change
135
+ watch(
136
+ [
137
+ () => props.theme,
138
+ () => props.darkMode,
139
+ () => contextTheme?.value,
140
+ () => contextDarkMode?.value,
141
+ ],
142
+ () => {
143
+ if (!containerRef.value) return;
144
+ destroySankey();
145
+ mountSankey();
146
+ },
147
+ );
148
+
149
+ const rootClass = () => {
150
+ const base = 'oc-sankey-root';
151
+ return props.class ? `${base} ${props.class}` : base;
152
+ };
153
+
154
+ return () =>
155
+ h('div', {
156
+ ref: containerRef,
157
+ class: rootClass(),
158
+ style: props.style,
159
+ });
160
+ },
161
+ });
@@ -6,11 +6,12 @@
6
6
  */
7
7
 
8
8
  import type { DarkMode, ThemeConfig, VizSpec } from '@opendata-ai/openchart-core';
9
- import { isGraphSpec, isTableSpec } from '@opendata-ai/openchart-core';
9
+ import { isGraphSpec, isSankeySpec, isTableSpec } from '@opendata-ai/openchart-core';
10
10
  import { type CSSProperties, defineComponent, h, type PropType } from 'vue';
11
11
  import { Chart } from './Chart';
12
12
  import { DataTable } from './DataTable';
13
13
  import { Graph } from './Graph';
14
+ import { Sankey } from './Sankey';
14
15
 
15
16
  export interface VisualizationProps {
16
17
  spec: VizSpec;
@@ -55,6 +56,9 @@ export const Visualization = defineComponent({
55
56
  if (isGraphSpec(spec)) {
56
57
  return h(Graph, { ...sharedProps, spec });
57
58
  }
59
+ if (isSankeySpec(spec)) {
60
+ return h(Sankey, { ...sharedProps, spec });
61
+ }
58
62
  return h(Chart, { ...sharedProps, spec });
59
63
  };
60
64
  },
package/src/index.ts CHANGED
@@ -35,6 +35,7 @@ export type {
35
35
  NormalizedChartSpec,
36
36
  NormalizedChrome,
37
37
  NormalizedGraphSpec,
38
+ NormalizedSankeySpec,
38
39
  NormalizedSpec,
39
40
  NormalizedTableSpec,
40
41
  SimulationConfig,
@@ -47,6 +48,7 @@ export {
47
48
  compile,
48
49
  compileChart,
49
50
  compileGraph,
51
+ compileSankey,
50
52
  compileTable,
51
53
  getChartRenderer,
52
54
  normalizeSpec,
@@ -73,6 +75,8 @@ export type { DataTableProps } from './DataTable';
73
75
  export { DataTable } from './DataTable';
74
76
  export type { GraphProps } from './Graph';
75
77
  export { Graph } from './Graph';
78
+ export type { SankeyProps } from './Sankey';
79
+ export { Sankey } from './Sankey';
76
80
  export type { VizThemeProviderProps } from './ThemeProvider';
77
81
  export { VizThemeProvider } from './ThemeProvider';
78
82
  export type { VisualizationProps } from './Visualization';