虽然想要自定义Google DataVisualization,但我想参数化控件的构造函数,但由于某些原因,当我将inputDataTable
作为参数传递时,它似乎无法工作。
这是我使用的默认数据:
module Example =
let headers = [|"Country"; "Population (mil)"; "Area (km2)" |]
let inputDataTable = [|
[|box "CN"; box 1234000; box 9640821|]
[|box "IN"; box 1133000; box 3287263|]
[|box "US"; box 304000; box 9629091|]
[|box "ID"; box 232000; box 1904569|]
[|box "BR"; box 187000; box 8514877|]
|]
在网页上生成图表的代码。
let GeoChart headers inputDataTable =
Div []
|>! OnAfterRender (fun container ->
let dataFormatter = DefaultOptions.NumberFormatter ""
let options = DefaultOptions.GeoChart
let visualization = new GeoChart(container.Dom)
let data = Data.GeoMapData headers inputDataTable
dataFormatter.format(data, 1)
visualization.draw(data, options)
)
"期待"控制。
type GoogleGeoChartViewer(headers, inputDataTable) =
inherit Web.Control()
[<JavaScript>]
override this.Body =
Google.Charts.GeoChart headers inputDataTable :> _
使用基本模板进行测试。
let HomePage =
let headers = Google.Example.headers
let inputDataTable = Google.Example.inputDataTable
Skin.WithTemplate "HomePage" <| fun ctx ->
[
Div [Text "HOME"]
Div [new Controls.EntryPoint()]
Div [new Controls.GoogleGeoChartViewer(headers, inputDataTable)]
Links ctx
]
但是,当我使用此代码时:地理图表不会显示。
但如果我从参数列表中删除inputDataTable
并使用:
let GeoChart headers =
Div []
|>! OnAfterRender (fun container ->
let dataFormatter = DefaultOptions.NumberFormatter ""
let options = DefaultOptions.GeoChart
let visualization = new GeoChart(container.Dom)
let inputDataTable = Example.inputDataTable
let data = Data.GeoMapData headers inputDataTable
dataFormatter.format(data, 1)
visualization.draw(data, options)
)
它有效......
headers
数组不会造成任何问题。
有人会知道发生了什么事吗?
感谢您的见解。
答案 0 :(得分:1)
传递给Web.Control
的构造函数的值是在服务器端构造页面期间序列化为JSON的服务器端值。但是,类型obj
没有序列化程序,因此inputDataTable
(类型obj[][]
)的序列化失败。相反,在有效的版本中,inputDataTable
是在客户端上构建的,因此不需要进行序列化。
如果inputDataTable
确实需要来自服务器端,则需要使用可序列化类型。我不确切知道如何在GeoMapData
函数中填充数据对象,但解决方案可能是定义inputDataTable
,如下所示:
let inputDataTable = [|
("CN", 1234000, 9640821)
("IN", 1133000, 3287263)
("US", 304000, 9629091)
("ID", 232000, 1904569)
("BR", 187000, 8514877)
|]
然后在客户端,执行以下操作:
let data = new Base.DataTable()
data.addRows(inputDataTable) |> ignore
诀窍是WebSharper在客户端使用JavaScript数组表示元组。通常需要addRows
的方法obj[][]
也有一个需要'T[]
的重载。这允许您编写上面正确键入的F#代码,并将其编译为完全相同的JavaScript代码,就像传递obj[][]
一样。这个技巧在this example中使用(第155行)。