|
|
|
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: |
|
//[0..7] // different layout of graphs, e.g.: Enums.RenderingEngine.Neato |
|
[1] |> List.map(fun i -> |
|
wrapper.RenderingEngine <- enum<Enums.RenderingEngine> i |
|
//wrapper.GraphvizPath <- "C:/Program Files (x86)/Graphviz2.38/bin//" |
|
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 generateWeatherGraph (data:seq<char * seq<char * float>>) = |
|
|
|
let genId() = Guid.NewGuid().ToString("N") |
|
|
|
let probabilities = data |> Map.ofSeq |
|
|
|
let states = |
|
data |> Seq.toArray |> Array.map (fun k -> fst k, genId()) |
|
|
|
let statesMap = states |> Map.ofSeq |
|
|
|
let stateItems, changeItems = |
|
states |> Array.collect(fun (stateLabel, stateId) -> |
|
probabilities.[stateLabel] |> Seq.toArray |
|
|> Array.map(fun (toState, propabilityLabel) -> |
|
let changeStateId = genId() |
|
(stateId, stateLabel.ToString(), changeStateId), |
|
(changeStateId, propabilityLabel.ToString(), false, statesMap.[toState]) |
|
) |
|
) |> Array.unzip |
|
|
|
let graphdata = sampleGraphData stateItems changeItems |
|
genereateGraphFile AppDomain.CurrentDomain.BaseDirectory graphdata |
|
|
|
|
|
// https://github.com/mariuszwojcik/Presentations/blob/ff095259ea75f790723ada0e6e0612150ead061d/Introduction%20to%20Markov%20Chains%20in%20F%23/code/src/WeatherForecast.fsx#L10 |
|
let calcTransitionProbability items = |
|
let total = items |> Seq.length |
|
items |
|
|> Seq.groupBy(id) |
|
|> Seq.map(fun (g,i) -> g, float (i |> Seq.length) / float total) |
|
|
|
let data = |
|
"RRRRSSSSRRRRRRRRRRRRRRRRRRRSSSSSRR" |
|
|> Seq.windowed 2 |
|
|> Seq.groupBy(fun a -> a.[0]) |
|
|> Seq.map(fun (k, e) -> (k,e |> Seq.map(Seq.skip 1 >> Seq.head) |> calcTransitionProbability)) |
|
|
|
[<EntryPoint>] |
|
let main argv = |
|
let r = generateWeatherGraph data |
|
printfn "%A" argv |
|
0 // return an integer exit code |