|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +This is a Java library implementing the Walker Node-Positioning Algorithm for general trees, as described in John Q. Walker II's paper. The algorithm aesthetically positions tree nodes in 2D space using a two-pass approach. |
| 8 | + |
| 9 | +## Build Commands |
| 10 | + |
| 11 | +This project uses Gradle with Java 17: |
| 12 | + |
| 13 | +- **Build the project**: `./gradlew build` |
| 14 | +- **Run tests**: `./gradlew test` |
| 15 | +- **Generate test coverage report**: `./gradlew jacocoTestReport` |
| 16 | + - Coverage reports are generated in `build/reports/jacoco/test/html/` |
| 17 | +- **Clean build artifacts**: `./gradlew clean` |
| 18 | +- **Run the demo**: `./gradlew run` or directly run `DemoFrame.main()` |
| 19 | +- **Publish to GitHub Packages**: `./gradlew publish` |
| 20 | + |
| 21 | +### Running Individual Tests |
| 22 | + |
| 23 | +Use JUnit 5 test filtering: |
| 24 | +```bash |
| 25 | +./gradlew test --tests WalkerAlgorithmTest |
| 26 | +./gradlew test --tests WalkerAlgorithmTest.testPosition |
| 27 | +``` |
| 28 | + |
| 29 | +## Code Architecture |
| 30 | + |
| 31 | +### Core Algorithm Components |
| 32 | + |
| 33 | +The Walker algorithm positions tree nodes through two traversal passes: |
| 34 | + |
| 35 | +1. **WalkerAlgorithm** (`src/main/java/org/behrang/algorithm/tree/WalkerAlgorithm.java`) |
| 36 | + - Main algorithm class implementing the two-pass layout |
| 37 | + - **First pass** (`firstWalk`): Performs post-order traversal, calculating preliminary x-coordinates (`prelim`) and modifiers for each node |
| 38 | + - **Second pass** (`secondWalk`): Performs pre-order traversal, computing final x,y coordinates by accumulating modifiers down the tree |
| 39 | + - **Apportionment** (`apportion`): Resolves conflicts between subtrees by shifting them apart when they would overlap |
| 40 | + - Configurable spacing parameters: `siblingSeparation`, `subtreeSeparation`, `levelSeparation` |
| 41 | + - Maintains `previousNodeAtLevel` map to track left neighbors during traversal |
| 42 | + |
| 43 | +2. **Node** (`src/main/java/org/behrang/algorithm/tree/Node.java`) |
| 44 | + - Generic tree node structure holding user data and layout information |
| 45 | + - **Layout fields**: `prelim` (preliminary x-position), `modifier` (x-adjustment), `x`, `y` (final coordinates), `width`, `height` |
| 46 | + - **Tree navigation**: Methods for parent/child access, sibling traversal (`getLeftSibling`, `getRightSibling`), and finding leftmost descendants |
| 47 | + - **Left neighbor**: Tracks the previous node at the same level for conflict detection |
| 48 | + |
| 49 | +3. **TreeTraversal** (`src/main/java/org/behrang/algorithm/tree/TreeTraversal.java`) |
| 50 | + - Utility for tree traversal operations (currently preorder only) |
| 51 | + |
| 52 | +4. **DimensionCalculator** (`src/main/java/org/behrang/algorithm/tree/DimensionCalculator.java`) |
| 53 | + - Calculates bounding box dimensions after layout |
| 54 | + - `calculateTreeDimension`: Returns total width/height of positioned tree |
| 55 | + - `calculateMaxNodeDimension`: Returns maximum node dimensions in tree |
| 56 | + |
| 57 | +### Demo Package |
| 58 | + |
| 59 | +Located in `src/main/java/org/behrang/algorithm/tree/demo/`: |
| 60 | +- **DemoFrame**: Swing JFrame showing visual tree layout |
| 61 | +- **TreePanel**: Custom panel that renders positioned tree nodes |
| 62 | +- **SampleTree**: Generates test tree structures |
| 63 | + |
| 64 | +### Algorithm Key Concepts |
| 65 | + |
| 66 | +- **Prelim**: Preliminary x-coordinate calculated during first walk (relative to parent) |
| 67 | +- **Modifier**: Offset to be added to all descendant nodes during second walk |
| 68 | +- **Apportion**: Process of shifting subtrees to prevent overlap while maintaining aesthetic centering |
| 69 | +- **Left Neighbor**: The rightmost node at the same level in the previously processed subtree, used for detecting potential overlaps |
| 70 | + |
| 71 | +### Testing Structure |
| 72 | + |
| 73 | +Tests are in `src/test/java/org/behrang/algorithm/tree/`: |
| 74 | +- **WalkerAlgorithmTest**: Tests the complete positioning algorithm with a complex tree structure |
| 75 | +- **DimensionCalculatorTest**: Tests dimension calculation utilities |
| 76 | +- Uses JUnit 5 with `@BeforeEach` setup |
| 77 | +- Helper methods: `node()` creates test nodes, `link()` establishes parent-child relationships |
| 78 | +- Tests verify exact x,y coordinates after positioning |
| 79 | + |
| 80 | +## Important Notes |
| 81 | + |
| 82 | +- The algorithm is stateful per positioning operation (uses `previousNodeAtLevel` map), so call `position()` with the root for each layout |
| 83 | +- Node dimensions (`width`, `height`) must be set before calling `position()` |
| 84 | +- Coordinates are in abstract units; scale as needed for rendering |
| 85 | +- The implementation is heavily inspired by https://github.com/soerenreichardt/graph-drawing |
0 commit comments