F# Set a property on ViewBag dynamic object (passing an image) - asp.net-mvc

I tried to use the solution that Tomas Petricek wrote on this website but not for a string but for an image. Unfortunately, it doesn't work. This is my code:
Model:
let ChartModelCumulativePerformance =
let numMths = 60
let trackOfDates numMths = firstDate.AddMonths(numMths)
let trackHF = [for x in 0 .. 59 ->(trackOfDates x, HFReturns.[x])]
let trackBchk = [for x in 0 .. 59 ->(trackOfDates x, BchkReturns.[x])]
Chart.Line(trackHF,Name="Hedge Fund") |> ignore
Chart.Line(trackBchk,Name="Benchmark") |> ignore
let myChart = Chart.Combine(
[Chart.Line(trackHF,Name="Hedge Fund")
Chart.Line(trackBchk,Name="Benchmark")])
myChart.CopyAsBitmap()
member this.CreateCumulativePerformanceGraph() = ChartModelCumulativePerformance
Controller:
let dataChart = res.CreateCumulativePerformanceGraph()
let (?<-) (viewData:ViewDataDictionary) (name:string) (value: Image) = viewData.Add(name, value)
this.ViewData?chartCumulative <- dataChart
this.View("HFAnalysis") :> ActionResult
View
<img src =#ViewBag.chartCumulative height="80" width="80"/ alt="" />
or
<img src =#ViewData["chartCumulative"] height="80" width="80"/ alt="" />
Otherwise, do you know another methodologies? Thank in advance for your help

Ultimately you've got an HTML problem, not an F# problem here.
If you want to put image data directly into the src attribute of an img tag, you have to convert it to a base-64 string and then prefix it with the appropriate meta-data according to the Data URI standard.
I would convert your bitmap to a PNG (to shrink the file size) and then get a byte array for the image and pass it to Convert.ToBase64String. Ultimately you'll end up with something like this:
<img width="80" height="80" src="data:image/png;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" />

Many thanks Joel !!!!
This is the code for those who would be interested:
Model:
let ChartModelCumulativePerformance =
//... code for building a Chart
let myChart = myChart.CopyAsBitmap()
let ms = new MemoryStream()
let tempVar = myChart.Save(ms,Imaging.ImageFormat.Png)
let imageData = ms.ToArray()
let imageBase64 = Convert.ToBase64String(imageData)
String.Format("data:image/png;base64,{0}", imageBase64)
Controller:
let dataChart = res.CreateCumulativePerformanceGraph()
let (?<-) (viewData:ViewDataDictionary) (name:string) (value: String) = viewData.Add(name, value)
this.ViewData?chartCumulative <- dataChart
this.View("HFAnalysis") :> ActionResult
View:

Related

Incomplete structured construct

i am new with f# , will be great if some 1 can help , nearly half a day gone solving this problem Thank you
module Certificate =
type T = {
Id: int
IsECert: bool
IsPrintCert: bool
CertifiedBy: string
Categories: Category.T list
}
let createPending now toZonedDateTime toBeCertifiedByName (job: Models.Job.T) (certificateType: Models.CertificateType.T) (pendingCertificate: Models.PendingCertificate.T) visualization (categories: Category.T list) =
let forCompletion = Models.PendingCertificate.getCertificateForCompletion pendingCertificate
{
Id = forCompletion.Id |> CertificateId.toInt
IsECert = Models.PendingCertificate.isECertificate pendingCertificate
IsPrintCert = Models.PendingCertificate.isPrintCertificate pendingCertificate
CertifiedBy = toBeCertifiedByName
Categories = categories}
i am getting an error in "Incomplete structured construct at or before this point"
Your formatting is all off. I will assume here that this is just a result of posting to StackOverflow, and your actual code is well indented.
The error comes from the definition of createPending: this function does not have a result. All its body consists of defining a forCompletion value, but there is nothing after it. Here's a simpler example that has the same problem:
let f x =
let y = 5
This function will produce the same error, because it also doesn't have a result. In F#, every function has to return something. The body cannot contain only definitions of helper functions or values. For example, I could fix my broken function above like this:
let f x =
let y = 5
x + y
This function first defines a helper value y, then adds it to its argument x, and returns the result.
> f 2
> 7
>
> f 0
> 5
How exactly you need to fix your function depends on what exactly you want it to mean. I can't help you here, because you haven't provided that information.

