GithubHelp home page GithubHelp logo

wouterdek / nodenetwork Goto Github PK

View Code? Open in Web Editor NEW
803.0 45.0 141.0 11.2 MB

A C# library with a WPF node editor component based on ReactiveUI

License: Apache License 2.0

C# 99.11% GLSL 0.12% Batchfile 0.21% PowerShell 0.56%
wpf wpf-controls node-editor csharp reactiveui

nodenetwork's Introduction

NodeNetwork https://www.nuget.org/packages/NodeNetwork/

NodeNetwork is a .NET C# WPF library that provides a node editor component.

Here is a demo of a calculator example application:

A more realistic use case of this library could be a shader editor.
Here is a demo of a shader editor example made using NodeNetwork:

These example applications are available for download here and their source is included in the repository. Binary releases of the library are available on NuGet.

Features

  • Built for .NET Framework 4.7.2 and .NET Core 3.1 or newer
  • An open, permissive license.
  • Interactive, robust controls build using modern reactive MVVM code.
  • Proper panning, zooming controls
  • Automatic layout system
  • Highly customizable, but easy to use by default.
  • Extensive network and connection validation support.
  • Backed by unit tests
  • ...

Getting started

For an easy quickstart guide to using this library, see the cookbook chapters on this page. The documentation includes setup information, cookbook chapters, examples and an API reference.

License

This library is licensed under the Apache License 2.0. (See choosealicense.com/licenses/apache-2.0 for a brief summery)
A copy of this license is included in the repository under LICENSE.

Documentation

Documentation is available here. If you want to make changes to the documentation, you can do so by making a pull-request to the gh-pages branch.

Contributions

Bug reports, patches, feature requests, pull requests, ... are very welcome on the GitHub page!

nodenetwork's People

Contributors

crener avatar danielcaceresm avatar fabiannitsche avatar gitii avatar napa-hp avatar rscoopers avatar stonelance avatar wouterdek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nodenetwork's Issues

How to programatically connect nodes?

Sorry if I am being a dummy, but I cannot seem to work out how to connect two nodes programatically.
I am trying to work out how to do save / load of networks.
Sample code that would do it for the Calculator example or something would be great

Confused by Nodelist

Hey, I'm confused by the Nodelist page in your docs. I didn't understand to which viewmodel I have to add the property and method, as well as how to bind the viewmodel property to the correct viewmodel. I'm sorry for my incompetence but could you add a small example to your explanation in the docs?
Julian

Nodes as MEF plugins?

I was wondering if you see any potential blockers for supporting arbitrary Node types as MEF plugins.
Editors and Port types will not need need to be extensible, just Node Views and ViewModels

To clarify our desired use-case, we have an input remapping application and are investigating using a library such as yours to allow the end-user to chain together nodes to achieve various remapping options.
For example, a mockup of a remapper that takes two buttons (eg keyboard keys) as input, and one joystick axis as output may look vaguely like this ("Constant" node is simulating the button inputs):

We would like to be able to allow the various nodes (eg ButtonsToAxis in this example) available to the end-user to be extensible via MEF plugins
I would envisage having, for example, two port types (Buttons and Axes) which are hard-coded - all the node plugins could do is consume these port types. We would need no editors for the port values, as the input values are provided by manipulating the input device (Although editors may be useful for debugging)
Ideally we would also want nodes to be able to have arbitrary GuiControls which control various settings etc (eg we may want a "Deadzone" node which applies a DeadZone to an axis, and would need a TextBox to input the percentage value for the DZ)

Sometimes ports get cut in half

The node port connectors sometimes get cut in half depending on the size of the node:
image
sometimes not:
image

It even occurs when connected:
image

ShaderEditor example doesn't work

I tried using the ShaderEditor example and it looks like there are a couple issues. The cube.obj and suzanne.obj files are missing. I managed to find other copies elsewhere, and then I ran into an exception in FindVariableLocation while running:
System.ArgumentException: 'cameraPos is not a uniform variable in this shader program.'

It looks like since cameraPos is not used it is probably optimized out of the shader?

Edit: once I worked around these issues it looks like the model doesn't render. I commented out the code at the end of LoadMesh that is deleting the mesh data, and that seemed to work (RenderDoc was showing no buffers were bound).

Issue removing the last connection

Hi,

There appears to be an issue around removing connections.

I created the example below with the Code Gen example. When you remove the last connection from "Button Events" I think the connection count is going to 0 but there is still 1 value left so the output still shows the last connection.

image

Visual enhancements

Hi,

