8 people like it.
Like the snippet!
Generating GraphViz images using C# wrapper.
How you can programmatically use GraphViz from F#.
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:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
|
// 1. Install: http://www.graphviz.org/Download..php
//
// 2. Add <appSettings> under <configuration> to app.config/web.config
// Add Nuget / Paket: GraphViz.NET
//
// 3. Add under <configuration><appSettings>:
// <add key="graphVizLocation" value="C:\Program Files (x86)\Graphviz2.38\bin" />
//
// Add references to System.Configuration.dll and System.Drawing.dll
module GraphVizSample
open GraphVizWrapper
open GraphVizWrapper.Commands
open GraphVizWrapper.Queries
open System
open System.Configuration
open System.Drawing
open System.IO
/// Creates some pngs
let genereateGraphFile (path:string) graphVizImageData =
let procqry = GetStartProcessQuery()
let infoqry = GetProcessStartInfoQuery()
let wrapper = GraphGeneration(procqry, infoqry,
RegisterLayoutPluginCommand(infoqry, procqry))
// You probably don't need all 7:
//[1] // different layout of graphs, e.g.: Enums.RenderingEngine.Neato
[0..7] |> List.map(fun i ->
wrapper.RenderingEngine <- enum<Enums.RenderingEngine> i
let output = wrapper.GenerateGraph(graphVizImageData, Enums.GraphReturnType.Png)
use image = System.Drawing.Image.FromStream(new MemoryStream(output))
let filename = sprintf "%sgraph-%i-%i.png" path (output.GetHashCode()) i
do image.Save(filename, System.Drawing.Imaging.ImageFormat.Png)
let creationtime = File.GetLastWriteTime filename
filename, creationtime
)
/// Replace your version of data generation.
/// This is just a silly example to give some starting point.
/// Note: If you use Guid based Ids, it's better to use some text-prefix!
let sampleGraphData items1 items2 =
// shapes: box, diamond, circle, ...
// colors: lightgray, lightblue, goldenrod2, thistle2, ...
// Click on picture under http://www.graphviz.org/Gallery.php
// ...and picture again to get the sample txt-file.
let idPrefix = "item"
let nodes1 =
let items = items1 |> Array.map(fun (id,name,_) ->
sprintf "%s%s [label=\"%s\"]; " idPrefix id name)
"node [shape=box,style=filled,color=lightblue]; " +
(items |> String.Concat)
let nodes2 =
let printStr =
sprintf "%s%s [label=\"€%s\",color=%s]; " idPrefix
"node [shape=circle,style=filled]; " +
(items2 |> Array.map(function
| id, name, true, _ -> printStr id name "goldenrod2"
| id, name, false, _ -> printStr id name "lightgray"
) |> String.Concat)
let graphPart =
let printArrow aFrom aTo =
sprintf "%s%s -> %s%s;" idPrefix aFrom idPrefix aTo
let arrows1 =
items1 |> Array.filter(fun (i,_,lnk) -> lnk<>"")
|> Array.map(fun (item,_,lnk) -> printArrow item lnk)
let arrows2 =
items2 |> Array.filter(fun (i,_,_,lnk) -> lnk<>"")
|> Array.map(fun (item,_,_,lnk) -> printArrow item lnk)
(String.Concat arrows1) + (String.Concat arrows2)
"digraph myDiagram { " + nodes1 + nodes2 + graphPart + "overlap=false}"
// Create some data.
let doSample() =
let genId() = Guid.NewGuid().ToString("N")
let someId1 = genId()
let someId2 = genId()
let someId3 = genId()
let ten = someId1, "10", true, "";
let five = genId(), "5", false, someId2;
let six = someId3, "6", false, "";
let fork = genId(), "Fork", someId3;
let spoon = someId2, "Spoon", someId1;
let knife = genId(), "Knife", someId1;
let graphdata = sampleGraphData [|fork; spoon; knife|] [|ten; five; six; |]
genereateGraphFile AppDomain.CurrentDomain.BaseDirectory graphdata
|
module GraphVizSample
namespace GraphVizWrapper
namespace GraphVizWrapper.Commands
namespace GraphVizWrapper.Queries
namespace System
namespace System.Configuration
namespace System.Drawing
namespace System.IO
val genereateGraphFile : path:string -> graphVizImageData:string -> (string * DateTime) list
Full name: GraphVizSample.genereateGraphFile
Creates some pngs
val path : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = String
Full name: Microsoft.FSharp.Core.string
val graphVizImageData : string
val procqry : GetStartProcessQuery
Multiple items
type GetStartProcessQuery =
new : unit -> GetStartProcessQuery
member Invoke : processStartInfo:ProcessStartInfo -> Process
Full name: GraphVizWrapper.Queries.GetStartProcessQuery
--------------------
GetStartProcessQuery() : unit
val infoqry : GetProcessStartInfoQuery
Multiple items
type GetProcessStartInfoQuery =
new : unit -> GetProcessStartInfoQuery
member Invoke : startInfoWrapper:IProcessStartInfoWrapper -> ProcessStartInfo
Full name: GraphVizWrapper.Queries.GetProcessStartInfoQuery
--------------------
GetProcessStartInfoQuery() : unit
val wrapper : GraphGeneration
Multiple items
type GraphGeneration =
new : startProcessQuery:IGetStartProcessQuery * getProcessStartInfoQuery:IGetProcessStartInfoQuery * registerLayoutPlugincommand:IRegisterLayoutPluginCommand -> GraphGeneration
member GenerateGraph : dotFile:string * returnType:GraphReturnType -> byte[]
member GraphvizPath : string with get, set
member RenderingEngine : RenderingEngine with get, set
Full name: GraphVizWrapper.GraphGeneration
--------------------
GraphGeneration(startProcessQuery: IGetStartProcessQuery, getProcessStartInfoQuery: IGetProcessStartInfoQuery, registerLayoutPlugincommand: IRegisterLayoutPluginCommand) : unit
Multiple items
type RegisterLayoutPluginCommand =
new : getProcessStartInfoQuery:IGetProcessStartInfoQuery * getStartProcessQuery:IGetStartProcessQuery -> RegisterLayoutPluginCommand
member Invoke : unit -> unit + 1 overload
Full name: GraphVizWrapper.Commands.RegisterLayoutPluginCommand
--------------------
RegisterLayoutPluginCommand(getProcessStartInfoQuery: IGetProcessStartInfoQuery, getStartProcessQuery: IGetStartProcessQuery) : unit
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
Full name: Microsoft.FSharp.Collections.List<_>
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
Full name: Microsoft.FSharp.Collections.List.map
val i : int
property GraphGeneration.RenderingEngine: Enums.RenderingEngine
val enum : value:int32 -> 'U (requires enum)
Full name: Microsoft.FSharp.Core.Operators.enum
type Enums =
nested type GraphReturnType
nested type RenderingEngine
Full name: GraphVizWrapper.Enums
type RenderingEngine =
| Dot = 0
| Neato = 1
| Twopi = 2
| Circo = 3
| Fdp = 4
| Sfdp = 5
| Patchwork = 6
| Osage = 7
Full name: GraphVizWrapper.Enums.RenderingEngine
val output : byte []
GraphGeneration.GenerateGraph(dotFile: string, returnType: Enums.GraphReturnType) : byte []
type GraphReturnType =
| Pdf = 0
| Jpg = 1
| Png = 2
| Plain = 3
| PlainExt = 4
| Svg = 5
Full name: GraphVizWrapper.Enums.GraphReturnType
field Enums.GraphReturnType.Png = 2
val image : Image
type Image =
inherit MarshalByRefObject
member Clone : unit -> obj
member Dispose : unit -> unit
member Flags : int
member FrameDimensionsList : Guid[]
member GetBounds : pageUnit:GraphicsUnit -> RectangleF
member GetEncoderParameterList : encoder:Guid -> EncoderParameters
member GetFrameCount : dimension:FrameDimension -> int
member GetPropertyItem : propid:int -> PropertyItem
member GetThumbnailImage : thumbWidth:int * thumbHeight:int * callback:GetThumbnailImageAbort * callbackData:nativeint -> Image
member Height : int
...
nested type GetThumbnailImageAbort
Full name: System.Drawing.Image
Image.FromStream(stream: Stream) : Image
Image.FromStream(stream: Stream, useEmbeddedColorManagement: bool) : Image
Image.FromStream(stream: Stream, useEmbeddedColorManagement: bool, validateImageData: bool) : Image
Multiple items
type MemoryStream =
inherit Stream
new : unit -> MemoryStream + 6 overloads
member CanRead : bool
member CanSeek : bool
member CanWrite : bool
member Capacity : int with get, set
member Flush : unit -> unit
member GetBuffer : unit -> byte[]
member Length : int64
member Position : int64 with get, set
member Read : buffer:byte[] * offset:int * count:int -> int
...
Full name: System.IO.MemoryStream
--------------------
MemoryStream() : unit
MemoryStream(capacity: int) : unit
MemoryStream(buffer: byte []) : unit
MemoryStream(buffer: byte [], writable: bool) : unit
MemoryStream(buffer: byte [], index: int, count: int) : unit
MemoryStream(buffer: byte [], index: int, count: int, writable: bool) : unit
MemoryStream(buffer: byte [], index: int, count: int, writable: bool, publiclyVisible: bool) : unit
val filename : string
val sprintf : format:Printf.StringFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
Object.GetHashCode() : int
Image.Save(filename: string) : unit
Image.Save(stream: Stream, format: Imaging.ImageFormat) : unit
Image.Save(filename: string, format: Imaging.ImageFormat) : unit
Image.Save(stream: Stream, encoder: Imaging.ImageCodecInfo, encoderParams: Imaging.EncoderParameters) : unit
Image.Save(filename: string, encoder: Imaging.ImageCodecInfo, encoderParams: Imaging.EncoderParameters) : unit
namespace System.Drawing.Imaging
Multiple items
type ImageFormat =
new : guid:Guid -> ImageFormat
member Equals : o:obj -> bool
member GetHashCode : unit -> int
member Guid : Guid
member ToString : unit -> string
static member Bmp : ImageFormat
static member Emf : ImageFormat
static member Exif : ImageFormat
static member Gif : ImageFormat
static member Icon : ImageFormat
...
Full name: System.Drawing.Imaging.ImageFormat
--------------------
Imaging.ImageFormat(guid: Guid) : unit
property Imaging.ImageFormat.Png: Imaging.ImageFormat
val creationtime : DateTime
type File =
static member AppendAllLines : path:string * contents:IEnumerable<string> -> unit + 1 overload
static member AppendAllText : path:string * contents:string -> unit + 1 overload
static member AppendText : path:string -> StreamWriter
static member Copy : sourceFileName:string * destFileName:string -> unit + 1 overload
static member Create : path:string -> FileStream + 3 overloads
static member CreateText : path:string -> StreamWriter
static member Decrypt : path:string -> unit
static member Delete : path:string -> unit
static member Encrypt : path:string -> unit
static member Exists : path:string -> bool
...
Full name: System.IO.File
File.GetLastWriteTime(path: string) : DateTime
val sampleGraphData : items1:(string * string * string) [] -> items2:(string * string * bool * string) [] -> string
Full name: GraphVizSample.sampleGraphData
Replace your version of data generation.
This is just a silly example to give some starting point.
Note: If you use Guid based Ids, it's better to use some text-prefix!
val items1 : (string * string * string) []
val items2 : (string * string * bool * string) []
val idPrefix : string
val nodes1 : string
val items : string []
type Array =
member Clone : unit -> obj
member CopyTo : array:Array * index:int -> unit + 1 overload
member GetEnumerator : unit -> IEnumerator
member GetLength : dimension:int -> int
member GetLongLength : dimension:int -> int64
member GetLowerBound : dimension:int -> int
member GetUpperBound : dimension:int -> int
member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
member Initialize : unit -> unit
member IsFixedSize : bool
...
Full name: System.Array
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []
Full name: Microsoft.FSharp.Collections.Array.map
val id : string
val name : string
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
String.Concat([<ParamArray>] values: string []) : string
(+0 other overloads)
String.Concat(values: Collections.Generic.IEnumerable<string>) : string
(+0 other overloads)
String.Concat<'T>(values: Collections.Generic.IEnumerable<'T>) : string
(+0 other overloads)
String.Concat([<ParamArray>] args: obj []) : string
(+0 other overloads)
String.Concat(arg0: obj) : string
(+0 other overloads)
String.Concat(str0: string, str1: string) : string
(+0 other overloads)
String.Concat(arg0: obj, arg1: obj) : string
(+0 other overloads)
String.Concat(str0: string, str1: string, str2: string) : string
(+0 other overloads)
String.Concat(arg0: obj, arg1: obj, arg2: obj) : string
(+0 other overloads)
String.Concat(str0: string, str1: string, str2: string, str3: string) : string
(+0 other overloads)
val nodes2 : string
val printStr : (string -> string -> string -> string)
val graphPart : string
val printArrow : (string -> string -> string)
val aFrom : string
val aTo : string
val arrows1 : string []
val filter : predicate:('T -> bool) -> array:'T [] -> 'T []
Full name: Microsoft.FSharp.Collections.Array.filter
val i : string
val lnk : string
val item : string
val arrows2 : string []
val doSample : unit -> (string * DateTime) list
Full name: GraphVizSample.doSample
val genId : (unit -> string)
Multiple items
type Guid =
struct
new : b:byte[] -> Guid + 4 overloads
member CompareTo : value:obj -> int + 1 overload
member Equals : o:obj -> bool + 1 overload
member GetHashCode : unit -> int
member ToByteArray : unit -> byte[]
member ToString : unit -> string + 2 overloads
static val Empty : Guid
static member NewGuid : unit -> Guid
static member Parse : input:string -> Guid
static member ParseExact : input:string * format:string -> Guid
...
end
Full name: System.Guid
--------------------
Guid()
Guid(b: byte []) : unit
Guid(g: string) : unit
Guid(a: int, b: int16, c: int16, d: byte []) : unit
Guid(a: uint32, b: uint16, c: uint16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : unit
Guid(a: int, b: int16, c: int16, d: byte, e: byte, f: byte, g: byte, h: byte, i: byte, j: byte, k: byte) : unit
Guid.NewGuid() : Guid
val someId1 : string
val someId2 : string
val someId3 : string
val ten : string * string * bool * string
val five : string * string * bool * string
val six : string * string * bool * string
val fork : string * string * string
val spoon : string * string * string
val knife : string * string * string
val graphdata : string
type AppDomain =
inherit MarshalByRefObject
member ActivationContext : ActivationContext
member AppendPrivatePath : path:string -> unit
member ApplicationIdentity : ApplicationIdentity
member ApplicationTrust : ApplicationTrust
member ApplyPolicy : assemblyName:string -> string
member BaseDirectory : string
member ClearPrivatePath : unit -> unit
member ClearShadowCopyPath : unit -> unit
member CreateComInstanceFrom : assemblyName:string * typeName:string -> ObjectHandle + 1 overload
member CreateInstance : assemblyName:string * typeName:string -> ObjectHandle + 3 overloads
...
Full name: System.AppDomain
property AppDomain.CurrentDomain: AppDomain
property AppDomain.BaseDirectory: string
More information