Convert Xml String with node prefixes to XElement

This is my xml string
string fromHeader= "<a:From><a:Address>http://ex1.example.org/</a:Address></a:From>";
I want to load it into an XElement, but doing XElement.Parse(fromHeader) gives me an error due to the 'a' prefixes. I tried the following:
XNamespace xNSa = "http://www.w3.org/2005/08/addressing";
string dummyRoot = "<root xmlns:a=\"{0}\">{1}</root>";
var fromXmlStr = string.Format(dummyRoot, xNSa, fromHeader);
XElement xFrom = XElement.Parse(fromXmlStr).Elements().First();
which works, but seriously, do i need 4 lines of code to do this! What is a quickest / shortest way of getting my XElement?
I found out the above 4 lines are equivalent to
XNamespace xNSa = "http://www.w3.org/2005/08/addressing";
XElement xFrom = new XElement(xNSa + "From", new XElement(xNSa + "Address", "http://ex1.example.org/"));
OR ALTERNATIVELY move the NS into the 'From' element before parsing.
var fromStr = "<a:From xmlns:a=\"http://www.w3.org/2005/08/addressing\"><a:Address>http://ex1.example.org/</a:Address></a:From>";
XElement xFrom = XElement.Parse(fromStr);

Flex SDK: how to assign tabs to a Spark RichtText with TextLayoutFramework

I'm experimenting with the TextLayoutFramework to try to use tabs. Based on some examples this should work, but doesn't...
Any ideas why the txt is shown as follows with spaces instead of linebreaks or tabs?
111111 222222 33333 44444 55555 66666 77777
This is the code used:
<fx:Script>
<![CDATA[
import flash.text.engine.TabAlignment;
import flashx.textLayout.conversion.TextConverter;
import flashx.textLayout.formats.TabStopFormat;
import flashx.textLayout.formats.TextLayoutFormat;
private function setText() : void
{
// Test content
var txt : String = "<p><span>111111\n222222\t33333\t44444\t55555\n66666\t77777</span></p>";
var xml : XML = new XML("<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'>" + txt + "</TextFlow>");
// Define three tab positions
var tabStop1:TabStopFormat = new TabStopFormat();
tabStop1.alignment = TabAlignment.START;
tabStop1.position = 50;
var tabStop2:TabStopFormat = new TabStopFormat();
tabStop2.alignment = TabAlignment.CENTER;
tabStop2.position = 150;
var tabStop3:TabStopFormat = new TabStopFormat();
tabStop3.alignment = TabAlignment.END;
tabStop3.position = 250;
// Define the formatter
var format:TextLayoutFormat = new TextLayoutFormat();
format.tabStops = new Array(tabStop1, tabStop2, tabStop3);
// Put the text in the textbox
txtBox.textFlow = TextConverter.importToFlow(xml, TextConverter.TEXT_LAYOUT_FORMAT);
// Assign the formatter to the textbox
txtBox.textFlow.format = format;
}
]]>
</fx:Script>
<s:RichText id="txtBox" top="25" left="25" width="400" height="200" />
With help from the Apache Flex user group, this is the easiest way to achieve this, with a lot less code!!!
var txt : String = "11111\n222222222222222\t333\t44444444\t555555\n66666\t77777777\t88\t99999\naaaa\tbbbbbbbb\tcccccccc\tddd";
txtBox.text = txt;
txtBox.setStyle("tabStops", "e200 c250 s300");
<s:RichText id="txtBox" top="25" left="25" width="600" height="200" />
See: http://apache-flex-users.2333346.n4.nabble.com/How-to-assign-tabs-to-a-Spark-RichtText-with-TextLayoutFramework-td11883.html

F# Excel Range.AutoFilter() fails

