-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
165 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -176,3 +176,4 @@ struct MermaidVisualization: View { | |
|
||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,118 @@ | ||
# Creating a Force Directed Graph | ||
|
||
## Overview | ||
## Overview | ||
|
||
A graph is a collection of nodes and links. Each node is connected to other nodes by links. In Grape, you describe a node with a `NodeMark` and a link with a `LinkMark`. `NodeMark` and `LinkMark` are associated with an `id` or `id`s that identifies them. An `id` can be any type that conforms to `Hashable`. | ||
|
||
Grape provides a `ForceDirectedGraph` view to visualize a graph. You can easily initialize it like you would do in SwiftUI. | ||
|
||
```swift | ||
|
||
struct MyGraph: View { | ||
var body: some View { | ||
ForceDirectedGraph { | ||
NodeMark(id: "A") | ||
NodeMark(id: "B") | ||
LinkMark(from: "A", to: "B") | ||
} | ||
} | ||
} | ||
|
||
``` | ||
|
||
For the array data, `Series` comes handy for describing a collection of nodes and links. Consider it a simplified version of `ForEach` in SwiftUI. | ||
|
||
```swift | ||
|
||
struct MyGraph: View { | ||
let myNodes = ["A", "B", "C"] | ||
let myLinks = [("A", "B"), ("B", "C")] | ||
|
||
var body: some View { | ||
ForceDirectedGraph { | ||
Series(myNodes) { id in | ||
NodeMark(id: id) | ||
} | ||
Series(myLinks) { from, to in | ||
LinkMark(from: from, to: to) | ||
} | ||
} | ||
} | ||
} | ||
|
||
``` | ||
|
||
@Image(source: "BasicExample.png", alt: "A basic force directied graph.") | ||
|
||
> **Note**: Grape currently does not protect you from linking to non-existing nodes. If you link to a node that does not exist, view crashes. | ||
|
||
## Customizing forces | ||
|
||
You can customize the forces that interfere with the nodes and links. By default, Grape uses a `LinkForce` and a `ManyBodyForce`. | ||
|
||
For example, the `CenterForce` can keep the mass center of the graph at the center of the view, so it does not drift away. To add a `CenterForce`, you can do the following. | ||
|
||
|
||
```swift | ||
struct MyGraph: View { | ||
let myNodes = ["A", "B", "C"] | ||
let myLinks = [("A", "B"), ("B", "C")] | ||
|
||
var body: some View { | ||
ForceDirectedGraph { | ||
Series(myNodes) { id in | ||
NodeMark(id: id) | ||
} | ||
Series(myLinks) { from, to in | ||
LinkMark(from: from, to: to) | ||
} | ||
} force: { | ||
ManyBodyForce() | ||
LinkForce() | ||
CenterForce() | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Note that when you override the default forces, you may need to add the `LinkForce` and `ManyBodyForce` back. Otherwise, the nodes may stay static since no forces are moving them to other places. | ||
|
||
## Customizing appearances | ||
|
||
Add modifiers like you would do in SwiftUI to style your nodes and links. | ||
|
||
```swift | ||
|
||
struct MyGraph: View { | ||
let myNodes = ["A", "B", "C"] | ||
let myLinks = [("A", "B"), ("B", "C")] | ||
|
||
var body: some View { | ||
ForceDirectedGraph { | ||
Series(myNodes) { id in | ||
NodeMark(id: id) | ||
.foregroundColor(.blue) | ||
} | ||
Series(myLinks) { from, to in | ||
LinkMark(from: from, to: to) | ||
} | ||
} | ||
} | ||
} | ||
|
||
``` | ||
|
||
|
||
## Responding to interactions and events | ||
|
||
Grape provides a set of interactions and events to help you respond to user interactions, including dragging, zooming, and tapping. They are mostly supported by default, and you can install your callbacks to respond to them. | ||
|
||
|
||
For detailed usages, please refer to [MermaidVisualization.swift](https://github.com/li3zhen1/Grape/blob/main/Examples/ForceDirectedGraphExample/ForceDirectedGraphExample/MermaidVisualization.swift). | ||
|
||
|
||
@Video(source: "https://github.com/li3zhen1/Grape/assets/45376537/80d933c1-8b5b-4b1a-9062-9628577bd2e0", alt: "A screen record of mermaid") | ||
|
||
|
||
// TODO: Add examples |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters