Symmetric layout in React Diagram control

6 Dec 202411 minutes to read

The symmetric layout has been formed using nodes position by closer together or pushing them further apart. This is repeated iteratively until the system comes to an equilibrium state.

Symmetric layout

The layout’s springLength defined as how long edges should be, ideally. This will be the resting length for the springs. Edge attraction and vertex repulsion forces to be defined by using layout’s springFactor, the more sibling nodes repel each other. The relative positions do not change any more from one iteration to the next. The number of iterations can be specified by using layout’s maxIteration.

The following code illustrates how to arrange the nodes in a radial tree structure.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, Inject, SymmetricLayout } from '@syncfusion/ej2-react-diagrams';


//Initialize nodes 
let nodes = [];

//Initializes connectors
let connectors = [];

// creating the connection between the layout nodes and connectors.
function connectNodes(parentNode, childNode) {
    const connector = {
        id: parentNode.id + childNode.id,
        sourceID: parentNode.id,
        targetID: childNode.id,
        targetDecorator: { shape: 'None' },
    };
    return connector;
}

// creating the layout nodes as rectangle in shape.
function getRectangle(name) {
    const shape = { type: 'Basic', shape: 'Ellipse' };
    const node = {
        id: name,
        height: 25,
        width: 25,
        style: { fill: '#ff6329' },
        shape: shape,
    };
    return node;
}

// creating the symmetrical layout child elements hierarchy.
function populateNodes() {
    const parentRect = getRectangle('p');
    nodes.push(parentRect);
    for (let i = 0; i < 2; i++) {
        const childRect_i = getRectangle('c' + i);
        nodes.push(childRect_i);
        for (let j = 0; j < 2; j++) {
            const childRect_j = getRectangle('c' + i + j);
            nodes.push(childRect_j);
            for (let k = 0; k < 6; k++) {
                const childRect_k = getRectangle('c' + i + j + k);
                nodes.push(childRect_k);
                connectors.push(connectNodes(childRect_j, childRect_k));
            }
            connectors.push(connectNodes(childRect_i, childRect_j));
        }
        connectors.push(connectNodes(parentRect, childRect_i));
    }
    return nodes;
}

//sets the layout child elements
populateNodes();

export default function App() {

    return (
        <div>
            <DiagramComponent
                id="container"
                width={'80%'}
                height={'550px'}
                nodes={nodes}
                connectors={connectors}

                //Uses layout to auto-arrange nodes on the diagram page
                layout={{
                    //Sets layout type
                    type: 'SymmetricalLayout',
                    springLength: 80,
                    springFactor: 0.8,
                    maxIteration: 500,
                    margin: { left: 20, top: 20 },
                }}
            >

                {/* Inject necessary services for the diagram */}
                <Inject services={[SymmetricLayout]} />
            </DiagramComponent>

        </div>
    );
}

// Render the App component into the 'diagram' element in the DOM
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DiagramComponent, Inject, SymmetricLayout, ConnectorModel, NodeModel, BasicShapeModel } from '@syncfusion/ej2-react-diagrams';


//Initialize nodes 
let nodes: NodeModel[] = [];

//Initializes connectors
let connectors: ConnectorModel[] = [];

// creating the connection between the layout nodes and connectors.
function connectNodes(parentNode: NodeModel | any, childNode: NodeModel): ConnectorModel {
  const connector: ConnectorModel = {
    id: parentNode.id + childNode.id,
    sourceID: parentNode.id,
    targetID: childNode.id,
    targetDecorator: { shape: 'None' },
  };
  return connector;
}

// creating the layout nodes as rectangle in shape.
function getRectangle(name: string): NodeModel {
  const shape: BasicShapeModel = {
    type: 'Basic',
    shape: 'Ellipse',
  };
  const node: NodeModel = {
    id: name,
    height: 25,
    width: 25,
    style: { fill: '#ff6329' },
    shape: shape,
  };
  return node;
}

// creating the symmetrical layout child elements hierarchy.
function populateNodes() {
  const parentRect: NodeModel = getRectangle('p');
  nodes.push(parentRect);
  for (let i = 0; i < 2; i++) {
    const childRect_i: NodeModel = getRectangle('c' + i);
    nodes.push(childRect_i);
    for (let j = 0; j < 2; j++) {
      const childRect_j: NodeModel = getRectangle('c' + i + j);
      nodes.push(childRect_j);
      for (let k = 0; k < 6; k++) {
        const childRect_k: NodeModel = getRectangle('c' + i + j + k);
        nodes.push(childRect_k);
        connectors.push(connectNodes(childRect_j, childRect_k));
      }
      connectors.push(connectNodes(childRect_i, childRect_j));
    }
    connectors.push(connectNodes(parentRect, childRect_i));
  }
  return nodes;
}

//sets the layout child elements
populateNodes();

export default function App() {

  return (
    <div>
      <DiagramComponent
        id="container"
        width={'80%'}
        height={'550px'}
        nodes={nodes}
        connectors={connectors}

        //Uses layout to auto-arrange nodes on the diagram page
        layout={{
          //Sets layout type
          type: 'SymmetricalLayout',
          springLength: 80,
          springFactor: 0.8,
          maxIteration: 500,
          margin: { left: 20, top: 20 },
        }}
      >

        {/* Inject necessary services for the diagram */}
        <Inject services={[SymmetricLayout]} />
      </DiagramComponent>

    </div>
  );
}

// Render the App component into the 'diagram' element in the DOM
const root = ReactDOM.createRoot(document.getElementById('diagram') as HTMLElement);
root.render(<App />);

Note: If you want to use symmetric layout in diagram, you need to inject SymmetricLayout in the diagram.

Symmetric layout