I'm trying to turn on AutoFilter for the users who will consume the data.
open Microsoft.Office.Interop.Excel
let xl = ApplicationClass()
xl.Workbooks.OpenText(fileName...)
let wb = xl.Workbooks.Item(1)
let ws = wb.ActiveSheet :?> Worksheet
let rows = string ws.UsedRange.Rows.Count
// AutoFilter method of Range class failed.
ws.Range("A7:I" + rows).AutoFilter() |> ignore
Thanks for any help you can offer.
According to the documentation, you need to pass 5 parameters to AutoFilter.
Unspecified parameters can be filled by System.Reflection.Missing.Value.
Something like
ws.Range("A7:I" + rows).AutoFilter(1, System.Reflection.Missing.Value,
Excel.XlAutoFilterOperator.xlAnd,
System.Reflection.Missing.Value, true)
|> ignore
should work.

How do I create a multi-level TreeView using F#?

I would like to display a directory structure using Gtk# widgets through F#, but I'm having a hard time figuring out how to translate TreeViews into F#. Say I had a directory structure that looks like this:
Directory1
SubDirectory1
SubDirectory2
SubSubDirectory1
SubDirectory3
Directory2
How would I show this tree structure with Gtk# widgets using F#?
EDIT:
gradbot's was the answer I was hoping for with a couple of exceptions. If you use ListStore, you loose the ability to expand levels, if you instead use :
let musicListStore = new Gtk.TreeStore([|typeof<String>; typeof<String>|])
you get a layout with expandable levels. Doing this, however, breaks the calls to AppendValues so you have to add some clues for the compiler to figure out which overloaded method to use:
musicListStore.AppendValues (iter, [|"Fannypack" ; "Nu Nu (Yeah Yeah) (double j and haze radio edit)"|])
Note that the columns are explicitly passed as an array.
Finally, you can nest levels even further by using the ListIter returned by Append Values
let iter = musicListStore.AppendValues ("Dance")
let subiter = musicListStore.AppendValues (iter, [|"Fannypack" ; "Nu Nu (Yeah Yeah) (double j and haze radio edit)"|])
musicListStore.AppendValues (subiter, [|"Some Dude"; "Some Song"|]) |> ignore
I'm not exactly sure what you're looking for but here is a translated example from their tutorials. It may help you get started. Image taken from tutorial site.
I think the key to a multi-level tree view is to append values to values, iter in this line musicListStore.AppendValues (iter, "Fannypack", "Nu Nu (Yeah Yeah) (double j and haze radio edit)") |> ignore
// you will need to add these references gtk-sharp, gtk-sharp, glib-sharp
// and set the projects running directory to
// C:\Program Files (x86)\GtkSharp\2.12\bin\
module SOQuestion
open Gtk
open System
let main() =
Gtk.Application.Init()
// Create a Window
let window = new Gtk.Window("TreeView Example")
window.SetSizeRequest(500, 200)
// Create our TreeView
let tree = new Gtk.TreeView()
// Add our tree to the window
window.Add(tree)
// Create a column for the artist name
let artistColumn = new Gtk.TreeViewColumn()
artistColumn.Title <- "Artist"
// Create the text cell that will display the artist name
let artistNameCell = new Gtk.CellRendererText()
// Add the cell to the column
artistColumn.PackStart(artistNameCell, true)
// Create a column for the song title
let songColumn = new Gtk.TreeViewColumn()
songColumn.Title <- "Song Title"
// Do the same for the song title column
let songTitleCell = new Gtk.CellRendererText()
songColumn.PackStart(songTitleCell, true)
// Add the columns to the TreeView
tree.AppendColumn(artistColumn) |> ignore
tree.AppendColumn(songColumn) |> ignore
// Tell the Cell Renderers which items in the model to display
artistColumn.AddAttribute(artistNameCell, "text", 0)
songColumn.AddAttribute(songTitleCell, "text", 1)
let musicListStore = new Gtk.ListStore([|typeof<String>; typeof<String>|])
let iter = musicListStore.AppendValues ("Dance")
musicListStore.AppendValues (iter, "Fannypack", "Nu Nu (Yeah Yeah) (double j and haze radio edit)") |> ignore
let iter = musicListStore.AppendValues ("Hip-hop")
musicListStore.AppendValues (iter, "Nelly", "Country Grammer") |> ignore
// Assign the model to the TreeView
tree.Model <- musicListStore
// Show the window and everything on it
window.ShowAll()
// add event handler so Gtk will exit
window.DeleteEvent.Add(fun _ -> Gtk.Application.Quit())
Gtk.Application.Run()
[<STAThread>]
main()

Resources