Skip to content

#120 Add layout slider #232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Plotly.NET.sln
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{7B09CC0A-F
docs\02_6_table.fsx = docs\02_6_table.fsx
docs\02_7_heatmaps.fsx = docs\02_7_heatmaps.fsx
docs\02_8_Images.fsx = docs\02_8_Images.fsx
docs\02_9_Sliders.fsx = docs\02_9_Sliders.fsx
docs\03_0_3d-scatter-plots.fsx = docs\03_0_3d-scatter-plots.fsx
docs\03_1_3d-surface-plots.fsx = docs\03_1_3d-surface-plots.fsx
docs\03_2_3d-mesh-plots.fsx = docs\03_2_3d-mesh-plots.fsx
Expand Down
111 changes: 111 additions & 0 deletions docs/02_9_Sliders.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
(**
---
title: Sliders
category: Simple Charts
categoryindex: 3
index: 10
---
*)

(*** hide ***)

(*** condition: prepare ***)
#r "nuget: Newtonsoft.JSON, 12.0.3"
#r "nuget: DynamicObj"
#r "../bin/Plotly.NET/netstandard2.0/Plotly.NET.dll"

(*** condition: ipynb ***)
#if IPYNB
#r "nuget: Plotly.NET, {{fsdocs-package-version}}"
#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}"
#endif // IPYNB

(**
# Sliders

[![Binder]({{root}}img/badge-binder.svg)](https://mybinder.org/v2/gh/plotly/Plotly.NET/gh-pages?filepath={{fsdocs-source-basename}}.ipynb) 
[![Script]({{root}}img/badge-script.svg)]({{root}}{{fsdocs-source-basename}}.fsx) 
[![Notebook]({{root}}img/badge-notebook.svg)]({{root}}{{fsdocs-source-basename}}.ipynb)

*Summary:* This example shows how to create charts with sliders in F#.

The sliders give the option of passing the arguments to the Plotly chart. In the example we use the visibility parameter to make the step chosen in the slider visible.

The original exapmle is made with python and can be found [here](https://plotly.com/python/sliders)
*)

open Plotly.NET
open Plotly.NET.LayoutObjects

/// Similar to numpy.arrange
let nparange (start: double) (stop:double) (step: double) =
let stepsCount = ((stop-start) / step) |> int
seq { for i in 0 .. stepsCount -> start + double(i) * step }
|> Array.ofSeq

let steps = nparange 0. 5. 0.1
let scattersChart =
steps
|> Seq.map
(fun step ->
// Create a scatter plot for every step
let x = nparange 0. 10. 0.01
let y = seq { for x_ in x -> sin(step * x_) }
// Some plot must be visible here or the chart is empty at the beginning
let chartVisibility = if step = 0. then StyleParam.Visible.True else StyleParam.Visible.False;
let go =
Chart2D.Chart.Scatter
(
x=x, y=y,
mode=StyleParam.Mode.Lines,
Name="v = " + string(step),
Color=Color.fromHex("#00CED1"),
Width=6.
)
|> Chart.withTraceName(Visible=chartVisibility)
go
)
|> GenericChart.combine

let sliderSteps =
steps |>
Seq.indexed |>
Seq.map
(fun (i, step) ->
// Create a visibility and a title parameters
// The visibility parameter includes an array where every parameter
// is mapped onto the trace visibility
let visible =
// Set true only for the current step
(fun index -> index=i)
|> Array.init steps.Length
|> box
let title =
sprintf "Slider switched to step: %f" step
|> box
SliderStep.init(
Args = ["visible", visible; "title", title],
Method = StyleParam.Method.Update,
Label="v = " + string(step)
)
)

let slider =
Slider.init(
CurrentValue=SliderCurrentValue.init(Prefix="Frequency: "),
Padding=Padding.init(T=50),
Steps=sliderSteps
)

let chart =
scattersChart
|> Chart.withSlider slider

(*** condition: ipynb ***)
#if IPYNB
chart
#endif // IPYNB

(***hide***)
chart |> GenericChart.toChartHTML
(***include-it-raw***)
12 changes: 11 additions & 1 deletion src/Plotly.NET/CSharpLayer/GenericChartExtensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -714,4 +714,14 @@ module GenericChartExtensions =
[<CompiledName("WithLayoutImages")>]
[<Extension>]
member this.WithLayoutImages(images:seq<LayoutImage>, [<Optional;DefaultParameterValue(true)>]?Append:bool) =
this |> Chart.withLayoutImages(images, ?Append = Append)
this |> Chart.withLayoutImages(images, ?Append = Append)

[<CompiledName("WithSlider")>]
[<Extension>]
member this.WithSlider(slider:Slider) =
this |> Chart.withSlider(slider)

[<CompiledName("WithSliders")>]
[<Extension>]
member this.WithSliders(sliders:seq<Slider>) =
this |> Chart.withSliders sliders
21 changes: 19 additions & 2 deletions src/Plotly.NET/ChartAPI/Chart.fs
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ type Chart =
)
let updatedLayout = layout |> Layout.SetLayoutGrid updatedGrid
GenericChart.setLayout updatedLayout ch)

[<CompiledName("WithConfig")>]
static member withConfig (config:Config) =
(fun (ch:GenericChart) ->
Expand Down Expand Up @@ -1710,4 +1710,21 @@ type Chart =
[<Optional;DefaultParameterValue(true)>] ?Append: bool
) =

Chart.withLayoutImages([image], ?Append = Append)
Chart.withLayoutImages([image], ?Append = Append)

[<CompiledName("WithSliders")>]
static member withSliders
(
sliders:seq<Slider>
) =
fun (ch:GenericChart) ->
ch
|> GenericChart.mapLayout
(Layout.style (Sliders = sliders))

[<CompiledName("WithSlider")>]
static member withSlider
(
slider:Slider
) =
Chart.withSliders([slider])
26 changes: 25 additions & 1 deletion src/Plotly.NET/CommonAbstractions/StyleParams.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1401,6 +1401,25 @@ module StyleParam =
//--------------------------
// #M#
//--------------------------

[<RequireQualifiedAccess>]
type Method =
| Restyle
| Relayout
| Animate
| Update
| Skip

static member toString = function
| Restyle -> "restyle"
| Relayout -> "relayout"
| Animate -> "animate"
| Update -> "update"
| Skip -> "skip"

static member convert = Method.toString >> box
override this.ToString() = this |> Method.toString
member this.Convert() = this |> Method.convert

[<RequireQualifiedAccess>]
type ModeBarButton =
Expand Down Expand Up @@ -2676,12 +2695,17 @@ module StyleParam =
type Visible =
| True | False | LegendOnly

static member toObject = function
| True -> box(true)
| False -> box(false)
| LegendOnly -> box("legendonly")

static member toString = function
| True -> "true"
| False -> "false"
| LegendOnly -> "legendonly"

static member convert = Visible.toString >> box
static member convert = Visible.toObject >> box
override this.ToString() = this |> Visible.toString
member this.Convert() = this |> Visible.convert

Expand Down
10 changes: 7 additions & 3 deletions src/Plotly.NET/Layout/Layout.fs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ type Layout() =
[<Optional;DefaultParameterValue(null)>] ?IcicleColorWay : Color,
[<Optional;DefaultParameterValue(null)>] ?Annotations : seq<Annotation>,
[<Optional;DefaultParameterValue(null)>] ?Shapes : seq<Shape>,
[<Optional;DefaultParameterValue(null)>] ?Images : seq<LayoutImage>
[<Optional;DefaultParameterValue(null)>] ?Images : seq<LayoutImage>,
[<Optional;DefaultParameterValue(null)>] ?Sliders : seq<Slider>
) =
Layout()
|> Layout.style
Expand Down Expand Up @@ -147,7 +148,8 @@ type Layout() =
?IcicleColorWay = IcicleColorWay ,
?Annotations = Annotations ,
?Shapes = Shapes ,
?Images = Images
?Images = Images ,
?Sliders = Sliders
)

