-
-
Save kMutagene/77aca4941e89f96bdbf5700f45ff27b3 to your computer and use it in GitHub Desktop.
//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 | |
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 = | |
//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 kI = KaleidoInput() | |
data |> DynObj.setValue kI "data" | |
layout |> DynObj.setValue kI "layout" | |
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 "%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: | |
//Path to kaleido executable. | |
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("png",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 | |
|> Convert.FromBase64String | |
|> File.writeBytes ( | |
sprintf | |
@"path/to/kaleido.cmd\testFigure.%s" | |
r.Format | |
) |
I think the problem with the format not working might have to do with needing a one extra level of nesting.
Yes absolutely, i missed that one
Here's a version that adds the extra level of nesting and works with different formats:
Very cool, especially considering that you said that you don't have much first hand experience in .NET! So what do you think is the way to go from here, I think i could work out a PR for the kaleido repo that adds a F# project with all the build and package distribution scripts and proper typing but i think for integrating tests etc. into your CI i would need your help.
Very cool, especially considering that you said that you don't have much first hand experience in .NET!
I played with F# several years ago for a class project, and I love the language. But I never got deep enough into to it to understand how packaging works. And that was before .NET core, so I'm also not clear on the Linux packaging story right now.
I think i could work out a PR for the kaleido repo that adds a F# project with all the build and package distribution scripts and proper typing but i think for integrating tests etc. into your CI i would need your help.
Cool! If you could include bash/cmd scripts that build the packages, given a path to the executable directory, I think that would be enough for me to use to integrate it into CI. What I'd be doing would be to create a CI task that runs after the executable is created, builds the package, and then uploads it to circleci as an artifact. Then I'd look to you for help on how to publish these packages.
I haven't added the Python tests to CI yet, but that's something I'll work on soon.
Here's a version that adds the extra level of nesting and works with different formats: https://gist.github.com/jonmmease/2616440ebea523b83f25100f5c6a9a7f.