Skip to content

Commit

Permalink
feat: update graph UI
Browse files Browse the repository at this point in the history
  • Loading branch information
AykutSarac committed Jan 22, 2025
1 parent d58d090 commit 4a604ca
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 32 deletions.
4 changes: 4 additions & 0 deletions src/constants/graph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const NODE_DIMENSIONS = {
ROW_HEIGHT: 24, // Regular row height
PARENT_HEIGHT: 36, // Height for parent nodes
} as const;
14 changes: 8 additions & 6 deletions src/constants/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const nodeColors = {
PARENT_ARR: "#FC9A40",
PARENT_OBJ: "#59b8ff",
CHILD_COUNT: "white",
DIVIDER: "#383838",
},
},
light: {
Expand All @@ -63,6 +64,7 @@ const nodeColors = {
PARENT_ARR: "#FF6B00",
PARENT_OBJ: "#761CEA",
CHILD_COUNT: "#535353",
DIVIDER: "#e6e6e6",
},
},
};
Expand All @@ -89,9 +91,9 @@ export const darkTheme = {
MODAL_BACKGROUND: "#36393E",
TEXT_NORMAL: "#dcddde",
TEXT_POSITIVE: "hsl(139,calc(var(--saturation-factor, 1)*51.6%),52.2%)",
GRID_BG_COLOR: "#1E1E1E",
GRID_COLOR_PRIMARY: "#272626",
GRID_COLOR_SECONDARY: "#232323",
GRID_BG_COLOR: "#141414",
GRID_COLOR_PRIMARY: "#1c1b1b",
GRID_COLOR_SECONDARY: "#191919",
};

