Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FSharpChart.SaveAs () saves blank image if called before chart rendering is complete

When run in F# Interactive, I expect the following code to create a simple pie chart and save it to disk:

let pie = FSharpChart.Pie([("Apples",1);("Oranges",2);("Bananas",3)])
FSharpChart.SaveAs "test.png" ChartImageFormat.Png pie

However, what actually gets saved in "test.png" is a blank image. The same happens if I pipe the chart into the FShartChart.SaveAs function. But if I first execute only the chart creation code and give the chart time to render before manually executing SaveAs, the image gets saved as expected.

Is there a way to block the call to FSharpChart.Pie until the rendering is complete? I'm using FSharpChart.fsx version 0.60 in Visual Studio 2013.

like image 529
Kevin D. Avatar asked Oct 29 '13 04:10

Kevin D.


2 Answers

The problem is that the underlying chart control first needs to be displayed before it can save the chart to a file (this is pretty silly, but sadly, F# chart is just a lightweight wrapper over underlying .NET chart libraries).

I think you can either run the two lines separately in F# interactive, or you need to explicitly call some method that displays the chart (I believe there is FSharpChart.Show or something like that)

I tested this using F# Charting which is a newer version of the library (with some API changes, but very similar ideas) and the following works (even when executed all in a single command):

#load @"packages\FSharp.Charting.0.87\FSharp.Charting.fsx"
open FSharp.Charting

let pie = Chart.Pie([("Apples",1);("Oranges",2);("Bananas",3)])
pie.ShowChart()
pie.SaveChartAs("D:\\temp\\test.png", ChartTypes.ChartImageFormat.Png)
like image 54
Tomas Petricek Avatar answered Sep 19 '22 01:09

Tomas Petricek


I have found the following to work well, requiring no need to display. (FSharp.Charting, v 0.90.14, .net 4.5)

open FSharp.Charting
// etc
let prices = getPriceData ()
let chart = Chart.Candlestick(prices)
Chart.Save @"C:\Charts\prices.png" chart

Update

let renderChart ch = 
    let frm = new Form(Visible = false, TopMost = true, Width = 700, Height = 500)
    let ctl = new ChartControl(ch, Dock = DockStyle.Fill)
    frm.Controls.Add(ctl)

calling this on your given chart will allow you to render the chart without any forms pop ups.

like image 29
rbonallo Avatar answered Sep 18 '22 01:09

rbonallo