Skip to content

Commit

Permalink
Merge pull request #7 from wizeline/feat/GL-52-table-display
Browse files Browse the repository at this point in the history
Feat/gl 52 table display
  • Loading branch information
raulMarvanWizeline authored Mar 26, 2024
2 parents 4b99201 + 4b775cb commit a023e10
Show file tree
Hide file tree
Showing 10 changed files with 437 additions and 87 deletions.
59 changes: 10 additions & 49 deletions app/components/charts/BubbleChart.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +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";

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

const colors = [
Expand All @@ -22,45 +20,22 @@ 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 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 @@ -117,10 +92,11 @@ const BubbleChart: FC<BubbleChartProps> = ({
setSelectedNode(null);
focus !== d && (zoom(event, d), event.stopPropagation());
d3.selectAll("circle")
.filter((dd: any) => dd.parent === d)
.filter((dd: any) => dd?.parent === d)
.style("visibility", "visible");
} else {
setSelectedNode(d as any);
onSelectNode && onSelectNode((d?.data as any)?.name ?? "");
event.stopPropagation();
}

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

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

const label = svg
Expand Down Expand Up @@ -225,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 @@ -251,26 +229,9 @@ const BubbleChart: FC<BubbleChartProps> = ({
});
}
setIsSVGRendered(true);
}, [data, isSVGRendered, onSelectNode, selectedNode, size]);
}, [data, isSVGRendered, onSelectNode, onSelectNodePath, selectedNode, size]);

return (
<>
<svg ref={svgRef}></svg>
{isInfoModalOpen && selectedNode && !selectedNode?.children && (
<ModalInformation
onClose={handleIsInfoModalClose}
node={selectedNode}
modalData={modalData}
/>
)}
<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;
4 changes: 2 additions & 2 deletions app/components/charts/SunburstChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ const SunburstChart = (props: SunburstElementProps) => {
{isInfoModalOpen && selectedNode && !selectedNode?.children && (
<ModalInformation
onClose={handleIsInfoModalClose}
node={selectedNode}
modalData={{}}
nodeName={selectedNode?.name}
modalData={[]}
/>
)}
</>
Expand Down
25 changes: 16 additions & 9 deletions app/components/information/ModalInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,30 @@ import { OpenInNew } from "@mui/icons-material";
import CloseIcon from "@mui/icons-material/Close";
import { IconButton } from "@mui/material";
import { FC } from "react";
import { AIProducts, NodeType } from "~/types";
import { AIProducts } from "~/types";
import Pill from "../common/Pill";

interface ModalInformationProps {
node: NodeType | null;
modalData: AIProducts;
nodeName: string;
modalData: AIProducts | null;
onClose: () => void;
className?: string;
}

const ModalInformation: FC<ModalInformationProps> = ({
node,
nodeName,
modalData,
onClose,
className,
}) => {
const name = node?.data?.name ?? node?.name;
const product = modalData.find((product) => product.name === name);
const name = nodeName;
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 @@ -39,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-50">
<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/TopNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const TopNavigation: React.FC<Props> = ({

return (
<>
<div className="flex justify-between items-center border border-top-nav-border rounded w-28 h-9 p-2 bg-primary z-[9999]">
<div className="flex justify-between items-center border border-top-nav-border rounded w-28 h-9 p-2 bg-primary">
<IconButton className="!p-0" onClick={() => {}}>
<HelpOutlineOutlinedIcon className="w-5 h-5 !fill-white cursor-pointer" />
</IconButton>
Expand Down
57 changes: 57 additions & 0 deletions app/components/navigation/ViewSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { FC, useState } from "react";
import { IconButton } from "@mui/material";
import TableChartIcon from "@mui/icons-material/TableChart";
import { BubbleChart } from "@mui/icons-material";

export enum ViewType {
Table,
BubbleChart,
}

interface ViewSwitcherProps {
onSwitch?: (args?: any) => void;
}

const ViewSwitcher: FC<ViewSwitcherProps> = ({ onSwitch }) => {
const [currentView, setCurrentView] = useState<ViewType>(
ViewType.BubbleChart
);

const handleTableClick = () => {
setCurrentView(ViewType.Table);
if (onSwitch) {
onSwitch(ViewType.Table);
}
};

const handleChartClick = () => {
setCurrentView(ViewType.BubbleChart);
if (onSwitch) {
onSwitch(ViewType.BubbleChart);
}
};

return (
<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 ${
currentView === ViewType.BubbleChart
? "!fill-white"
: "!fill-gray-500"
}`}
/>
</IconButton>
<IconButton className="!p-0" onClick={handleTableClick}>
<TableChartIcon
className={`w-5 h-5 cursor-pointer ${
currentView === ViewType.Table ? "!fill-white" : "!fill-gray-500"
}`}
/>
</IconButton>
</div>
);
};

export default ViewSwitcher;
Loading

0 comments on commit a023e10

Please sign in to comment.