Google Line Chart
This example shows how to create scatter (point) charts and line charts using the
XPlot.GoogleCharts
library.
To create a line chart, use Chart.Line
. To create a scatter (point) chart, use
Chart.Scatter
. In both cases, you can also combine multiple charts in the same
chart area, simply by calling the functions with a list of lists (rather
than with just a plan list of key value pairs)
The following example calls Chart.Line
with a list of key value pairs, created
using a simple F# list comprehension:
open XPlot.GoogleCharts
let chart1 = Chart.Line [ for x in 0. .. 0.5 .. 6.3 -> x, sin x ]
Google Chart
By default, line charts use straight line segments between the points. You can add
smoothing by creating Options
with curveType="function"
as follows:
let chart2 =
[ for x in 0. .. 0.5 .. 6.3 -> x, sin x ]
|> Chart.Line
|> Chart.WithOptions(Options(curveType = "function"))
Google Chart
You can find more information about other options that you can specify in the documentation
for the Options
type in the API
reference. Another way to explore the available configuration options is to type dot right
after the value, i.e. Options().
- and see what fields (lower-case, at the end of the list)
are available.
Finally, you can also pass multiple series of values to both point and line charts. This creates
a chart that shows multiple data sets using a different line or point color for each data set.
The following example plots sales and expenses of some non-existent company in a single line
chart with annotations:
let sales = [("2013", 1000); ("2014", 1170); ("2015", 660); ("2016", 1030)]
let expenses = [("2013", 400); ("2014", 460); ("2015", 1120); ("2016", 540)]
let options =
Options
( title = "Company Performance", curveType = "function",
legend = Legend(position = "bottom") )
let chart3 =
[sales; expenses]
|> Chart.Line
|> Chart.WithOptions options
|> Chart.WithLabels ["Sales"; "Expenses"]
Google Chart
Note that the two inputs are sequences of tuples with X (year) and Y (value) pairs. We then
create Options
object to specify the title, smooth curve and also the legend of the chart.
Then we call Chart.Line
followed by Chart.WithOptions
and also Chart.WithLabels
to
provide labels for the two series.
*)
(*
Create a line chart with two different Y-axes (the example above has two lines plotted by only a single Y-axis).
Plot values of different data types
Based off of this sample: https://developers.google.com/chart/interactive/docs/gallery/linechart#dual-y-charts
open System
//Make up some fake data. Two sets of values for the same sequence of dates
let values1 = [1..7]
let values2 = [20.1..10.3..90.0] //using floats here to demonstrate that we can use a different data type on the second Y axis
let dates = [ for i in [6.0..(-1.0)..0.0] -> DateTime.Today.AddDays(-i) ]
let first = Deedle.Series(dates, values1)
let second = Deedle.Series(dates, values2)
let df = Deedle.Frame(["IntVals"; "FloatVals"], [first; second])
let dfOptions =
Options
( title = "Value 1 & Value 2 by Date",
legend = Legend(position = "bottom") ,
series = [|Series("IntVals", targetAxisIndex = 0); Series("FloatVals", targetAxisIndex = 1)|],
vAxes = [|Axis(title = "Foo"); Axis(title = "Bar")|])
let chart4 =
df
|> Chart.Line
|> Chart.WithOptions dfOptions
Google Chart
namespace XPlot
namespace XPlot.GoogleCharts
val chart1 : GoogleChart
type Chart =
static member Annotation : data:seq<DateTime * #value * string * string> * ?Labels:seq<string> * ?Options:Options -> GoogleChart + 1 overload
static member Area : data:seq<#value> * ?Labels:seq<string> * ?Options:Options -> GoogleChart + 2 overloads
static member Bar : data:seq<#value> * ?Labels:seq<string> * ?Options:Options -> GoogleChart + 2 overloads
static member Bubble : data:seq<string * #value * #value> * ?Labels:seq<string> * ?Options:Options -> GoogleChart + 2 overloads
static member Calendar : data:seq<DateTime * #value> * ?Labels:seq<string> * ?Options:Options -> GoogleChart
static member Candlestick : data:seq<#key * #value * #value * #value * #value> * ?Labels:seq<string> * ?Options:Options -> GoogleChart + 1 overload
static member Column : data:seq<#value> * ?Labels:seq<string> * ?Options:Options -> GoogleChart + 2 overloads
static member Combo : data:seq<#seq<'K * 'V>> * ?Labels:seq<string> * ?Options:Options -> GoogleChart (requires 'K :> key and 'V :> value)
static member private Create : data:seq<#seq<'T>> -> labels:seq<string> option -> options:Options option -> chartType:ChartGallery -> datumNew:('T -> Datum) -> GoogleChart
static member private Create' : data:seq<#value> -> labels:seq<string> option -> options:Options option -> chartType:ChartGallery -> GoogleChart
...
static member Chart.Line : data:Deedle.Frame<'K,'V> * ?Options:Options -> GoogleChart (requires equality and equality)
static member Chart.Line : data:Deedle.Series<'K,#value> * ?Labels:seq<string> * ?Options:Options -> GoogleChart (requires equality and 'K :> key)
static member Chart.Line : data:seq<Deedle.Series<'K,#value>> * ?Labels:seq<string> * ?Options:Options -> GoogleChart (requires equality and 'K :> key)
static member Chart.Line : data:seq<#seq<'K * 'V>> * ?Labels:seq<string> * ?Options:Options -> GoogleChart (requires 'K :> key and 'V :> value)
static member Chart.Line : data:seq<#key * #value> * ?Labels:seq<string> * ?Options:Options -> GoogleChart
static member Chart.Line : data:seq<#value> * ?Labels:seq<string> * ?Options:Options -> GoogleChart
val x : float
val sin : value:'T -> 'T (requires member Sin)
member GoogleChart.GetHtml : unit -> string
val chart2 : GoogleChart
static member Chart.WithOptions : options:Options -> chart:GoogleChart -> GoogleChart
Multiple items
type Options =
new : unit -> Options
member ShouldSerializeaggregationTarget : unit -> bool
member ShouldSerializeallValuesSuffix : unit -> bool
member ShouldSerializeallowHtml : unit -> bool
member ShouldSerializealternatingRowStyle : unit -> bool
member ShouldSerializeanimation : unit -> bool
member ShouldSerializeannotations : unit -> bool
member ShouldSerializeannotationsWidth : unit -> bool
member ShouldSerializeareaOpacity : unit -> bool
member ShouldSerializeavoidOverlappingGridLines : unit -> bool
...
--------------------
new : unit -> Options
val sales : (string * int) list
val expenses : (string * int) list
val options : Options
Multiple items
type Legend =
new : unit -> Legend
member ShouldSerializealignment : unit -> bool
member ShouldSerializemaxLines : unit -> bool
member ShouldSerializenumberFormat : unit -> bool
member ShouldSerializeposition : unit -> bool
member ShouldSerializetextStyle : unit -> bool
member alignment : string
member maxLines : int
member numberFormat : string
member position : string
...
--------------------
new : unit -> Legend
val chart3 : GoogleChart
static member Chart.WithLabels : labels:seq<string> -> chart:GoogleChart -> GoogleChart
namespace System
val values1 : int list
val values2 : float list
val dates : DateTime list
val i : float
Multiple items
[<Struct>]
type DateTime =
new : year: int * month: int * day: int -> unit + 10 overloads
member Add : value: TimeSpan -> DateTime
member AddDays : value: float -> DateTime
member AddHours : value: float -> DateTime
member AddMilliseconds : value: float -> DateTime
member AddMinutes : value: float -> DateTime
member AddMonths : months: int -> DateTime
member AddSeconds : value: float -> DateTime
member AddTicks : value: int64 -> DateTime
member AddYears : value: int -> DateTime
...
--------------------
DateTime ()
(+0 other overloads)
DateTime(ticks: int64) : DateTime
(+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : DateTime
(+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : DateTime
(+0 other overloads)
property DateTime.Today: DateTime with get
DateTime.AddDays(value: float) : DateTime
val first : Deedle.Series<DateTime,int>
Multiple items
module Deedle
from XPlot.GoogleCharts
--------------------
namespace Deedle
Multiple items
module Series
from Deedle
--------------------
type Series<'K,'V (requires equality)> =
interface IFsiFormattable
interface ISeries<'K>
new : index:IIndex<'K> * vector:IVector<'V> * vectorBuilder:IVectorBuilder * indexBuilder:IIndexBuilder -> Series<'K,'V> + 3 overloads
member After : lowerExclusive:'K -> Series<'K,'V>
member Aggregate : aggregation:Aggregation<'K> * keySelector:Func<DataSegment<Series<'K,'V>>,'TNewKey> * valueSelector:Func<DataSegment<Series<'K,'V>>,OptionalValue<'R>> -> Series<'TNewKey,'R> (requires equality) + 1 overload
member AsyncMaterialize : unit -> Async<Series<'K,'V>>
member Before : upperExclusive:'K -> Series<'K,'V>
member Between : lowerInclusive:'K * upperInclusive:'K -> Series<'K,'V>
member Compare : another:Series<'K,'V> -> Series<'K,Diff<'V>>
member Convert : forward:Func<'V,'R> * backward:Func<'R,'V> -> Series<'K,'R>
...
--------------------
new : pairs:seq<Collections.Generic.KeyValuePair<'K,'V>> -> Deedle.Series<'K,'V>
new : keys:seq<'K> * values:seq<'V> -> Deedle.Series<'K,'V>
new : keys:'K [] * values:'V [] -> Deedle.Series<'K,'V>
new : index:Deedle.Indices.IIndex<'K> * vector:Deedle.IVector<'V> * vectorBuilder:Deedle.Vectors.IVectorBuilder * indexBuilder:Deedle.Indices.IIndexBuilder -> Deedle.Series<'K,'V>
val second : Deedle.Series<DateTime,float>
val df : Deedle.Frame<DateTime,string>
Multiple items
module Frame
from Deedle
--------------------
type Frame =
static member ReadCsv : location:string * hasHeaders:Nullable<bool> * inferTypes:Nullable<bool> * inferRows:Nullable<int> * schema:string * separators:string * culture:string * maxRows:Nullable<int> * missingValues:string [] * preferOptions:bool -> Frame<int,string> + 1 overload
static member ReadReader : reader:IDataReader -> Frame<int,string>
static member CustomExpanders : Dictionary<Type,Func<obj,seq<string * Type * obj>>>
static member NonExpandableInterfaces : ResizeArray<Type>
static member NonExpandableTypes : HashSet<Type>
--------------------
type Frame<'TRowKey,'TColumnKey (requires equality and equality)> =
interface IDynamicMetaObjectProvider
interface INotifyCollectionChanged
interface IFsiFormattable
interface IFrame
new : rowIndex:IIndex<'TRowKey> * columnIndex:IIndex<'TColumnKey> * data:IVector<IVector> * indexBuilder:IIndexBuilder * vectorBuilder:IVectorBuilder -> Frame<'TRowKey,'TColumnKey> + 1 overload
member AddColumn : column:'TColumnKey * series:seq<'V> -> unit + 3 overloads
member AggregateRowsBy : groupBy:seq<'TColumnKey> * aggBy:seq<'TColumnKey> * aggFunc:Func<Series<'TRowKey,'a>,'b> -> Frame<int,'TColumnKey>
member Clone : unit -> Frame<'TRowKey,'TColumnKey>
member ColumnApply : f:Func<Series<'TRowKey,'T>,ISeries<'TRowKey>> -> Frame<'TRowKey,'TColumnKey> + 1 overload
member DropColumn : column:'TColumnKey -> unit
...
--------------------
new : names:seq<'TColumnKey> * columns:seq<Deedle.ISeries<'TRowKey>> -> Deedle.Frame<'TRowKey,'TColumnKey>
new : rowIndex:Deedle.Indices.IIndex<'TRowKey> * columnIndex:Deedle.Indices.IIndex<'TColumnKey> * data:Deedle.IVector<Deedle.IVector> * indexBuilder:Deedle.Indices.IIndexBuilder * vectorBuilder:Deedle.Vectors.IVectorBuilder -> Deedle.Frame<'TRowKey,'TColumnKey>
val dfOptions : Options
Multiple items
type Series =
new : ?type:string -> Series
member ShouldSerializeannotations : unit -> bool
member ShouldSerializeareaOpacity : unit -> bool
member ShouldSerializecolor : unit -> bool
member ShouldSerializecurveType : unit -> bool
member ShouldSerializefallingColor : unit -> bool
member ShouldSerializelineWidth : unit -> bool
member ShouldSerializepointShape : unit -> bool
member ShouldSerializepointSize : unit -> bool
member ShouldSerializerisingColor : unit -> bool
...
--------------------
new : ?type:string -> Series
Multiple items
type Axis =
new : unit -> Axis
member ShouldSerializeallowContainerBoundaryTextCufoff : unit -> bool
member ShouldSerializebaseline : unit -> bool
member ShouldSerializebaselineColor : unit -> bool
member ShouldSerializedirection : unit -> bool
member ShouldSerializeformat : unit -> bool
member ShouldSerializegridlines : unit -> bool
member ShouldSerializelogScale : unit -> bool
member ShouldSerializemaxAlternation : unit -> bool
member ShouldSerializemaxTextLines : unit -> bool
...
--------------------
new : unit -> Axis
val chart4 : GoogleChart