{"id":19100527,"url":"https://github.com/KristofferStrube/Blazor.GraphEditor","last_synced_at":"2025-04-18T17:33:56.759Z","repository":{"id":188983864,"uuid":"679817571","full_name":"KristofferStrube/Blazor.GraphEditor","owner":"KristofferStrube","description":"A simple graph editor for Blazor.","archived":false,"fork":false,"pushed_at":"2024-10-17T23:42:05.000Z","size":33455,"stargazers_count":79,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-10-21T06:14:50.864Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KristofferStrube.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-17T17:29:47.000Z","updated_at":"2024-10-19T07:13:53.000Z","dependencies_parsed_at":"2023-10-25T19:33:09.689Z","dependency_job_id":"47d7fbe7-c4cb-4b79-a9be-f6f8226a74b2","html_url":"https://github.com/KristofferStrube/Blazor.GraphEditor","commit_stats":null,"previous_names":["kristofferstrube/blazor.grapheditor"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KristofferStrube%2FBlazor.GraphEditor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KristofferStrube%2FBlazor.GraphEditor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KristofferStrube%2FBlazor.GraphEditor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KristofferStrube%2FBlazor.GraphEditor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KristofferStrube","download_url":"https://codeload.github.com/KristofferStrube/Blazor.GraphEditor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223783096,"owners_count":17201904,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T03:52:52.467Z","updated_at":"2025-04-18T17:33:56.748Z","avatar_url":"https://github.com/KristofferStrube.png","language":"C#","funding_links":[],"categories":["others"],"sub_categories":[],"readme":"﻿# Blazor.GraphEditor\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](/LICENSE)\r\n[![GitHub issues](https://img.shields.io/github/issues/KristofferStrube/Blazor.GraphEditor)](https://github.com/KristofferStrube/Blazor.GraphEditor/issues)\r\n[![GitHub forks](https://img.shields.io/github/forks/KristofferStrube/Blazor.GraphEditor)](https://github.com/KristofferStrube/Blazor.GraphEditor/network/members)\r\n[![GitHub stars](https://img.shields.io/github/stars/KristofferStrube/Blazor.GraphEditor)](https://github.com/KristofferStrube/Blazor.GraphEditor/stargazers)\r\n[![NuGet Downloads (official NuGet)](https://img.shields.io/nuget/dt/KristofferStrube.Blazor.GraphEditor?label=NuGet%20Downloads)](https://www.nuget.org/packages/KristofferStrube.Blazor.GraphEditor/)\r\n\r\nA simple graph editor for Blazor.\r\n\r\n![A video showing off the demo site](./docs/demo.gif?raw=true)\r\n\r\n# Demo\r\nThe WASM sample project can be demoed at [https://kristofferstrube.github.io/Blazor.GraphEditor/](https://kristofferstrube.github.io/Blazor.GraphEditor/)\r\n\r\n# Getting Started\r\n## Prerequisites\r\nYou need to install .NET 7.0 or newer to use the library.\r\n\r\n[Download .NET 7](https://dotnet.microsoft.com/download/dotnet/7.0)\r\n\r\n## Installation\r\nYou can install the package via NuGet with the Package Manager in your IDE or alternatively using the command line:\r\n```bash\r\ndotnet add package KristofferStrube.Blazor.GraphEditor\r\n```\r\nThe package can be used in Blazor WebAssembly and Blazor Server projects. In the samples folder of this repository, you can find a project that shows how to use the `GraphEditor` component in both Blazor WASM.\r\n\r\n## Import\r\nYou need to reference the package to use it in your pages. This can be done in `_Import.razor` by adding the following.\r\n```razor\r\n@using KristofferStrube.Blazor.GraphEditor\r\n```\r\n\r\n## Add to service collection\r\nTo use the component in your pages you also need to register some services in your service collection. We have a single method that is exposed via the **Blazor.** library which adds all these services.\r\n\r\n```csharp\r\nvar builder = WebAssemblyHostBuilder.CreateDefault(args);\r\nbuilder.RootComponents.Add\u003cApp\u003e(\"#app\");\r\nbuilder.RootComponents.Add\u003cHeadOutlet\u003e(\"head::after\");\r\n\r\nbuilder.Services.AddScoped(sp =\u003e new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });\r\n\r\n// Adding the needed services.\r\nbuilder.Services.Add();\r\n\r\nawait builder.Build().RunAsync();\r\n```\r\n\r\n## Include needed stylesheets and scripts\r\nThe libraries that the component uses also need to have some stylesheets and scripts added to function.\r\nFor this, you need to insert the following tags in the `\u003chead\u003e` section of your `index.html` or `Host.cshtml` file:\r\n```html\r\n\u003clink href=\"_content/BlazorColorPicker/colorpicker.css\" rel=\"stylesheet\" /\u003e\r\n\u003clink href=\"_content/Blazor.ContextMenu/blazorContextMenu.min.css\" rel=\"stylesheet\" /\u003e\r\n\u003clink href=\"_content/KristofferStrube.Blazor./kristofferStrubeBlazor.css\" rel=\"stylesheet\" /\u003e\r\n```\r\nThe 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:\r\n```html\r\n\u003clink href=\"KristofferStrube.Blazor.GraphEditor.WasmExample.styles.css\" rel=\"stylesheet\" /\u003e\r\n```\r\n\r\nAt the end of the file, after you have referenced the Blazor Server or Wasm bootstrapper, insert the following:\r\n\r\n```html\r\n\u003cscript src=\"_content/Blazor.ContextMenu/blazorContextMenu.min.js\"\u003e\u003c/script\u003e\r\n```\r\n\r\n## Adding the component to a site.\r\nNow, you are ready to use the component in your page. A minimal example of this would be the following:\r\n\r\n```razor\r\n\u003cdiv style=\"height:80vh;\"\u003e\r\n    \u003cGraphEditor \r\n        @ref=GraphEditor\r\n        TNode=\"Page\"\r\n        TEdge=\"Transition\"\r\n        NodeIdMapper=\"n =\u003e n.id\"\r\n        NodeRadiusMapper=\"n =\u003e n.size\"\r\n        NodeColorMapper=\"n =\u003e n.color\"\r\n        EdgeFromMapper=\"e =\u003e e.from\"\r\n        EdgeToMapper=\"e =\u003e e.to\"\r\n        EdgeWidthMapper=\"e =\u003e e.weight*5\"\r\n        EdgeSpringConstantMapper=\"e =\u003e e.weight\"\r\n        EdgeSpringLengthMapper=\"e =\u003e e.length\"\r\n        /\u003e\r\n\u003c/div\u003e\r\n@code {\r\n    private GraphEditor\u003cPage, Transition\u003e GraphEditor = default!;\r\n    private bool running = true;\r\n\r\n    protected override async Task OnAfterRenderAsync(bool firstRender)\r\n    {\r\n        if (!firstRender) return;\r\n        while (!GraphEditor.IsReadyToLoad)\r\n        {\r\n            await Task.Delay(50);\r\n        }\r\n\r\n        var pages = new List\u003cPage\u003e() { new(\"1\", size: 60), new(\"2\", \"#3333AA\"), new(\"3\", \"#AA33AA\"), new(\"4\", \"#AA3333\"), new(\"5\", \"#AAAA33\"), new(\"6\", \"#33AAAA\"), new(\"7\"), new(\"8\") };\r\n\r\n        var edges = new List\u003cTransition\u003e() {\r\n            new(pages[0], pages[1], 1),\r\n            new(pages[0], pages[2], 1),\r\n            new(pages[0], pages[3], 1),\r\n            new(pages[0], pages[4], 1),\r\n            new(pages[0], pages[5], 1),\r\n            new(pages[0], pages[6], 1),\r\n            new(pages[6], pages[7], 2, 150) };\r\n\r\n        await GraphEditor.LoadGraph(pages, edges);\r\n\r\n        DateTimeOffset startTime = DateTimeOffset.UtcNow;\r\n        while (running)\r\n        {\r\n            await GraphEditor.ForceDirectedLayout();\r\n            /// First 5 seconds also fit the viewport to all the nodes and edges in the graph.\r\n            if (startTime - DateTimeOffset.UtcNow \u003c TimeSpan.FromSeconds(5))\r\n                GraphEditor..FitViewportToAllShapes(delta: 0.8);\r\n            await Task.Delay(1);\r\n        }\r\n    }\r\n\r\n    public record Page(string id, string color = \"#66BB6A\", float size = 50);\r\n    public record Transition(Page from, Page to, float weight, float length = 200);\r\n\r\n    public void Dispose()\r\n    {\r\n        running = false;\r\n    }\r\n}\r\n```\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKristofferStrube%2FBlazor.GraphEditor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKristofferStrube%2FBlazor.GraphEditor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKristofferStrube%2FBlazor.GraphEditor/lists"}