From 9a8e6f4bb2f63471672d2119479614b93c24fb59 Mon Sep 17 00:00:00 2001 From: Leonardo Christino <leomilho@gmail.com> Date: Sun, 3 Mar 2024 17:59:18 +0100 Subject: [PATCH] chore: optimize build chunking --- apps/web/src/app/app.tsx | 8 ++-- apps/web/src/app/panels/Visualization.tsx | 14 +++--- .../src/app/panels/VisualizationDialog.tsx | 2 +- .../components/navbar/search/SearchBar.tsx | 6 +-- .../src/components/onboarding/onboarding.tsx | 3 +- apps/web/vite.config.ts | 3 +- .../lib/components/buttons/button.stories.tsx | 7 +-- libs/shared/lib/components/buttons/index.tsx | 16 +++---- .../lib/components/color-mode/index.tsx | 5 +- libs/shared/lib/components/forms/index.tsx | 5 +- .../lib/components/icon/icon.stories.tsx | 5 +- libs/shared/lib/components/icon/index.tsx | 19 ++++---- .../lib/components/pagination/index.tsx | 5 +- .../authorization/dashboardAlerts.tsx | 11 ++--- .../lib/graph-layout/cytoscape-layouts.ts | 47 +++++++++---------- .../lib/graph-layout/graphology-layouts.ts | 8 ++-- libs/shared/lib/graph-layout/layout.ts | 7 ++- libs/shared/lib/querybuilder/index.ts | 4 ++ .../lib/querybuilder/panel/querybuilder.tsx | 17 +++---- .../queryBuilderLogicPillsPanel.tsx | 18 +++---- .../queryBuilderRelatedNodesPanel.tsx | 17 +++---- libs/shared/lib/schema/panel/index.ts | 3 ++ libs/shared/lib/schema/panel/schema.tsx | 17 ++++--- libs/shared/lib/vis/index.tsx | 38 +++++++++------ libs/shared/lib/vis/panel/index.ts | 3 ++ libs/shared/lib/vis/panel/visualization.tsx | 5 +- .../shared/ResultNodeLinkParserUseCase.tsx | 2 +- libs/shared/lib/vis/visualizations/index.tsx | 10 ++-- .../lib/vis/visualizations/matrix/index.ts | 1 + .../nodelink/components/NLForce.tsx | 4 +- .../nodelink/components/NLMachineLearning.tsx | 4 +- .../nodelink/components/NLPixi.tsx | 12 ++--- .../nodelink/components/NLPopup.tsx | 2 +- .../nodelink/components/query2NL.tsx | 4 +- .../nodelink/components/utils.tsx | 2 +- .../lib/vis/visualizations/nodelink/index.ts | 12 +++++ .../visualizations/nodelink/nodelinkvis.tsx | 15 ++---- .../nodelink/{Types.tsx => types.ts} | 0 .../lib/vis/visualizations/paohvis/index.ts | 1 + .../vis/visualizations/paohvis/paohvis.tsx | 2 +- .../table_vis/components/Table.tsx | 5 +- .../lib/vis/visualizations/table_vis/index.ts | 1 + 42 files changed, 202 insertions(+), 168 deletions(-) create mode 100644 libs/shared/lib/vis/visualizations/matrix/index.ts create mode 100644 libs/shared/lib/vis/visualizations/nodelink/index.ts rename libs/shared/lib/vis/visualizations/nodelink/{Types.tsx => types.ts} (100%) create mode 100644 libs/shared/lib/vis/visualizations/paohvis/index.ts create mode 100644 libs/shared/lib/vis/visualizations/table_vis/index.ts diff --git a/apps/web/src/app/app.tsx b/apps/web/src/app/app.tsx index 11413ebde..ea709980a 100644 --- a/apps/web/src/app/app.tsx +++ b/apps/web/src/app/app.tsx @@ -2,10 +2,8 @@ import React, { useEffect, useRef, useState } from 'react'; import { useAuthorizationCache, useQuerybuilderGraph, useSessionCache } from '@graphpolaris/shared/lib/data-access'; import { useAppDispatch, useML, useQuerybuilderSettings } from '@graphpolaris/shared/lib/data-access/store'; import { resetGraphQueryResults, queryingBackend } from '@graphpolaris/shared/lib/data-access/store/graphQueryResultSlice'; -import { Query2BackendQuery, QueryBuilder, QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder'; -import { Schema } from '@graphpolaris/shared/lib/schema/panel'; +import { Query2BackendQuery, QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder'; import { Navbar } from '../components/navbar/navbar'; -import { VisualizationPanel } from '@graphpolaris/shared/lib/vis/panel'; import { Resizable } from '@graphpolaris/shared/lib/components/Resizable'; import { DashboardAlerts } from '@graphpolaris/shared/lib/data-access/authorization/dashboardAlerts'; import { EventBus } from '@graphpolaris/shared/lib/data-access/api/eventBus'; @@ -13,6 +11,10 @@ import Onboarding from '../components/onboarding/onboarding'; import { wsQueryRequest } from '@graphpolaris/shared/lib/data-access/broker'; import { URLParams, setParam } from '@graphpolaris/shared/lib/data-access/api/url'; +const Schema = React.lazy(() => import('@graphpolaris/shared/lib/schema/panel')); +const VisualizationPanel = React.lazy(() => import('@graphpolaris/shared/lib/vis/panel')); +const QueryBuilder = React.lazy(() => import('@graphpolaris/shared/lib/querybuilder')); + export type App = { load?: string; }; diff --git a/apps/web/src/app/panels/Visualization.tsx b/apps/web/src/app/panels/Visualization.tsx index 6f83691ec..3a28806cb 100644 --- a/apps/web/src/app/panels/Visualization.tsx +++ b/apps/web/src/app/panels/Visualization.tsx @@ -5,8 +5,9 @@ import { Visualizations, setActiveVisualization } from '@graphpolaris/shared/lib import { DropdownItem, DropdownItemContainer } from '@graphpolaris/shared/lib/components/dropdowns'; import ControlContainer from '@graphpolaris/shared/lib/components/controls'; import { Button } from '@graphpolaris/shared/lib/components/buttons'; -import { createVisualizationComponent } from '@graphpolaris/shared/lib/vis'; +import { VisualizationComponent } from '@graphpolaris/shared/lib/vis'; import VisualizationDialog from './VisualizationDialog'; +import { Settings as SettingsIcon, Apps as AppsIcon } from '@mui/icons-material'; export const VisualizationPanel = () => { const vis = useVisualizationState(); @@ -16,9 +17,6 @@ export const VisualizationPanel = () => { const [visDropdownOpen, setVisDropdownOpen] = useState<boolean>(false); const [showVisSettings, setShowVisSettings] = useState<boolean>(false); - const createVisComponent = createVisualizationComponent(); - const visualizationInstance = createVisComponent(); - return ( <div className="vis-panel h-full w-full overflow-y-auto" style={graphQueryResult.nodes.length === 0 ? { overflow: 'hidden' } : {}}> <VisualizationDialog open={showVisSettings} onClose={() => setShowVisSettings(false)} /> @@ -29,7 +27,7 @@ export const VisualizationPanel = () => { type="secondary" variant="ghost" size="xs" - iconName="Settings" + iconComponent={<SettingsIcon />} onClick={() => { setShowVisSettings(!showVisSettings); }} @@ -38,7 +36,7 @@ export const VisualizationPanel = () => { type="secondary" variant="ghost" size="xs" - iconName="Apps" + iconComponent={<AppsIcon />} onClick={() => { setVisDropdownOpen(!visDropdownOpen); }} @@ -70,7 +68,9 @@ export const VisualizationPanel = () => { {query.nodes.length > 0 ? <p>Query resulted in empty dataset</p> : <p>Query for data to visualize</p>} </div> ) : ( - <div className="w-full h-full">{visualizationInstance}</div> + <div className="w-full h-full"> + <VisualizationComponent /> + </div> )} </div> ); diff --git a/apps/web/src/app/panels/VisualizationDialog.tsx b/apps/web/src/app/panels/VisualizationDialog.tsx index 2c360bfc9..805d201b1 100644 --- a/apps/web/src/app/panels/VisualizationDialog.tsx +++ b/apps/web/src/app/panels/VisualizationDialog.tsx @@ -4,7 +4,7 @@ import { DialogProps } from '@graphpolaris/shared/lib/components/Dialog'; import { useAppDispatch, useVisualizationState } from '@graphpolaris/shared/lib/data-access'; import { updateGeneralSettings, updateVisualizationSettings } from '@graphpolaris/shared/lib/data-access/store/visualizationSlice'; import Input from '@graphpolaris/shared/lib/components/inputs'; -import { globalConfigSchemaTypes, localConfigSchemaType } from '@graphpolaris/shared/lib/vis/Types'; +import { globalConfigSchemaTypes, localConfigSchemaType } from '@graphpolaris/shared/lib/vis/types'; export default function VisualizationDialog(props: DialogProps) { const dispatch = useAppDispatch(); diff --git a/apps/web/src/components/navbar/search/SearchBar.tsx b/apps/web/src/components/navbar/search/SearchBar.tsx index 797b267f6..6ed73c56c 100644 --- a/apps/web/src/components/navbar/search/SearchBar.tsx +++ b/apps/web/src/components/navbar/search/SearchBar.tsx @@ -9,6 +9,7 @@ import { useRecentSearches, } from '@graphpolaris/shared/lib/data-access'; import { filterData } from './similarity'; +import { Search as SearchIcon } from '@mui/icons-material'; import { addSearchResultData, addSearchResultSchema, @@ -16,7 +17,6 @@ import { CATEGORY_KEYS, addRecentSearch, } from '@graphpolaris/shared/lib/data-access/store/searchResultSlice'; -import Icon from '@graphpolaris/shared/lib/components/icon'; const SIMILARITY_THRESHOLD = 0.7; @@ -168,7 +168,7 @@ export function SearchBar({}) { className="flex items-center border border-secondary-300 hover:bg-secondary-50 px-2 rounded text-sm w-44 h-8 text-secondary-900 cursor-pointer" onClick={toggleSearch} > - <Icon name="Search" /> + <SearchIcon /> <span className="ml-1 text-secondary-900"> Type <span className="border border-secondary-900 rounded px-1">/</span> to search </span> @@ -180,7 +180,7 @@ export function SearchBar({}) { {/* <label className="sr-only">Search</label> */} <div className="relative"> <div className="absolute inset-y-0 start-0 flex items-center ps-3 pointer-events-none"> - <Icon name="Search" className="text-secondary500" /> + <SearchIcon className="text-secondary500" /> </div> <input type="text" diff --git a/apps/web/src/components/onboarding/onboarding.tsx b/apps/web/src/components/onboarding/onboarding.tsx index 886d6799d..e7526d3f8 100644 --- a/apps/web/src/components/onboarding/onboarding.tsx +++ b/apps/web/src/components/onboarding/onboarding.tsx @@ -4,6 +4,7 @@ import { useLocation } from 'react-router-dom'; import { Button } from '@graphpolaris/shared/lib/components/buttons'; import { useCases } from './use-cases'; import { useAuthorizationCache } from '@graphpolaris/shared/lib/data-access'; +import { Close } from '@mui/icons-material'; interface OnboardingState { run?: boolean; @@ -56,7 +57,7 @@ export default function Onboarding({}) { {showWalkthrough && ( <div className="bg-accent-light alert absolute bottom-5 left-5 w-fit cursor-pointer z-50"> <Button onClick={startWalkThrough} label={'Start a Tour'} variant="ghost" /> - <Button onClick={() => addWalkthroughCookie()} iconName="Close" variant="ghost" rounded /> + <Button onClick={() => addWalkthroughCookie()} iconComponent={<Close />} variant="ghost" rounded /> </div> )} <Joyride diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index c433dfe4d..9265feb90 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -1,4 +1,4 @@ -import { defineConfig } from 'vite'; +import { defineConfig, splitVendorChunkPlugin } from 'vite'; import react from '@vitejs/plugin-react-swc'; import path from 'path'; import dts from 'vite-plugin-dts'; @@ -8,6 +8,7 @@ import ImportMetaEnvPlugin from '@import-meta-env/unplugin'; export default defineConfig({ plugins: [ react(), + splitVendorChunkPlugin(), // basicSsl(), dts({ insertTypesEntry: true, diff --git a/libs/shared/lib/components/buttons/button.stories.tsx b/libs/shared/lib/components/buttons/button.stories.tsx index e250be5fa..ba7b83568 100644 --- a/libs/shared/lib/components/buttons/button.stories.tsx +++ b/libs/shared/lib/components/buttons/button.stories.tsx @@ -1,6 +1,7 @@ import React from 'react'; import type { Meta, StoryObj } from '@storybook/react'; import { Button } from '.'; +import { ArrowBack } from '@mui/icons-material'; const meta: Meta<typeof Button> = { title: 'Components/Button', @@ -31,9 +32,9 @@ const meta: Meta<typeof Button> = { rounded: { control: 'boolean', }, - iconName: { + iconComponent: { control: 'select', - options: ['ArrowBack', 'DeleteOutline', 'KeyboardArrowLeft', 'Settings'], + options: [], // TODO }, iconPosition: { control: 'select', @@ -98,7 +99,7 @@ export const IconButton: Story = { args: { type: 'primary', variant: 'outline', - iconName: 'ArrowBack', + iconComponent: <ArrowBack />, rounded: true, }, }; diff --git a/libs/shared/lib/components/buttons/index.tsx b/libs/shared/lib/components/buttons/index.tsx index fa96b6ccb..a83936dcc 100644 --- a/libs/shared/lib/components/buttons/index.tsx +++ b/libs/shared/lib/components/buttons/index.tsx @@ -1,6 +1,6 @@ -import React from 'react'; +import React, { ReactElement } from 'react'; import styles from './buttons.module.scss'; -import { Icon, Sizes } from '../icon'; +import Icon, { Sizes } from '../icon'; type ButtonProps = { type?: 'primary' | 'secondary' | 'danger'; @@ -11,7 +11,7 @@ type ButtonProps = { disabled?: boolean; block?: boolean; onClick: (e: any) => void; - iconName?: string; + iconComponent?: React.ReactElement; iconPosition?: 'leading' | 'trailing'; ariaLabel?: string; children?: React.ReactNode; @@ -27,7 +27,7 @@ export function Button({ disabled = false, onClick, block = false, - iconName, + iconComponent, iconPosition = 'leading', ariaLabel, additionalClasses, @@ -91,9 +91,9 @@ export function Button({ return null; } - const iconComponent = iconName ? <Icon name={iconName} size={iconSize} /> : null; + const icon = iconComponent ? <Icon component={iconComponent} size={iconSize} /> : null; - const iconOnlyClass = iconName && !label && !children ? styles['btn-icon-only'] : ''; + const iconOnlyClass = iconComponent && !label && !children ? styles['btn-icon-only'] : ''; return ( <button @@ -103,10 +103,10 @@ export function Button({ aria-label={ariaLabel} {...props} > - {iconPosition === 'leading' && iconComponent} + {iconPosition === 'leading' && icon} {label && <span>{label}</span>} {children && <span>{children}</span>} - {iconPosition === 'trailing' && iconComponent} + {iconPosition === 'trailing' && icon} </button> ); } diff --git a/libs/shared/lib/components/color-mode/index.tsx b/libs/shared/lib/components/color-mode/index.tsx index 6cf8486fe..5ee1198ff 100644 --- a/libs/shared/lib/components/color-mode/index.tsx +++ b/libs/shared/lib/components/color-mode/index.tsx @@ -1,5 +1,6 @@ import React, { useState, useEffect } from 'react'; import { Button } from '../buttons'; // Adjust the import path according to your project structure +import { DarkMode, LightMode } from '@mui/icons-material'; const ColorMode = () => { // Initialize theme state without setting a default yet @@ -37,9 +38,9 @@ const ColorMode = () => { const toggleTheme = () => { setTheme((currentTheme) => (currentTheme === 'light-mode' ? 'dark-mode' : 'light-mode')); }; - const iconName = theme === 'dark-mode' ? 'DarkMode' : 'LightMode'; + const iconComponent = theme === 'dark-mode' ? <DarkMode /> : <LightMode />; - return <Button variant="ghost" iconName={iconName} onClick={toggleTheme} />; + return <Button variant="ghost" iconComponent={iconComponent} onClick={toggleTheme} />; }; export default ColorMode; diff --git a/libs/shared/lib/components/forms/index.tsx b/libs/shared/lib/components/forms/index.tsx index 5669b8e10..194772150 100644 --- a/libs/shared/lib/components/forms/index.tsx +++ b/libs/shared/lib/components/forms/index.tsx @@ -1,5 +1,6 @@ import React, { PropsWithChildren } from 'react'; import { Button } from '../buttons'; +import { Close } from '@mui/icons-material'; export const FormDiv = React.forwardRef<HTMLDivElement, PropsWithChildren<{ className?: string; hAnchor?: string; offset?: string }>>( (props, ref) => { @@ -65,7 +66,7 @@ export const FormDiv = React.forwardRef<HTMLDivElement, PropsWithChildren<{ clas {props.children} </div> ); - } + }, ); export const FormCard = (props: PropsWithChildren<{ className?: string }>) => ( <div className={'card card-bordered bg-light rounded-none ' + (props.className ? props.className : '')}>{props.children}</div> @@ -82,7 +83,7 @@ export const FormTitle = ({ children, title, onClose }: PropsWithChildren<{ titl return ( <div className="card-title p-5 py-0 flex w-full"> <h2 className="w-full">{title}</h2> - <Button rounded variant="ghost" iconName="Close" onClick={() => onClose()} /> + <Button rounded variant="ghost" iconComponent={<Close />} onClick={() => onClose()} /> </div> ); }; diff --git a/libs/shared/lib/components/icon/icon.stories.tsx b/libs/shared/lib/components/icon/icon.stories.tsx index 6eef104db..1b506cf2e 100644 --- a/libs/shared/lib/components/icon/icon.stories.tsx +++ b/libs/shared/lib/components/icon/icon.stories.tsx @@ -1,14 +1,15 @@ import { StoryObj, Meta } from '@storybook/react'; import Icon from '../icon'; +import { ArrowBack, DeleteOutline, KeyboardArrowLeft, Settings } from '@mui/icons-material'; export default { title: 'Components/Icon', component: Icon, decorators: [(Story) => <div className="p-5">{Story()}</div>], argTypes: { - name: { + component: { control: 'select', - options: ['ArrowBack', 'DeleteOutline', 'KeyboardArrowLeft', 'Settings'], + options: [], // TODO }, size: { control: 'radio', diff --git a/libs/shared/lib/components/icon/index.tsx b/libs/shared/lib/components/icon/index.tsx index fb2a905f1..937427828 100644 --- a/libs/shared/lib/components/icon/index.tsx +++ b/libs/shared/lib/components/icon/index.tsx @@ -1,22 +1,19 @@ -import * as Icons from '@mui/icons-material'; -import { ElementType, SVGProps } from 'react'; +import React, { ReactElement } from 'react'; +import { SVGProps } from 'react'; export type Sizes = 16 | 20 | 24 | 28 | 32 | 40; - export type IconProps = SVGProps<SVGSVGElement> & { - name: string; + component: ReactElement<any>; size?: Sizes; }; -export const Icon: React.FC<IconProps> = ({ name, size = 24, ...props }) => { - const IconComponent = (Icons as { [index: string]: ElementType })[name]; - - if (!IconComponent) { - console.error(`No icon found for name: ${name}`); - return null; +export const Icon: React.FC<IconProps> = ({ component, size = 24, ...props }) => { + if (!component) { + console.error(`No icon found`); + return <div></div>; } - return <IconComponent style={{ fontSize: size }} width={size} height={size} {...props} />; + return <div>{React.cloneElement(component, { style: { fontSize: size }, width: size, height: size, ...props })}</div>; }; export default Icon; diff --git a/libs/shared/lib/components/pagination/index.tsx b/libs/shared/lib/components/pagination/index.tsx index 2de28ec31..097275ccc 100644 --- a/libs/shared/lib/components/pagination/index.tsx +++ b/libs/shared/lib/components/pagination/index.tsx @@ -1,5 +1,6 @@ import React, { useRef } from 'react'; import { Button } from '../buttons'; +import { ArrowBack, ArrowForward } from '@mui/icons-material'; export type PaginationProps = { currentPage: number; @@ -45,7 +46,7 @@ export const Pagination: React.FC<PaginationProps> = ({ size={'sm'} label="Previous" variant="outline" - iconName="ArrowBack" + iconComponent={<ArrowBack />} onClick={goToPreviousPage} disabled={currentPage === 1} /> @@ -53,7 +54,7 @@ export const Pagination: React.FC<PaginationProps> = ({ size={'sm'} label="Next" variant="outline" - iconName="ArrowForward" + iconComponent={<ArrowForward />} iconPosition="trailing" onClick={goToNextPage} disabled={currentPage === totalPages} diff --git a/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx b/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx index 1de404128..0a396532c 100644 --- a/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx +++ b/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx @@ -1,8 +1,7 @@ import React, { ReactNode, useEffect, useState, useImperativeHandle, useRef } from 'react'; import { useImmer } from 'use-immer'; -import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; +import { CheckCircleOutline as CheckCircleOutlineIcon, ErrorOutline as ErrorOutlineIcon } from '@mui/icons-material'; import { useAppDispatch, useConfig } from '../store'; -import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; import { removeLastError, removeLastInfo, removeLastSuccess, removeLastWarning } from '../store/configSlice'; import { includes } from 'lodash-es'; import { ReceiveMessageI } from '../broker/types'; @@ -75,7 +74,7 @@ export const DashboardAlerts = (props: { timer?: number }) => { className: 'alert-error', }, undefined, - 'error' + 'error', ); dispatch(removeLastError()); } @@ -93,7 +92,7 @@ export const DashboardAlerts = (props: { timer?: number }) => { className: 'alert-warning', }, undefined, - 'warning' + 'warning', ); dispatch(removeLastWarning()); } @@ -111,7 +110,7 @@ export const DashboardAlerts = (props: { timer?: number }) => { className: 'alert-success bg-primary', }, undefined, - 'info' + 'info', ); dispatch(removeLastInfo()); } @@ -129,7 +128,7 @@ export const DashboardAlerts = (props: { timer?: number }) => { className: 'alert-success', }, undefined, - 'success' + 'success', ); dispatch(removeLastSuccess()); } diff --git a/libs/shared/lib/graph-layout/cytoscape-layouts.ts b/libs/shared/lib/graph-layout/cytoscape-layouts.ts index 42d5d5e0c..7d6e8a7ed 100644 --- a/libs/shared/lib/graph-layout/cytoscape-layouts.ts +++ b/libs/shared/lib/graph-layout/cytoscape-layouts.ts @@ -1,24 +1,10 @@ import cytoscape from 'cytoscape'; -// @ts-ignore -import cise from 'cytoscape-cise'; -// @ts-ignore -import coseBilkent from 'cytoscape-cose-bilkent'; -// @ts-ignore -import elk from 'cytoscape-elk'; - -import fcose from 'cytoscape-fcose'; -import klay from 'cytoscape-klay'; -import dagre from 'cytoscape-dagre'; - import Graph from 'graphology'; import { Attributes } from 'graphology-types'; import { Layout } from './layout'; import { ILayoutFactory } from './layout-creator-usecase'; import { CytoscapeLayoutAlgorithms, LayoutAlgorithm } from './types'; -cytoscape.use(klay); -cytoscape.use(elk); - export type CytoscapeProvider = 'Cytoscape'; type CytoNode = { @@ -204,11 +190,12 @@ class CytoscapeKlay extends Cytoscape { super('Cytoscape_klay'); } - public override layout(graph: Graph<Attributes, Attributes, Attributes>): void { + public override async layout(graph: Graph<Attributes, Attributes, Attributes>): Promise<void> { + await import('cytoscape-klay').then((m) => { + cytoscape.use(m.default); + }); const cytonodes: CytoNode[] = this.convertToCytoscapeModel(graph); - cytoscape.use(klay); - const cy = this.makeCytoscapeInstance(cytonodes); const layout = cy.layout({ @@ -329,7 +316,11 @@ class CytoscapeElk extends Cytoscape { super('Cytoscape_elk'); } - public override layout(graph: Graph<Attributes, Attributes, Attributes>, verbose?: boolean): void { + public override async layout(graph: Graph<Attributes, Attributes, Attributes>, verbose?: boolean): Promise<void> { + //@ts-ignore + await import('cytoscape-elk').then((m) => { + cytoscape.use(m.default); + }); const cytonodes: CytoNode[] = this.convertToCytoscapeModel(graph); const cy = this.makeCytoscapeInstance(cytonodes); @@ -428,10 +419,12 @@ class CytoscapeElk extends Cytoscape { class CytoscapeDagre extends Cytoscape { constructor() { super('Cytoscape_dagre'); - cytoscape.use(dagre); } - public override layout(graph: Graph<Attributes, Attributes, Attributes>, verbose?: boolean): void { + public override async layout(graph: Graph<Attributes, Attributes, Attributes>, verbose?: boolean): Promise<void> { + await import('cytoscape-dagre').then((m) => { + cytoscape.use(m.default); + }); const cytonodes: CytoNode[] = this.convertToCytoscapeModel(graph); const cy = this.makeCytoscapeInstance(cytonodes); @@ -461,10 +454,10 @@ class CytoscapeDagre extends Cytoscape { class CytoscapeFCose extends Cytoscape { constructor() { super('Cytoscape_fcose'); - cytoscape.use(fcose); } - public override layout(graph: Graph<Attributes, Attributes, Attributes>, verbose?: boolean): void { + public override async layout(graph: Graph<Attributes, Attributes, Attributes>, verbose?: boolean): Promise<void> { + await import('cytoscape-fcose').then((m) => cytoscape.use(m.default)); const cytonodes: CytoNode[] = this.convertToCytoscapeModel(graph); const cy = this.makeCytoscapeInstance(cytonodes); @@ -492,10 +485,11 @@ class CytoscapeFCose extends Cytoscape { class CytoscapeCoseBilkent extends Cytoscape { constructor() { super('Cytoscape_cose-bilkent'); - cytoscape.use(coseBilkent); } - public override layout(graph: Graph<Attributes, Attributes, Attributes>, verbose?: boolean): void { + public override async layout(graph: Graph<Attributes, Attributes, Attributes>, verbose?: boolean): Promise<void> { + //@ts-ignore + await import('cytoscape-cose-bilkent').then((m) => cytoscape.use(m.default)); const cytonodes: CytoNode[] = this.convertToCytoscapeModel(graph); const cy = this.makeCytoscapeInstance(cytonodes); @@ -522,10 +516,11 @@ class CytoscapeCoseBilkent extends Cytoscape { class CytoscapeCise extends Cytoscape { constructor() { super('Cytoscape_cise'); - cytoscape.use(cise); } - public override layout(graph: Graph<Attributes, Attributes, Attributes>, verbose?: boolean): void { + public override async layout(graph: Graph<Attributes, Attributes, Attributes>, verbose?: boolean): Promise<void> { + //@ts-ignore + await import('cytoscape-cise').then((m) => cytoscape.use(m.default)); const cytonodes: CytoNode[] = this.convertToCytoscapeModel(graph); const cy = this.makeCytoscapeInstance(cytonodes); diff --git a/libs/shared/lib/graph-layout/graphology-layouts.ts b/libs/shared/lib/graph-layout/graphology-layouts.ts index c4b2d1424..f2ccccd6d 100644 --- a/libs/shared/lib/graph-layout/graphology-layouts.ts +++ b/libs/shared/lib/graph-layout/graphology-layouts.ts @@ -60,7 +60,7 @@ export class GraphologyCircular extends Graphology { super('Graphology_circular'); } - public override layout(graph: Graph<Attributes, Attributes, Attributes>): void { + public override async layout(graph: Graph<Attributes, Attributes, Attributes>): Promise<void> { // To directly assign the positions to the nodes: circular.assign(graph, { scale: 100, @@ -79,7 +79,7 @@ export class GraphologyRandom extends Graphology { super('Graphology_random'); } - public override layout(graph: Graph<Attributes, Attributes, Attributes>): void { + public override async layout(graph: Graph<Attributes, Attributes, Attributes>): Promise<void> { // const positions = random(graph); // To directly assign the positions to the nodes: @@ -107,7 +107,7 @@ export class GraphologyNoverlap extends Graphology { super('Graphology_noverlap'); } - public override layout(graph: Graph<Attributes, Attributes, Attributes>): void { + public override async layout(graph: Graph<Attributes, Attributes, Attributes>): Promise<void> { // To directly assign the positions to the nodes: noverlap.assign(graph, { maxIterations: 10000, @@ -142,7 +142,7 @@ export class GraphologyForceAtlas2 extends Graphology { super('Graphology_forceAtlas2'); } - public override layout(graph: Graph<Attributes, Attributes, Attributes>): void { + public override async layout(graph: Graph<Attributes, Attributes, Attributes>): Promise<void> { forceAtlas2.assign(graph, { iterations: 500, settings: DEFAULT_FORCEATLAS2_SETTINGS, diff --git a/libs/shared/lib/graph-layout/layout.ts b/libs/shared/lib/graph-layout/layout.ts index fae32336f..761994a64 100644 --- a/libs/shared/lib/graph-layout/layout.ts +++ b/libs/shared/lib/graph-layout/layout.ts @@ -7,11 +7,14 @@ import { Providers, LayoutAlgorithm } from './types'; */ export abstract class Layout<provider extends Providers> { - constructor(public provider: provider, public algorithm: LayoutAlgorithm<provider>) { + constructor( + public provider: provider, + public algorithm: LayoutAlgorithm<provider>, + ) { // console.info(`Created the following Layout: ${provider} - ${this.algorithm}`); } - public layout(graph: Graph, verbose?: boolean) { + public async layout(graph: Graph, verbose?: boolean) { // console.log(`${this.provider} [${this.algorithm}] layouting now`); graph.forEachNode((node) => { diff --git a/libs/shared/lib/querybuilder/index.ts b/libs/shared/lib/querybuilder/index.ts index 698ce9f89..378297a42 100644 --- a/libs/shared/lib/querybuilder/index.ts +++ b/libs/shared/lib/querybuilder/index.ts @@ -1,4 +1,8 @@ +import { QueryBuilder } from './panel'; + export * from './panel'; export * from './pills'; export * from './query-utils'; export * from './model'; + +export default QueryBuilder; diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.tsx index 4ee961daa..c2621af5d 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.tsx +++ b/libs/shared/lib/querybuilder/panel/querybuilder.tsx @@ -40,6 +40,7 @@ import { QueryBuilderRelatedNodesPanel } from './querysidepanel/queryBuilderRela import { QueryMLDialog } from './querysidepanel/queryMLDialog'; import { QuerySettingsDialog } from './querysidepanel/querySettingsDialog'; import { ConnectingNodeDataI } from './utils/connectorDrop'; +import { CameraAlt, Cached, Difference, ImportExport, Lightbulb, Settings, Fullscreen, Delete } from '@mui/icons-material'; export type QueryBuilderProps = { onRunQuery?: () => void; @@ -439,13 +440,13 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { <div className="relative flex items-center justify-between z-[2] py-0 px-2 bg-secondary-100 border-b border-secondary-200"> <h1 className="text-xs font-semibold text-secondary-800">Query builder</h1> <ControlContainer> - <Button type="secondary" variant="ghost" size="xs" iconName="Fullscreen" onClick={fitView} /> - <Button type="secondary" variant="ghost" size="xs" iconName="Delete" onClick={() => clearAllNodes()} /> + <Button type="secondary" variant="ghost" size="xs" iconComponent={<Fullscreen />} onClick={fitView} /> + <Button type="secondary" variant="ghost" size="xs" iconComponent={<Delete />} onClick={() => clearAllNodes()} /> <Button type="secondary" variant="ghost" size="xs" - iconName="CameraAlt" + iconComponent={<CameraAlt />} onClick={(event) => { event.stopPropagation(); }} @@ -454,7 +455,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { type="secondary" variant="ghost" size="xs" - iconName="ImportExport" + iconComponent={<ImportExport />} onClick={(event) => { event.stopPropagation(); applyLayout(); @@ -464,7 +465,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { type="secondary" variant="ghost" size="xs" - iconName="Settings" + iconComponent={<Settings />} additionalClasses="query-settings" onClick={(event) => { event.stopPropagation(); @@ -476,7 +477,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { type="secondary" variant="ghost" size="xs" - iconName="Cached" + iconComponent={<Cached />} onClick={(event) => { event.stopPropagation(); if (props.onRunQuery) props.onRunQuery(); @@ -486,7 +487,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { type="secondary" variant="ghost" size="xs" - iconName="Difference" + iconComponent={<Difference />} onClick={(event) => { event.stopPropagation(); if (toggleSettings === 'logic') setToggleSettings(undefined); @@ -497,7 +498,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { type="secondary" variant="ghost" size="xs" - iconName="Lightbulb" + iconComponent={<Lightbulb />} onClick={(event) => { event.stopPropagation(); if (toggleSettings === 'ml') setToggleSettings(undefined); diff --git a/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderLogicPillsPanel.tsx b/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderLogicPillsPanel.tsx index 193a1991f..fdd6fc002 100644 --- a/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderLogicPillsPanel.tsx +++ b/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderLogicPillsPanel.tsx @@ -1,11 +1,13 @@ -import FilterAltIcon from '@mui/icons-material/FilterAlt'; -import FunctionsIcon from '@mui/icons-material/Functions'; -import GridOnIcon from '@mui/icons-material/GridOn'; -import NumbersIcon from '@mui/icons-material/Numbers'; -import AbcIcon from '@mui/icons-material/Abc'; -import { useMemo, useState } from 'react'; -import { AllLogicDescriptions, AllLogicMap, NodeAttribute, QueryElementTypes, QueryGraphNodes, toHandleData } from '../../model'; -import { OnConnectStartParams, XYPosition } from 'reactflow'; +import { + FilterAlt as FilterAltIcon, + Functions as FunctionsIcon, + GridOn as GridOnIcon, + Numbers as NumbersIcon, + Abc as AbcIcon, +} from '@mui/icons-material'; + +import { useState } from 'react'; +import { AllLogicDescriptions, AllLogicMap, QueryElementTypes, toHandleData } from '../../model'; import { ConnectingNodeDataI } from '../utils/connectorDrop'; import { useQuerybuilderGraph } from '@graphpolaris/shared/lib/data-access'; import { toQuerybuilderGraphology, setQuerybuilderGraphology } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; diff --git a/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderRelatedNodesPanel.tsx b/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderRelatedNodesPanel.tsx index 004bf405f..70150333f 100644 --- a/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderRelatedNodesPanel.tsx +++ b/libs/shared/lib/querybuilder/panel/querysidepanel/queryBuilderRelatedNodesPanel.tsx @@ -1,11 +1,6 @@ -import FilterAltIcon from '@mui/icons-material/FilterAlt'; -import FunctionsIcon from '@mui/icons-material/Functions'; -import GridOnIcon from '@mui/icons-material/GridOn'; -import NumbersIcon from '@mui/icons-material/Numbers'; -import AbcIcon from '@mui/icons-material/Abc'; + import { useMemo, useState } from 'react'; -import { AllLogicDescriptions, AllLogicMap, Handles, NodeAttribute, QueryElementTypes, QueryGraphNodes, toHandleData } from '../../model'; -import { OnConnectStartParams, XYPosition } from 'reactflow'; +import { Handles, QueryElementTypes, toHandleData } from '../../model'; import { ConnectingNodeDataI } from '../utils/connectorDrop'; import { useQuerybuilderGraph, useQuerybuilderSettings, useSchemaGraph } from '@graphpolaris/shared/lib/data-access'; import { toQuerybuilderGraphology, setQuerybuilderGraphology } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; @@ -67,7 +62,7 @@ export const QueryBuilderRelatedNodesPanel = (props: { handleData?.handleType === Handles.EntityRight ? schemaGraph.outboundEdges(props.connection.node.schemaKey) : schemaGraph.inboundEdges(props.connection.node.schemaKey); - return edges.map((edge) => ({ ...schemaGraph.getEdgeAttributes(edge), label: edge } as SchemaEdge)); + return edges.map((edge) => ({ ...schemaGraph.getEdgeAttributes(edge), label: edge }) as SchemaEdge); } else if (type === QueryElementTypes.Relation) { // find relations that are connected to the proper neighboring entity of current relation const attributes = schemaGraph.getEdgeAttributes(props.connection.node.schemaKey); @@ -75,7 +70,7 @@ export const QueryBuilderRelatedNodesPanel = (props: { handleData?.handleType === Handles.RelationRight ? schemaGraph.outboundEdges(attributes.to) : schemaGraph.inboundEdges(attributes.from); - return edges.map((edge) => ({ ...schemaGraph.getEdgeAttributes(edge), label: edge } as SchemaEdge)); + return edges.map((edge) => ({ ...schemaGraph.getEdgeAttributes(edge), label: edge }) as SchemaEdge); } return []; @@ -98,7 +93,7 @@ export const QueryBuilderRelatedNodesPanel = (props: { name: entity.name, schemaKey: entity.name, }, - schemaGraph.getNodeAttribute(entity.name, 'attributes') + schemaGraph.getNodeAttribute(entity.name, 'attributes'), ); if (!newNode?.id) throw new Error('Logic node has no id'); @@ -131,7 +126,7 @@ export const QueryBuilderRelatedNodesPanel = (props: { name: relation.collection, collection: relation.collection, }, - schemaGraph.getEdgeAttribute(relation.label, 'attributes') + schemaGraph.getEdgeAttribute(relation.label, 'attributes'), ); if (!newNode?.id) throw new Error('Logic node has no id'); diff --git a/libs/shared/lib/schema/panel/index.ts b/libs/shared/lib/schema/panel/index.ts index e27a6e2f5..c25be6796 100644 --- a/libs/shared/lib/schema/panel/index.ts +++ b/libs/shared/lib/schema/panel/index.ts @@ -1 +1,4 @@ export * from './schema'; + +import Schema from './schema'; +export default Schema; diff --git a/libs/shared/lib/schema/panel/schema.tsx b/libs/shared/lib/schema/panel/schema.tsx index 51e761af8..a70b190d1 100644 --- a/libs/shared/lib/schema/panel/schema.tsx +++ b/libs/shared/lib/schema/panel/schema.tsx @@ -19,6 +19,7 @@ import SelfEdge from '../pills/edges/self-edge'; import { EntityNode } from '../pills/nodes/entity/entity-node'; import { RelationNode } from '../pills/nodes/relation/relation-node'; import { SchemaDialog } from './schemaDialog'; +import { Fullscreen, Cached, Settings } from '@mui/icons-material'; interface Props { content?: string; @@ -79,7 +80,7 @@ export const Schema = (props: Props) => { setAuth(props.auth); }, [props.auth]); - useEffect(() => { + async function layoutGraph() { if (schemaGraphology === undefined || schemaGraphology.order == 0) { setNodes([]); setEdges([]); @@ -88,10 +89,14 @@ export const Schema = (props: Props) => { updateLayout(); const expandedSchema = schemaExpandRelation(schemaGraphology); - layout.current?.layout(expandedSchema); + await layout.current?.layout(expandedSchema); const schemaFlow = schemaGraphology2Reactflow(expandedSchema, settings.connectionType, settings.animatedEdges); setNodes(schemaFlow.nodes); setEdges(schemaFlow.edges); + } + + useEffect(() => { + layoutGraph(); }, [schemaGraph, settings]); useEffect(() => { @@ -99,7 +104,7 @@ export const Schema = (props: Props) => { nds.map((node) => ({ ...node, selected: searchResults.includes(node.id) || searchResults.includes(node.data.label), - })) + })), ); }, [searchResults]); @@ -109,12 +114,12 @@ export const Schema = (props: Props) => { <div className="relative flex items-center justify-between z-[2] py-0 px-2 bg-secondary-100 border-b border-secondary-200"> <h1 className="text-xs font-semibold text-secondary-800">Schema</h1> <ControlContainer> - <Button type="secondary" variant="ghost" size="xs" iconName="Fullscreen" onClick={fitView} /> + <Button type="secondary" variant="ghost" size="xs" iconComponent={<Fullscreen />} onClick={fitView} /> <Button type="secondary" variant="ghost" size="xs" - iconName="Cached" + iconComponent={<Cached />} onClick={(e) => { e.stopPropagation(); if (session.currentSaveState) wsSchemaRequest(session.currentSaveState); @@ -125,7 +130,7 @@ export const Schema = (props: Props) => { type="secondary" variant="ghost" size="xs" - iconName="Settings" + iconComponent={<Settings />} additionalClasses="schema-settings" onClick={(e) => { e.stopPropagation(); diff --git a/libs/shared/lib/vis/index.tsx b/libs/shared/lib/vis/index.tsx index 30215155e..cb72178b7 100644 --- a/libs/shared/lib/vis/index.tsx +++ b/libs/shared/lib/vis/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React, { Suspense, useEffect, useState } from 'react'; import { useAppDispatch } from '@graphpolaris/shared/lib/data-access'; import { addVisualization } from '../data-access/store/visualizationSlice'; import { @@ -9,7 +9,6 @@ import { useVisualizationState, } from '@graphpolaris/shared/lib/data-access/store/hooks'; import { localConfigPropTypes, globalConfigPropTypes, VISComponentType } from './types'; -import { MatrixVisComponent, NodeLinkComponent, PaohVisComponent, RawJSONComponent, TableComponent } from './visualizations'; // export * from './rawjsonvis'; // export * from './nodelink/nodelinkvis'; @@ -18,13 +17,13 @@ import { MatrixVisComponent, NodeLinkComponent, PaohVisComponent, RawJSONCompone // export * from './table_vis/tableVis'; // export * from './mapvis/mapvis'; -export const Visualizations = { - TableVis: TableComponent, - PaohVis: PaohVisComponent, - RawJSONVis: RawJSONComponent, - NodeLinkVis: NodeLinkComponent, - MapVis: '', - MatrixVis: MatrixVisComponent, +export const Visualizations: Record<string, Function> = { + TableVis: () => import('./visualizations/table_vis/tableVis'), + PaohVis: () => import('./visualizations/paohvis/paohvis'), + RawJSONVis: () => import('./visualizations/rawjsonvis/rawjsonvis'), + NodeLinkVis: () => import('./visualizations/nodelink/index'), + // MapVis: () => import(''), + MatrixVis: () => import('./visualizations/matrix/matrixvis'), }; export const VisualizationComponent = () => { @@ -35,13 +34,21 @@ export const VisualizationComponent = () => { const schema = useSchemaGraph(); const ml = useML(); - const VisualizationComponent: VISComponentType = Visualizations[vis.activeVisualization]; + const [visualizationComponent, setVisualizationComponent] = useState<VISComponentType>(); useEffect(() => { - if (VisualizationComponent) { - dispatch(addVisualization({ id: VisualizationComponent.displayName, settings: VisualizationComponent.localConfigSchema })); + if (vis.activeVisualization && vis.activeVisualization in Visualizations) { + Visualizations[vis.activeVisualization]().then((r: any) => { + setVisualizationComponent(r.default); + }); } - }, [dispatch, VisualizationComponent]); + }, [vis.activeVisualization]); + + useEffect(() => { + if (visualizationComponent) { + dispatch(addVisualization({ id: visualizationComponent.displayName, settings: visualizationComponent.localConfigSchema })); + } + }, [vis.activeVisualization]); if (!VisualizationComponent) { return <div className="w-full h-full flex items-center justify-center">Visualization not found</div>; @@ -68,9 +75,10 @@ export const VisualizationComponent = () => { }, {}) as localConfigPropTypes<typeof displayName>); return ( - localConfig && ( + localConfig && + visualizationComponent && ( <div className="w-full h-full"> - <VisualizationComponent.VIS + <visualizationComponent.VIS data={graphQueryResult} schema={schema} ml={ml} diff --git a/libs/shared/lib/vis/panel/index.ts b/libs/shared/lib/vis/panel/index.ts index 676d86491..bda371666 100644 --- a/libs/shared/lib/vis/panel/index.ts +++ b/libs/shared/lib/vis/panel/index.ts @@ -1 +1,4 @@ export * from './visualization'; + +import { VisualizationPanel } from './visualization'; +export default VisualizationPanel; diff --git a/libs/shared/lib/vis/panel/visualization.tsx b/libs/shared/lib/vis/panel/visualization.tsx index 504d09ddc..67557ff45 100644 --- a/libs/shared/lib/vis/panel/visualization.tsx +++ b/libs/shared/lib/vis/panel/visualization.tsx @@ -7,6 +7,7 @@ import ControlContainer from '@graphpolaris/shared/lib/components/controls'; import { Button } from '@graphpolaris/shared/lib/components/buttons'; import { VisualizationComponent } from '../'; import VisualizationDialog from './dialog'; +import { Settings, Apps } from '@mui/icons-material'; export const VisualizationPanel = () => { const vis = useVisualizationState(); @@ -26,7 +27,7 @@ export const VisualizationPanel = () => { type="secondary" variant="ghost" size="xs" - iconName="Settings" + iconComponent={<Settings />} onClick={() => { setShowVisSettings(!showVisSettings); }} @@ -35,7 +36,7 @@ export const VisualizationPanel = () => { type="secondary" variant="ghost" size="xs" - iconName="Apps" + iconComponent={<Apps />} onClick={() => { setVisDropdownOpen(!visDropdownOpen); }} diff --git a/libs/shared/lib/vis/shared/ResultNodeLinkParserUseCase.tsx b/libs/shared/lib/vis/shared/ResultNodeLinkParserUseCase.tsx index 0154edafb..965d7a1d3 100644 --- a/libs/shared/lib/vis/shared/ResultNodeLinkParserUseCase.tsx +++ b/libs/shared/lib/vis/shared/ResultNodeLinkParserUseCase.tsx @@ -3,7 +3,7 @@ * Utrecht University within the Software Project course. * © Copyright Utrecht University (Department of Information and Computing Sciences) */ -import { GraphType, LinkType, NodeType } from '../visualizations/nodelink/Types'; +import { GraphType, LinkType, NodeType } from '../visualizations/nodelink/types'; import { Edge, Node, GraphQueryResult } from '../../data-access/store'; import { ML } from '../../data-access/store/mlSlice'; /** ResultNodeLinkParserUseCase implements methods to parse and translate websocket messages from the backend into a GraphType. */ diff --git a/libs/shared/lib/vis/visualizations/index.tsx b/libs/shared/lib/vis/visualizations/index.tsx index 0009a7afe..2ba6e220c 100644 --- a/libs/shared/lib/vis/visualizations/index.tsx +++ b/libs/shared/lib/vis/visualizations/index.tsx @@ -1,6 +1,6 @@ export * from './rawjsonvis'; -export * from './nodelink/nodelinkvis'; -export * from './paohvis/paohvis'; -export * from './semanticsubstrates/semanticsubstrates'; -export * from './table_vis/tableVis'; -export * from './matrix/matrixvis'; \ No newline at end of file +export * from './nodelink'; +export * from './paohvis'; +export * from './semanticsubstrates'; +export * from './table_vis'; +export * from './matrix'; diff --git a/libs/shared/lib/vis/visualizations/matrix/index.ts b/libs/shared/lib/vis/visualizations/matrix/index.ts new file mode 100644 index 000000000..86c7abe7c --- /dev/null +++ b/libs/shared/lib/vis/visualizations/matrix/index.ts @@ -0,0 +1 @@ +export * from './matrixvis'; diff --git a/libs/shared/lib/vis/visualizations/nodelink/components/NLForce.tsx b/libs/shared/lib/vis/visualizations/nodelink/components/NLForce.tsx index f6c1d9aa3..7aa66407e 100644 --- a/libs/shared/lib/vis/visualizations/nodelink/components/NLForce.tsx +++ b/libs/shared/lib/vis/visualizations/nodelink/components/NLForce.tsx @@ -1,5 +1,5 @@ import { forceCenter, forceCollide, forceLink, forceManyBody, forceRadial, forceSimulation } from 'd3'; -import { GraphType, LinkType, NodeType } from '../Types'; +import { GraphType, LinkType, NodeType } from '../types'; export const simulation = forceSimulation<NodeType, LinkType>(); @@ -13,7 +13,7 @@ export function startSimulation(graph: GraphType, windowSize: { width: number; h forceLink<NodeType, LinkType>() .id((d: any) => d.id) .strength((link, i, links) => (link.mlEdge ? 0.001 : 1)) - .distance(25) + .distance(25), ) .force('charge', forceManyBody().strength(-4).distanceMax(200).distanceMin(0)) .force('center', forceCenter(windowSize.width / 2, windowSize.height / 2).strength(0.02)) diff --git a/libs/shared/lib/vis/visualizations/nodelink/components/NLMachineLearning.tsx b/libs/shared/lib/vis/visualizations/nodelink/components/NLMachineLearning.tsx index 771e88bc6..7f51d9148 100644 --- a/libs/shared/lib/vis/visualizations/nodelink/components/NLMachineLearning.tsx +++ b/libs/shared/lib/vis/visualizations/nodelink/components/NLMachineLearning.tsx @@ -1,8 +1,8 @@ import { useState } from 'react'; import { AttributeData, NodeAttributeData } from '../../../shared/InputDataTypes'; import { AttributeCategory } from '../../../shared/Types'; -import { GraphType, LinkType, NodeType } from '../Types'; -import { ML } from '@graphpolaris/shared/lib/data-access/store/mlSlice'; +import { GraphType, LinkType, NodeType } from '../types'; +import { ML } from '../../../../data-access/store/mlSlice'; export function processLinkPrediction(ml: ML, graph: GraphType): GraphType { if (ml === undefined || ml.linkPrediction === undefined) return graph; diff --git a/libs/shared/lib/vis/visualizations/nodelink/components/NLPixi.tsx b/libs/shared/lib/vis/visualizations/nodelink/components/NLPixi.tsx index 935fe3bc2..b8d90ed2d 100644 --- a/libs/shared/lib/vis/visualizations/nodelink/components/NLPixi.tsx +++ b/libs/shared/lib/vis/visualizations/nodelink/components/NLPixi.tsx @@ -1,11 +1,11 @@ -import { GraphType, LinkType, NodeType } from '../Types'; +import { GraphType, LinkType, NodeType } from '../types'; import { tailwindColors } from 'config'; import { ReactEventHandler, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; import { Application, Circle, Container, FederatedPointerEvent, Graphics, IPointData } from 'pixi.js'; import { binaryColor, nodeColor as nodeColor } from './utils'; import * as force from './NLForce'; import { Viewport } from 'pixi-viewport'; -import { useAppDispatch, useML, useSearchResultData } from '@graphpolaris/shared/lib/data-access'; +import { useAppDispatch, useML, useSearchResultData } from '../../../../data-access'; import { NLPopup } from './NLPopup'; type Props = { @@ -179,10 +179,10 @@ export const NLPixi = (props: Props) => { const lineColor = node.isShortestPathSource ? tailwindColors.entity[950] : node.isShortestPathTarget - ? tailwindColors.relation[950] - : node.selected - ? tailwindColors.entity[400] - : '#000000'; + ? tailwindColors.relation[950] + : node.selected + ? tailwindColors.entity[400] + : '#000000'; const lineWidth = node.selected ? 3 : 1.5; gfx.lineStyle(lineWidth, binaryColor(lineColor)); diff --git a/libs/shared/lib/vis/visualizations/nodelink/components/NLPopup.tsx b/libs/shared/lib/vis/visualizations/nodelink/components/NLPopup.tsx index 8e413b31a..7e07fbe08 100644 --- a/libs/shared/lib/vis/visualizations/nodelink/components/NLPopup.tsx +++ b/libs/shared/lib/vis/visualizations/nodelink/components/NLPopup.tsx @@ -1,5 +1,5 @@ import { IPointData } from 'pixi.js'; -import { NodeType } from '../Types'; +import { NodeType } from '../types'; export type NodelinkPopupProps = { data: { node: NodeType; pos: IPointData }; diff --git a/libs/shared/lib/vis/visualizations/nodelink/components/query2NL.tsx b/libs/shared/lib/vis/visualizations/nodelink/components/query2NL.tsx index 4aa527a8d..a2c56a6ff 100644 --- a/libs/shared/lib/vis/visualizations/nodelink/components/query2NL.tsx +++ b/libs/shared/lib/vis/visualizations/nodelink/components/query2NL.tsx @@ -3,7 +3,7 @@ * Utrecht University within the Software Project course. * © Copyright Utrecht University (Department of Information and Computing Sciences) */ -import { GraphType, LinkType, NodeType } from '../Types'; +import { GraphType, LinkType, NodeType } from '../types'; import { Edge, Node, GraphQueryResult } from '../../../../data-access/store'; import { ML } from '../../../../data-access/store/mlSlice'; import { processML } from './NLMachineLearning'; @@ -252,7 +252,7 @@ export function parseQueryResult(queryResult: GraphQueryResult, ml: ML, options: //TODO: is this in use? const maxCount = links.reduce( (previousValue, currentValue) => (currentValue.value > previousValue ? currentValue.value : previousValue), - -1 + -1, ); //TODO: is this in use? // Scale the value from 0 to 50 diff --git a/libs/shared/lib/vis/visualizations/nodelink/components/utils.tsx b/libs/shared/lib/vis/visualizations/nodelink/components/utils.tsx index 20e348a3f..bb8094ccb 100644 --- a/libs/shared/lib/vis/visualizations/nodelink/components/utils.tsx +++ b/libs/shared/lib/vis/visualizations/nodelink/components/utils.tsx @@ -1,5 +1,5 @@ import { tailwindColors } from 'config'; -import { GraphType, LinkType, NodeType } from '../Types'; +import { GraphType, LinkType, NodeType } from '../types'; /** * Colour is a function that takes a string of a number and returns a number of a color out of the d3 color scheme. diff --git a/libs/shared/lib/vis/visualizations/nodelink/index.ts b/libs/shared/lib/vis/visualizations/nodelink/index.ts new file mode 100644 index 000000000..e019d6524 --- /dev/null +++ b/libs/shared/lib/vis/visualizations/nodelink/index.ts @@ -0,0 +1,12 @@ +import React from 'react'; +import { VISComponentType } from '../../types'; +import { displayName, NodeLinkVis, localConfigSchema } from './nodelinkvis'; +export type { NodeLinkProps } from './nodelinkvis'; + +export const NodeLinkComponent: VISComponentType = { + displayName, + VIS: NodeLinkVis, + localConfigSchema: localConfigSchema, +}; + +export default NodeLinkComponent; diff --git a/libs/shared/lib/vis/visualizations/nodelink/nodelinkvis.tsx b/libs/shared/lib/vis/visualizations/nodelink/nodelinkvis.tsx index b72741285..1ddefa86e 100644 --- a/libs/shared/lib/vis/visualizations/nodelink/nodelinkvis.tsx +++ b/libs/shared/lib/vis/visualizations/nodelink/nodelinkvis.tsx @@ -1,13 +1,13 @@ import React, { useEffect, useRef, useState } from 'react'; import * as PIXI from 'pixi.js'; -import { GraphType, LinkType, NodeType } from './Types'; +import { GraphType, LinkType, NodeType } from './types'; import { NLPixi } from './components/NLPixi'; import { parseQueryResult } from './components/query2NL'; import { useImmer } from 'use-immer'; import { ML, setShortestPathSource, setShortestPathTarget } from '../../../data-access/store/mlSlice'; import { VisualizationPropTypes, VISComponentType } from '../../types'; -export interface NodeLinkProps {} +export type NodeLinkProps = {}; /** Return default radius */ function Radius() { @@ -29,7 +29,7 @@ export interface NodeLinkComponentState { scalexy: number; } -const displayName = 'NodeLinkVis'; +export const displayName = 'NodeLinkVis'; export const NodeLinkVis = React.memo(({ data, ml, dispatch }: VisualizationPropTypes<typeof displayName>) => { const ref = useRef<HTMLDivElement>(null); @@ -111,12 +111,5 @@ export const NodeLinkVis = React.memo(({ data, ml, dispatch }: VisualizationProp ); }); -const localConfigSchema = {}; - -export const NodeLinkComponent: VISComponentType = { - displayName: displayName, - VIS: NodeLinkVis, - localConfigSchema: localConfigSchema, -}; - +export const localConfigSchema = {}; export default NodeLinkVis; diff --git a/libs/shared/lib/vis/visualizations/nodelink/Types.tsx b/libs/shared/lib/vis/visualizations/nodelink/types.ts similarity index 100% rename from libs/shared/lib/vis/visualizations/nodelink/Types.tsx rename to libs/shared/lib/vis/visualizations/nodelink/types.ts diff --git a/libs/shared/lib/vis/visualizations/paohvis/index.ts b/libs/shared/lib/vis/visualizations/paohvis/index.ts new file mode 100644 index 000000000..73e83811d --- /dev/null +++ b/libs/shared/lib/vis/visualizations/paohvis/index.ts @@ -0,0 +1 @@ +export * from './paohvis'; diff --git a/libs/shared/lib/vis/visualizations/paohvis/paohvis.tsx b/libs/shared/lib/vis/visualizations/paohvis/paohvis.tsx index 915e793f0..0e81c7bfb 100644 --- a/libs/shared/lib/vis/visualizations/paohvis/paohvis.tsx +++ b/libs/shared/lib/vis/visualizations/paohvis/paohvis.tsx @@ -646,4 +646,4 @@ export const PaohVisComponent: VISComponentType = { localConfigSchema: localConfigSchema, }; -export default PaohVis; +export default PaohVisComponent; diff --git a/libs/shared/lib/vis/visualizations/table_vis/components/Table.tsx b/libs/shared/lib/vis/visualizations/table_vis/components/Table.tsx index 65c10c0fb..dddec9dc4 100644 --- a/libs/shared/lib/vis/visualizations/table_vis/components/Table.tsx +++ b/libs/shared/lib/vis/visualizations/table_vis/components/Table.tsx @@ -1,13 +1,14 @@ import React, { useState, useEffect, useMemo } from 'react'; import * as d3 from 'd3'; import Pagination from '@graphpolaris/shared/lib/components/pagination'; -import Icon from '@graphpolaris/shared/lib/components/icon'; import BarPlot from '@graphpolaris/shared/lib/components/charts/barplot'; import { NodeAttributes } from '@graphpolaris/shared/lib/data-access/store/graphQueryResultSlice'; import { SchemaAttributeTypes } from '@graphpolaris/shared/lib/schema'; import styles from './table.module.scss'; +import { ArrowDownward, ArrowUpward, Sort } from '@mui/icons-material'; +import Icon from '@graphpolaris/shared/lib/components/icon'; export type AugmentedNodeAttributes = { attribute: NodeAttributes; type: Record<string, SchemaAttributeTypes> }; @@ -213,7 +214,7 @@ export const Table = ({ data, itemsPerPage, showBarPlot }: TableProps) => { } > <Icon - name={sortColumn === item ? (sortOrder === 'asc' ? 'ArrowDownward' : 'ArrowUpward') : 'Sort'} + component={sortColumn === item ? sortOrder === 'asc' ? <ArrowDownward /> : <ArrowUpward /> : <Sort />} size={20} className={`${sortColumn === item && sortOrder ? 'text-secondary-800' : 'text-secondary-500'}`} /> diff --git a/libs/shared/lib/vis/visualizations/table_vis/index.ts b/libs/shared/lib/vis/visualizations/table_vis/index.ts new file mode 100644 index 000000000..87bfb9628 --- /dev/null +++ b/libs/shared/lib/vis/visualizations/table_vis/index.ts @@ -0,0 +1 @@ +export * from './tableVis'; -- GitLab