用FSharp.Charting探索F#我以为我会从一个简单的“你好世界”开始#39;但它给我留下了更多问题,然后是代码行。
#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,但是没有创建图表。我需要做什么?
答案 0 :(得分:3)
简短回答:在程序结束时添加以下行:
System.Windows.Forms.Application.Run()
图表确实已创建,但会立即消失,因为您的程序会在创建图表后立即退出。在Visual Studio的F#Interactive窗口中不会发生这种情况,因为F#交互式窗口在执行程序后不会立即关闭 - 它只是挂起,等待您提交更多代码以供执行。
为了使您的程序不立即退出,您可以实现一些等待机制,例如等待一段时间(请参阅System.Threading.Thread.Sleep
)或等待用户按Enter键(通过{{1等等。
然而,这实际上对你没有帮助,因为还有下一个问题:图表是通过Windows Forms绘制的,它依赖于message loop运行 - 否则窗口无法接收消息,所以不能事件画自己。
FSI does have its own built-in event loop,这就是你的程序在VS下的工作方式。但是,如果您实现“等待”机制(例如stdin.ReadLine()
),则此事件循环将被阻止 - 将无法抽取消息。因此,保持程序退出的唯一理智方法是在不干扰图表窗口功能的情况下启动自己的事件循环。这正是stdin.ReadLine()
所做的。
(回应评论)
根据我的理解,Application.Run()
库旨在作为在屏幕上显示图表的快捷方式,主要用例是在F#Interactive中浏览数据集。更具体地说,FSharp.Charting
对象的某些关键属性(例如ChartAreas
和Series
)在创建图表时未初始化,但仅在屏幕上显示时才会初始化(请参阅{{3} }),没有这些属性,图表仍为空。
如果没有向库提交拉取请求,我建议您下载到基础Chart
:
System.Windows.Forms.DataVisualization.Charting.Chart