component tree view in react native

I wrote a template to draw the components as a tree, but there is only one linear relationship with the first child from the parent template to the child template, if it should be a linear relationship for everyone.

I used the onLayout feature to do this, but it worked a bit How can I use linear communication for each child?

import { useTheme } from "@react-navigation/native";
import { ScrollView, View, Text } from "react-native";
import Svg, { Circle, Polyline } from "react-native-svg";
let App = () => {
  let node = {
    value: {
      name: "1",
    },
    childs: [
      {
        value: {
          name: "2",
        },
        childs: [
          {
            value: {
              name: "3",
            },
            childs: [],
          },
        ],
      },
      {
        value: {
          name: "4",
        },
        childs: [
          {
            value: {
              name: "5",
            },
            childs: [],
          },
          {
            value: {
              name: "6",
            },
            childs: [],
          },
        ],
      },
      {
        value: {
          name: "7",
        },
        childs: [
          {
            value: {
              name: "8",
            },
            childs: [],
          },
          {
            value: {
              name: "9",
            },
            childs: [],
          },
          {
            value: {
              name: "10",
            },
            childs: [],
          },
          {
            value: {
              name: "11",
            },
            childs: [],
          },
        ],
      },
      {
        value: {
          name: "12",
        },
        childs: [
          {
            value: {
              name: "13",
            },
            childs: [],
          },
          {
            value: {
              name: "14",
            },
            childs: [],
          },
        ],
      },
    ],
  };
  return (
    <ScrollView
      style={{
        width: 1000,
        height: 1000,
      }}
    >
      <ScrollView
        style={{
          width: 1000,
          height: 1000,
        }}
        horizontal
      >
        <RenderNode {...node} />
      </ScrollView>
    </ScrollView>
  );
};
let RenderNode = ({ value, childs }) => {
  let { colors, dark } = useTheme();
  let [parentLayout, setParentLayout] = React.useState({});
  let [childsLayout, setChildsLayout] = React.useState([]);
  // let onLayout = (layout) => {
  //   console.log("====================================");
  //   console.log(layout);
  //   console.log("====================================");
  // };
  return (
    <View
      style={{
        alignItems: "center",
      }}
    >
      <View
        onLayout={(e) => setParentLayout(e?.nativeEvent?.layout)}
        style={{
          backgroundColor: "transparent",
        }}
      >
        <RenderValue value={value} />
      </View>
      {childs?.length !== 0 && (
        <View
          style={{
            display: "flex",
            flexDirection: "row",
            justifyContent: "space-evenly",
          }}
        >
          {childs?.map((child, i) => (
            <View
              key={i}
              onLayout={(e) => {
                e.persist();
                setChildsLayout((cl) => [...cl, e?.nativeEvent?.layout]);
              }}
              style={{
                backgroundColor: "transparent",
              }}
            >
              <RenderNode value={child?.value} childs={child?.childs} />
            </View>
          ))}
        </View>
      )}
      {childsLayout.length !== 0 && (
        <View
          style={{
            width: "100%",
            height: "100%",
            position: "absolute",
            backgroundColor: "transparent",
          }}
        >
          <View
            onLayout={() => {
              console.log("\n\nparent : ");
              console.log(parentLayout);
              console.log("\n\nchilds : ");
              console.log(childsLayout);
            }}
            style={{
              backgroundColor: "transparent",
            }}
          >
            {childsLayout.map((cl, i) => (
              <Svg
                key={i}
                // height={cl?.y - parentLayout?.y}
                // width={cl?.x - parentLayout?.x}
              >
                <Polyline
                  // x1={`${parentLayout?.x + parentLayout?.width / 2 }`}
                  // y1={`${parentLayout?.y + parentLayout?.height / 2 }`}
                  // x2={`${cl?.x + cl?.width / 2 }`}
                  // y2={`${cl?.y + cl?.height / 2 }`}
                  points={`${parentLayout?.x + parentLayout?.width / 2},${
                    parentLayout?.y + parentLayout?.height - 10
                  } ${cl?.x + cl?.width / 2},${cl?.y + cl?.height + 10}`}
                  fill="none"
                  stroke={colors.notification}
                  strokeWidth="2"
                />
                <Circle
                  cx={`${parentLayout?.x + parentLayout?.width / 2}`}
                  cy={`${parentLayout?.y + parentLayout?.height - 10}`}
                  r="10"
                  fill={colors.notification}
                />
                {/* <Circle
                  cx={`${parentLayout?.x + parentLayout?.width - 10}`}
                  cy={`${parentLayout?.y + parentLayout?.height / 2}`}
                  r="10"
                  fill={colors.notification}
                /> */}
                <Circle
                  cx={`${cl?.x + cl?.width / 2}`}
                  cy={`${cl?.y + cl?.height + 10}`}
                  r="10"
                  fill={colors.notification}
                />
              </Svg>
            ))}
          </View>
        </View>
      )}
    </View>
  );
};
let RenderValue = ({ value }) => {
  let { colors } = useTheme();
  return (
    <View
      style={{
        width: 100,
        height: 175,
        margin: 10,
        alignItems: "center",
        borderWidth: 1,
        backgroundColor: colors.primary,
        borderRadius: 10,
        justifyContent: "space-evenly",
      }}
    >
      <View
        style={{
          width: 100,
          height: 140,
          backgroundColor: "transparent",
        }}
      />
      <Text
        style={{
          fontSize: 18,
          padding: 10,
        }}
      >
        {value?.name}
      </Text>
    </View>
  );
};

photo

ios template

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum