the wpf build of the silverlight charting toolkit has recently been released:
Delay's Blog


using jafar husain's excellent tutorial on creating a custom chart series:
Writing Your Own Silverlight Chart Series (Part 1): Making Designers Happy
and
Writing Your Own Silverlight Chart Series (Part 2): Implementing the Series

i was able to create a function series in f#:

fun x -> [3.0..2.0..49.0] |> List.fold (fun a b -> a + Math.Sin(b * x) / b) (Math.Sin x)



#light

namespace Charts

open System
open System.Windows
open System.Windows.Media
open System.Windows.Markup
open System.Windows.Shapes
open System.Windows.Controls
open System.Windows.Controls.DataVisualization
open System.Windows.Controls.DataVisualization.Charting

module Seq =
   let of_type<'a> (s : System.Collections.IEnumerable) =
      seq {
         for item in s do
            match item with
            | :? 'a as item -> yield item
            | _ -> ()
      }  
   let range (s : 'a seq) =
      if Seq.isEmpty s then None else
      s |> Seq.fold
         (fun (min, max) a ->
            let max = if a > max then a else max
            let min = if a < min then a else min
            (min, max)
         ) (Seq.hd s, Seq.hd s) |> Some

   let (|Range|_|) (range : 'a Range) =
      if range.HasData then Range (range.Minimum, range.Maximum) |> Some else None


type public FunctionSeries(?fx : float -> float) as this =
   inherit Series()
   
   [<DefaultValue>]
   static val mutable public PointsProperty : DependencyProperty
   static do FunctionSeries.PointsProperty <- DependencyProperty.Register("Points", typeof<PointCollection>, typeof<FunctionSeries>)

   let mutable itemSource : System.Collections.IEnumerable = null
   let mutable plotArea : Canvas = null
   let mutable (xaxis : IAxis), (yaxis : IRangeAxis) = null, null
   let mutable range = Range(-1.0, 1.0)
   let mutable f = fun x -> x
   let calculateItems () =
      let detail = 600.0
      match range with
      | Seq.Range (min, max) ->
         [0.0..detail]
            |> List.map (fun x -> x * ((max - min) / detail) + min)
            |> Seq.map (fun x -> Point(x, f x))
      | _ -> Seq.empty

   do
      match fx with | Some fx -> f <- fx | None -> ()
      itemSource <- calculateItems()
   
   do
      use stream = (Application.GetResourceStream(Uri("FunctionSeries.xaml", UriKind.RelativeOrAbsolute))).Stream
      this.Style <- (XamlReader.Load(stream) :?> Style)

   override this.Refresh() =
      if xaxis <> null && yaxis <> null then
         this.Points <-
            itemSource |> Seq.of_type<Point>
               |> Seq.map
                  (fun p ->
                     let x = xaxis.GetPlotAreaCoordinate(p.X).Value.Value
                     let y = this.ActualHeight - yaxis.GetPlotAreaCoordinate(p.Y).Value.Value
                     Point(x, y))
               |> Seq.sortBy (fun p -> p.X)        
               |> (fun s -> PointCollection s)
      else ()

   override this.OnApplyTemplate() =
      plotArea <- (this.GetTemplateChild("canvas") :?> Canvas)
      this.Refresh()

   override this.OnSeriesHostPropertyChanged(o, n) =
      let points = itemSource |> Seq.of_type<Point>
      if n <> null && Seq.isEmpty points |> not then  
         let first = Seq.nth 0 points
         xaxis <- n.Axes
            |> Seq.filter (fun a -> a.CanPlot(first.X) && a.Orientation = AxisOrientation.X)
            |> Seq.nth 0
         yaxis <- n.Axes
            |> Seq.of_type<IRangeAxis>
            |> Seq.filter (fun a -> a.CanPlot(first.Y) && a.Orientation = AxisOrientation.Y)
            |> Seq.nth 0

         xaxis.RegisteredListeners.Add(this)
         yaxis.RegisteredListeners.Add(this)
         
   do this.SizeChanged.Add(fun e -> this.Refresh())

   member this.Range
      with set value =
         range <- value
         itemSource <- calculateItems()
      and get () = range
     
   member this.Function
      with set value =
         f <- value
         itemSource <- calculateItems()
      and get () = f

   member this.Points
      with get () = this.GetValue(FunctionSeries.PointsProperty) :?> PointCollection
      and set (value : PointCollection) = this.SetValue(FunctionSeries.PointsProperty, value)

   interface IAxisListener with
      member this.AxisInvalidated(a) = this.Refresh()

   interface IRangeProvider with
      member this.GetRange(consumer : IRangeConsumer ) =
         if obj.ReferenceEquals(consumer, xaxis) then
            let range =
               itemSource
               |> Seq.cast<Point>
               |> Seq.map (fun p -> p.X)
               |> Seq.range
            match range with
               | Some (min, max) -> Range<IComparable>(min, max)
               | None -> Range()
         else if obj.ReferenceEquals(consumer, yaxis) then
            let range =
               itemSource
               |> Seq.cast<Point>
               |> Seq.map (fun p -> p.Y)
               |> Seq.range
            match range with
               | Some (min, max) -> Range<IComparable>(min, max)
               | None -> Range()
               
         else Range<IComparable>()


[<STAThread>]
do
   let window = Window()
   let app = Application()
   let chart = Chart()
   
   //parabola:
   let functionSeries = FunctionSeries(fun x -> x * x)

   //sine wave:
   functionSeries.Function <- fun x -> Math.Sin x
   functionSeries.Range <- Range(-10.0, 10.0)

   //square wave:
   functionSeries.Range <- Range(0.0, 50.0)
   functionSeries.Function <- fun x -> [3.0..2.0..49.0] |> List.fold (fun a b -> a + Math.Sin(b * x) / b) (Math.Sin x)
   window.Width <- 1050.0; window.Height <- 400.0

   chart.Axes.Add(LinearAxis(Orientation = AxisOrientation.X))
   chart.Axes.Add(LinearAxis(Orientation = AxisOrientation.Y))
   chart.Series.Add functionSeries

   window.Content <- chart
   app.Run(window) |> ignore
 




you will also require this xaml file:

<Style
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:Charts;assembly=achart"    
  TargetType="local:FunctionSeries">
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="local:FunctionSeries">
            <Canvas x:Name="canvas">
               <Polyline Points="{TemplateBinding Points}" Stroke="Red" StrokeThickness="1" StrokeMiterLimit="1" />
            </Canvas>
         </ControlTemplate>
      </Setter.Value>  
   </Setter>
</Style>
 

note that you will have to replace "assembly=achart" in the xaml file with the name of your project/assembly.