Serialize Chart into JSON string in Plotly.NET

129 views Asked by At

I want to serialize a Plotly chart in F# into JSON string so it can be passed as a payload through a HTTP request.

In theory, this should be trivial as the Plotly.NET documentation states, "Plotly.NET is a .NET wrapper for creation of plotly charts. This means that, under the hood, all functionality creates JSON objects that can be rendered by plotly".

From having used Plotly in Python, the the way to do this is:

json.dumps(obj=Figure(), cls=utils.PlotlyJSONEncoder)

Is there an equivalent method for F#?

1

There are 1 answers

3
kMutagene On BEST ANSWER

In general, note that json creation in Plotly.NET is a one-way road, you can not deserialize the json objects into Plotly.NET types easily.

However, since you only asked for serialization only, one way is converting the GenericChart (which is a Union, therefore you cannot serialize it directly) to a Figure, and then serializing it (note that i use UseDefaults=false to reduce json size for this example, otherwise it would include large amounts of template stuff):

open Plotly.NET
open Newtonsoft.Json

let settings = JsonSerializerSettings(ReferenceLoopHandling = ReferenceLoopHandling.Serialize)

Chart.Point([1,2], UseDefaults = false) 
|> GenericChart.toFigure
|> fun c -> JsonConvert.SerializeObject(c, settings)

result:

{"data":[{"type":"scatter","mode":"markers","x":[1],"y":[2],"marker":{},"line":{}}],"layout":{},"frames":[]}

this does not include the config object though. if you want to include that, there is currently no easy built-in for that, as internally the respective charts are deconstructed into data, layout, and config objects and then serialized and injected into html.

So you could do this if you need the config object serialized:

type ChartDTO = {
    data: Trace list
    layout: Layout
    config: Config
}

Chart.Point([1,2], UseDefaults = false)
|> fun c ->
    {
        data = c |> GenericChart.getTraces
        layout = c |> GenericChart.getLayout
        config = c |> GenericChart.getConfig
    }

|> fun c -> JsonConvert.SerializeObject(c, settings)

result:

{"data":[{"type":"scatter","mode":"markers","x":[1],"y":[2],"marker":{},"line":{}}],"layout":{},"config":{}}

I agree that this is harder than it should be though, so I opened #399 to track this. Ideally, there should be GenericChart.toFigureJson and GenericChart.toJson, and the internal serializer settings should be exposed instead of being private.