export const lightTheme = {
Expand All @@ -116,9 +118,9 @@ export const lightTheme = {
MODAL_BACKGROUND: "#FFFFFF",
TEXT_NORMAL: "#2e3338",
TEXT_POSITIVE: "#008736",
GRID_BG_COLOR: "#f3f3f3",
GRID_COLOR_PRIMARY: "#E0E0E0",
GRID_COLOR_SECONDARY: "#E4E4E4",
GRID_BG_COLOR: "#f7f7f7",
GRID_COLOR_PRIMARY: "#ebe8e8",
GRID_COLOR_SECONDARY: "#f2eeee",
};

const themeDs = {
Expand Down
14 changes: 13 additions & 1 deletion src/features/editor/views/GraphView/CustomEdge/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
import React from "react";
import { useComputedColorScheme } from "@mantine/core";
import type { EdgeProps } from "reaflow";
import { Edge } from "reaflow";

const CustomEdgeWrapper = (props: EdgeProps) => {
return <Edge containerClassName={`edge-${props.id}`} {...props} />;
const colorScheme = useComputedColorScheme();

return (
<Edge
containerClassName={`edge-${props.id}`}
style={{
stroke: colorScheme === "dark" ? "#444444" : "#BCBEC0",
strokeWidth: 1.5,
}}
{...props}
/>
);
};

export const CustomEdge = React.memo(CustomEdgeWrapper);
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import { NODE_DIMENSIONS } from "src/constants/graph";
import type { CustomNodeProps } from "src/features/editor/views/GraphView/CustomNode";
import { TextRenderer } from "./TextRenderer";
import * as Styled from "./styles";
Expand All @@ -17,8 +18,10 @@ const Row = ({ val, x, y, index }: RowProps) => {
const rowKey = JSON.stringify(val[0]).replaceAll('"', "");
const rowValue = JSON.stringify(val[1]);

const rowPosition = index * NODE_DIMENSIONS.ROW_HEIGHT;

return (
<Styled.StyledRow $value={rowValue} data-key={key} data-x={x} data-y={y + index * 17.8}>
<Styled.StyledRow $value={rowValue} data-key={key} data-x={x} data-y={y + rowPosition}>
<Styled.StyledKey $type="object">{rowKey}: </Styled.StyledKey>
<TextRenderer>{rowValue}</TextRenderer>
</Styled.StyledRow>
Expand Down
13 changes: 8 additions & 5 deletions src/features/editor/views/GraphView/CustomNode/TextNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,23 @@ const StyledExpand = styled.button`
color: ${({ theme }) => theme.TEXT_NORMAL};
background: rgba(0, 0, 0, 0.1);
height: 100%;
width: 40px;
width: 36px;
border-left: 1px solid ${({ theme }) => theme.BACKGROUND_MODIFIER_ACCENT};
&:hover {
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
}
`;

const StyledTextNodeWrapper = styled.span<{ $hasCollapse: boolean }>`
const StyledTextNodeWrapper = styled.span<{ $hasCollapse: boolean; $isParent: boolean }>`
display: flex;
justify-content: ${({ $hasCollapse }) => ($hasCollapse ? "space-between" : "center")};
justify-content: ${({ $hasCollapse, $isParent }) =>
$hasCollapse ? "space-between" : $isParent ? "center" : "flex-start"};
align-items: center;
height: 100%;
width: 100%;
overflow: hidden;
padding: ${({ $hasCollapse }) => ($hasCollapse ? "0" : "0 10px")};
`;

const StyledImageWrapper = styled.div`
Expand Down Expand Up @@ -81,14 +84,14 @@ const Node = ({ node, x, y, hasCollapse = false }: CustomNodeProps) => {
data-y={y}
data-key={JSON.stringify(text)}
$hasCollapse={isParent && collapseButtonVisible}
$isParent={isParent}
>
<Styled.StyledKey $value={value} $parent={isParent} $type={type}>
<TextRenderer>{value}</TextRenderer>
</Styled.StyledKey>
{isParent && childrenCount > 0 && childrenCountVisible && (
<Styled.StyledChildrenCount>({childrenCount})</Styled.StyledChildrenCount>
<Styled.StyledChildrenCount>[{childrenCount}]</Styled.StyledChildrenCount>
)}

{isParent && hasCollapse && collapseButtonVisible && (
<StyledExpand aria-label="Expand" onClick={handleExpand}>
{isExpanded ? <MdLinkOff size={18} /> : <MdLink size={18} />}
Expand Down
7 changes: 7 additions & 0 deletions src/features/editor/views/GraphView/CustomNode/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import { useComputedColorScheme } from "@mantine/core";
import type { NodeProps } from "reaflow";
import { Node } from "reaflow";
import useGraph from "src/features/editor/views/GraphView/stores/useGraph";
Expand All @@ -23,6 +24,7 @@ const CustomNodeWrapper = (nodeProps: NodeProps<NodeData["data"]>) => {
const data = nodeProps.properties.data;
const setSelectedNode = useGraph(state => state.setSelectedNode);
const setVisible = useModal(state => state.setVisible);
const colorScheme = useComputedColorScheme();

const handleNodeClick = React.useCallback(
(_: React.MouseEvent<SVGGElement, MouseEvent>, data: NodeData) => {
Expand All @@ -39,6 +41,11 @@ const CustomNodeWrapper = (nodeProps: NodeProps<NodeData["data"]>) => {
onClick={handleNodeClick as any}
animated={false}
label={null as any}
style={{
fill: colorScheme === "dark" ? "#292929" : "#ffffff",
stroke: colorScheme === "dark" ? "#424242" : "#BCBEC0",
strokeWidth: 1.5,
}}
>
{({ node, x, y }) => {
if (Array.isArray(nodeProps.properties.text)) {
Expand Down
23 changes: 14 additions & 9 deletions src/features/editor/views/GraphView/CustomNode/styles.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { DefaultTheme } from "styled-components";
import styled from "styled-components";
import { LinkItUrl } from "react-linkify-it";
import { NODE_DIMENSIONS } from "src/constants/graph";

type TextColorFn = {
theme: DefaultTheme;
Expand Down Expand Up @@ -64,31 +65,35 @@ export const StyledForeignObject = styled.foreignObject<{ $isObject?: boolean }>
`;

export const StyledKey = styled.span<{ $parent?: boolean; $type: string; $value?: string }>`
display: inline;
display: ${({ $parent }) => ($parent ? "flex" : "inline")};
align-items: center;
justify-content: center; // Always center for parent nodes
flex: 1;
min-width: 0;
height: ${({ $parent }) => ($parent ? `${NODE_DIMENSIONS.PARENT_HEIGHT}px` : "auto")};
line-height: ${({ $parent }) => ($parent ? `${NODE_DIMENSIONS.PARENT_HEIGHT}px` : "inherit")};
padding: 0; // Remove padding
color: ${({ theme, $type, $parent = false, $value = "" }) =>
getTextColor({ $parent, $type, $value, theme })};
font-size: ${({ $parent }) => $parent && "14px"};
overflow: hidden;
text-overflow: ellipsis;
padding: ${({ $type }) => $type !== "object" && "10px"};
white-space: nowrap;
`;

export const StyledRow = styled.span<{ $value: string }>`
padding: 0 10px;
padding: 3px 10px;
height: ${NODE_DIMENSIONS.ROW_HEIGHT}px;
line-height: 18px;
color: ${({ theme, $value }) => getTextColor({ $value, theme })};
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&:first-of-type {
padding-top: 10px;
}
border-bottom: 1px solid ${({ theme }) => theme.NODE_COLORS.DIVIDER};
box-sizing: border-box;
&:last-of-type {
padding-bottom: 10px;
border-bottom: none;
}
`;

Expand Down
6 changes: 4 additions & 2 deletions src/features/editor/views/GraphView/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { LoadingOverlay } from "@mantine/core";
import { LoadingOverlay, useComputedColorScheme } from "@mantine/core";
import styled from "styled-components";
import debounce from "lodash.debounce";
import { Space } from "react-zoomable-ui";
Expand Down Expand Up @@ -83,6 +83,7 @@ const GraphCanvas = ({ isWidget }: GraphProps) => {
const centerView = useGraph(state => state.centerView);
const direction = useGraph(state => state.direction);
const nodes = useGraph(state => state.nodes);
const colorScheme = useComputedColorScheme();
const edges = useGraph(state => state.edges);
const [paneWidth, setPaneWidth] = React.useState(2000);
const [paneHeight, setPaneHeight] = React.useState(2000);
Expand Down Expand Up @@ -116,13 +117,14 @@ const GraphCanvas = ({ isWidget }: GraphProps) => {
edge={p => <CustomEdge {...p} />}
nodes={nodes}
edges={edges}
arrow={null}
maxHeight={paneHeight}
maxWidth={paneWidth}
height={paneHeight}
width={paneWidth}
direction={direction}
layoutOptions={layoutOptions}
key={direction}
key={[direction, colorScheme].join("-")}
pannable={false}
zoomable={false}
animated={false}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { NODE_DIMENSIONS } from "src/constants/graph";
import useConfig from "src/store/useConfig";

type Text = string | [string, string][];
Expand All @@ -24,24 +25,23 @@ const calculateWidthAndHeight = (str: string, single = false) => {
if (!str) return { width: 45, height: 45 };

const dummyElement = document.createElement("div");

dummyElement.style.whiteSpace = single ? "nowrap" : "pre-wrap";
dummyElement.innerHTML = str;
dummyElement.style.fontSize = "12px";
dummyElement.style.width = "fit-content";
dummyElement.style.height = "fit-content";
dummyElement.style.padding = "10px";
dummyElement.style.padding = "0 10px";
dummyElement.style.fontWeight = "500";
dummyElement.style.overflowWrap = "break-word";
dummyElement.style.fontFamily = "monospace";
document.body.appendChild(dummyElement);

const clientRect = dummyElement.getBoundingClientRect();
const lines = str.split("\n").length;

const width = clientRect.width + 4;
const height = clientRect.height;
// Use parent height for single line nodes that are parents
const height = single ? NODE_DIMENSIONS.PARENT_HEIGHT : lines * NODE_DIMENSIONS.ROW_HEIGHT;

document.body.removeChild(dummyElement);

return { width, height };
};

Expand All @@ -59,7 +59,6 @@ export const calculateNodeSize = (text: Text, isParent = false) => {
// check cache if data already exists
if (sizeCache.has(cacheKey)) {
const size = sizeCache.get(cacheKey);

if (size) return size;
}

Expand All @@ -71,7 +70,7 @@ export const calculateNodeSize = (text: Text, isParent = false) => {
sizes.height = 80;
}

if (isParent) sizes.width += 100;
if (isParent) sizes.width += 80;
if (sizes.width > 700) sizes.width = 700;

sizeCache.set(cacheKey, sizes);
Expand Down

0 comments on commit 4a604ca

Please sign in to comment.