Handle node rearranging in d3 org chart

262 views Asked by At

In my React app, I have been using the d3 org chart library to display some of my charts.

The example I used is from here:

https://codesandbox.io/s/org-chart-fnx0zi?file=/src/components/orgChart.js

This is the component code:

import React, { useState, useRef, useLayoutEffect } from "react";
import ReactDOMServer from "react-dom/server";
import { OrgChart } from "d3-org-chart";
import CustomNodeContent from "./customNodeContent";
import CustomExpandButton from "./customExpandButton";
import EmployeeDetailsCard from "./employeeDetailsCard";

const styles = {
  orgChart: {
    height: "calc(100vh - 60px)",
    backgroundColor: "#eaeaea",
  },
};

const OrganizationalChart = (props) => {
  const d3Container = useRef(null);
  const [cardShow, setCardShow] = useState(false);
  const [employeeId, setEmployeeId] = useState("");

  const handleShow = () => setCardShow(true);
  const handleClose = () => setCardShow(false);

  useLayoutEffect(() => {
    const toggleDetailsCard = (nodeId) => {
      handleShow();
      setEmployeeId(nodeId);
    };
    const chart = new OrgChart();
    if (props.data && d3Container.current) {
      chart
        .container(d3Container.current)
        .data(props.data)
        .nodeWidth((d) => 300)
        .nodeHeight((d) => 150)
        .compactMarginBetween((d) => 80)
        .onNodeClick((d) => {
          toggleDetailsCard(d);
        })
        .buttonContent((node, state) => {
          return ReactDOMServer.renderToStaticMarkup(
            <CustomExpandButton {...node.node} />
          );
        })
        .nodeContent((d) => {
          return ReactDOMServer.renderToStaticMarkup(
            <CustomNodeContent {...d} />
          );
        })
        .render();
    }
  }, [props, props.data]);

  return (
    <div style={styles.orgChart} ref={d3Container}>
      {cardShow && (
        <EmployeeDetailsCard
          employees={props.data}
          employee={props.data.find((employee) => employee.id === employeeId)}
          handleClose={handleClose}
        />
      )}
    </div>
  );
};

export default OrganizationalChart;

It works ok, but I dislike how it rearranges the nodes automatically; for example, when I add children to the root node, it initially arranges them like this:

enter image description here

and then rearranges when expanding further.

I would much prefer it if it displayed all of the same-level nodes in a single line, is there any way to do this?

1

There are 1 answers

1
coding.... On

Initial view of organization chart will be in vertical view. You can adjust this by adding .compact(false). By this you can view your chart iniline.