Searching for visual scripting tools, I found Bolt for Unity : https://ludiq.io/bolt
I really like the visual rendering.
I think there's some interesting things that could be added to node network:

  • adding an icon in the header part
  • use icon as name for inputs/outputs
  • the ability to put an input at the the same height than an input
  • editors can be at the same height than the port itself
    Maybe it's feasible by now , but maybe it could be changed directly as properties of the nodes ?

And Thanks again for your tool :)

I want to always display PortView

This is what I was looking for and it is very wonderful
However, once Node is connected, checking Collapse can not shorten Node.
By rewriting a bit, I succeeded in contracting Node while connecting Node.
Now, if you press the Collapse button, PortView will be hidden and connections will not be updated.
Is it possible to display PortView or update connection information even if Collapse is checked?

stuck in customizing node visuals

I'm trying to follow your tutorial. but I'm stuck in step : customizing node visuals. Actually, I was stuck in where declare views in CustomNodeView.xaml. I added below codes into usercontrol so that I solved it though.

xmlns:views="clr-namespace:NodeNetwork.Views;assembly=NodeNetwork"

Now I'm stuck in below parts


public partial class CustomNodeView : IViewFor<\CustomNodeViewModel\>
{
    #region ViewModel
    ...
    #endregion

    public CustomNodeView()
    {
        InitializeComponent();

        this.WhenActivated(d =>
        {
            this.WhenAnyValue(v => v.ViewModel).BindTo(this, v => v.NodeView.ViewModel).DisposeWith(d);
        });
    }
}

I can not find CustomNodeViewModel. What should be in #region ViewModel? I guess both are related, right? Plz, could you give me codes or guide for me?

thx in advance.

Modification to physics based layouter

I notice that your repulsion force is proportional to 1/Distance. this is causing unconnected nodes to get ejected from a local group quite drastically. I would propose increasing the repulsion coefficent slightly and making the force proportional to 1/Distance^2 (similar to how gravity attracts). you cold then increase the friction component so that nodes slow down faster.

Naming Nodes

Hi,

For a FBP graph embedded system , I need to name some Nodes (not all) . So the name could be used for the embedded system to allow value editing.
For example on a graph , I have a Timer node linked to a Time integer value. I want to name the Integer value, 'Motor Time On' , so I could present a GUI on my system to edit 'Motor Time On' value. Is it possible to do this at this time ?

And thanks for your great library !

Get Connected Nodes in order

Hi,

Is there a way to get the connected nodes in Order.

I have created a node that connects to multiple children and need to get those children in the top down order as seen in the UI.

Thanks

Requires .NET 4.7 ?

FYI, it seems that in VS2017, if I start a project and leave it on the default (For my system at least) of .NET 4.5.2, I get the following error when I try to add the NodeNetwork NuGet package:

Severity Code Description Project File Line Suppression State Error Could not install package 'ReactiveUI.Events.WPF 9.1.4'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.5.2', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

Dunno if this is intentional or what, but you may want to update the docs?
If I switch to .NET 4.7.2, all is fine

Question about use of MarkupExtension in Name property

I'm in the process of porting this project to SDK-style projects so it can multi-target .NET Framework 4.7 and .NET Core 3.0. However, some code is giving me trouble; some XAML objects have their name set to an {x:Static} MarkupExtension pointed to a constant string. I have done quite a bit of testing, but I invariably get this error:

error MC3079: MarkupExtensions are not allowed for Uid or Name property values, so '{x:Static views:ConnectionView.HighlightVisualStatesGroup}' is not valid.

If anybody could help give any insight as to what's going on, that would be greatly appreciated. Thank you.

Not an issue: More of a question

Is there an easy way to add color to our custom NodeViewModel? Wanted to add it to the custom class so it it static for that node.

Tutorial not working

Hello,

I was trying to get the tutorial project running, but the stated instructions did not work.
First, this:

In your viewmodel definition, change
var node1Input = new NodeInputViewModel();
to
var node1Input = new ValueNodeInputViewModel<string>();

It took some time until I found out that it requires the NodeNetworkToolkit, which fixed the issue.

Later on, the tutorial states:

To print the input value each time it changes, add the following code.
node1Input.ValueChanged.Subscribe(newValue => { Console.WriteLine(newValue); });

But visual studio says that there is no definition for "ValueChanged". I did not find any information about it in the docs or anywhere else in the internet. I tried different namespaces, workarounds or other fixes, but did not manage to get it running.

Is the documentation maybe outdated? I did not find information about for which version it was written.

