DEV Community

Cover image for How to - Make a Flow Chart Power App
david wyatt
david wyatt

Posted on • Updated on

How to - Make a Flow Chart Power App

When making Power Apps we are often only as good as the components we have, and although Microsoft is doing a great job at rolling out new ones, we are still limited compared to ProCode.

Fortunately there is Component Framework which allows you to create custom components, but this has a few drawbacks:

  • It isn't LowCode (professional developers required)
  • Requires enablement in environment (security risks may require turned off)
  • Requires premium license for users

Fortunately as with most LowCode, if we think outside of the box we can create a custom component like experience, without any of the above issues.

How exactly? Certain API's (some free) allow you to unload the complexity to outside of the app, in this demo I'm going to create a Flow diagram tool (like Visio) leveraging a great free API called QuickChart. How is this not a premium connector, well the API returns images (png or svg), which means we can pass the get request as an image source url.

power app sdd gif

Open gif


power app sdd

The Viso tool is going to be used to create SDD's (Simple Design Diagrams) for Flows, Apps and PVA's. The App will do the following:

  • Get list of connectors from Microsoft*
  • Populate dropdowns
  • Create diagram code url from dropdowns
  • Use QuickChart API to populate image
  • Send diagram code url to a flow
  • Use HTTP request to get image content*
  • Save to SharePoint
  • Send link so app user can download

* Requires premium license, but this is for the demo, the flow chart diagram would work without these added functionality.


  1. Custom Connector
  2. App Setup
  3. API request
  4. Flow to create file

1. Connectors

The custom connector is relatively simple, there is a free API provided by Microsoft that returns all connectors.

https://powerautomate.microsoft.com/en-us/api/connectors/all

I wrote a previous blog about how to create a custom connector here if you need some guidance.

custom connector

In the App I save the response as an object, then convert it to a collection to be used in combo boxes. To make it easier I copy some nested fields to the route and I create a formatted value for the diagram, as unfortunately this API won't work with following in the labels:

  • leading numbers
  • spaces
  • special characters (excluding _ )

so we remove them with a substitute regex function.

Set(colValue,PowerPlatformConenctors.GetConnectors().value);
ClearCollect(colConnectors,
    AddColumns(colValue,
        "DisplayName",
            properties.displayName,
        "DesignLabel",
            Concat(Split(properties.displayName,""),
                If(IsMatch(Value,"[A-Za-z]"),Value,"")
            ),
        "Trigger",
            "_"&Concat(Split(properties.displayName,""),
                If(IsMatch(Value,"[A-Za-z]"),Value,"")
            ),
        "Output",
            Concat(Split(properties.displayName,""),
                If(IsMatch(Value,"[A-Za-z]"),Value,"")
            )&"_",
        "Tier",properties. Tier
    )  
)
Enter fullscreen mode Exit fullscreen mode

To keep the trigger and output unique I add a leading/trailing '_' to the label. Else the diagram wouldn't know the difference between trigger, connector, output and only render it once.

2. App Setup

For the app I have a few combo boxes for the inputs to the diagram.

  • Type - is it a flow, app, pva, or app & flow (if not flow there is no trigger, so we use a 'User' as the trigger)
  • Trigger - connector for flows only (connector collection)
  • Connectors - any connector used (connector collection)
  • Privileges - the permissions each connector uses (Create,Read,Update,Delete)
  • Output - the primary end point of the data (connector collection)

I then added an image to the render the diagram. To help with the demo I have also added a label that displays the code created for the API call (also great for debugging during the build).

3. API request

Now this is where it gets a little complex. We have to dynamically create the url and use that as the source of an image component.

The QuickChart API uses DOT (graph description language) so there is plenty of documentation (Mermaid and other libraries all use it). I recommend graphviz as the best documentation site.

The API has the following end point we are using:

https://quickchart.io/graphviz?format=svg&graph=digraph{YOURCODE}

As you can see we have selected svg format instead of png (I always find png quality low) and type digraph (change for different QuickChart chart types).

Next is the code, a simple one would be

start -> middle;
middle -> end;
Enter fullscreen mode Exit fullscreen mode

https://quickchart.io/graphviz?format=svg&graph=digraph{start -> middle; middle -> end;}

graphvis api

We can add formatting to the nodes and the links by using []

start [style=filled,color="grey", shape="square"];
start -> end [penwidth=3,label=" label"]
Enter fullscreen mode Exit fullscreen mode

graphvis api

Finally we can add formatting for the entire diagram and add containers/boxes/clusters:

rankdir=LR; 
Node [shape=rectangle];
subgraph cluster_1 {
    label="a box";
    start;
}
start [style=filled,color="grey",shape="square"];
start -> end [penwidth=3,label=" label"]
Enter fullscreen mode Exit fullscreen mode

simple graphwiz

There is so much more to graphviz, and better documentation out there so I won't go into it much more. But I recommend this online editor to play with magjac.com/graphviz-visual-editor.

So how did I build it, with lots of variables and concat's is the answer.

Apologise now, I'm old fashioned and don't like $-String syntax, for some reason I find it harder to read so expect lots of &'s

My crazy code is:

