Here is the complete code if it helps...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
namespace WorldBank

type DataPoint = int * float

type ChartData = {
                    indicator : string
                    yAxis : string
                    data : (string * DataPoint[])[]
                 }

type Country = {
                Years : int[]
                Values : float[]
                IndicatorName : string
                Country : string
                YAxisLable : string        
               } 
module WBData = 
    open FSharp.Data
    open System.Text.RegularExpressions

    let re str = Regex(@"(\()([^\)]*)(\))").Match(str).Groups.[2].Value
    let getYAxisLable s = 
        let t = re s
        match t with
        | "" -> "quantity"
        | _ -> t
    
    type WorldBank = WorldBankDataProvider<"World Development Indicators", Asynchronous=true>    
    let data = WorldBank.GetDataContext()
      
    let makeCountry (c:Runtime.WorldBank.Indicator) cName = 
            {
               Years = Seq.toArray c.Years
               Values = Seq.toArray c.Values
               IndicatorName = c.Name
               Country = cName
               YAxisLable = getYAxisLable c.Name
             }

    let countryList = Seq.toList data.Countries
    
    let countryNameList = 
        let nameList = List.map (fun (x : WorldBank.ServiceTypes.Country) -> x.Name) countryList
        let countryIndex = [0..(countryList.Length-1)]
        List.zip countryIndex nameList
    
    let indicatorNameList = 
        let cntry = countryList.[0].Indicators
        let indicatorNames = Seq.map (fun (x : Runtime.WorldBank.Indicator) -> x.Name) cntry
        let indicatorCodes = Seq.map (fun (x : Runtime.WorldBank.Indicator) -> x.IndicatorCode) cntry
        Seq.zip (Seq.toList indicatorCodes) (Seq.toList indicatorNames)
        |> Seq.distinct
        |> Seq.toList
    
    // max indicator list size due to select box size limitations
    let mILS = 300
    
    let indicatorNameListArray = 
        let iL = indicatorNameList.Length
        let indListSize = (iL/mILS,iL%mILS)
        let indArraySize iLS = 
            match snd iLS with
            | 0 -> fst iLS
            | _ -> fst iLS + 1

        let take n (l : _ seq) = match Seq.length l > n with
                                 | true -> Seq.take n l
                                 | false -> Seq.take (Seq.length l) l

        let list i l = l |> Seq.skip ((i - 1) * mILS) 
                         |> take 300                           
                         |> Seq.toList    
        [| for i in 1 .. indArraySize indListSize -> list i indicatorNameList |]


    let getCountryData countryIndex indicatorCode = 
        let getCountry countryIndex = countryList.[countryIndex]
        let getIndicators (country:WorldBank.ServiceTypes.Country) = country.Indicators :> Runtime.WorldBank.IIndicators
        let getIndicator indicatorCode (indicators:Runtime.WorldBank.IIndicators) = indicators.GetIndicator(indicatorCode)        
        async {
                let country = getCountry countryIndex
                let indicators = getIndicators country
                let indicator = getIndicator indicatorCode indicators
                let countryData = makeCountry indicator country.Name
                return countryData
              }

module Remoting =

open IntelliFactory.WebSharper
open WBData   

    [<Rpc>]
    let countryNameList() = countryNameList

    [<Rpc>]
    let indicatorNameListArray() = indicatorNameListArray

    [<Rpc>]
    let getCountry countryIndexArray indicatorCode =
        Array.map (fun x -> 
            let c = [getCountryData x indicatorCode]
                    |> Async.Parallel 
                    |> Async.RunSynchronously
            let name = c.[0].Country
            c.[0]
        ) countryIndexArray

open IntelliFactory.WebSharper
open IntelliFactory.WebSharper.Html
open IntelliFactory.WebSharper.JQuery
open IntelliFactory.WebSharper.Highcharts

[<JavaScript>]
module WorldBankChart =
    module Chart =

        let Chart (country : ChartData) =              
            Div[] |>! OnAfterRender (fun el ->                          
                Highcharts.Create(JQuery.Of el.Body,
                    HighchartsCfg(                        
                        Title = TitleCfg(
                            Text = country.indicator,
                            X = -20.
                        ),
                        Subtitle = SubtitleCfg(
                            Text = "Source: WorldBank",
                            X = -20.
                        ),                              
                        YAxis = YAxisCfg(
                            Title = YAxisTitleCfg(
                                Text = country.yAxis        
                            ),
                            PlotLines = [|
                                YAxisPlotLinesCfg(
                                    Value = 0.,
                                    Width = 1.,
                                    Color = "#808080"
                                )
                            |]
                        ),
                        Tooltip = TooltipCfg(
                            ValueSuffix = " " + country.yAxis
                        ), 
                        Legend = LegendCfg(
                            Layout = "vertical",
                            Align = "right",
                            VerticalAlign = "middle",
                            BorderWidth = 0.
                        ),
                        Series = ((country.data) |> Array.map (fun (c, d) -> SeriesCfg (Name = c, Data = As d)))                            
                    )
                ) |> ignore
            )
open IntelliFactory.WebSharper
open IntelliFactory.WebSharper.Html5
open IntelliFactory.WebSharper.Html
open IntelliFactory.WebSharper.JQuery
open IntelliFactory.WebSharper.Highcharts