[question] The way to provide NodeOutputViewModel for ValueListNodeInputViewModel

How could I provide output from one node to ValueListNodeInputViewModel input of another one? There is no ValueNodeOutputViewModel for the IReadOnlyReactiveList<>. If I use ValueNodeOutputViewModel<IReadOnlyReactiveList<>> the value of output will be IObservable<IReadOnlyReactiveList<>> which couldn't be connect with ValueListNodeInputViewModel input.

[question] After adding node back to node view - no reaction on connection

I'm working on undo/redo operation for add/remove nodes. I notice, when I do _networkViewModel.Nodes.Remove(selectedNode) and after _networkViewModel.Nodes.Add(selectedNode) with the same instance of node, all node input editors are visible and don't hide when you attach connections to them.

Before restoring
image

After restoring
image

ForceDirectedLayouter Configuration IsFixedNode

I have a project where not every node is connected all the time. When using the ForceDirectedLayouter any node with no 'Spring' connector gets ejected from the local cluster at quite a speed! (ammusing to watch running the LayoutAsync version!)

I've tried to implement the following (VB rather than C# sorry):

Dim config As New Configuration With {.Network = Network, .IsFixedNode = 
    Function(t)
        For Each pInput In t.Inputs.Items
            If pInput.Connections.Count > 0 Then
                Return False
            End If
        Next
        For Each pOutput In t.Outputs.Items
            If pOutput.Connections.Count > 0 Then
                Return False
            End If
        Next
        Return True
    End Function}

When i run the layouter.Layout method I get the following error: System.Collections.Generic.KeyNotFoundException

If i run the layouter.LayoutAsync version I don't get this error; however, none of the nodes move unless all nodes are connected. I.e. if any node is marked as fixed none of the nodes get moved.

Question on layout.

Importing a certain file type and creating the nodes + their connections programatically. Is there a way to auto-layout them so they aren't on top of each other upon creation based off connections?

Catch DoubleClick/ Right Click on Node

Hi,

I would like to be able to manage double click on a specific node , or right click for contextual actions with it.
Is there a mechanism that allow it ?

Delete nodes

Hi,

This looks like a great project. I've started having a look at it and was wondering how to delete Nodes?

Thanks

can't find docs website github to fix docs..

this project looks neat.

I was just going through the "passing values between nodes" tutorial here...

https://wouterdek.github.io/NodeNetwork/cookbook/value_nodes

And none of the instructions work out of the box, because the names are not fully qualified and they don't explain what you have to import... I got it working, but I also want to fix the page to help others not stumble over this, and I can't find the github for the documentation website itself.

Please make the docs website github public, and put a link on the bottom of the github docs pages to that github so we can edit and improve the docs....

And make that page use the fully qualified names in the example... (or tell people what using statements to add)

var node1Input = new NodeNetwork.Toolkit.ValueNode.ValueNodeInputViewModel<string>();
var node2Output = new NodeNetwork.Toolkit.ValueNode.ValueNodeOutputViewModel<string>();
node2Output.Value = System.Reactive.Linq.Observable.Return("Example String");

Arbitrary GUIs inside Nodes?

Hi, so I have been fiddling with this awesome library for a little while now, starting to learn the ropes somewhat.
It seems that GuiControls inside Nodes are intended to be an Input - an example being the DDL in Vec3MathNode (Add|Subtract|Multiply|Divide...), and in this scenario, you have very limited control over the placement of these inputs (ie only vertical order). Am I correct in assuming that for each input, there is one Editor view, and each editor view can only handle 1 or more values of the same data type? ie the vec3 with 3 floats is fine, but if I wanted two ints and a bool all on the same row in a Node, that would need to be part of the same Editor, and thus not possible.
From my experience with a similar setup in our existing project, we find this dynamic extremely limiting - it would be really nice to have a "Body" area for a Node that contains an arbitrary view.
I am fine with anything that has an Input or Output port visible staying with the usual stacked approach, but am I missing something, or is there no "Body" of a Node?
To give you some insight to the kinds of use-cases I am talking about, consider this plugin from our existing app (The controls on the left are all I am talking about):

Unfortunately, in this system, we don't have DDLs or labels, but the constraints are otherwise similar to what I see with the NodeNetwork Toolkit - all we can do for GuiControls is specify row / column.
What we really want is something like this:

However, with the current design of the Toolkit, it seems that this kind of use-case is not really catered for? Or am I, yet again, missing something? Obviously one could throw the Toolkit out the window and roll your own, but that's maybe a bit beyond my ability level right now...

