좌측 데이터 목록은 AI 학습 로직
우측은 Flow Chart로 학습시키고자 하는 모델을 Drag & Drop으로 가져와 관계도를 형성하고 해당 관계 순서로 통합 학습을 진행함.
여기서 학습 데이터는 배열 형태로 구성이 되어 있고 중간에 모델들의 순서와 구성을 언제든지 바꿀 수 있어야 하기 때문에 실시간으로 배열 구조를 바꿀 수 있는 방법을 찾았어야 함.
처음에는 index를 부여하여 순서를 적용시키고자 하였지만, 위 사진과 같이 여러 학습 로직 아이템이 많아지고 관계가 복잡해질수록 index는 효과가 떨어지게 됨.
그래서 고민을 하다가 두가지 상태 값을 생각해봄.
예시 코드는 아래와 같음.
// 데이터 관리
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;
};
이외에도 아직 해결해야 되는 이슈가 많지만 그룹과 순서를 원하는 방식으로 병합시킬 수 있는 방법을 찾아낼 수 있어서 좋은 이슈 경험이 되었음.