Execution Plan
Refactor the 3382-line GraphRenderer.tsx into smaller, composable components and utilities while maintaining all existing functionality. This plan follows principles that a principal frontend engineer would approve.
Overview
Component Organization Strategy
Subdirectory Structure with Index Files
Goal: Organize components into subdirectories with index.tsx files for cleaner imports and better maintainability.
Target Directory Structure
src/components/Graph/
├── GraphRenderer/ # Main component (stays at root for now)
│ ├── index.tsx # Re-exports GraphRenderer
│ ├── GraphRenderer.tsx # Main implementation
│ ├── GraphRenderer.module.css
│ └── GraphRenderer.stories.tsx
├── GraphMenuBar/
│ ├── index.tsx # Re-exports GraphMenuBar
│ ├── GraphMenuBar.tsx
│ └── GraphMenuBar.stories.tsx
├── GraphInfoPanel/
│ ├── index.tsx # Re-exports GraphInfoPanel
│ ├── GraphInfoPanel.tsx
│ └── GraphInfoPanel.stories.tsx
├── GraphCanvas/
│ ├── index.tsx # Re-exports GraphCanvas
│ ├── GraphCanvas.tsx
│ └── GraphCanvas.stories.tsx
├── GraphRightClickMenu/ # New component (extracted)
│ ├── index.tsx
│ ├── GraphRightClickMenu.tsx
│ └── GraphRightClickMenu.stories.tsx
├── GraphContextMenu/ # New component (extracted)
│ ├── index.tsx
│ ├── GraphContextMenu.tsx
│ └── GraphContextMenu.stories.tsx
├── hooks/ # Custom hooks
│ ├── index.ts # Re-exports all hooks
│ ├── useGraphDimensions.ts
│ ├── useGraphState.ts
│ ├── useGraphData.ts
│ ├── useGraphInteractions.ts
│ ├── useGraphCanvasSetup.ts
│ ├── useGraphMenuHandlers.ts
│ └── useGraphUrlFragment.ts
├── utils/ # Utility functions
│ ├── index.ts # Re-exports all utils
│ ├── graphConstants.ts
│ ├── GraphDataUtils.ts
│ ├── GraphNodeUtils.ts
│ ├── GraphRenderingUtils.ts
│ ├── GraphTextUtils.ts
│ ├── GraphCanvasDrawingUtils.ts
│ ├── GraphEdgeDrawingUtils.ts
│ └── graphUtils.ts # Backward compatibility re-exports
├── types.ts # Shared types
└── README.md # Component documentation
Index File Pattern
Each component subdirectory will have an index.tsx that re-exports the component:
export { GraphMenuBar } from './GraphMenuBar';
export type { GraphMenuBarProps } from './GraphMenuBar';
This allows clean imports:
import { GraphMenuBar } from './GraphMenuBar/GraphMenuBar';
import { GraphMenuBar } from './GraphMenuBar';
Story Organization
Stories will be co-located with components in their subdirectories:
import { Meta, StoryObj } from '@storybook/react';
import { GraphMenuBar } from './GraphMenuBar';
const meta: Meta<typeof GraphMenuBar> = {
title: 'Graph/GraphMenuBar',
component: GraphMenuBar,
};
export default meta;
type Story = StoryObj<typeof GraphMenuBar>;
export const Default: Story = {
};
Benefits of This Structure
- Cleaner Imports:
import { GraphMenuBar } from './GraphMenuBar' instead of './GraphMenuBar/GraphMenuBar'
- Co-location: Component, styles, stories, and tests in one place
- Better Discoverability: Easy to find all files related to a component
- Scalability: Easy to add new components without cluttering root
- Maintainability: Clear boundaries between components
Migration Strategy
Phase 0: Reorganize Existing Components (Before refactoring)
-
Create subdirectories for existing components
mkdir -p src/components/Graph/GraphMenuBar
mkdir -p src/components/Graph/GraphInfoPanel
mkdir -p src/components/Graph/GraphCanvas
-
Move component files
mv GraphMenuBar.tsx GraphMenuBar/GraphMenuBar.tsx
mv GraphMenuBar.stories.tsx GraphMenuBar/GraphMenuBar.stories.tsx
-
Create index.tsx files
export { GraphMenuBar } from './GraphMenuBar';
export type { GraphMenuBarProps } from './GraphMenuBar';
-
Update imports in GraphRenderer
import { GraphMenuBar } from './GraphMenuBar';
import { GraphMenuBar } from './GraphMenuBar';
-
Create hooks/ subdirectory
mkdir -p src/components/Graph/hooks
mv useGraphState.ts hooks/
mv useGraphData.ts hooks/
mv useGraphInteractions.ts hooks/
-
Create hooks/index.ts
export { useGraphState } from './useGraphState';
export { useGraphData } from './useGraphData';
export { useGraphInteractions } from './useGraphInteractions';
-
Create utils/ subdirectory (if not exists)
mkdir -p src/components/Graph/utils
# Move utility files to utils/
-
Update all imports
- Update GraphRenderer imports
- Update Storybook stories
- Update tests
- Update documentation
Timing: This reorganization should happen before starting the refactoring phases, as it provides a clean foundation.
Current State Analysis
File Size: 3382 lines
Main Sections:
- Drawing Functions (~600 lines):
drawNodeCircle, drawDebugSectionSeparators, drawTitle, drawStatusIndicator
- Edge Rendering Functions (~100 lines):
getEdgeWidth, getEdgeCoordinates, drawComparisonEdge, drawEdgeLabel
- Main Component Logic (~2600 lines): State, event handlers, dimension calculations, canvas setup, menus, info panel
- Constants:
NEO4J_COLORS, DEBUG_SHOW_NODE_SECTIONS
- ✅
GraphDataUtils.ts - Tree traversal, data cleaning
- ✅
GraphNodeUtils.ts - Node properties, styling, validation
- ✅
GraphRenderingUtils.ts - Rendering calculations, coordinates
- ✅
GraphTextUtils.ts - Text processing, wrapping, font sizing
- ✅
NodeRenderer.ts - Node rendering class
- ✅
useGraphData.ts - Graph data hooks
- ✅
useGraphInteractions.ts - Interaction hooks
- ✅
useGraphState.ts - State management hooks
- ✅
GraphCanvas.tsx - Canvas wrapper
- ✅
GraphInfoPanel.tsx - Info panel component
- ✅
GraphMenuBar.tsx - Menu bar component
Refactoring Strategy
Goal: Move pure drawing functions to utility files
1.1 Create GraphCanvasDrawingUtils.ts
Extract:
drawNodeCircle → drawNodeCircle
drawDebugSectionSeparators → drawDebugSectionSeparators
drawStatusIndicator → drawStatusIndicator
drawTitle → drawTitle (complex, ~400 lines - keep as-is but move to utils)
Location: src/components/Graph/GraphCanvasDrawingUtils.ts
Dependencies:
- Canvas context
- Node data
- Styling parameters (colors, sizes)
Risk: Low - Pure functions, no component state
1.2 Create GraphEdgeDrawingUtils.ts
Extract:
drawComparisonEdge → drawComparisonEdge
drawEdgeLabel → drawEdgeLabel
getEdgeWidth → getEdgeWidth (already in GraphRenderingUtils? Check)
Location: src/components/Graph/GraphEdgeDrawingUtils.ts
Risk: Low - Pure functions
Goal: Move responsive dimension calculations to a custom hook
2.1 Create useGraphDimensions.ts
Extract:
- Dimension calculation logic (lines ~2349-2361)
baseGraphAreaHeight, graphCanvasHeight, graphAreaHeight calculations
graphWidth, panelWidth calculations
- Container width measurement logic
Location: src/components/Graph/useGraphDimensions.ts
Returns:
{
graphAreaHeight: number;
graphCanvasHeight: number;
graphWidth: number;
panelWidth: number;
actualContainerWidth: number;
isMobile: boolean;
}
Risk: Low - Isolated logic, easy to test
Phase 3: Extract Event Handlers (Medium Risk)
Goal: Move event handler logic to custom hooks
3.1 Enhance useGraphInteractions.ts
Extract:
handleNodeClick → useNodeClickHandler
handleNodeRightClick → useNodeRightClickHandler
handleLinkClick → useLinkClickHandler
handleLinkRightClick → useLinkRightClickHandler
handleNodeDrag → useNodeDragHandler
handleNodeDragEnd → useNodeDragEndHandler
handleZoom → useZoomHandler
handleWheel → useWheelHandler
Location: src/components/Graph/useGraphInteractions.ts (enhance existing)
Risk: Medium - Need to ensure all dependencies are passed correctly
3.2 Create useGraphMenuHandlers.ts
Extract:
copyAnchorLink → useCopyAnchorLink
togglePane → useTogglePane
- Context menu click outside handler
- Right-click menu logic
Location: src/components/Graph/useGraphMenuHandlers.ts
Risk: Low - Isolated menu logic
Goal: Move canvas initialization and event listeners to a hook
4.1 Create useGraphCanvasSetup.ts
Extract:
- Canvas ref setup
- Event listener registration (wheel, contextmenu)
- Canvas cleanup
nodeCanvasObject and linkCanvasObject creation
Location: src/components/Graph/useGraphCanvasSetup.ts
Returns:
{
graphRef: RefObject<any>;
nodeCanvasObject: (node, ctx, globalScale) => void;
linkCanvasObject: (link, ctx, globalScale) => void;
linkCanvasObjectMode: (link) => string;
}
Risk: Medium - Complex setup logic, need to ensure all dependencies
Goal: Extract inline menu JSX to separate components
Extract:
- Right-click menu JSX (lines ~2425-2486)
- Menu item rendering logic
Location: src/components/Graph/GraphRightClickMenu.tsx
Props:
{
menu: { nodeId: string; x: number; y: number } | null;
isDarkMode: boolean;
expandedNodes: Set<string>;
onToggleExpansion: (nodeId: string) => void;
onCopyLink: (nodeId: string) => void;
onClose: () => void;
}
Risk: Low - Pure presentational component
Extract:
- Context menu JSX (lines ~2487-2510)
Location: src/components/Graph/GraphContextMenu.tsx
Props:
{
menu: { x: number; y: number; nodeId?: string; edgeId?: string } | null;
isDarkMode: boolean;
onCopyLink: (nodeId?: string, edgeId?: string) => void;
onClose: () => void;
}
Risk: Low - Pure presentational component
Phase 6: Extract URL Fragment Handling (Low Risk)
Goal: Move URL fragment parsing and highlighting to a hook
6.1 Create useGraphUrlFragment.ts
Extract:
- URL fragment parsing logic
highlightNode and highlightEdge calls from URL
- Scroll to graph logic
Location: src/components/Graph/useGraphUrlFragment.ts
Risk: Low - Isolated URL handling
Goal: Move constants to a separate file
7.1 Create graphConstants.ts
Extract:
NEO4J_COLORS → NEO4J_COLORS
DEBUG_SHOW_NODE_SECTIONS → DEBUG_SHOW_NODE_SECTIONS
Location: src/components/Graph/graphConstants.ts
Risk: Low - Simple constants
Phase 8: Refactor Main Component (High Risk - Do Last)
Goal: Simplify GraphRendererImpl to orchestrate hooks and components
8.1 Final GraphRendererImpl Structure
const GraphRendererImpl = ({ ... }) => {
const dimensions = useGraphDimensions(width, height, paneVisible, isMobile);
const graphState = useGraphState(initialExpandedNodes);
const interactions = useGraphInteractions();
const canvasSetup = useGraphCanvasSetup();
const menuHandlers = useGraphMenuHandlers(graphId);
const urlFragment = useGraphUrlFragment();
const nodeCanvasObject = canvasSetup.nodeCanvasObject;
const linkCanvasObject = canvasSetup.linkCanvasObject;
return (
<div>
<GraphMenuBar />
<div className={styles.graphArea}>
<GraphCanvas>
<ForceGraph2D {...props} />
</GraphCanvas>
{paneVisible && <GraphInfoPanel />}
</div>
<GraphRightClickMenu />
<GraphContextMenu />
</div>
);
};
Risk: High - This is the integration point, need careful testing
Implementation Order (Risk-Based)
Phase 0: Reorganize Structure (Week 0 - Prerequisite)
Goal: Set up subdirectory structure before refactoring
- ✅ Create subdirectories for existing components
- ✅ Move components to subdirectories with index.tsx
- ✅ Move stories to component subdirectories
- ✅ Create hooks/ subdirectory and move hooks
- ✅ Create utils/ subdirectory (if needed)
- ✅ Update all imports across codebase
- ✅ Verify all tests still pass
- ✅ Verify Storybook stories still work
Timing: Do this before starting Phase 1
- ✅ Phase 7: Extract Constants →
utils/graphConstants.ts
- ✅ Phase 1: Extract Canvas Drawing Utilities →
utils/GraphCanvasDrawingUtils.ts & utils/GraphEdgeDrawingUtils.ts
- ✅ Phase 2: Extract Dimension Calculation Logic →
hooks/useGraphDimensions.ts
- ✅ Phase 5: Extract Menu Components →
GraphRightClickMenu/ & GraphContextMenu/
- ✅ Phase 3: Extract Event Handlers →
hooks/useGraphInteractions.ts (enhance)
- ✅ Phase 4: Extract Canvas Setup Logic →
hooks/useGraphCanvasSetup.ts
- ✅ Phase 6: Extract URL Fragment Handling →
hooks/useGraphUrlFragment.ts
- ✅ Phase 7: Extract Menu Handlers →
hooks/useGraphMenuHandlers.ts
Week 3: High-Risk Integration
- ✅ Phase 8: Refactor Main Component
- ✅ Comprehensive Testing
- ✅ Update Documentation
Testing Strategy
Test Directory Structure
test/
├── e2e/ # End-to-end tests (Playwright)
│ ├── graph-renderer.spec.ts
│ ├── graph-selection-state.spec.ts
│ ├── graph-title-rendering.spec.ts
│ └── helpers/
│ └── canvas-utils.ts
├── unit/ # Unit tests (Jest)
│ └── GraphRenderer.title.test.ts
├── utils/ # Test utilities
│ └── canvasMock.ts
└── setup.ts # Jest setup
Unit Tests (Jest) - test/unit/
Phase 1: Utility Function Tests
Location: test/unit/
New Test Files to Create:
-
GraphCanvasDrawingUtils.test.ts
- Test
drawNodeCircle with various parameters
- Test
drawDebugSectionSeparators (when debug enabled)
- Test
drawStatusIndicator for leaf vs parent nodes
- Test
drawTitle with various text lengths and zoom levels
- Use
createMockCanvasContext() from test/utils/canvasMock.ts
-
GraphEdgeDrawingUtils.test.ts
- Test
drawComparisonEdge rendering
- Test
drawEdgeLabel with various labels and scales
- Test
getEdgeWidth calculations
-
graphConstants.test.ts
- Test
NEO4J_COLORS array structure
- Test
DEBUG_SHOW_NODE_SECTIONS flag
-
useGraphDimensions.test.ts
- Test dimension calculations for mobile vs desktop
- Test pane visibility impact on dimensions
- Test container width measurement
- Use React Testing Library to test hook
Update Existing:
GraphRenderer.title.test.ts: Update imports if drawTitle moves to utils
Phase 2: Hook Tests
Location: test/unit/
New Test Files:
-
useGraphMenuHandlers.test.ts
- Test
useCopyAnchorLink with clipboard API
- Test
useTogglePane state changes
- Test context menu click outside handler
-
useGraphUrlFragment.test.ts
- Test URL fragment parsing
- Test
highlightNode from URL
- Test
highlightEdge from URL
- Test scroll to graph behavior
-
useGraphCanvasSetup.test.ts
- Test canvas ref setup
- Test event listener registration
- Test
nodeCanvasObject creation
- Test
linkCanvasObject creation
Enhance Existing:
useGraphInteractions.ts (if exists): Add tests for extracted handlers
Test Utilities to Create/Update
Location: test/utils/
-
graphHookTestUtils.ts (New)
export function renderGraphHook<T>(hook: () => T, wrapper?: ReactWrapper)
export function createMockGraphRef()
export function createMockGraphData()
-
canvasMock.ts (Update)
- Add more mock methods if needed for new drawing functions
- Ensure compatibility with extracted drawing utilities
End-to-End Tests (Playwright) - test/e2e/
Update Strategy for E2E Tests
Key Principle: E2E tests should remain largely unchanged since they test the public API of GraphRenderer, not internal implementation details.
Files to Update:
-
graph-renderer.spec.ts
- No changes needed - Tests public API (canvas rendering, interactions)
- May need to update selectors if component structure changes slightly
- Verify canvas still renders correctly after refactoring
-
graph-selection-state.spec.ts
- No changes needed - Tests selection behavior (public API)
- Verify node/edge selection still works after refactoring
- Test URL hash behavior still works
-
graph-title-rendering.spec.ts
- No changes needed - Tests title rendering (visual output)
- Verify ellipsis regression test still passes
- May need screenshot updates if rendering changes slightly
New E2E Tests to Add:
-
graph-responsive-behavior.spec.ts (New)
- Test mobile layout (pane below graph)
- Test desktop layout (pane beside graph)
- Test pane visibility toggle
- Test graph area resizing
- Test canvas overflow prevention
-
graph-menu-interactions.spec.ts (New)
- Test right-click menu
- Test context menu
- Test copy anchor link
- Test menu positioning
E2E Test Helpers to Update:
helpers/canvas-utils.ts
- No changes needed - Generic canvas utilities
- May add helpers for testing responsive behavior if needed
Integration Tests (New Category)
Location: test/integration/ (Create if doesn't exist)
Purpose
Test interactions between hooks and components in isolation from full E2E flow.
New Test Files:
-
GraphRenderer.integration.test.tsx
- Test component renders with all hooks
- Test hook interactions (e.g., dimension changes trigger re-render)
- Test state synchronization between hooks
- Use React Testing Library
-
GraphHooks.integration.test.tsx
- Test useGraphDimensions + useGraphState interaction
- Test useGraphInteractions + useGraphCanvasSetup interaction
- Test useGraphUrlFragment + useGraphState interaction
Test Update Checklist Per Phase
Phase 3: Extract Event Handlers
Phase 6: Extract URL Fragment Handling
Phase 7: Extract Menu Handlers
Phase 8: Refactor Main Component
Test Maintenance Strategy
After Each Phase:
-
Run Test Suite
# Unit tests
yarn test
# E2E tests
yarn test:e2e
# With coverage
yarn test:coverage
-
Update Test Documentation
- Update
test/README.md if test structure changes
- Update
test/e2e/README.md if E2E tests change
- Update
test/unit/README.md if unit tests change
-
Fix Broken Tests
- Update imports if code moves
- Update mocks if APIs change
- Update selectors if component structure changes
-
Add New Tests
- Add tests for newly extracted code
- Ensure coverage doesn't decrease
- Add integration tests for hook interactions
Test Coverage Goals:
- Unit Tests: > 80% coverage for utility functions
- Hook Tests: > 70% coverage for custom hooks
- Component Tests: > 60% coverage for components
- E2E Tests: Cover all critical user flows
Regression Testing
Visual Regression Tests
- Use Storybook for visual regression testing
- Compare screenshots before/after refactoring
- Test all graph states (expanded, collapsed, selected, etc.)
- Measure render time before/after refactoring
- Measure memory usage
- Test with large graphs (100+ nodes)
- Ensure no performance degradation
Functional Regression Tests
- Run full E2E test suite after each phase
- Test all user interactions
- Test all responsive breakpoints
- Test all pane visibility states
Test Utilities to Create
test/utils/graphHookTestUtils.ts (New)
import { renderHook } from '@testing-library/react';
import { ReactNode } from 'react';
export function renderGraphHook<T>(
hook: () => T,
options?: {
wrapper?: ({ children }: { children: ReactNode }) => JSX.Element;
}
) {
}
export function createMockGraphRef() {
}
export function createMockGraphData() {
}
test/utils/graphComponentTestUtils.tsx (New)
export function renderGraphComponent(props: GraphRendererProps) {
}
export function waitForGraphToStabilize() {
}
E2E Test Updates
Minimal Changes Required
E2E tests should require minimal changes because they test the public API. However:
-
Selector Updates (if component structure changes)
- Update canvas selectors if wrapper structure changes
- Update menu selectors if menu components are extracted
-
Wait Strategy Updates (if initialization changes)
- Update wait times if hook initialization changes
- Update wait conditions if component mounting changes
-
Screenshot Updates (if visual changes)
- Update baseline screenshots if rendering changes
- Add new screenshots for new features
E2E Test Maintenance
- Keep E2E tests focused on user-facing behavior
- Don't test internal implementation details
- Use page objects if tests become complex
- Add visual regression tests for critical UI states
Blog Post and Documentation Updates
Files That Import Graph Components
Documentation Files:
-
docs/6-techniques/3-blogging-techniques/1-embed-structural-components/graph.mdx
- Imports:
GraphRenderer, NodeRendererDemo
- Usage: Component documentation and examples
- Impact: High - Main component documentation
-
docs/3-mental-models/6-understanding-the-genai-domain/2025-11-10-ai-framework-landscape.md
- Imports:
AIFrameworkGraph
- Usage: Displays AI framework comparison graph
- Impact: High - Live graph visualization
Blog Posts:
-
blog/2025-03-07-DFS-vs-BFS.md
- May reference graph concepts (needs verification)
- Impact: Low - Likely just mentions, not imports
-
blog/2025-09-27-my-contributions.mdx
- May reference graph components (needs verification)
- Impact: Low - Likely just mentions, not imports
Import Path Updates Required
When components move to subdirectories, import paths in MDX files need updates:
Before:
import GraphRenderer from '@site/src/components/Graph/GraphRenderer';
import NodeRendererDemo from '@site/src/components/Graph/NodeRendererDemo';
import AIFrameworkGraph from '@site/src/components/Graph/AIFrameworkGraph';
After (if components move to subdirectories):
// Option 1: If index.tsx is created, no change needed
import GraphRenderer from '@site/src/components/Graph/GraphRenderer';
import NodeRendererDemo from '@site/src/components/Graph/NodeRendererDemo';
import AIFrameworkGraph from '@site/src/components/Graph/AIFrameworkGraph';
// Option 2: If explicit paths are preferred
import GraphRenderer from '@site/src/components/Graph/GraphRenderer/GraphRenderer';
import NodeRendererDemo from '@site/src/components/Graph/NodeRendererDemo/NodeRendererDemo';
import AIFrameworkGraph from '@site/src/components/Graph/AIFrameworkGraph/AIFrameworkGraph';
Recommendation: Use index.tsx files so imports don't need to change.
Update Strategy for Blog Posts and Docs
Phase 0: Before Reorganization
-
Audit all imports
# Find all files importing Graph components
grep -r "from '@site/src/components/Graph" blog/ docs/
-
Document current import paths
- List all files that import Graph components
- Note which components are imported
- Create checklist for updates
Phase 0: During Reorganization
-
Update import paths (if needed)
- If using
index.tsx, imports may not need changes
- If not using
index.tsx, update all import paths
- Test each file after updating
-
Verify components still work
- Build Docusaurus site:
make build
- Check each page that uses Graph components
- Verify graphs render correctly
- Test interactive features (clicking, zooming, etc.)
After Each Refactoring Phase
-
Test affected pages
- Rebuild Docusaurus:
make build
- Check pages that use Graph components
- Verify no regressions
-
Update documentation if needed
- Update component documentation if APIs change
- Update examples if usage patterns change
- Update README files if structure changes
Files to Update Checklist
Documentation:
Blog Posts:
Other Documentation:
Testing Blog Posts and Docs
After Each Phase:
-
Build Docusaurus
cd bytesofpurpose-blog
yarn build
-
Check for Build Errors
- Look for import errors
- Look for component not found errors
- Fix any broken imports
-
Visual Verification
- Start dev server:
yarn start
- Navigate to each page that uses Graph components
- Verify graphs render correctly
- Test interactive features
-
Anchor Link Testing
- Test URL hash navigation (e.g.,
#graph-node-123)
- Verify nodes/edges highlight correctly
- Verify scrolling to graph works
Backward Compatibility Strategy
Goal: Ensure existing blog posts and docs continue to work without changes.
Strategy:
- Use index.tsx files - Allows imports to remain unchanged
- Maintain public API - Don't change component props or behavior
- Re-export from root - Consider re-exporting from
Graph/index.ts for convenience
Example re-export file:
export { GraphRenderer } from './GraphRenderer';
export { AIFrameworkGraph } from './AIFrameworkGraph';
export { NodeRendererDemo } from './NodeRendererDemo';
export type { GraphRendererProps } from './GraphRenderer';
This allows imports like:
import { GraphRenderer, AIFrameworkGraph } from '@site/src/components/Graph';
Documentation Update Guidelines
When to Update Documentation:
- ✅ Component moves to subdirectory (update import paths)
- ✅ Component API changes (update examples)
- ✅ New features added (document new features)
- ✅ Breaking changes (document migration path)
- ❌ Internal refactoring only (no doc updates needed if public API unchanged)
What to Update:
- Import statements - If paths change
- Code examples - If API changes
- Usage patterns - If best practices change
- Component documentation - If features change
- README files - If structure changes
What NOT to Update:
- Internal implementation details (unless relevant to users)
- File structure (unless it affects imports)
- Utility functions (unless they're part of public API)
Storybook Story Updates
Story Path Updates
When components move to subdirectories, Storybook story paths may need updates:
Before:
import { Meta } from '@storybook/addon-docs/blocks';
<Meta title="Graph/GraphMenuBar" />
After:
import { Meta } from '@storybook/addon-docs/blocks';
<Meta title="Graph/GraphMenuBar" />
Story Co-location Benefits
- Stories live next to components
- Easy to find component documentation
- Stories can import from
./ComponentName (same directory)
- Better organization in Storybook sidebar
Story Import Updates
When components move to subdirectories:
Before:
import { GraphMenuBar } from './GraphMenuBar';
After:
import { GraphMenuBar } from './GraphMenuBar';
import { GraphMenuBar } from '.';
Migration Checklist
Phase 0: Reorganization (Before Refactoring)
For Each Refactoring Phase:
Success Criteria
- ✅ GraphRenderer.tsx reduced to < 500 lines
- ✅ All existing functionality preserved
- ✅ No performance degradation
- ✅ All tests passing
- ✅ Storybook stories working
- ✅ Docusaurus integration working
- ✅ Code review approved
- ✅ Documentation updated
Notes
- Incremental Approach: Each phase is independent and can be merged separately
- Backward Compatibility: Maintain existing public API
- Type Safety: Ensure all extracted code is properly typed
- Performance: Monitor for any performance regressions
- Documentation: Update JSDoc comments as code moves
Potential Challenges
- Circular Dependencies: Watch for circular imports between utilities
- Hook Dependencies: Ensure all hook dependencies are correctly passed
- Ref Management: Graph ref needs careful handling across hooks
- State Synchronization: Ensure state updates don't cause infinite loops
- Event Handler Context: Ensure event handlers have correct context
Future Improvements (Post-Refactoring)
- Consider extracting ForceGraph2D wrapper to separate component
- Consider using React Context for graph state (if needed)
- Consider memoization optimizations
- Consider TypeScript strict mode improvements
- Consider adding more comprehensive error boundaries
Execution Results / Attempts
✅ Work In Progress (2025-11-08 to 2025-11-17)
Work Period: November 8, 2025 to November 17, 2025
Commits: 10 commits related to graph component refactoring
Key Accomplishments:
- Initial graph component implementation
- Added menu bar to graph component
- Made graph component reactive/responsive
- Added anchor links to specific nodes in graphs
- Added integration and E2E tests for graph component
- Checkpointed graph renderer refactoring work
- Finalized graph component as part of blog structure overhaul
- Revamped graph component with modularization
- Added Storybook tab to document components
- Improved graph rendering on mobile devices
Notable Commits:
a64d629e (2025-11-08): Updating authors and adding graph component plus stats structures and algos
7333d884 (2025-11-08): Making graph component reactive
d2e8bf6d (2025-11-08): Adding menu bar to graph component
92e82a04 (2025-11-08): Added ability to have anchor links to specific nodes in specific graphs
f57ee652 (2025-11-10): Adding integ and e2e tests for graph component
b5c58a8a (2025-11-10): Checkpointing graph renderer
cca8ae25 (2025-11-12): Big blog structure overhaul + finalization of graph component
e657ebde (2025-11-12): Revamp to readmes plus fix for graph
7634d68b (2025-11-16): Revamping graph component, modularizing it, etc. Also added storybook tab to document components
6ec4aaac (2025-11-17): Revamp component setup, story book stories, graph render on mobile, etc
Status: Work is in progress. The graph component has been significantly refactored and modularized, with Storybook integration added for documentation. Mobile responsiveness has been improved. Further refactoring work continues based on the comprehensive plan outlined above.