By the way, here's a recording of what I have so far - there's no actual Input/Output manipulation going on (The nodes on the left and right edges are stand-ins for the actual Inputs & Outputs), but I have the basic functionality of our app implemented using NodeNetwork

Getting something like this going has been a dream of mine for over 10 years, so from the bottom of my heart, thank you for this amazing library!

Memory usage bug

I have a problem in my project. If you create a tab control and switching between tabs you will see memory increase each time.

image

Replace Deprecated ReactiveLists with Dynamic Data

I am in the process of updating the ReactiveUI and Reactive nuget packages to the lastest versions. I am also starting to replace all instances of [Deprecated]ReactiveList<T> with Dynamic Data's SourceList<T>, per the suggestion here on the ReactiveUI site.

I was wondering if updating was planned or purposefully avoided. Is the use of ReactiveLists just legacy or is there a functional reason for using them that you found?

Error in multiple ViewModels with PropertyChanged.Fody

With property changed fody the CodePreviewViewModel causes this error:

MethodAccessException: Attempt by method 'SodeEditorWPFUI.ViewModels.CodePreviewViewModel.set_Code(SodeEditorWPFUI.Models.Compiler.IStatement)' to access method 'ReactiveUI.ReactiveObject.ReactiveUI.IReactiveObject.RaisePropertyChanged(System.ComponentModel.PropertyChangedEventArgs)' failed.

I was able to get past this error by placing [DoNotNotify] on top of the class

Interconnected ForLoops

Would it be possible in the ExampleCodeGenApp project to connect a Current Index endpoint from a ForLoop to a First/Last Index endpoint of other ForLoop?

Apparently the Validator won't allow it.

In the short timeframe I made the Input Connection Validator to accept it (Generic Arguments checks) and dynamically get the Observable Value. But then I observed that its Value is null.

image

Everything is straightforward but this Current Index is a bit confusing for me at this stage and I was thinking to buzz you. ๐Ÿค•

What are your thoughts?

Exception starting ExampleCodeGen App

Hi,

I can compile the project but I get this error when starting it :
https://ibb.co/mD6FMny
It seems sys is looking for "System.ValueTuple, Version=4.0.3.0"
Last V4.5 is installed . The ValueTuple dll exists in the debug folder.

I'm really stucked at this point :)

Error while following "Hello world" example

I have tried to use example "Hello World". But I have recieved error. "ISourceList" contains no definition for "Add" ...
In line network.Nodes.Add(node1); and node1.Inputs.Add(node1Input);

image

How to get node view or size of node?

I want to layout nodes pragmatically but I can only see position on ViewModel but I can't see any option to get size of a node. How can I get node size so I can position them properly? Or how could I editor port position so that connection will not lay under node?

[question] What could be a reason of the long time nodes creation?

I'm using NodeNetwork 3.1.0 nuget. In my project creating of 80 nodes takes ~10sec. But Creating 80 nodes + 107 connections takes ~1m 10 sec.

image

The timeline profiler in Rider shows the next picture

image

I guess the reason is events which are raised by creating of connections, but i can't figure out how to avoid that. I have subscriptions on input value changed, on input connection changed. On these events I update data inside of node. I thought that networkViewModel.SuppressChangeNotifications(); helps, but it doesn't. Also in profiler picture I can see that Graph Validator's Find Loops takes ~5 sec, I guess I can turned it off while scene is loading.

Autolayout for overlapping nodes causes NaN position

This is a fairly specific case, but I noticed when trying to autolayout a set of newly added nodes.
When there are two or more nodes in exactly the same position, such as {0,0}, autolayout will set the positions to be {NaN,NaN}. This seems to happen to any nodes connected to the overlapping nodes as well.
This causes the nodes to be immovable.
When some of the network is overlapping, but there are other nodes connected, it does not always happen, and seems to be whether there is a majority of nodes overlapping, though I need to test that more.

Connection selection

Hi,

is there any way to actually select a connection line?

I have 2 nodes and I would like to associate some parameters with the connection line between the 2 nodes. Is this possible?

Execution Node Action<> or Func<>

I think it would be useful to have associated Func<> or Action<> with the execution node types. I think this would be more in-line with how the Unreal Engine Blueprint system functions, where each execution node would propagate synchronously, performing its respective action and then returning to execute the next node.

I didnt see any examples of this. I suppose it is possible currently to generate the sourcecode to do this via string building as in the current code example, but this seems clunky to me.

Any insight on how this could be implemented or if it something you have thought about/ tried already?

Auto adjust nodes