[<JavaScript>]
module CustomControls =
        open IntelliFactory.WebSharper.Piglets
        let Button (writer: Writer<int>) =
            Button []
            |>! OnClick (fun _ _ -> writer.Trigger(Success 0))

[<JavaScript>]
module WorldBankForm =
    open IntelliFactory.WebSharper.Piglets
    open WBData
    open WorldBankChart.Chart    
    
    module Form =
        
        type WBdata = {countries : int[]; indicator : string}

        let countries = Remoting.countryNameList()
        let indicators = Remoting.indicatorNameListArray()

        //Piglets
        let countrySelector (c : int) =
            Piglet.Yield c
        
        let indicatorSelector (c : int) =
            Piglet.Yield c

        let dataSelector (c : WBdata) =
            Piglet.Return (fun x y -> {countries = x; indicator = y})            
            <*> Piglet.ManyInit c.countries 
                       0 
                       countrySelector
            <*> Piglet.Yield c.indicator
        
        //Render Functions
        let renderCountrySelector (countryS : Stream<int>) =             
            [Div [Controls.Select countryS countries]]

        let renderIndicatorListSelector (indicatorListS : Stream<int>) indicatorS =             
            [Div [Controls.Radio indicatorListS [for i in 0 .. (indicators.Length - 1) -> (i, (i+1).ToString())]]
             Br []                
             Div [] |> Controls.Show indicatorListS (fun x ->                         
                       [Div [Text "Indicator  "] -< [Controls.Select indicatorS indicators.[x]]])]
                    
        let renderCountryPiglet country (indicatorS : Stream<string>) = 
            let wbDataS = Stream.Map2 (fun x y -> {countries = x; indicator = y}) country indicatorS
            let indicatorListS = (indicatorSelector 0).Stream
            Div [                     
                    Div [] |> Controls.Show wbDataS (fun x -> let countryData = Remoting.getCountry x.countries x.indicator
                                                              let dataPoints : DataPoint [][] =
                                                                  Array.map (fun x -> (Array.zip x.Years x.Values)) countryData
                                                              let country = Array.map2 (fun x y-> (x.Country,y)) countryData dataPoints
                                                              let chartData : ChartData = {
                                                                                            yAxis = countryData.[0].YAxisLable
                                                                                            indicator = countryData.[0].IndicatorName
                                                                                            data = country
                                                                                          }     
                                                              [Chart (chartData)])
                    //Indicator Selector
                    Div [] -< renderIndicatorListSelector indicatorListS indicatorS                   
                    
                    //Country Selector
                    Br []
                    Table [Attr.Style "border:solid 1px #111; color:#111; margin:5px; padding:5px"] -<
                        [TBody [                            
                            TR [
                                TH [Attr.ColSpan "1"] -< [Text "Countries"]
                            ]
                            TR [
                                TD []  |> Controls.RenderMany country (fun ops x ->
                                        Div [Attr.Style "border:dotted 2px #111; color:#111; margin:5px; padding:5px"]
                                            -<  renderCountrySelector x                                                       
                                            -<  [Div [] |> Controls.Show wbDataS (fun y -> 
                                                    let cnt = y.countries.Length
                                                    match cnt with 
                                                    | 1 -> []
                                                    | _ -> [Controls.Button ops.Delete -< [Text "Delete"]]
                                                    )])]]]
                    P [CustomControls.Button country.Add -< [B [Text "Add Country"]]]]

        //Form
        let countryForm () =
            dataSelector {countries = [|202|]; indicator = "AG.AGR.TRAC.NO"}
            |> Piglet.Render renderCountryPiglet 

        let Main () = Div [countryForm()]

type WBViewer() =
    inherit Web.Control()
    [<JavaScript>]
    override this.Body = WorldBankForm.Form.Main () :>_

open IntelliFactory.Html
open IntelliFactory.WebSharper
open IntelliFactory.WebSharper.Sitelets

//***ACTIONS***
type Action = | Home

//***ROUTERS***
//module Router =

//***CONTROLERS***
//module Controler =

//***CONTENT***
module SiteContent =
    open System.Web

    type Page =
        {
            Title : string
            Body : list<Content.HtmlElement>
        }

    let MainTemplate =
        Content.Template<Page>("~/Main.html")
            .With("title", fun x -> x.Title)
            .With("body", fun x -> x.Body)

    let SkinWithTemplate body : Content<Action> =
        Content.WithTemplate MainTemplate <| fun context ->
            {   
                Title = "Frank Lideros"
                Body = body context
            }
    
    //***Pages***
    let HomePage =
        SkinWithTemplate <| fun ctx ->
            [                
                Div [new WBViewer()]
            ]

[<Sealed>]
type Website() =
    interface IWebsite<Action> with
        member this.Actions = [ Action.Home ]
        member this.Sitelet = Sitelet.Content "/" Action.Home SiteContent.HomePage

type Global() =
    inherit System.Web.HttpApplication()

    member g.Application_Start(sender: obj, args: System.EventArgs) =
        ()

[<assembly: Website(typeof<Website>)>]
do ()
By on 7/17/2014 4:45 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper