Skip to content

Commit 3710d35

Browse files
Update sample and README.
1 parent 5d0d626 commit 3710d35

File tree

4 files changed

+127
-18
lines changed

4 files changed

+127
-18
lines changed

README.md

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,126 @@
77

88
A simple graph editor for Blazor.
99

10+
![A video showing off the demo site](./docs/demo.gif?raw=true)
11+
1012
# Demo
1113
The WASM sample project can be demoed at [https://kristofferstrube.github.io/Blazor.GraphEditor/](https://kristofferstrube.github.io/Blazor.GraphEditor/)
1214

13-
![A video showing off the demo site](./docs/demo.gif?raw=true)
15+
# Getting Started
16+
## Prerequisites
17+
You need to install .NET 7.0 or newer to use the library.
18+
19+
[Download .NET 7](https://dotnet.microsoft.com/download/dotnet/7.0)
20+
21+
## Installation
22+
You can install the package via NuGet with the Package Manager in your IDE or alternatively using the command line:
23+
```bash
24+
dotnet add package KristofferStrube.Blazor.SVGEditor
25+
```
26+
The package can be used in Blazor WebAssembly and Blazor Server projects. In the samples folder of this repository, you can find two projects that show how to use the `SVGEditor` component in both Blazor Server and WASM.
27+
28+
## Import
29+
You need to reference the package to use it in your pages. This can be done in `_Import.razor` by adding the following.
30+
```razor
31+
@using KristofferStrube.Blazor.GraphEditor
32+
```
33+
34+
## Add to service collection
35+
To use the component in your pages you also need to register som services in your service collection. We have a single method that is exposed via the **Blazor.SVGEditor** library which adds all these services.
36+
37+
```csharp
38+
var builder = WebAssemblyHostBuilder.CreateDefault(args);
39+
builder.RootComponents.Add<App>("#app");
40+
builder.RootComponents.Add<HeadOutlet>("head::after");
41+
42+
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
43+
44+
// Adding the needed services.
45+
builder.Services.AddSVGEditor();
46+
47+
await builder.Build().RunAsync();
48+
```
49+
50+
## Include needed stylesheets and scripts
51+
The libraries that the component uses also need to have some stylesheets and scripts added to function.
52+
For this, you need to insert the following tags in the `<head>` section of your `index.html` or `Host.cshtml` file:
53+
```html
54+
<link href="_content/BlazorColorPicker/colorpicker.css" rel="stylesheet" />
55+
<link href="_content/Blazor.ContextMenu/blazorContextMenu.min.css" rel="stylesheet" />
56+
<link href="_content/KristofferStrube.Blazor.SVGEditor/kristofferStrubeBlazorSVGEditor.css" rel="stylesheet" />
57+
```
58+
The library uses Scoped CSS, so you must include your project-specific `.styles.css` CSS file in your project for the scoped styles of the library components. An example is in the test project in this repo:
59+
```html
60+
<link href="KristofferStrube.Blazor.GraphEditor.WasmExample.styles.css" rel="stylesheet" />
61+
```
62+
63+
At the end of the file, after you have referenced the Blazor Server or Wasm bootstrapper, insert the following:
64+
65+
```html
66+
<script src="_content/Blazor.ContextMenu/blazorContextMenu.min.js"></script>
67+
```
68+
69+
## Adding the component to a site.
70+
Now, you are ready to use the component in your page. A minimal example of this would be the following:
71+
72+
```razor
73+
<div style="height:80vh;">
74+
<GraphEditor
75+
@ref=GraphEditor
76+
TNode="Page"
77+
TEdge="Transition"
78+
NodeIdMapper="n => n.id"
79+
NodeRadiusMapper="n => n.size"
80+
NodeColorMapper="n => n.color"
81+
EdgeFromMapper="e => e.from"
82+
EdgeToMapper="e => e.to"
83+
EdgeWidthMapper="e => e.weight*5"
84+
EdgeSpringConstantMapper="e => e.weight"
85+
EdgeSpringLengthMapper="e => e.length"
86+
/>
87+
</div>
88+
@code {
89+
private GraphEditor.GraphEditor<Page, Transition> GraphEditor = default!;
90+
private bool running = true;
91+
92+
protected override async Task OnAfterRenderAsync(bool firstRender)
93+
{
94+
if (!firstRender) return;
95+
while (!GraphEditor.IsReadyToLoad)
96+
{
97+
await Task.Delay(50);
98+
}
99+
100+
var pages = new List<Page>() { new("1", size: 60), new("2", "#3333AA"), new("3", "#AA33AA"), new("4", "#AA3333"), new("5", "#AAAA33"), new("6", "#33AAAA"), new("7"), new("8") };
101+
102+
var edges = new List<Transition>() {
103+
new(pages[0], pages[1], 1),
104+
new(pages[0], pages[2], 1),
105+
new(pages[0], pages[3], 1),
106+
new(pages[0], pages[4], 1),
107+
new(pages[0], pages[5], 1),
108+
new(pages[0], pages[6], 1),
109+
new(pages[6], pages[7], 2, 150) };
110+
111+
await GraphEditor.LoadGraph(pages, edges);
112+
113+
DateTimeOffset startTime = DateTimeOffset.UtcNow;
114+
while (running)
115+
{
116+
await GraphEditor.ForceDirectedLayout();
117+
/// First 5 seconds also fit the viewport to all the nodes and edges in the graph.
118+
if (startTime - DateTimeOffset.UtcNow < TimeSpan.FromSeconds(5))
119+
GraphEditor.SVGEditor.FitViewportToAllShapes(delta: 0.8);
120+
await Task.Delay(1);
121+
}
122+
}
123+
124+
public record Page(string id, string color = "#66BB6A", float size = 50);
125+
public record Transition(Page from, Page to, float weight, float length = 200);
126+
127+
public void Dispose()
128+
{
129+
running = false;
130+
}
131+
}
132+
```

samples/KristofferStrube.Blazor.GraphEditor.WasmExample/KristofferStrube.Blazor.GraphEditor.WasmExample.csproj

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,12 @@
99

1010
<ItemGroup>
1111
<PackageReference Include="KristofferStrube.ActivityStreams" Version="0.2.3" />
12-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0" />
13-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0" PrivateAssets="all" />
12+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.10" />
13+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.10" PrivateAssets="all" />
1414
</ItemGroup>
1515

1616
<ItemGroup>
1717
<ProjectReference Include="..\..\src\KristofferStrube.Blazor.GraphEditor\KristofferStrube.Blazor.GraphEditor.csproj" />
1818
</ItemGroup>
1919

20-
<ItemGroup>
21-
<Content Update="Pages\FollowingGraph.razor">
22-
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
23-
</Content>
24-
</ItemGroup>
25-
2620
</Project>

samples/KristofferStrube.Blazor.GraphEditor.WasmExample/Pages/Christmas.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
edges.Add(edgesToAdd[i]);
8888

8989
await GraphEditor.UpdateGraph(points, edges);
90-
await Task.Delay(2000);
90+
await Task.Delay(1000);
9191
}
9292
refitToScreen = false;
9393
}

