Skip to content

Commit

Permalink
updated sdk and subgraph entities, made map improvements based on lat…
Browse files Browse the repository at this point in the history
…est feedback
  • Loading branch information
mrtmeeseeks committed Jul 6, 2024
1 parent ec74d2f commit 3ac4dee
Show file tree
Hide file tree
Showing 10 changed files with 541 additions and 143 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@
},
"dependencies": {
"@apollo/client": "^3.9.1",
"@aut-labs/abi-types": "^0.0.75-dev",
"@aut-labs/abi-types": "^0.0.76-dev",
"@aut-labs/connector": "^0.0.93",
"@aut-labs/d-aut": "^1.0.163-dev",
"@aut-labs/sdk": "^0.0.160-dev",
"@aut-labs/d-aut": "^1.0.165-dev",
"@aut-labs/sdk": "^0.0.161-dev",
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@leenguyen/react-flip-clock-countdown": "^1.5.0",
Expand Down
11 changes: 6 additions & 5 deletions src/api/holder.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,23 +143,24 @@ export const fetchHolder = createAsyncThunk(

const loadNova = async (novaAddress: string): Promise<Community> => {
const novaQuery = gql`
query GetNovaDAO {
novaDAO(id: "${novaAddress?.toLowerCase()}") {
query GetHub {
hub(id: "${novaAddress?.toLowerCase()}") {
id
address
market
minCommitment
metadataUri
domain
}
}
`;
const novaResponse = await apolloClient.query<any>({
query: novaQuery
});
const { novaDAO } = novaResponse.data;
const { hub } = novaResponse.data;

const novaMetadata = await fetchMetadata<BaseNFTModel<Community>>(
novaDAO.metadataUri,
hub.metadataUri,
environment.ipfsGatewayUrl
);

Expand All @@ -171,7 +172,7 @@ export const fetchHolder = createAsyncThunk(
properties: {
...novaMetadata.properties,
address: novaAddress,
market: +novaDAO.market - 1,
market: +hub.market - 1,
userData: {
role: autID.role.toString(),
commitment: autID.commitment.toString(),
Expand Down
145 changes: 128 additions & 17 deletions src/components/InteractionMap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ import {
calculatePLCircleCentersAndRadii,
getProximityLevels
} from "./misc/pl-generator";
import { generateGraphData, cloneGraphData, linkWidth } from "./misc/map-utils";
import {
generateGraphData,
cloneGraphData,
linkWidth,
getParticleColor
} from "./misc/map-utils";
import { MapLink, MapNode } from "./node.model";
import { AutOsButton } from "@components/AutButton";
import { MapNova } from "@api/map.model";
Expand All @@ -44,6 +49,7 @@ import {
} from "@store/ui-reducer";
import { useAppDispatch } from "@store/store.model";
import { useSelector } from "react-redux";
import LinkStatsPopover from "@components/LinkStatsPopover";

const StyledBadge = styled(Badge)<BadgeProps>(({ theme }) => ({
"& .MuiBadge-badge": {
Expand All @@ -64,10 +70,18 @@ function InteractionMap({
}) {
const fgRef = useRef<ForceGraphMethods>();
const [anchorPos, setAnchorPos] = useState({ x: 0, y: 0 });
const [centralNode, setCentralNode] = useState<NodeObject<MapNode>>(null);
const [hoveredNode, setHoveredNode] = useState(null);
const [showPopover, setShowPopover] = useState(false);
const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
const [highlightedPl, setHighlightedPl] = useState(null);
const [showLinkPopover, setShowLinkPopover] = useState(false);
const [hoveredLink, setHoveredLink] = useState(null);
const [linkStats, setLinkStats] = useState<{
x: number;
y: number;
data: any;
} | null>(null);
const [pLevels, setProximityLevels] = useState([]);
const [initialGraphData, setInitialGraphData] = useState<
GraphData<MapNode, LinkObject<MapNode, MapLink>>
Expand All @@ -86,6 +100,10 @@ function InteractionMap({
const isInteractionDialogOpen = useSelector(IsInteractionDialogOpen);
const showPopoverTimeoutRef = useRef(null);
const hidePopoverTimeoutRef = useRef(null);
const showLinkPopoverTimeoutRef = useRef<number | null>(null);
const hideLinkPopoverTimeoutRef = useRef<number | null>(null);

console.log(centralNode, "this");

const handleClose = () => {
dispatch(setOpenInteractions(false));
Expand Down Expand Up @@ -129,10 +147,13 @@ function InteractionMap({

const graphDataAndPL = useMemo(() => {
const { proximityLevels, centralAutId } = getProximityLevels(mapData);
const _graphData = generateGraphData(centralAutId, proximityLevels);
const { graphData: _graphData, centralNode: _centralNode } =
generateGraphData(centralAutId, proximityLevels);

return {
graphData: _graphData,
proximityLevels
proximityLevels,
centralNode: _centralNode
};
}, [mapData]);

Expand All @@ -141,6 +162,8 @@ function InteractionMap({
setInitialGraphData(graphDataAndPL.graphData);
setGraphData(cloneGraphData(graphDataAndPL.graphData));
setProximityLevels(graphDataAndPL.proximityLevels);
console.log("graphDataAndPL", graphDataAndPL);
setCentralNode(graphDataAndPL.centralNode);
}, [graphDataAndPL]);

const handleNodeHover = useCallback(
Expand Down Expand Up @@ -200,21 +223,30 @@ function InteractionMap({
);
}, [fgRef]);

// Handle link popover close
const handleLinkPopoverClose = () => {
console.log("handleLinkPopoverClose");
clearTimeout(hideLinkPopoverTimeoutRef.current as number);
clearTimeout(showLinkPopoverTimeoutRef.current as number);
setShowLinkPopover(false);
};

// Cancel link popover close
const cancelLinkPopoverClose = () => {
clearTimeout(hideLinkPopoverTimeoutRef.current as number);
};

useEffect(() => {
if (isDragging || !isActive) {
clearTimeout(hidePopoverTimeoutRef.current);
clearTimeout(showPopoverTimeoutRef.current);
clearTimeout(hidePopoverTimeoutRef.current as number);
clearTimeout(showPopoverTimeoutRef.current as number);
setShowPopover(false);
clearTimeout(hideLinkPopoverTimeoutRef.current as number);
clearTimeout(showLinkPopoverTimeoutRef.current as number);
setShowLinkPopover(false);
}
}, [isDragging, isActive]);

useEffect(() => {
return () => {
clearTimeout(showPopoverTimeoutRef.current);
clearTimeout(hidePopoverTimeoutRef.current);
};
}, []);

const drawNode = useCallback(
(node: NodeObject<MapNode>, ctx: CanvasRenderingContext2D) => {
const size = node.size;
Expand Down Expand Up @@ -253,8 +285,65 @@ function InteractionMap({
[]
);

const handleLinkHover = useCallback(
(link, prevLink) => {
console.log("handleLinkHover", link, prevLink);
if (isDragging || !isActive) return;
if (!link) {
clearTimeout(showLinkPopoverTimeoutRef.current as number);
hideLinkPopoverTimeoutRef.current = window.setTimeout(
() => setShowLinkPopover(false),
100
);
} else {
clearTimeout(hideLinkPopoverTimeoutRef.current as number);
showLinkPopoverTimeoutRef.current = window.setTimeout(() => {
setHoveredLink(link);
setShowLinkPopover(true);
}, 50);
}
if (!link) return;
const bbox = fgRef.current?.getGraphBbox(
(n) => n.id === link.source.id || n.id === link.target.id
);
const graphCenter = {
x: (bbox.x[0] + bbox.x[1]) / 2,
y: (bbox.y[0] + bbox.y[1]) / 2
};
const centerScreen = fgRef.current?.graph2ScreenCoords(
graphCenter.x,
graphCenter.y
);
const containerRect = containerRef.current?.getBoundingClientRect();

if (centerScreen && containerRect) {
const stats = {
x: centerScreen.x + containerRect.left,
y: centerScreen.y + containerRect.top,
data: {
link,
centralNode
}
};
setLinkStats(stats);
}
},
[fgRef, containerRef, isDragging, isActive]
);

const getNovaInfoByPl = (level: number): any => {
return pLevels.find((pl) => pl.level === level)?.members[0].nova || {};
let novaInfo = {};

for (const pl of pLevels) {
if (pl.level === level) {
if (pl.members.length === 0) {
return {};
}
novaInfo = pl.members[0].nova;
break;
}
}
return novaInfo;
};

const handlePopoverClose = () => {
Expand All @@ -267,6 +356,15 @@ function InteractionMap({
clearTimeout(hidePopoverTimeoutRef.current);
};

useEffect(() => {
return () => {
clearTimeout(showPopoverTimeoutRef.current as number);
clearTimeout(hidePopoverTimeoutRef.current as number);
clearTimeout(showLinkPopoverTimeoutRef.current as number);
clearTimeout(hideLinkPopoverTimeoutRef.current as number);
};
}, []);

return (
<>
<ForceGraph2D
Expand All @@ -276,7 +374,7 @@ function InteractionMap({
graphData={graphData}
onRenderFramePre={onRenderFramePre}
onEngineStop={() => {
if (mapData?.members?.length > 1) {
if (mapData?.members?.length > 1 && fgRef.current) {
fgRef.current.zoomToFit(300);
}
}}
Expand All @@ -291,10 +389,14 @@ function InteractionMap({
handleNodeDragEnd();
setGraphData(cloneGraphData(initialGraphData));
}}
linkWidth={linkWidth}
nodeCanvasObject={drawNode}
linkDirectionalParticles={0.5}
linkDirectionalParticleWidth={3}
linkWidth={(node) => node.is}
// linkDirectionalParticleWidth={3}
linkDirectionalParticles={2}
linkDirectionalParticleSpeed={(link) => link.speed}
linkDirectionalParticleColor={getParticleColor}
// onLinkHover={handleLinkHover}
linkHoverPrecision={8}
d3VelocityDecay={1}
cooldownTicks={0}
// enableZoomInteraction={false}
Expand All @@ -312,6 +414,15 @@ function InteractionMap({
onMouseEnter={cancelPopoverClose}
onMouseLeave={handlePopoverClose}
/>
{/* <LinkStatsPopover
type="custom"
anchorPos={{ x: linkStats?.x, y: linkStats?.y }}
data={linkStats?.data || {}}
open={showLinkPopover && !isDragging && isActive}
handleClose={handleLinkPopoverClose}
onMouseEnter={cancelLinkPopoverClose}
onMouseLeave={handleLinkPopoverClose}
/> */}
<Box>
<Box
sx={{
Expand Down
30 changes: 17 additions & 13 deletions src/components/InteractionMap/misc/is-calculator.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,45 @@
import { NodeObject } from "react-force-graph-2d";
import { MapNode } from "../node.model";

const getCompletedInteractions = (node: NodeObject<MapNode>) => {
interface Interaction {
name: string;
status: string;
}

const getCompletedInteractions = (node: NodeObject<MapNode>): string[] => {
return node.properties.interactions
.filter((interaction) => interaction.status === "Complete")
.map((interaction) => interaction.name);
.filter((interaction: Interaction) => interaction.status === "Complete")
.map((interaction: Interaction) => interaction.name);
};

const getSharedInteractions = (
sourceInteractions: string[],
targeInteractions: string[]
) => {
targetInteractions: string[]
): string[] => {
return sourceInteractions.filter((interaction) =>
targeInteractions.includes(interaction)
targetInteractions.includes(interaction)
);
};

export const calculateIS = (
source: NodeObject<MapNode>,
target: NodeObject<MapNode>,
centralNode: NodeObject<MapNode>
) => {
): number => {
const centralNodeInteractions = getCompletedInteractions(centralNode);
if (centralNodeInteractions.length === 0) {
return 0;
}
// if (centralNodeInteractions.length === 0) {
// return 0;
// }

const sourceInteractions = getCompletedInteractions(source);
const targetInteractions = getCompletedInteractions(target);

// get only same name/type interactions that both source and target have completed
// Get only same name/type interactions that both source and target have completed
const sharedInteractions = getSharedInteractions(
sourceInteractions,
targetInteractions
);

// now get only interactions that are shared with central node
// Get only interactions that are shared with central node
const sharedWithCentralNodeInteractions = getSharedInteractions(
sharedInteractions,
centralNodeInteractions
Expand Down
2 changes: 1 addition & 1 deletion src/components/InteractionMap/misc/map-constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export const CENTRAL_NODE_SIZE = 55;
export const NODE_PADDING = 2;
export const NODE_BORDER_WIDTH = 0.5;
export const MAX_LINK_THICKNESS = 6;
export const MAX_LINK_THICKNESS = 4;
export const LINK_COLOR = "rgba(255,255,255,0.2)";
export const NODE_FILL_COLOR = "rgba(54, 191, 250, 0.3)";
export const STROKE_COLOR = "rgba(54, 191, 250, 1)";
Loading

0 comments on commit 3ac4dee

Please sign in to comment.