FSharpGephiStreamer


Streaming a graph to gephi

First of all, you need to enable the master server of the graph streaming plugin in gephi (using default settings):

The next step is the creation of a workspace in Gephi. If you name it other than the default name (Workspace 1), make sure you adjust the streamer environment as shown here

Given the following node/edge types and converters introduced in the Grammar docs

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
/// Record type that represents a custom node 
type MyNode = {
    Id    : int
    Label : string
    Size  : float
    Data  : string
    }

/// Record type that represents a custom edge 
type MyEdge = {
    Id :     int
    Source : int
    Target : int
    Weight : float    
    }

///converts a MyNode type to a list of grammar attributes
let nodeConverter (node:MyNode) =
    [
        Grammar.Attribute.Label node.Label; 
        Grammar.Attribute.Size  node.Size; 
        Grammar.Attribute.Color (Colors.Table.StatisticalGraphics24.getRandomColor()); 
        Grammar.Attribute.UserDef ("UserData",node.Data); 
    ]

///converts a MyEdge type to a list of grammar attributes
let edgeConverter (edge:MyEdge) =
    [
        Grammar.Attribute.Size  edge.Weight; 
        Grammar.Attribute.EdgeType  Grammar.EdgeDirection.Undirected;             
        Grammar.Attribute.Color Colors.Table.Office.grey ;      
    ]

There are several ways to stream data to gephi:

Adding nodes & edges with node converters

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
///Adds a node of type MyNode using the node converter to the gephi graph
let addMyNode (node:MyNode) = 
    Streamer.addNode nodeConverter node.Id node
    

///Adds an edge of type MyEdge using the edge converter to the gephi graph
let addMyEdge (edge: MyEdge) =
    Streamer.addEdge edgeConverter edge.Id edge.Source edge.Target edge

Adding nodes & edges with simple id mapping

When no specific attribute conversion is needed, the addBy functions only need a simple Id mapping:

1: 
2: 
3: 
4: 
5: 
6: 
///Adds a node of type MyNode given a mapping from node type to an ID to the gephi graph
Streamer.addNodeBy (fun (node:MyNode) -> string node.Id)


///Adds an edge of type MyEdge given a mapping from edge type to an (ID,sourceId,targetID) tuple to the gephi graph
Streamer.addEdgeBy (fun (edge:MyEdge) -> (string edge.Id), (string edge.Source), (string edge.Target))

Update nodes & edges

The update functions are pretty similar to the Streamer.addNode functions. Note that you can use another converter to update all exisiting nodes in the gephi graph.

1: 
2: 
3: 
4: 
5: 
6: 
///Updates a node of type MyNode using the node converter to the gephi graph.
let updateMyNode (node:MyNode) =
    Streamer.updateNode nodeConverter node.Id node

let updateMyEdge (edge:MyEdge) =
    Streamer.updateEdge edgeConverter edge.Id edge.Source edge.Target edge

Removing nodes & edges

1: 
2: 
3: 
4: 
5: 
6: 
7: 
///Removes a node of type MyNode given a mapping from node type to an ID from the gephi graph
let removeMyNode (node:MyNode) =
    Streamer.removeNode node.Id node

///Removes an edge of type MyEdge given a mapping from edge type to an ID from the gephi graph
let removeMyEdge (edge:MyEdge) =
    Streamer.removeEdge edge.Id edge
namespace FSharpGephiStreamer
type MyNode =
  {Id: int;
   Label: string;
   Size: float;
   Data: string;}


 Record type that represents a custom node
MyNode.Id: int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

--------------------
type int = int32

--------------------
type int<'Measure> = int
MyNode.Label: string
Multiple items
val string : value:'T -> string

--------------------
type string = System.String
MyNode.Size: float
Multiple items
val float : value:'T -> float (requires member op_Explicit)

--------------------
type float = System.Double

--------------------
type float<'Measure> = float
Multiple items
MyNode.Data: string

