-
-
Save jonmmease/2616440ebea523b83f25100f5c6a9a7f to your computer and use it in GitHub Desktop.
Kaleido.FSharp POC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Use F#5 preview to use "#r:nuget..." | |
#r "nuget:FSharp.Plotly,Version=2.0.0-alpha" | |
#r "nuget:Fake.Core.Process" | |
open System | |
open System.Diagnostics | |
open Fake.IO | |
open FSharp.Plotly | |
open Newtonsoft.Json | |
open System.Collections.Generic | |
let randomPoints = | |
let rnd = new System.Random() | |
[for i = 0 to 999 do yield rnd.NextDouble(),rnd.NextDouble()] | |
let testFig = | |
Chart.Point( | |
randomPoints | |
) | |
|> Chart.withX_AxisStyle("TestTitle_X",Showgrid=false) | |
|> Chart.withY_AxisStyle("TestTitle_Y",Showgrid=false) | |
testFig |> Chart.Show | |
module Kaleido = | |
let stringFormats = Set.ofList ["svg"; "eps"; "json"] | |
//input and output should most likely be dynamic objects themselves instead of record types | |
type KaleidoInput () = | |
inherit DynamicObj() | |
///This function makes it possible to render Charts | |
///generated with FSharp.Plotly | |
static member ofChart | |
( | |
format:string, | |
gChart:GenericChart.GenericChart | |
) = | |
let data = GenericChart.getTraces gChart | |
let layout = GenericChart.getLayout gChart | |
let dict = new Dictionary<string, Object>() | |
dict.Add("data", data) | |
dict.Add("layout", layout) | |
let kI = KaleidoInput() | |
dict |> DynObj.setValue kI "data" | |
format |> DynObj.setValue kI "format" | |
kI | |
//TODO: Extend with all fields possibly returned by Kaleido and handle null properly | |
type KaleidoResponse = { | |
Code : int | |
Message : string | |
Format : string | |
Result : string | |
} | |
with | |
static member fromJsonString (jsonString) = | |
jsonString |> JsonConvert.DeserializeObject<KaleidoResponse> | |
///Starts a process using the kaleido executable and a scope name | |
//TODO: abstract scopes as types | |
let start executablePath scopeName = | |
let startInfo = | |
new ProcessStartInfo( | |
UseShellExecute = false, | |
RedirectStandardOutput = true, | |
RedirectStandardInput = true, | |
RedirectStandardError = false, | |
FileName = executablePath, | |
Arguments = scopeName | |
) | |
let kaleidoProcess = new Process(StartInfo = startInfo) | |
if kaleidoProcess.Start() then | |
let startupMsg = kaleidoProcess.StandardOutput.ReadLine() | |
printfn "startup response: %s" startupMsg | |
kaleidoProcess | |
else | |
failwith "Error starting Kaleido process" | |
let stop (kaleidoProcess:System.Diagnostics.Process) = | |
kaleidoProcess.Kill() | |
kaleidoProcess.Dispose() | |
///Render the given KaleidoInput using the given process. | |
///use keepRunning = true if you want to use the process again afterwards. | |
let render (kaleidoProcess:System.Diagnostics.Process) (keepRunning:bool) (input:KaleidoInput) = | |
input | |
|> JsonConvert.SerializeObject | |
|> kaleidoProcess.StandardInput.WriteLine | |
let result = | |
kaleidoProcess.StandardOutput.ReadLine() | |
|> KaleidoResponse.fromJsonString | |
if not keepRunning then stop kaleidoProcess | |
result | |
//Example usage: | |
printfn "Hello World from F#!" | |
//Path to kaleido executable. | |
let kaleidoPath = @"/media/jmmease/SSD1/kaleido/repos/build/kaleido/kaleido" | |
// let kaleidoPath = @"path/to/kaleido.cmd" | |
//Start a kaleido process | |
let proc = Kaleido.start kaleidoPath "plotly" | |
//Formats dont seem to work as I expected. Changing format here does nothing. | |
let input = Kaleido.KaleidoInput.ofChart("json", testFig) | |
//Render the chart with the started process. Save image using FAKE | |
input | |
|> Kaleido.render proc true | |
|> fun r -> | |
//save result as image | |
r.Result | |
|> (if Kaleido.stringFormats.Contains(r.Format) | |
then System.Text.Encoding.ASCII.GetBytes | |
else Convert.FromBase64String) | |
|> File.writeBytes ( | |
sprintf | |
@"testFigure.%s" | |
r.Format | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment