UNPKG

datajunction-ui

Version:
1 lines 19.1 kB
{"version":3,"file":"MetricFlowGraph-B4VECq74.cjs","sources":["../src/app/pages/QueryPlannerPage/MetricFlowGraph.jsx"],"sourcesContent":["import { useMemo, useEffect, useCallback } from 'react';\nimport ReactFlow, {\n Background,\n Controls,\n MarkerType,\n useNodesState,\n useEdgesState,\n Handle,\n Position,\n} from 'reactflow';\nimport dagre from 'dagre';\nimport 'reactflow/dist/style.css';\n\n/**\n * Compact Pre-aggregation node - clickable, shows minimal info\n */\nfunction PreAggNode({ data, selected }) {\n const componentCount = data.components?.length || 0;\n\n return (\n <div\n className={`compact-node compact-node-preagg ${\n selected ? 'selected' : ''\n }`}\n >\n <div className=\"compact-node-icon\">◫</div>\n <div className=\"compact-node-content\">\n <div className=\"compact-node-name\">{data.name}</div>\n <div className=\"compact-node-meta\">\n <span className=\"meta-item\">{componentCount} components</span>\n {data.grain?.length > 0 && (\n <span className=\"meta-item grain-count\">\n {data.grain.length} grain cols\n </span>\n )}\n </div>\n </div>\n <Handle type=\"source\" position={Position.Right} />\n </div>\n );\n}\n\n/**\n * Compact Metric node - clickable, shows minimal info\n */\nfunction MetricNode({ data, selected }) {\n return (\n <div\n className={`compact-node compact-node-metric ${\n data.isDerived ? 'compact-node-derived' : ''\n } ${selected ? 'selected' : ''}`}\n >\n <Handle type=\"target\" position={Position.Left} />\n <div className=\"compact-node-icon\">{data.isDerived ? '◇' : '◈'}</div>\n <div className=\"compact-node-content\">\n <div className=\"compact-node-name\">{data.shortName}</div>\n {data.isDerived && <div className=\"compact-node-badge\">Derived</div>}\n </div>\n </div>\n );\n}\n\n/**\n * Component node - shows metric building blocks (e.g., SUM, COUNT)\n */\nfunction ComponentNode({ data, selected }) {\n return (\n <div\n className={`compact-node compact-node-component ${\n selected ? 'selected' : ''\n }`}\n >\n <Handle type=\"target\" position={Position.Left} />\n <div className=\"compact-node-icon\">●</div>\n <div className=\"compact-node-content\">\n <div className=\"compact-node-name\">{data.shortName}</div>\n <div className=\"compact-node-meta\">\n <span className=\"meta-item\">{data.aggregation || 'RAW'}</span>\n </div>\n </div>\n <Handle type=\"source\" position={Position.Right} />\n </div>\n );\n}\n\nconst nodeTypes = {\n preagg: PreAggNode,\n component: ComponentNode,\n metric: MetricNode,\n};\n\n// Node dimensions for dagre layout\nconst NODE_WIDTH = 200;\nconst NODE_HEIGHT = 50;\n\n/**\n * Use dagre to automatically layout nodes\n */\nfunction getLayoutedElements(nodes, edges) {\n const dagreGraph = new dagre.graphlib.Graph();\n dagreGraph.setDefaultEdgeLabel(() => ({}));\n\n // Configure the layout\n dagreGraph.setGraph({\n rankdir: 'LR', // Left to right\n nodesep: 60, // Vertical spacing between nodes\n ranksep: 150, // Horizontal spacing between columns\n marginx: 40,\n marginy: 40,\n });\n\n // Add nodes to dagre\n nodes.forEach(node => {\n dagreGraph.setNode(node.id, { width: NODE_WIDTH, height: NODE_HEIGHT });\n });\n\n // Add edges to dagre\n edges.forEach(edge => {\n dagreGraph.setEdge(edge.source, edge.target);\n });\n\n // Run the layout\n dagre.layout(dagreGraph);\n\n // Apply the calculated positions back to nodes\n const layoutedNodes = nodes.map(node => {\n const nodeWithPosition = dagreGraph.node(node.id);\n return {\n ...node,\n position: {\n x: nodeWithPosition.x - NODE_WIDTH / 2,\n y: nodeWithPosition.y - NODE_HEIGHT / 2,\n },\n };\n });\n\n return { nodes: layoutedNodes, edges };\n}\n\n/**\n * MetricFlowGraph - Uses dagre for automatic layout\n */\nexport function MetricFlowGraph({\n grainGroups,\n metricFormulas,\n selectedNode,\n onNodeSelect,\n}) {\n const { nodes, edges } = useMemo(() => {\n if (!grainGroups?.length || !metricFormulas?.length) {\n return { nodes: [], edges: [] };\n }\n\n const rawNodes = [];\n const rawEdges = [];\n\n // Track mappings\n const preAggNodesMap = new Map();\n const componentNodeIds = new Map();\n const componentToPreAgg = new Map();\n\n let nodeId = 0;\n const getNextId = () => `node-${nodeId++}`;\n\n // Build component -> preAgg mapping\n grainGroups.forEach((gg, idx) => {\n gg.components?.forEach(comp => {\n componentToPreAgg.set(comp.name, idx);\n });\n });\n\n // Create pre-aggregation nodes\n grainGroups.forEach((gg, idx) => {\n const id = getNextId();\n preAggNodesMap.set(idx, id);\n\n const shortName = gg.parent_name?.split('.').pop() || `preagg_${idx}`;\n\n rawNodes.push({\n id,\n type: 'preagg',\n position: { x: 0, y: 0 }, // Will be set by dagre\n data: {\n name: shortName,\n fullName: gg.parent_name,\n grain: gg.grain || [],\n components: gg.components || [],\n grainGroupIndex: idx,\n },\n selected:\n selectedNode?.type === 'preagg' && selectedNode?.index === idx,\n });\n });\n\n // Create component nodes (building blocks for metrics)\n grainGroups.forEach((gg, ggIdx) => {\n gg.components?.forEach(comp => {\n if (!componentNodeIds.has(comp.name)) {\n const id = getNextId();\n componentNodeIds.set(comp.name, id);\n // Shorten name for display (e.g., \"unit_price_sum\" -> \"price_sum\")\n const shortName =\n comp.name.length > 40\n ? '...' + comp.name.split('_').slice(-2).join('_')\n : comp.name;\n\n rawNodes.push({\n id,\n type: 'component',\n position: { x: 0, y: 0 },\n data: {\n name: comp.name,\n shortName,\n aggregation: comp.aggregation,\n merge: comp.merge,\n grainGroupIndex: ggIdx,\n },\n selected:\n selectedNode?.type === 'component' &&\n selectedNode?.name === comp.name,\n });\n }\n });\n });\n\n // Create metric nodes\n const metricNodeIds = new Map();\n\n metricFormulas.forEach((metric, idx) => {\n const id = getNextId();\n metricNodeIds.set(metric.name, id);\n\n rawNodes.push({\n id,\n type: 'metric',\n position: { x: 0, y: 0 }, // Will be set by dagre\n data: {\n name: metric.name,\n shortName: metric.short_name,\n combiner: metric.combiner,\n isDerived: metric.is_derived,\n components: metric.components,\n metricIndex: idx,\n },\n selected:\n selectedNode?.type === 'metric' && selectedNode?.index === idx,\n });\n });\n\n // Create edges: PreAgg -> Component\n grainGroups.forEach((gg, ggIdx) => {\n const preAggId = preAggNodesMap.get(ggIdx);\n gg.components?.forEach(comp => {\n const compId = componentNodeIds.get(comp.name);\n if (preAggId && compId) {\n rawEdges.push({\n id: `edge-preagg-${preAggId}-${compId}`,\n source: preAggId,\n target: compId,\n style: { stroke: '#64748b', strokeWidth: 2 },\n markerEnd: {\n type: MarkerType.ArrowClosed,\n color: '#64748b',\n width: 16,\n height: 16,\n },\n });\n }\n });\n });\n\n // Create edges: Component -> Metric\n metricFormulas.forEach(metric => {\n const metricId = metricNodeIds.get(metric.name);\n metric.components?.forEach(compName => {\n const compId = componentNodeIds.get(compName);\n if (compId && metricId) {\n rawEdges.push({\n id: `edge-comp-${compId}-${metricId}`,\n source: compId,\n target: metricId,\n style: { stroke: '#64748b', strokeWidth: 2 },\n markerEnd: {\n type: MarkerType.ArrowClosed,\n color: '#64748b',\n width: 16,\n height: 16,\n },\n });\n }\n });\n });\n\n // Apply dagre layout\n return getLayoutedElements(rawNodes, rawEdges);\n }, [grainGroups, metricFormulas, selectedNode]);\n\n const [flowNodes, setNodes, onNodesChange] = useNodesState(nodes);\n const [flowEdges, setEdges, onEdgesChange] = useEdgesState(edges);\n\n // Update nodes/edges when data changes\n useEffect(() => {\n setNodes(nodes);\n setEdges(edges);\n }, [nodes, edges, setNodes, setEdges]);\n\n const handleNodeClick = useCallback(\n (event, node) => {\n if (node.type === 'preagg') {\n onNodeSelect?.({\n type: 'preagg',\n index: node.data.grainGroupIndex,\n data: grainGroups[node.data.grainGroupIndex],\n });\n } else if (node.type === 'component') {\n onNodeSelect?.({\n type: 'component',\n name: node.data.name,\n data: node.data,\n });\n } else if (node.type === 'metric') {\n onNodeSelect?.({\n type: 'metric',\n index: node.data.metricIndex,\n data: metricFormulas[node.data.metricIndex],\n });\n }\n },\n [onNodeSelect, grainGroups, metricFormulas],\n );\n\n const handlePaneClick = useCallback(() => {\n onNodeSelect?.(null);\n }, [onNodeSelect]);\n\n if (!grainGroups?.length || !metricFormulas?.length) {\n return (\n <div className=\"graph-empty-state\">\n <div className=\"empty-icon\">◎</div>\n <p>Select metrics and dimensions above to visualize the data flow</p>\n </div>\n );\n }\n\n return (\n <div className=\"compact-flow-container\">\n <ReactFlow\n nodes={flowNodes}\n edges={flowEdges}\n onNodesChange={onNodesChange}\n onEdgesChange={onEdgesChange}\n nodeTypes={nodeTypes}\n onNodeClick={handleNodeClick}\n onPaneClick={handlePaneClick}\n fitView\n fitViewOptions={{ padding: 0.2 }}\n minZoom={0.5}\n maxZoom={1.5}\n attributionPosition=\"bottom-left\"\n proOptions={{ hideAttribution: true }}\n >\n <Background color=\"#cbd5e1\" gap={20} size={1} />\n <Controls showInteractive={false} />\n </ReactFlow>\n\n {/* Legend */}\n <div className=\"graph-legend\">\n <div className=\"legend-item\">\n <span className=\"legend-dot preagg\"></span>\n <span>Pre-agg</span>\n </div>\n <div className=\"legend-item\">\n <span className=\"legend-dot component\"></span>\n <span>Component</span>\n </div>\n <div className=\"legend-item\">\n <span className=\"legend-dot metric\"></span>\n <span>Metric</span>\n </div>\n <div className=\"legend-item\">\n <span className=\"legend-dot derived\"></span>\n <span>Derived</span>\n </div>\n </div>\n </div>\n );\n}\n\nexport default MetricFlowGraph;\n"],"names":["PreAggNode","data","selected","componentCount","_a","jsxs","jsx","_b","Handle","Position","MetricNode","ComponentNode","nodeTypes","NODE_WIDTH","NODE_HEIGHT","getLayoutedElements","nodes","edges","dagreGraph","dagre","node","edge","nodeWithPosition","MetricFlowGraph","grainGroups","metricFormulas","selectedNode","onNodeSelect","useMemo","rawNodes","rawEdges","preAggNodesMap","componentNodeIds","componentToPreAgg","nodeId","getNextId","gg","idx","comp","id","shortName","ggIdx","metricNodeIds","metric","preAggId","compId","MarkerType","metricId","compName","flowNodes","setNodes","onNodesChange","useNodesState","flowEdges","setEdges","onEdgesChange","useEdgesState","useEffect","handleNodeClick","useCallback","event","handlePaneClick","ReactFlow","Background","Controls"],"mappings":"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"}