// Display-only summaries of the records already authorized by the server. export function summarizeHomes(homes = []) { const kinds = [ { key: 'home', label: '家庭', color: '#258b76', count: 0 }, { key: 'office', label: '办公', color: '#5c83cb', count: 0 }, { key: 'factory', label: '工厂', color: '#c69a52', count: 0 }, { key: 'other', label: '其他', color: '#8997a9', count: 0 }, ]; let devices = 0, areas = 0; for (const home of homes) { (kinds.find(k => k.key === (home.kind || 'home')) || kinds[3]).count++; devices += Math.max(0, Number(home.deviceCount) || 0); areas += Math.max(0, Number(home.sites) || 0); } let offset = 0; return { total: homes.length, devices, areas, kinds: kinds.filter(k => k.count).map(k => { const value = { ...k, share: k.count / homes.length * 100, offset }; offset += value.share; return value; }) }; } export function layoutNetwork(rows = []) { const nodes = rows.map((row, index) => ({ ...row, x: 28 + Math.max(0, row.depth) * 300, y: 26 + index * 112, })); const byId = new Map(nodes.map(n => [n.device.id, n])); const edges = nodes.flatMap(node => { const parent = byId.get(node.device.uplinkId); // Only draw an edge when the validated hierarchy confirms the parent. if (!parent || parent.depth + 1 !== node.depth) return []; const x = parent.x + 244, y = parent.y + 40, endY = node.y + 40; return [{ id: node.device.id, path: `M${x},${y} H${x + 24} V${endY} H${node.x}` }]; }); return { nodes, edges, width: Math.max(640, ...nodes.map(n => n.x + 272)), height: Math.max(172, nodes.length * 112 + 26) }; }