Skip to content

Commit 4191578

Browse files
author
Artem Makhno
committed
#120 Add layout slider
1 parent 41e1e11 commit 4191578

File tree

15 files changed

+626
-8
lines changed

15 files changed

+626
-8
lines changed

Diff for: Plotly.NET.sln

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{7B09CC0A-F
6161
docs\02_6_table.fsx = docs\02_6_table.fsx
6262
docs\02_7_heatmaps.fsx = docs\02_7_heatmaps.fsx
6363
docs\02_8_Images.fsx = docs\02_8_Images.fsx
64+
docs\02_9_Sliders.fsx = docs\02_9_Sliders.fsx
6465
docs\03_0_3d-scatter-plots.fsx = docs\03_0_3d-scatter-plots.fsx
6566
docs\03_1_3d-surface-plots.fsx = docs\03_1_3d-surface-plots.fsx
6667
docs\03_2_3d-mesh-plots.fsx = docs\03_2_3d-mesh-plots.fsx

Diff for: docs/02_9_Sliders.fsx

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
(**
2+
---
3+
title: Sliders
4+
category: Simple Charts
5+
categoryindex: 3
6+
index: 10
7+
---
8+
*)
9+
10+
(*** hide ***)
11+
12+
(*** condition: prepare ***)
13+
#r "nuget: Newtonsoft.JSON, 12.0.3"
14+
#r "nuget: DynamicObj"
15+
#r "../bin/Plotly.NET/netstandard2.0/Plotly.NET.dll"
16+
17+
(*** condition: ipynb ***)
18+
#if IPYNB
19+
#r "nuget: Plotly.NET, {{fsdocs-package-version}}"
20+
#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}"
21+
#endif // IPYNB
22+
23+
(**
24+
# Sliders
25+
26+
[![Binder]({{root}}img/badge-binder.svg)](https://mybinder.org/v2/gh/plotly/Plotly.NET/gh-pages?filepath={{fsdocs-source-basename}}.ipynb) 
27+
[![Script]({{root}}img/badge-script.svg)]({{root}}{{fsdocs-source-basename}}.fsx) 
28+
[![Notebook]({{root}}img/badge-notebook.svg)]({{root}}{{fsdocs-source-basename}}.ipynb)
29+
30+
*Summary:* This example shows how to create charts with sliders in F#.
31+
32+
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.
33+
34+
The original exapmle is made with python and can be found [here](https://plotly.com/python/sliders)
35+
*)
36+
37+
open Plotly.NET
38+
open Plotly.NET.LayoutObjects
39+
40+
/// Similar to numpy.arrange
41+
let nparange (start: double) (stop:double) (step: double) =
42+
let stepsCount = ((stop-start) / step) |> int
43+
seq { for i in 0 .. stepsCount -> start + double(i) * step }
44+
|> Array.ofSeq
45+
46+
let steps = nparange 0. 5. 0.1
47+
let scattersChart =
48+
steps
49+
|> Seq.map
50+
(fun step ->
51+
// Create a scatter plot for every step
52+
let x = nparange 0. 10. 0.01
53+
let y = seq { for x_ in x -> sin(step * x_) }
54+
// Some plot must be visible here or the chart is empty at the beginning
55+
let chartVisibility = if step = 0. then StyleParam.Visible.True else StyleParam.Visible.False;
56+
let go =
57+
Chart2D.Chart.Scatter
58+
(
59+
x=x, y=y,
60+
mode=StyleParam.Mode.Lines,
61+
Name="v = " + string(step),
62+
Color=Color.fromHex("#00CED1"),
63+
Width=6.
64+
)
65+
|> Chart.withTraceName(Visible=chartVisibility)
66+
go
67+
)
68+
|> GenericChart.combine
69+
70+
let sliderSteps =
71+
steps |>
72+
Seq.indexed |>
73+
Seq.map
74+
(fun (i, step) ->
75+
// Create a visibility and a title parameters
76+
// The visibility parameter includes an array where every parameter
77+
// is mapped onto the trace visibility
78+
let visible =
79+
// Set true only for the current step
80+
(fun index -> index=i)
81+
|> Array.init steps.Length
82+
|> box
83+
let title =
84+
sprintf "Slider switched to step: %f" step
85+
|> box
86+
SliderStep.init(
87+
Args = ["visible", visible; "title", title],
88+
Method = StyleParam.Method.Update,
89+
Label="v = " + string(step)
90+
)
91+
)
92+
93+
let slider =
94+
Slider.init(
95+
CurrentValue=SliderCurrentValue.init(Prefix="Frequency: "),
96+
Padding=Padding.init(T=50),
97+
Steps=sliderSteps
98+
)
99+
100+
let chart =
101+
scattersChart
102+
|> Chart.withSlider slider
103+
104+
(*** condition: ipynb ***)
105+
#if IPYNB
106+
chart
107+
#endif // IPYNB
108+
109+
(***hide***)
110+
chart |> GenericChart.toChartHTML
111+
(***include-it-raw***)

Diff for: src/Plotly.NET/CSharpLayer/GenericChartExtensions.fs

+11-1
Original file line numberDiff line numberDiff line change
@@ -714,4 +714,14 @@ module GenericChartExtensions =
714714
[<CompiledName("WithLayoutImages")>]
715715
[<Extension>]
716716
member this.WithLayoutImages(images:seq<LayoutImage>, [<Optional;DefaultParameterValue(true)>]?Append:bool) =
717-
this |> Chart.withLayoutImages(images, ?Append = Append)
717+
this |> Chart.withLayoutImages(images, ?Append = Append)
718+
719+
[<CompiledName("WithSlider")>]
720+
[<Extension>]
721+
member this.WithSlider(slider:Slider) =
722+
this |> Chart.withSlider(slider)
723+
724+
[<CompiledName("WithSliders")>]
725+
[<Extension>]
726+
member this.WithSliders(sliders:seq<Slider>) =
727+
this |> Chart.withSliders sliders

Diff for: src/Plotly.NET/ChartAPI/Chart.fs

+19-2
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ type Chart =
854854
)
855855
let updatedLayout = layout |> Layout.SetLayoutGrid updatedGrid
856856
GenericChart.setLayout updatedLayout ch)
857-
857+
858858
[<CompiledName("WithConfig")>]
859859
static member withConfig (config:Config) =
860860
(fun (ch:GenericChart) ->
@@ -1710,4 +1710,21 @@ type Chart =
17101710
[<Optional;DefaultParameterValue(true)>] ?Append: bool
17111711
) =
17121712

1713-
Chart.withLayoutImages([image], ?Append = Append)
1713+
Chart.withLayoutImages([image], ?Append = Append)
1714+
1715+
[<CompiledName("WithSliders")>]
1716+
static member withSliders
1717+
(
1718+
sliders:seq<Slider>
1719+
) =
1720+
fun (ch:GenericChart) ->
1721+
ch
1722+
|> GenericChart.mapLayout
1723+
(Layout.style (Sliders = sliders))
1724+
1725+
[<CompiledName("WithSlider")>]
1726+
static member withSlider
1727+
(
1728+
slider:Slider
1729+
) =
1730+
Chart.withSliders([slider])

Diff for: src/Plotly.NET/CommonAbstractions/StyleParams.fs

+25-1
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,25 @@ module StyleParam =
14011401
//--------------------------
14021402
// #M#
14031403
//--------------------------
1404+
1405+
[<RequireQualifiedAccess>]
1406+
type Method =
1407+
| Restyle
1408+
| Relayout
1409+
| Animate
1410+
| Update
1411+
| Skip
1412+
1413+
static member toString = function
1414+
| Restyle -> "restyle"
1415+
| Relayout -> "relayout"
1416+
| Animate -> "animate"
1417+
| Update -> "update"
1418+
| Skip -> "skip"
1419+
1420+
static member convert = Method.toString >> box
1421+
override this.ToString() = this |> Method.toString
1422+
member this.Convert() = this |> Method.convert
14041423

14051424
[<RequireQualifiedAccess>]
14061425
type ModeBarButton =
@@ -2676,12 +2695,17 @@ module StyleParam =
26762695
type Visible =
26772696
| True | False | LegendOnly
26782697

2698+
static member toObject = function
2699+
| True -> box(true)
2700+
| False -> box(false)
2701+
| LegendOnly -> box("legendonly")
2702+
26792703
static member toString = function
26802704
| True -> "true"
26812705
| False -> "false"
26822706
| LegendOnly -> "legendonly"
26832707

2684-
static member convert = Visible.toString >> box
2708+
static member convert = Visible.toObject >> box
26852709
override this.ToString() = this |> Visible.toString
26862710
member this.Convert() = this |> Visible.convert
26872711

Diff for: src/Plotly.NET/Layout/Layout.fs

+7-3
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ type Layout() =
7777
[<Optional;DefaultParameterValue(null)>] ?IcicleColorWay : Color,
7878
[<Optional;DefaultParameterValue(null)>] ?Annotations : seq<Annotation>,
7979
[<Optional;DefaultParameterValue(null)>] ?Shapes : seq<Shape>,
80-
[<Optional;DefaultParameterValue(null)>] ?Images : seq<LayoutImage>
80+
[<Optional;DefaultParameterValue(null)>] ?Images : seq<LayoutImage>,
81+
[<Optional;DefaultParameterValue(null)>] ?Sliders : seq<Slider>
8182
) =
8283
Layout()
8384
|> Layout.style
@@ -147,7 +148,8 @@ type Layout() =
147148
?IcicleColorWay = IcicleColorWay ,
148149
?Annotations = Annotations ,
149150
?Shapes = Shapes ,
150-
?Images = Images
151+
?Images = Images ,
152+
?Sliders = Sliders
151153
)
152154

