import { groupBy } from '@antv/util'; import { ChangeType } from '../constants'; import type { DataAdded, DataChange, DataChanges, DataRemoved, DataUpdated, ID } from '../types'; import { idOf } from './id'; /** * 对数据操作进行约简 * * Reduce data changes * @param changes - 数据操作 | data changes * @returns 约简后的数据操作 | reduced data changes */ export function reduceDataChanges(changes: DataChange[]): DataChange[] { const results = { Added: new Map(), Updated: new Map(), Removed: new Map(), }; changes.forEach((change) => { const { type, value } = change; const id = idOf(value); if (type === 'NodeAdded' || type === 'EdgeAdded' || type === 'ComboAdded') { results.Added.set(id, change); } else if (type === 'NodeUpdated' || type === 'EdgeUpdated' || type === 'ComboUpdated') { // 如果存在 Added,将当前操作置为 Added 操作 // If there is an Added operation, set the current operation to Added if (results.Added.has(id)) { results.Added.set(id, { type: type.replace('Updated', 'Added'), value } as DataAdded); } // 如果存在 Updated,将当前操作置为 Updated 操作,但使用更早版本的 original // If there is an Updated operation, set the current operation to Updated, but use an earlier version of original else if (results.Updated.has(id)) { const { original } = results.Updated.get(id)!; results.Updated.set(id, { type, value, original } as DataUpdated); } else if (results.Removed.has(id)) { // 如果存在 Removed,不做任何操作 // If there is a Removed operation, do nothing } else results.Updated.set(id, change); } else if (type === 'NodeRemoved' || type === 'EdgeRemoved' || type === 'ComboRemoved') { // 如果存在 Added 或者 Updated 的操作,删除 Removed 操作 // If there is an Added or Updated operation, delete the Removed operation if (results.Added.has(id)) { results.Added.delete(id); } else if (results.Updated.has(id)) { results.Updated.delete(id); results.Removed.set(id, change); } else { results.Removed.set(id, change); } } }); // 顺序并不重要 // The order is not important return [ ...Array.from(results.Added.values()), ...Array.from(results.Updated.values()), ...Array.from(results.Removed.values()), ]; } /** * 对数据操作进行分类 * * Classify data changes * @param changes - 数据操作 | data changes * @returns 分类后的数据操作 | classified data changes */ export function groupByChangeType(changes: DataChange[]): DataChanges { const { NodeAdded = [], NodeUpdated = [], NodeRemoved = [], EdgeAdded = [], EdgeUpdated = [], EdgeRemoved = [], ComboAdded = [], ComboUpdated = [], ComboRemoved = [], } = groupBy(changes, (change) => change.type) as unknown as Record<`${ChangeType}`, DataChange[]>; return { add: { nodes: NodeAdded, edges: EdgeAdded, combos: ComboAdded, }, update: { nodes: NodeUpdated, edges: EdgeUpdated, combos: ComboUpdated, }, remove: { nodes: NodeRemoved, edges: EdgeRemoved, combos: ComboRemoved, }, } as DataChanges; }