PreviewProvider
)Generate this flow chart:
From this code:
import SwiftFlow
let graph = Graph()
// setup configs
var blueConfig = NodeConfig()
blueConfig.backgroundColor = UIColor(red: 0.81, green: 0.96, blue: 1.00, alpha: 1.00)
var redConfig = NodeConfig()
redConfig.backgroundColor = UIColor(red: 1.00, green: 0.80, blue: 0.82, alpha: 1.00)
graph.nodeConfig = blueConfig
// add flows to graph
graph.addFlow([
Node("Start", shape: .pill),
Arrow(.down),
Node("Work\nsuccess?", shape: .diamond, id: "success"), // declare id for later reference
Arrow(.down, title: "Yes"),
Node("Go Party!", shape: .rect, id: "party"),
Arrow(.down),
Node("End", shape: .pill, id: "end")
])
graph.addFlow([
NodeShortcut(id: "success"), // refers back to the Node above
Arrow(.right, title: "No"), // branch out to the right side
Node("Cry", shape: .rect, config: redConfig), // different color using config
Arrow(.down),
Node("Go home", shape: .rect, id: "home"),
ArrowLoopBack(from: .bottom, to: .right),
NodeShortcut(id: "end")
])
let graphView = GraphView()
graphView.layoutMargins = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
// draw the graph!
try! graphView.draw(graph)
I often draw a flowchart to help understand some complex logic. It can also serves as a reference document for other engineers and testers. To draw one, I usually use popular tools like https://docs.google.com/drawings or https://app.diagrams.net/. However, I find it slow and tedious to do simple stuff like node alignment, auto text content hugging, adding arrow between nodes, or just adding arrow annotation. Not to mention that most of these styling will be out of place one you insert new nodes in between or update existing text.
Working with UIKit autolayout for years makes me aware that all of these UI styling can be handled in code very easily. Moreover, with the new SwiftUI, we can see live previews of the flowchart as we add each line of code. This will make flowchart drawing much faster and enjoyable.
We can do it better! 💪
Node
- Each rectangle / other shapes boxes you see are backed by this type.NodeShortcut
- A way to refer to an existing Node by id
.Arrow
- For chaining nodes together side-by-side. It has direction
property for telling which way the arrow is pointing out from a node. You can also add annotations to it.ArrowLoopBack
- Similar to Arrow, but it also support drawing an angled arrow to go around existing nodes, typically for looping back to an existing node above. It can be used for linking further away nodes that would look nicer using an angled arrow than a straight one.NodeConfig
- For customizing a Node properties like background color / border color / distance from other nodes. A Graph
can also take this property to apply to all nodes.ArrowConfig
- For customizing an Arrow.GraphElement
- A protocol that all above types conforms to.Graph
- This is the central piece that holds all information on how to draw the flowchart.
addFlow(_:)
which takes [GraphElement]
. Typically, the array be a sequence of "Node
, Arrow
, Node
, Arrow
, ...".GraphView
and call graphView.draw(graph)
to draw the view.GraphView
respects layoutMargins
, so you can adjust outer edge margins with it.This project is stil in early stage. Feel free to suggest features and fixes. 🙂
GraphView
in a SwiftUI's UIViewRepresentable
type. While it is not the most optimized way, I think it is good enough for general use.I know some other library has the same name, like https://github.com/Swift-Kit/Swift-Flow . But I still prefer this name.
There is a JavaScript library for drawing flowchart in code called mermaid. (There's a live editor you can try.) At first glance it is very powerful. It can draw not only flowcharts, but may other types of diagrams. But I find there are some problems for drawing flowchart...
A --> B
, B --> C
, C --> D
). In a long flowchart, most nodes will appear twice (B
and C
), which is very redundant. This won't happen if the syntax is flow based ( A --> B --> C --> D
) because most nodes will be referenced only once, except at the intersections. I think using flow-based syntax is cleaner and faster to write.<br />
😫. I could just be \n
.-->
for an arrow. It could have been just ->
or >
. This adds up with the link-based syntax mentioned.graph TD
means going from "top to bottom".link |
Stars: 65 |
Last commit: 1 year ago |
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics