【问题标题】:How do I generate data for Google Visualizations on the server using WebSharper如何使用 WebSharper 在服务器上为 Google 可视化生成数据
【发布时间】:2012-06-10 03:49:19
【问题描述】:

我的目标是能够在服务器上为 Google 可视化生成数据,然后将其作为 java 脚本传递给客户端,以便可以将其呈现为折线图。我下面的示例编译正确,但在浏览器中呈现时会产生错误。在服务器上构建 DataCommon 对象后,我需要做什么才能正确呈现为 java 脚本?

namespace Website

open System

type Action =
    | Test

module Page =
    open System.Web
    open IntelliFactory.WebSharper.Sitelets
    open IntelliFactory.WebSharper.Html

    let Page title body : Content<Action> =       
        PageContent (fun context -> 
            { Page.Default with
                Title = Some(title)
                Body = body context
            })

module Chart =
    open System

    open IntelliFactory.WebSharper
    open IntelliFactory.WebSharper.Html
    open IntelliFactory.WebSharper.Google
    open IntelliFactory.WebSharper.Google.Visualization
    open IntelliFactory.WebSharper.Google.Visualization.Base
    open IntelliFactory.WebSharper.EcmaScript

    open IntelliFactory.WebSharper.Web

    let RandomData () =

        let random = new Random()

        let valueCount = 100
        let maxValue = 300
        let seriesCount = random.Next(5)

        let data = new Base.DataTable()
        data.addRows(valueCount)
        |> ignore        

        let addSeries index =
            let name = sprintf "Series %d" index
            data.addColumn(ColumnType.NumberType, name)
            |> ignore

            Seq.init valueCount (fun index -> random.Next(maxValue))
            |> Seq.iteri (fun valueIndex value -> data.setValue(index, valueIndex, value) |> ignore)

        [0 .. seriesCount]
        |> List.iter addSeries

        data        

    type LineChart( data : DataCommon, title ) =    
        inherit Web.Control()

        [<JavaScript>]
        override this.Body = 
            let div = 
                Div [] 
                |>! OnAfterRender (fun container ->
                    let visualization = new Visualizations.LineChart(container.Dom)
                    let options = {
                        Visualizations.LineChartOptions.Default with
                            width = 400.0
                            height = 240.0
                            legend = Visualizations.LegendPosition.Bottom
                            title = title
                    }
                    visualization.draw(data, options))
            div :> _

module Site =
    open Chart
    open Page

    open IntelliFactory.Html
    open IntelliFactory.WebSharper.Sitelets

    let TestPage =
        Page "Test" (fun (context : Context<Action>) -> 
        [
            Div [Text "Test"]
            Div [new Chart.LineChart(RandomData(), "Test Chart")]
        ])            

    let Main =
        Sitelet.Sum [
            Sitelet.Content "/" Test TestPage
        ]

open IntelliFactory.WebSharper.Sitelets
type Website() =    
    interface IWebsite<Action> with
        member this.Sitelet = Site.Main
        member this.Actions = [Test]

[<assembly: WebsiteAttribute(typeof<Website>)>]
do ()

【问题讨论】:

    标签: f# websharper


    【解决方案1】:

    您的RandomData 函数在服务器上运行。因此,您正在服务器上构建纯 JavaScript DataTable 对象 - 这样做的结果通常是未定义的。

    你应该:

    1. [&lt;Remote&gt;]标记生成数据的服务器端函数。
    2. 将 UI 构造移至注释为 [&lt;JavaScript&gt;] 的客户端代码。
    3. 从客户端调用远程函数 - 这将使用 AJAX 来获取数据。最好通过远程功能async.Return,以免阻止浏览器。

    查看Remoting 页面或手册的相关部分了解更多信息。

    或者,您可以将数据传递给Control 对象的构造函数,并从Body 成员访问它。这将在 HTML 生成期间序列化数据并避免需要 AJAX 调用 - 例如,这对于生成静态 HTML 站点很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-22
      • 2011-08-05
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      • 2012-07-25
      • 1970-01-01
      相关资源
      最近更新 更多