--------------------
namespace Microsoft.FSharp.Data
type MyEdge =
  {Id: int;
   Source: int;
   Target: int;
   Weight: float;}


 Record type that represents a custom edge
MyEdge.Id: int
MyEdge.Source: int
MyEdge.Target: int
MyEdge.Weight: float
val nodeConverter : node:MyNode -> Grammar.Attribute list


converts a MyNode type to a list of grammar attributes
val node : MyNode
module Grammar

from FSharpGephiStreamer
type Attribute =
  | Size of float
  | Color of Color
  | EdgeType of EdgeDirection
  | PositionX of float
  | PositionY of float
  | PositionZ of float
  | Label of string
  | LabelSize of float
  | LabelColor of Color
  | LabelVisible of bool
  ...
union case Grammar.Attribute.Label: string -> Grammar.Attribute
union case Grammar.Attribute.Size: float -> Grammar.Attribute
union case Grammar.Attribute.Color: Colors.Color -> Grammar.Attribute
module Colors

from FSharpGephiStreamer
module Table

from FSharpGephiStreamer.Colors
module StatisticalGraphics24

from FSharpGephiStreamer.Colors.Table
val getRandomColor : unit -> Colors.Color
union case Grammar.Attribute.UserDef: string * obj -> Grammar.Attribute
MyNode.Data: string
val edgeConverter : edge:MyEdge -> Grammar.Attribute list


converts a MyEdge type to a list of grammar attributes
val edge : MyEdge
union case Grammar.Attribute.EdgeType: Grammar.EdgeDirection -> Grammar.Attribute
type EdgeDirection =
  | Directed
  | Undirected
    static member convert : (EdgeDirection -> bool)
union case Grammar.EdgeDirection.Undirected: Grammar.EdgeDirection
module Office

from FSharpGephiStreamer.Colors.Table
val grey : Colors.Color
val addMyNode : node:MyNode -> Either<string,RestfulAux.Error>


Adds a node of type MyNode using the node converter to the gephi graph
module Streamer

from FSharpGephiStreamer
val addNode : nodeConverter:Streamer.NodeConverter<'node> -> nodeId:obj -> ('node -> Either<string,RestfulAux.Error>)
val addMyEdge : edge:MyEdge -> Either<string,RestfulAux.Error>


Adds an edge of type MyEdge using the edge converter to the gephi graph
val addEdge : edgeConverter:Streamer.EdgeConverter<'edge> -> edgeId:obj -> sourceId:obj -> targetId:obj -> ('edge -> Either<string,RestfulAux.Error>)
val addNodeBy : f:('node -> string) -> ('node -> Either<string,RestfulAux.Error>)
val addEdgeBy : f:('edge -> string * string * string) -> ('edge -> Either<string,RestfulAux.Error>)
val updateMyNode : node:MyNode -> Either<string,RestfulAux.Error>


Updates a node of type MyNode using the node converter to the gephi graph.
val updateNode : nodeConverter:Streamer.NodeConverter<'node> -> nodeId:obj -> ('node -> Either<string,RestfulAux.Error>)
val updateMyEdge : edge:MyEdge -> Either<string,RestfulAux.Error>
val updateEdge : edgeConverter:Streamer.EdgeConverter<'edge> -> edgeId:obj -> sourceId:obj -> targetId:obj -> ('edge -> Either<string,RestfulAux.Error>)
val removeMyNode : node:MyNode -> Either<string,RestfulAux.Error>


Removes a node of type MyNode given a mapping from node type to an ID from the gephi graph
val removeNode : nodeId:obj -> ('node -> Either<string,RestfulAux.Error>)
val removeMyEdge : edge:MyEdge -> Either<string,RestfulAux.Error>


Removes an edge of type MyEdge given a mapping from edge type to an ID from the gephi graph
val removeEdge : edgeId:obj -> ('edge -> Either<string,RestfulAux.Error>)
Fork me on GitHub