github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/ui/dashboard/src/components/dashboards/flows/Flow/index.tsx (about) 1 import ErrorPanel from "../../Error"; 2 import merge from "lodash/merge"; 3 import useChartThemeColors from "../../../../hooks/useChartThemeColors"; 4 import useNodeAndEdgeData from "../../common/useNodeAndEdgeData"; 5 import { 6 buildNodesAndEdges, 7 buildSankeyDataInputs, 8 LeafNodeData, 9 toEChartsType, 10 } from "../../common"; 11 import { Chart } from "../../charts/Chart"; 12 import { FlowProperties, FlowProps, FlowType } from "../types"; 13 import { getFlowComponent } from ".."; 14 import { NodesAndEdges } from "../../common/types"; 15 import { registerComponent } from "../../index"; 16 import { useDashboard } from "../../../../hooks/useDashboard"; 17 18 const getCommonBaseOptions = () => ({ 19 animation: false, 20 tooltip: { 21 trigger: "item", 22 triggerOn: "mousemove", 23 }, 24 }); 25 26 const getCommonBaseOptionsForFlowType = (type: FlowType = "sankey") => { 27 switch (type) { 28 case "sankey": 29 return {}; 30 default: 31 return {}; 32 } 33 }; 34 35 const getSeriesForFlowType = ( 36 type: FlowType = "sankey", 37 data: LeafNodeData | undefined, 38 properties: FlowProperties | undefined, 39 nodesAndEdges: NodesAndEdges, 40 themeColors 41 ) => { 42 if (!data) { 43 return {}; 44 } 45 const series: any[] = []; 46 const seriesLength = 1; 47 for (let seriesIndex = 0; seriesIndex < seriesLength; seriesIndex++) { 48 switch (type) { 49 case "sankey": { 50 const { data: sankeyData, links } = 51 buildSankeyDataInputs(nodesAndEdges); 52 series.push({ 53 type: toEChartsType(type), 54 layout: "none", 55 draggable: true, 56 label: { color: themeColors.foreground, formatter: "{b}" }, 57 emphasis: { 58 focus: "adjacency", 59 blurScope: "coordinateSystem", 60 }, 61 lineStyle: { 62 color: "source", 63 curveness: 0.5, 64 }, 65 data: sankeyData, 66 links, 67 tooltip: { 68 formatter: "{b}", 69 }, 70 }); 71 break; 72 } 73 } 74 } 75 76 return { series }; 77 }; 78 79 const getOptionOverridesForFlowType = ( 80 type: FlowType = "sankey", 81 properties: FlowProperties | undefined 82 ) => { 83 if (!properties) { 84 return {}; 85 } 86 87 return {}; 88 }; 89 90 const buildFlowOptions = (props: FlowProps, themeColors) => { 91 const nodesAndEdges = buildNodesAndEdges( 92 props.categories, 93 props.data, 94 props.properties, 95 themeColors 96 ); 97 98 return merge( 99 getCommonBaseOptions(), 100 getCommonBaseOptionsForFlowType(props.display_type), 101 getSeriesForFlowType( 102 props.display_type, 103 props.data, 104 props.properties, 105 nodesAndEdges, 106 themeColors 107 ), 108 getOptionOverridesForFlowType(props.display_type, props.properties) 109 ); 110 }; 111 112 const FlowWrapper = (props: FlowProps) => { 113 const themeColors = useChartThemeColors(); 114 const { 115 themeContext: { wrapperRef }, 116 } = useDashboard(); 117 const nodeAndEdgeData = useNodeAndEdgeData( 118 props.data, 119 props.properties, 120 props.status 121 ); 122 123 if (!wrapperRef) { 124 return null; 125 } 126 127 if ( 128 !nodeAndEdgeData || 129 !nodeAndEdgeData.data || 130 !nodeAndEdgeData.data.rows || 131 nodeAndEdgeData.data.rows.length === 0 132 ) { 133 return null; 134 } 135 136 return ( 137 <Chart 138 options={buildFlowOptions( 139 { 140 ...props, 141 categories: nodeAndEdgeData.categories, 142 data: nodeAndEdgeData.data, 143 properties: nodeAndEdgeData.properties, 144 }, 145 themeColors 146 )} 147 type={props.display_type || "sankey"} 148 /> 149 ); 150 }; 151 152 const renderFlow = (definition: FlowProps) => { 153 // We default to sankey diagram if not specified 154 const { display_type = "sankey" } = definition; 155 156 const flow = getFlowComponent(display_type); 157 158 if (!flow) { 159 return <ErrorPanel error={`Unknown flow type ${display_type}`} />; 160 } 161 162 const Component = flow.component; 163 return <Component {...definition} />; 164 }; 165 166 const RenderFlow = (props: FlowProps) => { 167 return renderFlow(props); 168 }; 169 170 registerComponent("flow", RenderFlow); 171 172 export default FlowWrapper;