Is there any way to adjust all node automatically? i have around 100 nodes and user must move them from the corner to see all.

Nodes move when using scroll bar (e.g. in combo-box)

If I have a node with a ComboBox on it populated with a large list of items the currently selected node moves around drastically when i scroll up and down on the drop down list.

Main window:

Class MainWindow
    Public Enum TestEnum
        Value1
        Value2
        ...
        Value 30
    End Enum

    Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Dim pNetwork As New NetworkViewModel
        MainNetwork.ViewModel = pNetwork

        Dim pNode As New NodeViewModel

        pNetwork.Nodes.Add(pNode)

        Dim pInput As New ValueNode.ValueNodeInputViewModel(Of TestEnum)
        pNode.Inputs.Add(pInput)

        pInput.Editor = New EnumEditor_ViewModel

    End Sub
End Class

View:

    <Grid>
        <ComboBox x:Name="EnumCombobBox"/>
    </Grid>
Public Class EnumEditor_View
    Implements IViewFor(Of EnumEditor_ViewModel)
   
    ...
        ViewModel stuff
    ...

    Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        EnumCombobBox.ItemsSource = [Enum].GetValues(GetType(MainWindow.TestEnum)).Cast(Of MainWindow.TestEnum).ToList

    End Sub
End Class

View model:

Public Class EnumEditor_ViewModel
    Inherits ValueEditorViewModel(Of MainWindow.TestEnum)
    Shared Sub New()
        Splat.Locator.CurrentMutable.Register(Function() New EnumEditor_View(), GetType(IViewFor(Of EnumEditor_ViewModel)))
    End Sub
End Class

This produces the following
image
When the scroll bar is used, the untitled node pings all over the place.
Similarly if i use the middle mouse wheel to scroll the list, the network view zooms in and out

Event to detect selecting a node

I want to integrate a property grid into my program and need to detect when a user selects a node so I can display the properties I expose. How would I proceed?

Support for execution flow ports

First of all, thanks for this library. It seems like a great start and I've had a hard time finding anything else similar before.

I'm not sure if this is outside of the intended use cases for this library, but I am investigating doing some codegen using a node network, and would like to have "execution flow" ports in addition to the "data flow" ports. The main distinction is that they are evaluated in the opposite order, and multiple connections on an output is invalid, but multiple connections on an input is valid. This is similar to functionality in Unreal Engine's blueprint system if you are familiar with it.

Is this something that is reasonable to support in this library? If I wanted to go about adding support for it, what do you think the best approach would be? I tried actually just using ValueNodeOutputViewModel for inputs and ValueNodeInputViewModel for outputs, as this is essentially what I need but it doesn't work because NodeViewModel expects inputs to be derived from NodeInputViewModel and outputs derived from NodeOutputViewModel. I'm guessing I would run into other issues with that approach anyway :)

[question] How could I change color of node?

I've implemented live node search in nodeview. So I need a way to mark found nodes. I try to use IsSelected flag for this, but once you drag canvas - selection is cleared. Can I focus on node (scroll canvas to make node visible)?

I've seen that it's possible here #24 (comment)

Whats the best way to edit a NodeListView

I'm trying to change the look of the NodeListView but I cant find any properties for the look of the scrollbar, "Add Node" label or drop down. Whats the best way to go about editing the look of those properties?

Hide output

Is it possible to hide some of the outputs of a node while it is "open" (i.e. not collapsed)? I found out that it is possible to hide the port of an output by using the IsVisible property but the output name is still displayed.

Zooming in and out

Is there a way to zoom in and out further?

Also just wanted to say, that this is a pretty amazing project.

Node container

I'd like to suggest a container node which allows attachment of nodes. Having many nodes in a single window will make the view look cluttered and creating complex node graphs will result in many lines crossing each other or passing behind other nodes. The container should allow the same collapsing functionality as normal nodes without breaking outward-going connections. Even better would be if attached nodes can have their in/out ports connected to the container, creating ports on the container itself that will redirect the in/output. This would allow for isolated networks within the master network.

[Request] Categories / descriptions for node list

My list of nodes is getting pretty long - is there (or are there any plans for) any built-in functionality for organizing the node list?
It might also be nice to allow a short description of what each node does - in the list view it could be an extra line, in the tile view it could be a tooltip

Lots of nodes causing slowdown

I have a large collection of nodes (1000+) and it seems to slow down heavily.
I think I might have made several mistakes along the way, but I wanted to know if there was a way to improve performance, that ive overlooked.

Still love the Project by the way.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.