"https://quickchart.io/graphviz?format=svg&graph=digraph{
    rankdir=LR; 
    Node [shape=rectangle];
    subgraph cluster_0 {
        label=%22Microsoft Tenant - All connections HTTPS%22;
        "&
        "subgraph cluster_1 {
            label=%22Power Platform%22;
            "&
            vsType.label&
            ";
            "&If(vsType.flow,"PowerAutomate -> ")& "Connector"&If(vsType.flow,"[dir=%22both%22]")& ";
        }
        "&
         If(vsType.label<>"PowerAutomate",vsType.code,
        coTrigger.Selected.Trigger &" [style=filled,color=%22"&EncodeUrl("grey")&"%22,fontcolor=white, tooltip =%22Read%22];
        ")&
        If(vsType.label<>"PowerAutomate","User",coTrigger.Selected.Trigger)&"->"&vsType.label&" [penwidth=3,label=%22Trigger%22];
        "&
        If(Not("PowerVirtualAgent" in vsType.label),  vsType.label& "-> Connector [dir=%22both%22];
        ")&
        If(vsType.flow,vsType.label&"->"&"PowerAutomate [dir=%22both%22];")&
        Concat(coConnections.SelectedItems,DesignLabel&" [style=filled,color=%22"&EncodeUrl("Blue")&"%22,fontcolor=white, tooltip=%22"&Concat(Distinct(Filter(coPrivileges.SelectedItems,DesignLabel=connector),label),Value&" ")&"%22];
        ")&
        Concat(coConnections.SelectedItems,"Connector"&"->"&DesignLabel&" [dir=%22both%22,label=%22/ "&Concat(Filter(coPrivileges.SelectedItems,connector=DesignLabel),label&" / ")&"%22];")&
        "Connector ->"&coOutput.Selected.Output &
        " [penwidth=3,shape=oval,style=rounded,label=%22Output%22];
        "&
        coOutput.Selected.Output&
        "[style=filled,color=%22"&EncodeUrl("DarkGreen")&"%22,fontcolor=white,tooltip=%22Write / Update%22]
    }
}"
Enter fullscreen mode Exit fullscreen mode

As you can see, I add the combo box options in concat's for multi-select and single references for single select. I EncodeUrl for any " or just type %22. It is a lot of trial and error to get right, which is why I added the label. Top tip add new lines inside strings, as then the error returns the line number to find the issue.

If it goes to plan it ends up as this:

https://quickchart.io/graphviz?format=svg&graph=digraph{
    rankdir=LR;
    Node [shape=rectangle]; 
    subgraph cluster_0 {
        label=%22Microsoft Tenant - All connections HTTPS%22;
        subgraph cluster_1 {
            label=%22Power Platform%22;
            PowerAutomate;
            Connector;
        }
        _OfficeOutlook [style=filled, color=%22grey%22,fontcolor=white, tooltip =%22Read%22];
        _OfficeOutlook->PowerAutomate [penwidth=3,label=%22Trigger%22];
        PowerAutomate-> Connector [dir=%22both%22];
        SharePoint [style=filled, color=%22Blue%22,fontcolor=white, tooltip=%22Create Read Update %22];
        MicrosoftTeams [style=filled, color=%22Blue%22,fontcolor=white, tooltip=%22Create %22];
        MeCorporate  [style=filled, color=%22Blue%22,fontcolor=white, tooltip=%22Create %22];
        OfficeUsers [style=filled,color=%22Blue%22,fontcolor=white, tooltip=%22Read %22];
        Connector->SharePoint [dir=%22both%22,label=%22/ Create / Read / Update / %22];
        Connector->MicrosoftTeams [dir=%22both%22,label=%22/ Create / %22];
        Connector->OfficeUsers [dir=%22both%22,label=%22/ Read / %22];
        Connector->MeCorporate [dir=%22both%22,label=%22/ %22];
        Connector->SharePoint_ [penwidth=3,shape=oval, style=rounded, label=%22Output%22];
        SharePoint_[style=filled, color=%22DarkGreen%22,fontcolor=white,tooltip=%22Write / Update%22]
    }
}
Enter fullscreen mode Exit fullscreen mode

complx graphwiz

4. Flow to create file

The only thing we can't do in the app is download the diagram, so this is where we need a flow (for a http request). If we didn't want to be premium we could open the url in a Launch function. This would open it in a new browser window where we could save page as svg or save image if png.

flow

We simply pass the diagram code url we created as the input to the http request. To create a file we need to convert it:

base64ToBinary(base64(body('HTTP')))
Enter fullscreen mode Exit fullscreen mode

if we wanted to embed in a html file it would be:

base64ToString(base64(body('HTTP')))
Enter fullscreen mode Exit fullscreen mode

http connector


Although I wouldn't say the process is super simple, it is easier then custom components, and other API's are a lot simpler. challenge is the syntax of the API. There are loads of other great free image API's, QuickChart alone has loads and then there is Static Google maps just to name a few.

I've saved a none premium version of the app here (No custom connector or flow) if you want to explore more.


Further Reading

Top comments (2)

Collapse
 
kkazala profile image
Kinga • Edited

thx for the awesome article =)
Are you sure the PCF requires premium license for users?

Code components that connect to external services or data directly via the user's browser client and not through connectors are considered as premium. When these components are used in an app, the app becomes premium, and end-users are required to have Power Apps licenses.

Code components that don't connect to external services or data. When these components are used in an app that uses standard features, the app remains standard, and end- users are required to be licensed at minimum for Office 365. More information: Power Apps pricing

Code components can be declared as premium components by adding a node to the component's manifest file with all the external service domains this component is connecting to.
Licensing

Collapse
 
wyattdave profile image
david wyatt

Good shout out, I didn't realise if it didn't use a premium functionality it didn't need a premium licences. Think I need to avoid talking about Microsoft licensing as it's a nightmare lol.