diff --git a/libs/shared/lib/vis/components/VisualizationPanel.tsx b/libs/shared/lib/vis/components/VisualizationPanel.tsx index 8f178196bc139840517584d4a66c1f719317b273..8d5e4e2ebee870296e748200b843fad41b6dde7e 100644 --- a/libs/shared/lib/vis/components/VisualizationPanel.tsx +++ b/libs/shared/lib/vis/components/VisualizationPanel.tsx @@ -30,6 +30,7 @@ export const Visualizations: Record<string, PromiseFunc> = { SemanticSubstratesVis: () => import('../visualizations/semanticsubstratesvis/semanticsubstratesvis'), }), ...(isVisualizationReleased('MapVis') && { MapVis: () => import('../visualizations/mapvis/mapvis') }), + ...(isVisualizationReleased('Vis0D') && { Vis0D: () => import('../visualizations/Vis0D/Vis0D') }), }; export const VISUALIZATION_TYPES: string[] = Object.keys(Visualizations); diff --git a/libs/shared/lib/vis/visualizations/Vis0D/Vis0D.tsx b/libs/shared/lib/vis/visualizations/Vis0D/Vis0D.tsx new file mode 100644 index 0000000000000000000000000000000000000000..cc079a384abc81dc46850159c4af58a81f62a31c --- /dev/null +++ b/libs/shared/lib/vis/visualizations/Vis0D/Vis0D.tsx @@ -0,0 +1,97 @@ +import React, { useRef, useImperativeHandle, forwardRef } from 'react'; +import { VisualizationPropTypes, VISComponentType, VisualizationSettingsPropTypes } from '../../common'; +import { SettingsContainer } from '@graphpolaris/shared/lib/vis/components/config'; +import html2canvas from 'html2canvas'; +import { Input } from '@graphpolaris/shared/lib/components/inputs'; + +export interface Vis0DProps { + title: string; +} + +const settings: Vis0DProps = { + title: '', +}; + +export interface Vis0DVisHandle { + exportImageInternal: () => void; +} + +const formatNumber = (number: number) => { + return number.toLocaleString('de-DE'); +}; +const Vis0D = forwardRef<Vis0DVisHandle, VisualizationPropTypes<Vis0DProps>>(({ data, settings }, refExternal) => { + const internalRef = useRef<HTMLDivElement>(null); + useImperativeHandle(refExternal, () => ({ + exportImageInternal() { + const captureImage = () => { + const element = internalRef.current; + if (element) { + html2canvas(element, { + backgroundColor: '#FFFFFF', + }) + .then((canvas) => { + const finalImage = canvas.toDataURL('image/png'); + const link = document.createElement('a'); + link.href = finalImage; + link.download = 'Vis0D.png'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }) + .catch((error) => { + console.error('Error capturing image:', error); + }); + } else { + console.error('Container element not found'); + } + }; + + const renderCanvas = () => { + requestAnimationFrame(() => { + captureImage(); + }); + }; + + renderCanvas(); + }, + })); + + // !FIXME: When stats pills are ready, substitue results accordingly + return ( + <div className="h-full w-full flex flex-col items-center justify-center overflow-hidden" ref={internalRef}> + {settings.title && <span className="text-3xl text-center mb-4">{settings.title}</span>} + {data?.nodes?.length > 0 ? ( + <span className="text-4xl text-center">Select 0D data</span> + ) : ( + <span className="text-8xl text-center">{formatNumber(1231312)}</span> + )}{' '} + </div> + ); +}); + +const Vis0DSettings = ({ settings, updateSettings }: VisualizationSettingsPropTypes<Vis0DProps>) => { + return ( + <SettingsContainer> + <Input type="text" label="Title" value={settings.title} onChange={(value) => updateSettings({ title: value as string })} /> + </SettingsContainer> + ); +}; + +const Vis0DRef = React.createRef<Vis0DVisHandle>(); + +export const Vis0DComponent: VISComponentType<Vis0DProps> = { + displayName: '0Dvis', + description: 'KPI visualization', + component: React.forwardRef((props: VisualizationPropTypes<Vis0DProps>, ref) => <Vis0D {...props} ref={Vis0DRef} />), + settingsComponent: Vis0DSettings, + settings: settings, + exportImage: () => { + if (Vis0DRef.current) { + Vis0DRef.current.exportImageInternal(); + } else { + console.error('0Dvis reference is not set.'); + } + }, +}; + +export default Vis0DComponent; diff --git a/libs/shared/lib/vis/visualizations/Vis0D/index.ts b/libs/shared/lib/vis/visualizations/Vis0D/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..8b8204e59b129dd68208c6a5f7cf03cf4ce846b2 --- /dev/null +++ b/libs/shared/lib/vis/visualizations/Vis0D/index.ts @@ -0,0 +1 @@ +export * from './Vis0D'; diff --git a/libs/shared/lib/vis/visualizations/Vis0D/vis0D.stories.tsx b/libs/shared/lib/vis/visualizations/Vis0D/vis0D.stories.tsx new file mode 100644 index 0000000000000000000000000000000000000000..92fc6c951559a9c2234f487c165301fff4f97e8b --- /dev/null +++ b/libs/shared/lib/vis/visualizations/Vis0D/vis0D.stories.tsx @@ -0,0 +1,61 @@ +import { Meta } from '@storybook/react'; +import { configureStore } from '@reduxjs/toolkit'; +import { Provider } from 'react-redux'; +import { mockData } from '../../../mock-data'; +import { graphQueryResultSlice, querybuilderSlice, schemaSlice, visualizationSlice } from '../../../data-access/store'; +import Vis0DComponent from './Vis0D'; + +const Component: Meta<typeof Vis0DComponent.component> = { + title: 'Visualizations/0DVis', + component: Vis0DComponent.component, + decorators: [ + (story) => ( + <Provider store={Mockstore}> + <div + style={{ + width: '100%', + height: '100vh', + }} + > + {story()} + </div> + </Provider> + ), + ], +}; + +const Mockstore: any = configureStore({ + reducer: { + schema: schemaSlice.reducer, + graphQueryResult: graphQueryResultSlice.reducer, + visualize: visualizationSlice.reducer, + querybuilder: querybuilderSlice.reducer, + }, +}); + +export const TestWithData = { + args: { + data: { + nodes: 12313, + edges: [], + }, + ml: {}, + settings: { + ...Vis0DComponent.settings, + title: 'KPI Count Movie', + }, + }, +}; + +export const TestWithNoData = { + args: { + data: { + nodes: [123123, 1312, 21313], + edges: [], + }, + ml: {}, + settings: Vis0DComponent.settings, + }, +}; + +export default Component; diff --git a/libs/shared/lib/vis/visualizations/index.tsx b/libs/shared/lib/vis/visualizations/index.tsx index 5fa9f4221646eb5641dbec2409966e947a61c7a8..1a830c42e9c1ad50d6c2d88f1f12d23e5ed692eb 100644 --- a/libs/shared/lib/vis/visualizations/index.tsx +++ b/libs/shared/lib/vis/visualizations/index.tsx @@ -4,3 +4,4 @@ export * from './paohvis/paohvis'; export * from './tablevis/tablevis'; export * from './matrixvis/matrixvis'; export * from './semanticsubstratesvis/semanticsubstratesvis'; +export * from './Vis0D/Vis0D';