153155
// Applies the styles to Layout()
@@ -218,7 +220,8 @@ type Layout() =
218220
[<Optional;DefaultParameterValue(null)>] ?IcicleColorWay : Color,
219221
[<Optional;DefaultParameterValue(null)>] ?Annotations : seq<Annotation>,
220222
[<Optional;DefaultParameterValue(null)>] ?Shapes : seq<Shape>,
221-
[<Optional;DefaultParameterValue(null)>] ?Images : seq<LayoutImage>
223+
[<Optional;DefaultParameterValue(null)>] ?Images : seq<LayoutImage>,
224+
[<Optional;DefaultParameterValue(null)>] ?Sliders : seq<Slider>
222225
) =
223226
(fun (layout:Layout) ->
224227

@@ -288,6 +291,7 @@ type Layout() =
288291
Annotations |> DynObj.setValueOpt layout "annotations"
289292
Shapes |> DynObj.setValueOpt layout "shapes"
290293
Images |> DynObj.setValueOpt layout "images"
294+
Sliders |> DynObj.setValueOpt layout "sliders"
291295

292296
layout
293297
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
namespace Plotly.NET.LayoutObjects
2+
3+
open DynamicObj
4+
5+
type Padding() =
6+
inherit DynamicObj ()
7+
8+
/// <summary>
9+
/// Set the padding of the slider component along each side
10+
/// </summary>
11+
/// <param name="B">The amount of padding (in px) along the bottom of the component</param>
12+
/// <param name="L">The amount of padding (in px) on the left side of the component</param>
13+
/// <param name="R">The amount of padding (in px) on the right side of the component</param>
14+
/// <param name="T">The amount of padding (in px) along the top of the component</param>
15+
static member init
16+
(
17+
?B : int,
18+
?L : int,
19+
?R : int,
20+
?T : int
21+
) = Padding() |> Padding.style
22+
(
23+
?B=B,
24+
?L=L,
25+
?R=R,
26+
?T=T
27+
)
28+
29+
static member style(?B : int, ?L : int, ?R : int, ?T : int) = (fun (padding : Padding) ->
30+
B |> DynObj.setValueOpt padding "b"
31+
L |> DynObj.setValueOpt padding "l"
32+
R |> DynObj.setValueOpt padding "r"
33+
T |> DynObj.setValueOpt padding "t"
34+
padding)

0 commit comments

Comments
 (0)