// Applies the styles to Layout()
Expand Down Expand Up @@ -218,7 +220,8 @@ type Layout() =
[<Optional;DefaultParameterValue(null)>] ?IcicleColorWay : Color,
[<Optional;DefaultParameterValue(null)>] ?Annotations : seq<Annotation>,
[<Optional;DefaultParameterValue(null)>] ?Shapes : seq<Shape>,
[<Optional;DefaultParameterValue(null)>] ?Images : seq<LayoutImage>
[<Optional;DefaultParameterValue(null)>] ?Images : seq<LayoutImage>,
[<Optional;DefaultParameterValue(null)>] ?Sliders : seq<Slider>
) =
(fun (layout:Layout) ->

Expand Down Expand Up @@ -288,6 +291,7 @@ type Layout() =
Annotations |> DynObj.setValueOpt layout "annotations"
Shapes |> DynObj.setValueOpt layout "shapes"
Images |> DynObj.setValueOpt layout "images"
Sliders |> DynObj.setValueOpt layout "sliders"

layout
)
Expand Down
34 changes: 34 additions & 0 deletions src/Plotly.NET/Layout/ObjectAbstractions/Common/Padding.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace Plotly.NET.LayoutObjects

open DynamicObj

type Padding() =
inherit DynamicObj ()

/// <summary>
/// Set the padding of the slider component along each side
/// </summary>
/// <param name="B">The amount of padding (in px) along the bottom of the component</param>
/// <param name="L">The amount of padding (in px) on the left side of the component</param>
/// <param name="R">The amount of padding (in px) on the right side of the component</param>
/// <param name="T">The amount of padding (in px) along the top of the component</param>
static member init
(
?B : int,
?L : int,
?R : int,
?T : int
) = Padding() |> Padding.style
(
?B=B,
?L=L,
?R=R,
?T=T
)

static member style(?B : int, ?L : int, ?R : int, ?T : int) = (fun (padding : Padding) ->
B |> DynObj.setValueOpt padding "b"
L |> DynObj.setValueOpt padding "l"
R |> DynObj.setValueOpt padding "r"
T |> DynObj.setValueOpt padding "t"
padding)
Loading