Skip to content

Commit

Permalink
chore: saving changes
Browse files Browse the repository at this point in the history
  • Loading branch information
raulMarvanWizeline committed Mar 26, 2024
1 parent 6857511 commit 4b775cb
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 126 deletions.
64 changes: 9 additions & 55 deletions app/components/charts/BubbleChart.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable no-unexpected-multiline */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { FC, useEffect, useRef, useState } from "react";
import * as d3 from "d3";
import { NodeType } from "~/types";
import { ZoomControl } from "../zoom/ZoomControl";
import ModalInformation from "../information/ModalInformation";
import { useScreenSize } from "~/context/ScreenSizeContext";
import { Breadcrumb } from "../breadcrumb/Breadcrumb";

interface BubbleChartProps {
data: NodeType;
modalData: any;
onSelectNodePath?: (args: any) => void;
onSelectNode?: (args: any) => void;
onZoom?: (args: any) => void;
}

const colors = [
Expand All @@ -23,45 +20,21 @@ const colors = [
"#E5C8A6",
"#4D5D6D",
];
const minNodeRadius = 100;

const BubbleChart: FC<BubbleChartProps> = ({
data,
modalData,
onSelectNodePath,
onSelectNode,
}) => {
const svgRef = useRef<SVGSVGElement>(null);
const [isSVGRendered, setIsSVGRendered] = useState(false);
const [zoomPercentage, setZoomPercentage] = useState(100);
const [selectedNode, setSelectedNode] = useState<NodeType | null>(null);
const [isInfoModalOpen, setIsInfoModalOpen] = useState(false);
const { isDesktop, isTablet } = useScreenSize();
const size = isDesktop ? 900 : isTablet ? 600 : 300;
const domainMinValue = 0;
const domainMaxValue = 5;
const minFontSize = 1;
const maxFontSize = 22;
const [nodeAncestors, setNodeAncestors] = useState<string[]>([]);

const handleIsInfoModalOpen = () => {
setIsInfoModalOpen(true);
};

const handleIsInfoModalClose = () => {
setSelectedNode(null);
setIsInfoModalOpen(false);
};

const handleZoomChange = (newZoomPercentage: number) => {
setZoomPercentage(newZoomPercentage);
// TODO: Add here the zoom handler for the chart
};

useEffect(() => {
if (selectedNode) {
handleIsInfoModalOpen();
}
}, [selectedNode]);

useEffect(() => {
if (!svgRef.current || isSVGRendered) return;
Expand Down Expand Up @@ -123,6 +96,7 @@ const BubbleChart: FC<BubbleChartProps> = ({
.style("visibility", "visible");
} else {
setSelectedNode(d as any);
onSelectNode && onSelectNode((d?.data as any)?.name ?? "");
event.stopPropagation();
}

Expand All @@ -133,8 +107,7 @@ const BubbleChart: FC<BubbleChartProps> = ({
currentNode = currentNode.parent;
}

onSelectNode && onSelectNode(nodePath);
setNodeAncestors(nodePath);
onSelectNodePath && onSelectNodePath(nodePath);
});

const label = svg
Expand Down Expand Up @@ -228,13 +201,15 @@ const BubbleChart: FC<BubbleChartProps> = ({
function zoom(event: d3.D3ZoomEvent<SVGSVGElement, unknown>, d: any) {
if (selectedNode !== null || !d.children) return;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const focus0 = focus;

focus = d;

const transition = svg
.transition()
.duration((event as any).altKey ? 7500 : 750)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
.tween("zoom", (d) => {
const i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2]);
return (t) => zoomTo(i(t));
Expand All @@ -254,30 +229,9 @@ const BubbleChart: FC<BubbleChartProps> = ({
});
}
setIsSVGRendered(true);
}, [data, isSVGRendered, onSelectNode, selectedNode, size]);

return (
<>
<svg ref={svgRef}></svg>
{isInfoModalOpen && selectedNode && !selectedNode?.children && (
<ModalInformation
onClose={handleIsInfoModalClose}
nodeName={selectedNode?.data?.name}
modalData={modalData}
/>
)}
}, [data, isSVGRendered, onSelectNode, onSelectNodePath, selectedNode, size]);

<div className="hidden sm:block absolute bottom-0 left-0 mb-4 ml-4">
<Breadcrumb path={nodeAncestors} />
</div>
<div className="hidden sm:block absolute bottom-0 right-0 mb-4 mr-4">
<ZoomControl
zoomPercentage={zoomPercentage}
onZoomChange={handleZoomChange}
/>
</div>
</>
);
return <svg ref={svgRef}></svg>;
};

export default BubbleChart;
15 changes: 10 additions & 5 deletions app/components/information/ModalInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Pill from "../common/Pill";

interface ModalInformationProps {
nodeName: string;
modalData: AIProducts;
modalData: AIProducts | null;
onClose: () => void;
className?: string;
}
Expand All @@ -20,10 +20,13 @@ const ModalInformation: FC<ModalInformationProps> = ({
className,
}) => {
const name = nodeName;
const product = modalData.find((product) => product.name === name);
const product =
modalData && modalData.find((product) => product.name === name);
const relatedTools = modalData
?.filter((p) => p.name !== name && p.ecosystem === product?.ecosystem)
.map((p) => p.name);
? modalData
?.filter((p) => p.name !== name && p.ecosystem === product?.ecosystem)
.map((p) => p.name)
: [];
// TODO - Replace information with actual data from the node
const bestFeatures: any[] = [];
// TODO - Replace information with actual data from the node
Expand All @@ -41,7 +44,9 @@ const ModalInformation: FC<ModalInformationProps> = ({

return (
product && (
<div className={`fixed top-4 right-4 w-96 h-auto max-h-[90vh] bg-secondary rounded-md p-2 gap-2 overflow-auto !z-40 ${className}`}>
<div
className={`fixed top-4 right-4 w-96 h-auto max-h-[90vh] bg-secondary rounded-md p-2 gap-2 overflow-auto !z-40 ${className}`}
>
<div className="flex justify-between items-center mb-2">
<h2 className="text-white border border-primary p-4 mr-2 w-full rounded-md">
{product?.name}
Expand Down
2 changes: 1 addition & 1 deletion app/components/navigation/ViewSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const ViewSwitcher: FC<ViewSwitcherProps> = ({ onSwitch }) => {
};

return (
<div className="flex justify-between items-center border border-top-nav-border rounded w-28 h-9 p-2 bg-primary z-[9999] fixed right-1/2 transform translate-x-1/2">
<div className="flex justify-between items-center border border-top-nav-border rounded w-28 h-9 p-2 bg-primary fixed right-1/2 transform translate-x-1/2">
<IconButton className="!p-0" onClick={handleChartClick}>
<BubbleChart
className={`w-5 h-5 cursor-pointer ${
Expand Down
41 changes: 16 additions & 25 deletions app/components/tables/AIProductTable.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { FC, useState } from "react";
import {
Table,
Expand All @@ -13,16 +14,17 @@ import {
InputLabel,
} from "@mui/material";
import { Visibility } from "@mui/icons-material";
import { AIProduct, AIProducts } from "~/types";
import ModalInformation from "../information/ModalInformation";
import { AIProducts } from "~/types";

interface AIProductTableProps {
products: AIProducts;
onViewDetails: (args?: any) => void;
}

const AIProductTable: FC<AIProductTableProps> = ({ products }) => {
const [selectedProduct, setSelectedProduct] = useState<AIProduct | null>(null);
const [isInfoModalOpen, setIsInfoModalOpen] = useState(false);
const AIProductTable: FC<AIProductTableProps> = ({
products,
onViewDetails,
}) => {
const [filters, setFilters] = useState({
licence: "All",
ecosystem: "All",
Expand Down Expand Up @@ -79,15 +81,9 @@ const AIProductTable: FC<AIProductTableProps> = ({ products }) => {
)
);

const handleIsInfoOpenModal = (product: AIProduct) => {
setSelectedProduct(product);
setIsInfoModalOpen(true);
}

const handleIsInfoModalClose = () => {
setSelectedProduct(null);
setIsInfoModalOpen(false);
}
const handleViewDetails = (productName: string) => {
onViewDetails(productName);
};

return (
<>
Expand Down Expand Up @@ -169,7 +165,7 @@ const AIProductTable: FC<AIProductTableProps> = ({ products }) => {
<TableRow className="bg-primary font-montserrat">
<TableCell className="!text-white-alt">Name</TableCell>
<TableCell className="!text-white-alt">Category</TableCell>
<TableCell className="!text-white-alt">Ecosystem</TableCell>
<TableCell className="!text-white-alt">AI Model</TableCell>
<TableCell className="!text-white-alt">License</TableCell>
<TableCell className="!text-white-alt">Details</TableCell>
</TableRow>
Expand All @@ -181,7 +177,7 @@ const AIProductTable: FC<AIProductTableProps> = ({ products }) => {
className="bg-secondary font-nunito"
>
<TableCell className="!text-white-alt">
{product.name}
{product.name}
</TableCell>
<TableCell className="!text-white-alt max-w-[350px]">
{product.category.join(", ")}
Expand All @@ -193,7 +189,10 @@ const AIProductTable: FC<AIProductTableProps> = ({ products }) => {
{product.licence}
</TableCell>
<TableCell className="!text-center">
<IconButton className="!p-0" onClick={() => handleIsInfoOpenModal(product)}>
<IconButton
className="!p-0"
onClick={() => handleViewDetails(product.name)}
>
<Visibility className="!fill-white-alt" />
</IconButton>
</TableCell>
Expand All @@ -204,14 +203,6 @@ const AIProductTable: FC<AIProductTableProps> = ({ products }) => {
</TableContainer>
</div>
</div>
{isInfoModalOpen && selectedProduct && (
<ModalInformation
onClose={handleIsInfoModalClose}
nodeName={selectedProduct.name}
modalData={products}
className="max-h-[95vh]"
/>
)}
</>
);
};
Expand Down
30 changes: 30 additions & 0 deletions app/context/ModalContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { createContext, useState, ReactNode, FC } from "react";

interface ModalContextProps {
isModalOpen: boolean;
openModal: () => void;
closeModal: () => void;
}

export const ModalContext = createContext<ModalContextProps>({
isModalOpen: false,
openModal: () => {},
closeModal: () => {},
});

interface ModalProviderProps {
children: ReactNode;
}

export const ModalProvider: FC<ModalProviderProps> = ({ children }) => {
const [isModalOpen, setIsModalOpen] = useState(false);

const openModal = () => setIsModalOpen(true);
const closeModal = () => setIsModalOpen(false);

return (
<ModalContext.Provider value={{ isModalOpen, openModal, closeModal }}>
{children}
</ModalContext.Provider>
);
};
3 changes: 2 additions & 1 deletion app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from "@remix-run/react";
import "./tailwind.css";
import { ScreenSizeProvider } from "./context/ScreenSizeContext";
import { ModalProvider } from "./context/ModalContext";

export function Layout({ children }: { children: React.ReactNode }) {
return (
Expand All @@ -20,7 +21,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
</head>
<body>
<ScreenSizeProvider>
{children}
<ModalProvider>{children}</ModalProvider>
</ScreenSizeProvider>
<ScrollRestoration />
<Scripts />
Expand Down
Loading

0 comments on commit 4b775cb

Please sign in to comment.