samples/KristofferStrube.Blazor.GraphEditor.WasmExample/Pages/Index.razor

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,13 @@
4747

4848
await GraphEditor.LoadGraph(pages, edges);
4949

50-
double prevUnixTimeSeconds = DateTimeOffset.Now.ToUnixTimeMilliseconds() / 1000.0;
51-
double startUnixTimeSeconds = prevUnixTimeSeconds;
50+
DateTimeOffset startTime = DateTimeOffset.UtcNow;
5251
while (running)
5352
{
5453
await GraphEditor.ForceDirectedLayout();
55-
double unixTimeSeconds = DateTimeOffset.Now.ToUnixTimeMilliseconds() / 1000.0;
56-
if (unixTimeSeconds - startUnixTimeSeconds < 7)
57-
{
58-
GraphEditor.SVGEditor.FitViewportToAllShapes(delta: Math.Min((unixTimeSeconds - prevUnixTimeSeconds) * 2, 1), padding: 100);
59-
prevUnixTimeSeconds = unixTimeSeconds;
60-
}
54+
/// First 5 seconds also fit the viewport to all the nodes and edges in the graph.
55+
if (DateTimeOffset.UtcNow - startTime < TimeSpan.FromSeconds(5))
56+
GraphEditor.SVGEditor.FitViewportToAllShapes(delta: 0.8);
6157
await Task.Delay(1);
6258
}
6359
}

0 commit comments

Comments
 (0)