플로우 차트에서 관계 순서 이슈

SeongHyun_Kim·2024년 12월 20일
0

이슈

목록 보기
3/3

  1. 좌측 데이터 목록은 AI 학습 로직

  2. 우측은 Flow Chart로 학습시키고자 하는 모델을 Drag & Drop으로 가져와 관계도를 형성하고 해당 관계 순서로 통합 학습을 진행함.

  3. 여기서 학습 데이터는 배열 형태로 구성이 되어 있고 중간에 모델들의 순서와 구성을 언제든지 바꿀 수 있어야 하기 때문에 실시간으로 배열 구조를 바꿀 수 있는 방법을 찾았어야 함.

  4. 처음에는 index를 부여하여 순서를 적용시키고자 하였지만, 위 사진과 같이 여러 학습 로직 아이템이 많아지고 관계가 복잡해질수록 index는 효과가 떨어지게 됨.

  5. 그래서 고민을 하다가 두가지 상태 값을 생각해봄.

  • 각 아이템의 Start지점과 End지점을 각각 저장하여 상태값에 저장
  • 화면에 업데이트를 시킬 상태값 지정
  1. 이후에 End지점에 있는 아이템의 id가 다른 배열의 Start지점에 소속되어 있으면 해당 아이템의 상위 아이템으로 이동되게 함.

예시 코드는 아래와 같음.

  // 데이터 관리
  const [selected, setSelected] = useState<ColumnData[]>([]); 
  // 전체 데이터를 그룹화하여 관리
  const [groupedConnections, setGroupedConnections] = useState<ColumnData[][]>(
    [],
  ); // 객체 배열 형태로 연결 관리

  const [allConnections, setAllConnections] = useState<
    {source: string; target: string}[]
  >([]);

  const updateGroupedConnections = (
    connections: {source: string; target: string}[],
  ) => {
    const groups: ColumnData[][] = [];

    connections.forEach(({source, target}) => {
      const sourceNode = selected.find((node) => node.id === source);
      const targetNode = selected.find((node) => node.id === target);

      if (!sourceNode || !targetNode) return;

      // 겹치는 그룹 찾기
      const matchingGroups = groups.filter(
        (group) =>
          group[group.length - 1]?.id === source || group[0]?.id === target,
      );

      if (matchingGroups.length === 1) {
        // 하나의 그룹과 연결
        const [group] = matchingGroups;
        if (group[group.length - 1]?.id === source) {
          group.push(targetNode);
        } else if (group[0]?.id === target) {
          group.unshift(sourceNode);
        }
      } else if (matchingGroups.length === 2) {
        // 두 그룹을 병합
        const [group1, group2] = matchingGroups;
        const mergedGroup = [...new Set([...group1, ...group2])];
        groups.splice(groups.indexOf(group1), 1);
        groups.splice(groups.indexOf(group2), 1);
        groups.push(mergedGroup);
      } else {
        // 새로운 그룹 생성
        groups.push([sourceNode, targetNode]);
      }
    });

    setGroupedConnections(groups);
  };

  const handleConnection = (sourceId: string, targetId: string) => {
    setAllConnections((prev) => [
      ...prev,
      {source: sourceId, target: targetId},
    ]);
    updateGroupedConnections([
      ...allConnections,
      {source: sourceId, target: targetId},
    ]);
  };

  // groupedConnections 변경 시 로깅
  useEffect(() => {
    console.log('Updated groupedConnections:', groupedConnections);
  }, [groupedConnections]);

  const mergeConnections = (
    connections: {source: string; target: string}[],
    selected: ColumnData[],
  ) => {
    const mergedGroups: ColumnData[][] = [];

    connections.forEach(({source, target}) => {
      const sourceNode = selected.find((node) => node.id === source);
      const targetNode = selected.find((node) => node.id === target);

      if (!sourceNode || !targetNode) return;

      // 마지막 아이템과 첫 번째 아이템이 매칭되는 그룹 찾기
      const endingGroupIndex = mergedGroups.findIndex(
        (group) => group[group.length - 1]?.id === source,
      );
      const startingGroupIndex = mergedGroups.findIndex(
        (group) => group[0]?.id === target,
      );

      if (endingGroupIndex !== -1 && startingGroupIndex !== -1) {
        // 두 그룹을 병합
        const combinedGroup = [
          ...mergedGroups[endingGroupIndex],
          ...mergedGroups[startingGroupIndex].slice(1),
        ];

        // 기존 그룹 제거 후 병합된 그룹 추가
        mergedGroups.splice(startingGroupIndex, 1);
        mergedGroups[endingGroupIndex] = combinedGroup;
      } else if (endingGroupIndex !== -1) {
        // sourceNode가 있는 그룹의 끝에 targetNode 추가
        mergedGroups[endingGroupIndex].push(targetNode);
      } else if (startingGroupIndex !== -1) {
        // targetNode가 있는 그룹의 시작에 sourceNode 추가
        mergedGroups[startingGroupIndex].unshift(sourceNode);
      } else {
        // 새로운 그룹 추가
        mergedGroups.push([sourceNode, targetNode]);
      }
    });

    return mergedGroups;
  };

이외에도 아직 해결해야 되는 이슈가 많지만 그룹과 순서를 원하는 방식으로 병합시킬 수 있는 방법을 찾아낼 수 있어서 좋은 이슈 경험이 되었음.

profile
초보 개발자 찌랭이

0개의 댓글