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;