f# - 如何在 fsi 中运行 .fsx

标签 f# fsharpchart

使用 FSharp.Charting 探索 F# 我原以为我会从一个简单的“hello world”开始,但它留给我的问题比代码行还多。

#load @"..\packages\FSharp.Charting.0.90.14\FSharp.Charting.fsx"
open FSharp.Charting
let chart = Chart.Line([ for x in 0 .. 10 -> x, x*x ])
chart.ShowChart()
chart.SaveChartAs(@"C:\Temp\chart.png",ChartTypes.ChartImageFormat.Png)

这在 VS 的交互式窗口中有效,但我想做的是从 cmd 行(使用 fsi.exe)执行此脚本。我将 fsx 文件关联到 fsi,但是当我执行它时,它会打开 fsi 但没有创建图表。我需要做什么?

最佳答案

简答:在程序末尾添加以下行:

System.Windows.Forms.Application.Run()

长答案:

图表确实创建了,但它立即消失了,因为您的程序在创建图表后立即退出。这不会发生在 Visual Studio 的 F# 交互窗口中,因为 F# 交互窗口不会在执行您的程序后立即关闭 - 它只是卡在那里,等待您提交更多代码以供执行。

为了让你的程序不立即退出,你可以实现一些等待机制,比如等待一段设定的时间(参见System.Threading.Thread.Sleep)或者等待用户按 Enter(通过 stdin.ReadLine())等

但是,这实际上对您没有帮助,因为存在下一个问题:图表是通过 Windows 窗体绘制的,它依赖于 message loop正在运行 - 否则窗口无法接收消息,因此无法绘制自身。

金融服务机构does have its own built-in event loop ,这就是您的程序在 VS 下的工作方式。但是,如果您实现“等待”机制(例如 stdin.ReadLine()),此事件循环将被阻止 - 将无法发送消息。因此,在不干扰图表窗口功能的情况下,防止程序退出的唯一明智方法是启动您自己的事件循环。而这正是 Application.Run() 所做的。

保存到磁盘而不显示:

(回应评论)

据我了解,FSharp.Charting 库旨在作为一种在屏幕上显示 图表的快捷方式,主要用例是探索数据集生活在 F# Interactive 中。更具体地说,Chart 对象的一些关键属性,例如 ChartAreasSeries在创建图表时不会初始化,只有在屏幕上显示时才会初始化(请参阅 source code ),如果没有这些属性,图表将保持为空。

如果不向库提交拉取请求,我建议深入到底层 System.Windows.Forms.DataVisualization.Charting.Chart:

open System.Windows.Forms.DataVisualization.Charting

let ch = new Chart()
ch.ChartAreas.Add( new ChartArea() )
let s = new Series( ChartType = SeriesChartType.Line )
s.Points.DataBind( [for x in 1..10 -> x, x*x], "Item1", "Item2", "" )
ch.Series.Add s;

ch.SaveImage(@"C:\Temp\chart.png", System.Drawing.Imaging.ImageFormat.Png)

关于f# - 如何在 fsi 中运行 .fsx,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43968308/

相关文章:

MacOS 上的 F# 图表 (Xamarin)

f# - 为多个数据文件创建类似的 HTML 报告

f# - 是什么导致 F# 序列重新枚举?

f# - 带有活跃模式的 FizzBu​​zz

f# - 如何将 OpenXML SDK 与 F# 和 MemoryStreams 结合使用

scala - 思考 Elm 中所见模式的名称以及是否有其他类似情况

asynchronous - 在 F# 中优化映射异步序列的语法

macos - FSharp.Charting.Gtk 在启动时崩溃