Skip to content

Commit

Permalink
Merge branch 'explore-cytoscape' of https://github.com/finos-labs/arc…
Browse files Browse the repository at this point in the history
…hitecture-as-code into explore-cytoscape
  • Loading branch information
aidanm3341 committed Dec 18, 2024
2 parents 127b951 + 897441d commit 227ea10
Show file tree
Hide file tree
Showing 18 changed files with 551 additions and 31 deletions.
449 changes: 449 additions & 0 deletions calm-visualizer/example.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions calm-visualizer/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@
display: flex;
justify-content: center;
}

.z-1 {
z-index: 1;
}
24 changes: 21 additions & 3 deletions calm-visualizer/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
import { useState } from 'react';
import './App.css';
import Drawer from './components/drawer/Drawer';
import Menu from './components/menu/Menu';
import { CALMInstantiation } from '../../shared/src/types';
import Navbar from './components/navbar/Navbar';

function App() {
const [title, setTitle] = useState<string | undefined>(undefined);
const [instance, setCALMInstance] = useState<CALMInstantiation | undefined>(undefined);

async function handleFile(instanceFile: File) {
const title = instanceFile.name;
const file = await instanceFile.text();
const instance = JSON.parse(file);

setTitle(title);
setCALMInstance(instance);
}

return (
<>
<Drawer />
</>
<div className="h-screen flex flex-col">
<Navbar />
<Menu callback={handleFile} />
<Drawer calmInstance={instance} title={title} />
</div>
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import './cytoscape.css';
import { useEffect, useRef, useState } from 'react';
import cytoscape, { Core, EdgeSingular, NodeSingular } from 'cytoscape';
Expand Down Expand Up @@ -27,11 +28,11 @@ const fcoseLayoutOptions = {
nodeSeparation: 175,
// Power iteration tolerance
piTol: 0.0000001,
nodeRepulsion: (node) => 450000,
nodeRepulsion: (_node: unknown) => 450000,
// Ideal edge (non nested) length
idealEdgeLength: (edge) => 500,
idealEdgeLength: (_edge: unknown) => 500,
// Divisor to compute edge forces
edgeElasticity: (edge) => 0.85,
edgeElasticity: (_edge: unknown) => 0.85,
// Nesting factor (multiplier) to compute ideal edge length for nested edges
nestingFactor: 0.1,
// Maximum number of iterations to perform - this is a suggested value and might be adjusted by the algorithm as required
Expand Down Expand Up @@ -67,11 +68,12 @@ export type Edge = {
};

interface Props {
title: string;
nodes: Node[];
edges: Edge[];
}

const CytoscapeRenderer = ({ nodes = [], edges = [] }: Props) => {
const CytoscapeRenderer = ({ title, nodes = [], edges = [] }: Props) => {
const cyRef = useRef<HTMLDivElement>(null);
const [cy, setCy] = useState<Core | null>(null);
const [selectedNode, setSelectedNode] = useState<Node['data'] | null>(null);
Expand Down Expand Up @@ -164,16 +166,16 @@ const CytoscapeRenderer = ({ nodes = [], edges = [] }: Props) => {

return (
<div className="relative flex m-auto border">
<div className="text-l font-bold absolute">{title}</div>
<div
ref={cyRef}
className="flex-1 bg-white"
className="flex-1 bg-white visualizer"
style={{
height: '100vh',
}}
/>

{selectedNode && (
<div className="absolute right-0 top-0 h-full">
<div className="absolute right-0 h-full">
<Sidebar
selectedData={selectedNode}
closeSidebar={() => setSelectedNode(null)}
Expand All @@ -182,7 +184,7 @@ const CytoscapeRenderer = ({ nodes = [], edges = [] }: Props) => {
)}

{selectedEdge && (
<div className="absolute right-0 top-0 h-full">
<div className="absolute right-0 h-full">
<Sidebar
selectedData={selectedEdge}
closeSidebar={() => setSelectedEdge(null)}
Expand Down
31 changes: 12 additions & 19 deletions calm-visualizer/src/components/drawer/Drawer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import Sidebar from '../sidebar/Sidebar';
import { useState } from 'react';
import FileUploader from '../fileuploader/FileUploader';
import CytoscapeRenderer, { Node, Edge } from '../cytoscape-renderer/CytoscapeRenderer.tsx';
import {
CALMComposedOfRelationship,
Expand All @@ -11,6 +10,11 @@ import {
CALMInstantiation,
} from '../../../../shared/src';

interface DrawerProps {
calmInstance?: CALMInstantiation;
title?: string;
}

function isComposedOf(relationship: CALMRelationship): relationship is CALMComposedOfRelationship {
return 'composed-of' in relationship['relationship-type'];
}
Expand Down Expand Up @@ -73,16 +77,15 @@ const getDeployedInRelationships = (calmInstance: CALMInstantiation) => {
return deployedInRelationships;
};

function Drawer() {
function Drawer({ calmInstance, title }: DrawerProps) {
const [selectedNode, setSelectedNode] = useState(null);
const [calmInstance, setCALMInstance] = useState<CALMInstantiation | null>(null);

function closeSidebar() {
setSelectedNode(null);
}

function getNodes(): Node[] {
if (!calmInstance) return [];
if (!calmInstance || !calmInstance.relationships) return [];

const composedOfRelationships = getComposedOfRelationships(calmInstance);
const deployedInRelationships = getDeployedInRelationships(calmInstance);
Expand Down Expand Up @@ -162,14 +165,8 @@ function Drawer() {
const edges = getEdges();
const nodes = getNodes();

async function handleFile(instanceFile: File) {
const instanceString = await instanceFile.text();
const calmInstance: CALMInstantiation = JSON.parse(instanceString);
setCALMInstance(calmInstance);
}

return (
<>
<div className="flex-1 flex overflow-hidden">
<div className={`drawer drawer-end ${selectedNode ? 'drawer-open' : ''}`}>
<input
type="checkbox"
Expand All @@ -178,21 +175,17 @@ function Drawer() {
onChange={closeSidebar}
/>
<div className="drawer-content">
<div className="flex">
<div className="h-24 w-80 flex flex-col justify-center bg-blue-700 max-w-64 rounded-tr-[4rem] rounded-br-[4rem]">
<div className="text-4xl ml-4 text-white">CALM UI</div>
</div>
<FileUploader callback={handleFile} />
</div>
<div id="app m-5">
{calmInstance && <CytoscapeRenderer nodes={nodes} edges={edges} />}
{calmInstance && (
<CytoscapeRenderer title={title || ''} nodes={nodes} edges={edges} />
)}
</div>
</div>
{selectedNode && (
<Sidebar selectedData={selectedNode} closeSidebar={closeSidebar} />
)}
</div>
</>
</div>
);
}

Expand Down
44 changes: 44 additions & 0 deletions calm-visualizer/src/components/menu/Menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
interface MenuProps {
callback: (instanceFile: File) => void;
}

function Menu({ callback }: MenuProps) {
const handleUpload = (file: File) => {
callback(file);
};

return (
<ul className="menu menu-horizontal px-1 z-1">
<li>
<details>
<summary>File</summary>
<ul className="p-2 z-1">
<li>
<label>
Upload
<input
id="file"
type="file"
className="hidden"
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
e.target.files && handleUpload(e.target.files[0])
}
/>
</label>
</li>
<li>
<label>Save As</label>
</li>
</ul>
</details>
</li>
<li>
<details>
<summary>Edit</summary>
</details>
</li>
</ul>
);
}
// TODO: add edit ability
export default Menu;
10 changes: 10 additions & 0 deletions calm-visualizer/src/components/navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function Navbar() {
return (
<div className="navbar bg-base-300">
<div className="navbar-start">
<a className="btn btn-ghost text-xl">CALM UI</a>
</div>
</div>
);
}
export default Navbar;
2 changes: 1 addition & 1 deletion calm-visualizer/src/components/sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function Sidebar({ selectedData, closeSidebar }: SidebarProps) {
const isCALMEdge = isCALMEdgeData(selectedData);
console.log('This is the selectedData => ', selectedData);
return (
<div className="fixed right-0 top-0 h-full w-80 bg-gray-100 shadow-lg">
<div className="fixed right-0 h-full w-80 bg-gray-100 shadow-lg">
<label htmlFor="node-details" className="drawer-overlay" onClick={closeSidebar}></label>
<div className="menu bg-base-200 text-base-content min-h-full w-80 p-4">
<div className="flex justify-end">
Expand Down

0 comments on commit 227ea10

Please sign in to comment.