JavaScript is required

Force - Customer Force Layout 2

Circular Force Layout with Track Constraints

Demonstrates an advanced custom force layout that constrains nodes to move along concentric circular tracks while applying force-directed physics for hierarchical radial organization.

Circular Force Layout with Track Constraints

Functional Overview

This example demonstrates an advanced custom force layout that constrains nodes to move along concentric circular tracks while still applying force-directed physics. Nodes are organized into hierarchical layers (circular tracks) with the root at the center, creating an organized radial layout.

Implementation of Key Features

Circular Track Constraints

The custom layout enforces that nodes move only along their assigned circular orbit:

  • Track Assignment: Each node has a limitCircular property specifying which circular track it belongs to
  • Track Radii: Configurable array of diameters for each circular layer
  • Position Calculation: The getOvalPoint() function calculates positions on circular paths using angle and radius
const [circularSet, setCircularSet] = useState<number[]>([200, 550, 800, 1020, 1260]);

const updateLayoutCircleSet = async (myLayout: MyForceLayout) => {
    myLayout.setLevelCircleSet(circularSet.map(v => v / 2 - 60));
};

Hierarchical Node Organization

Nodes use custom properties for organization:

  • myLevel: Style classification (root, level1-4)
  • myColor: Color scheme for different branches
  • limitCircular: Which circular track the node should occupy
  • force_weight: Resistance to movement (heavier nodes move less)
{ id: 'a', text: '', color: '#cccccc', force_weight: 10000,
  disablePointEvent: true, disableDrag: true,
  data: { myColor: 'root-color', myLevel: 'my-root', limitCircular: 0 } }

Fixed Position Nodes

Level 1 nodes are fixed at specific positions on the innermost track:

  • Use fixed: true to prevent force layout from moving them
  • Manually set x, y coordinates using polar coordinates
  • Configure expandHolderPosition for collapse button placement
leve1NodeForSystem.fixed = true;
let nodePoint = getOvalPoint(rootNodeJson.x, rootNodeJson.y, circularSet[0] / 2, 90);
leve1NodeForSystem.x = nodePoint.x;
leve1NodeForSystem.y = nodePoint.y;
leve1NodeForSystem.expandHolderPosition = 'right';

Custom Node Styling with Slots

Use RGSlotOnNode to render different node styles based on level:

  • Root node displays an image
  • Other levels show colored text nodes
<RGSlotOnNode>
    {({ node }) => {
        return node.data?.myLevel === 'my-root' ? (
            <div className={`my-node ${node.data.myColor} ${node.data.myLevel}`}>
                <div className="node-content">
                    <img src={node.data.img} alt="" />
                </div>
            </div>
        ) : (
            <div className={`my-node ${node.data?.myColor} ${node.data?.myLevel}`}>
                <div className="node-content">
                    <div className="my-node-text">{node.text}</div>
                </div>
            </div>
        );
    }}
</RGSlotOnNode>

Visual Circular Tracks

Concentric circles are rendered as absolute positioned div elements with CSS variables for dynamic sizing:

<div style={{ position: 'absolute', left: `${circularSet[4] * -0.5}px`, top: `${circularSet[4] * -0.5}px` }}>
    <div className="c-circle" style={{ '--circle-size': `${circularSet[4]}px` }}>
        <div className="circle-title">Close In-Laws</div>
        {/* Nested circles */}
    </div>
</div>

Dashed Line Styles

Lines are configured with custom dash patterns and arrows disabled:

graphJsonData.lines.forEach(line => {
    line.dashType = 2;
    line.showEndArrow = false;
});

Creative Use Cases

  • Family Tree Visualization: Display generational relationships in concentric circles
  • Organization Charts: Show departments and teams in radial layers
  • Network Topology: Visualize network layers with center as core infrastructure
  • Solar System Models: Display celestial bodies in orbital tracks
  • Skill Radars: Show skills or competencies organized by category rings