diff --git a/Plotly.NET.sln b/Plotly.NET.sln index 18e6c67a9..e0ac2ff96 100644 --- a/Plotly.NET.sln +++ b/Plotly.NET.sln @@ -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 diff --git a/docs/02_9_Sliders.fsx b/docs/02_9_Sliders.fsx new file mode 100644 index 000000000..50978c72d --- /dev/null +++ b/docs/02_9_Sliders.fsx @@ -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***) \ No newline at end of file diff --git a/src/Plotly.NET/CSharpLayer/GenericChartExtensions.fs b/src/Plotly.NET/CSharpLayer/GenericChartExtensions.fs index 3366e2882..4db5f01d5 100644 --- a/src/Plotly.NET/CSharpLayer/GenericChartExtensions.fs +++ b/src/Plotly.NET/CSharpLayer/GenericChartExtensions.fs @@ -714,4 +714,14 @@ module GenericChartExtensions = [] [] member this.WithLayoutImages(images:seq, []?Append:bool) = - this |> Chart.withLayoutImages(images, ?Append = Append) \ No newline at end of file + this |> Chart.withLayoutImages(images, ?Append = Append) + + [] + [] + member this.WithSlider(slider:Slider) = + this |> Chart.withSlider(slider) + + [] + [] + member this.WithSliders(sliders:seq) = + this |> Chart.withSliders sliders \ No newline at end of file diff --git a/src/Plotly.NET/ChartAPI/Chart.fs b/src/Plotly.NET/ChartAPI/Chart.fs index 0b1860878..e04bf0423 100644 --- a/src/Plotly.NET/ChartAPI/Chart.fs +++ b/src/Plotly.NET/ChartAPI/Chart.fs @@ -854,7 +854,7 @@ type Chart = ) let updatedLayout = layout |> Layout.SetLayoutGrid updatedGrid GenericChart.setLayout updatedLayout ch) - + [] static member withConfig (config:Config) = (fun (ch:GenericChart) -> @@ -1710,4 +1710,21 @@ type Chart = [] ?Append: bool ) = - Chart.withLayoutImages([image], ?Append = Append) \ No newline at end of file + Chart.withLayoutImages([image], ?Append = Append) + + [] + static member withSliders + ( + sliders:seq + ) = + fun (ch:GenericChart) -> + ch + |> GenericChart.mapLayout + (Layout.style (Sliders = sliders)) + + [] + static member withSlider + ( + slider:Slider + ) = + Chart.withSliders([slider]) \ No newline at end of file diff --git a/src/Plotly.NET/CommonAbstractions/StyleParams.fs b/src/Plotly.NET/CommonAbstractions/StyleParams.fs index 991d21a3d..39bfd6723 100644 --- a/src/Plotly.NET/CommonAbstractions/StyleParams.fs +++ b/src/Plotly.NET/CommonAbstractions/StyleParams.fs @@ -1401,6 +1401,25 @@ module StyleParam = //-------------------------- // #M# //-------------------------- + + [] + 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 [] type ModeBarButton = @@ -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 diff --git a/src/Plotly.NET/Layout/Layout.fs b/src/Plotly.NET/Layout/Layout.fs index 050d940ae..a4b270173 100644 --- a/src/Plotly.NET/Layout/Layout.fs +++ b/src/Plotly.NET/Layout/Layout.fs @@ -77,7 +77,8 @@ type Layout() = [] ?IcicleColorWay : Color, [] ?Annotations : seq, [] ?Shapes : seq, - [] ?Images : seq + [] ?Images : seq, + [] ?Sliders : seq ) = Layout() |> Layout.style @@ -147,7 +148,8 @@ type Layout() = ?IcicleColorWay = IcicleColorWay , ?Annotations = Annotations , ?Shapes = Shapes , - ?Images = Images + ?Images = Images , + ?Sliders = Sliders ) // Applies the styles to Layout() @@ -218,7 +220,8 @@ type Layout() = [] ?IcicleColorWay : Color, [] ?Annotations : seq, [] ?Shapes : seq, - [] ?Images : seq + [] ?Images : seq, + [] ?Sliders : seq ) = (fun (layout:Layout) -> @@ -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 ) diff --git a/src/Plotly.NET/Layout/ObjectAbstractions/Common/Padding.fs b/src/Plotly.NET/Layout/ObjectAbstractions/Common/Padding.fs new file mode 100644 index 000000000..216577f55 --- /dev/null +++ b/src/Plotly.NET/Layout/ObjectAbstractions/Common/Padding.fs @@ -0,0 +1,34 @@ +namespace Plotly.NET.LayoutObjects + +open DynamicObj + +type Padding() = + inherit DynamicObj () + + /// + /// Set the padding of the slider component along each side + /// + /// The amount of padding (in px) along the bottom of the component + /// The amount of padding (in px) on the left side of the component + /// The amount of padding (in px) on the right side of the component + /// The amount of padding (in px) along the top of the component + 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) \ No newline at end of file diff --git a/src/Plotly.NET/Layout/ObjectAbstractions/Common/Slider/Slider.fs b/src/Plotly.NET/Layout/ObjectAbstractions/Common/Slider/Slider.fs new file mode 100644 index 000000000..7eeb85fc9 --- /dev/null +++ b/src/Plotly.NET/Layout/ObjectAbstractions/Common/Slider/Slider.fs @@ -0,0 +1,169 @@ +namespace Plotly.NET.LayoutObjects + +open Plotly.NET +open DynamicObj + +/// +/// The layout object for custom slider implementation +/// +type Slider() = + inherit DynamicObj () + + /// + /// Initializes the slider with style parameters + /// + /// Determines which button (by index starting from 0) is considered active + /// Sets the background color of the slider grip while dragging + /// Sets the background color of the slider + /// Sets the background color of the slider + /// Sets the color of the border enclosing the slider + /// Object containing the current slider value style + /// Sets the font of the slider step labels + /// + /// Sets the length of the slider This measure excludes the padding of both ends. + /// That is, the slider's length is this length minus the padding on both ends + /// + /// + /// Determines whether this slider length is set in units of plot "fraction" or in "pixels. + /// Use `len` to set the value + /// + /// Sets the length in pixels of minor step tick marks + /// + /// When used in a template, named items are created in the output figure in addition + /// to any items the figure already has in this array. + /// You can modify these items in the output figure by making your own item with `templateitemname` + /// matching this `name` alongside your modifications (including `visible: false` or `enabled: false` to hide it). + /// Has no effect outside of a template. + /// + /// Set the padding of the slider component along each side + /// The steps of the slider including step arguments + /// + /// Used to refer to a named item in this array in the template. + /// Named items from the template will be created even without a matching item + /// in the input figure, but you can modify one by making an item with + /// `templateitemname` matching its `name`, alongside your modifications + /// (including `visible: false` or `enabled: false` to hide it). + /// If there is no template or no matching item, this item will be hidden unless + /// you explicitly show it with `visible: true`. + /// + /// Sets the color of the border enclosing the slider + /// Sets the length in pixels of step tick marks + /// Sets the tick width (in px) + /// Object containing the information about steps transition + /// Determines whether or not the slider is visible + /// Sets the x position (in normalized coordinates) of the slider + /// + /// Sets the slider's horizontal position anchor. + /// This anchor binds the `x` position to the "left", "center" or "right" of the range selector + /// + /// Sets the y position (in normalized coordinates) of the slider + /// + /// Sets the slider's vertical position anchor. + /// This anchor binds the `y` position to the "top", "middle" or "bottom" of the range selector + /// + static member init + ( + ?Active : int, + ?ActiveBgColor : Color, + ?BgColor : Color, + ?BorderColor : Color, + ?BorderWidth : int, + ?CurrentValue : SliderCurrentValue, + ?Font : Font, + ?Len : float, + ?LenMode : StyleParam.UnitMode, + ?MinorTickLen : int, + ?Name : string, + ?Padding : Padding, + ?Steps : seq, + ?TemplateItemName : string, + ?TickColor : Color, + ?TickLen : int, + ?TickWidth : int, + ?Transition : Transition, + ?Visible : bool, + ?X : int, + ?XAnchor : StyleParam.XAnchorPosition, + ?Y : int, + ?YAnchor : StyleParam.YAnchorPosition + ) = + Slider() |> Slider.style + ( + ?Active=Active, + ?ActiveBgColor=ActiveBgColor, + ?BgColor=BgColor, + ?BorderColor=BorderColor, + ?BorderWidth=BorderWidth, + ?CurrentValue=CurrentValue, + ?Font=Font, + ?Len=Len, + ?LenMode=LenMode, + ?MinorTickLen=MinorTickLen, + ?Name=Name, + ?Padding=Padding, + ?Steps=Steps, + ?TemplateItemName=TemplateItemName, + ?TickColor=TickColor, + ?TickLen=TickLen, + ?TickWidth=TickWidth, + ?Transition=Transition, + ?Visible=Visible, + ?X=X, + ?XAnchor=XAnchor, + ?Y=Y, + ?YAnchor=YAnchor + ) + + static member style + ( + ?Active : int, + ?ActiveBgColor : Color, + ?BgColor : Color, + ?BorderColor : Color, + ?BorderWidth : int, + ?CurrentValue : SliderCurrentValue, + ?Font : Font, + ?Len : float, + ?LenMode : StyleParam.UnitMode, + ?MinorTickLen : int, + ?Name : string, + ?Padding : Padding, + ?Steps : seq, + ?TemplateItemName : string, + ?TickColor : Color, + ?TickLen : int, + ?TickWidth : int, + ?Transition : Transition, + ?Visible : bool, + ?X : int, + ?XAnchor : StyleParam.XAnchorPosition, + ?Y : int, + ?YAnchor : StyleParam.YAnchorPosition + ) = + (fun (slider : Slider) -> + Active |> DynObj.setValueOpt slider "active" + ActiveBgColor |> DynObj.setValueOpt slider "activebgcolor" + BgColor |> DynObj.setValueOpt slider "bgcolor" + BorderColor |> DynObj.setValueOpt slider "bordercolor" + BorderWidth |> DynObj.setValueOpt slider "borderwidth" + CurrentValue |> DynObj.setValueOpt slider "currentvalue" + Font |> DynObj.setValueOpt slider "font" + Len |> DynObj.setValueOpt slider "len" + LenMode |> DynObj.setValueOptBy slider "lenmode" StyleParam.UnitMode.convert + MinorTickLen |> DynObj.setValueOpt slider "minorticklen" + Name |> DynObj.setValueOpt slider "name" + Padding |> DynObj.setValueOpt slider "pad" + Steps |> DynObj.setValueOpt slider "steps" + TemplateItemName |> DynObj.setValueOpt slider "templateitemname" + TickColor |> DynObj.setValueOpt slider "tickcolor" + TickLen |> DynObj.setValueOpt slider "ticklen" + TickWidth |> DynObj.setValueOpt slider "tickwidth" + Transition |> DynObj.setValueOpt slider "transition" + Visible |> DynObj.setValueOpt slider "visible" + X |> DynObj.setValueOpt slider "x" + XAnchor |> DynObj.setValueOptBy slider "xanchor" StyleParam.XAnchorPosition.convert + Y |> DynObj.setValueOpt slider "y" + YAnchor |> DynObj.setValueOptBy slider "yanchor" StyleParam.YAnchorPosition.convert + + slider + ) \ No newline at end of file diff --git a/src/Plotly.NET/Layout/ObjectAbstractions/Common/Slider/SliderCurrentValue.fs b/src/Plotly.NET/Layout/ObjectAbstractions/Common/Slider/SliderCurrentValue.fs new file mode 100644 index 000000000..64054ccc0 --- /dev/null +++ b/src/Plotly.NET/Layout/ObjectAbstractions/Common/Slider/SliderCurrentValue.fs @@ -0,0 +1,58 @@ +namespace Plotly.NET.LayoutObjects + +open Plotly.NET +open DynamicObj + +type SliderCurrentValue() = + inherit DynamicObj () + + /// + /// Object containing the current slider value style + /// + /// Sets the font of the current value label text + /// The amount of space, in pixels, between the current value label and the slider + /// When currentvalue.visible is true, this sets the prefix of the label + /// When currentvalue.visible is true, this sets the suffix of the label + /// Shows the currently-selected value above the slider + /// The alignment of the value readout relative to the length of the slider + static member init + ( + ?Font : Font, + ?Offset : int, + ?Prefix : string, + ?Suffix : string, + ?Visible : bool, + ?XAnchor : StyleParam.XAnchorPosition + + ) = SliderCurrentValue() |> SliderCurrentValue.style + ( + ?Font=Font, + ?Offset=Offset, + ?Prefix=Prefix, + ?Suffix=Suffix, + ?Visible=Visible, + ?XAnchor=XAnchor + ) + + static member style + ( + ?Font : Font, + ?Offset : int, + ?Prefix : string, + ?Suffix : string, + ?Visible : bool, + ?XAnchor : StyleParam.XAnchorPosition + ) = (fun (currentValue : SliderCurrentValue) -> + let autoValueIsProvided = XAnchor |> + Option.exists (fun xAnchor -> xAnchor = StyleParam.XAnchorPosition.Auto) + if autoValueIsProvided + then printf "The value '%s' is not supported by CurrentValue" (StyleParam.XAnchorPosition.Auto |> string) + + Font |> DynObj.setValueOpt currentValue "font" + Offset |> DynObj.setValueOpt currentValue "offset" + Prefix |> DynObj.setValueOpt currentValue "prefix" + Suffix |> DynObj.setValueOpt currentValue "suffix" + Visible |> DynObj.setValueOpt currentValue "visible" + XAnchor |> DynObj.setValueOptBy currentValue "xanchor" StyleParam.XAnchorPosition.convert + currentValue + ) \ No newline at end of file diff --git a/src/Plotly.NET/Layout/ObjectAbstractions/Common/Slider/SliderStep.fs b/src/Plotly.NET/Layout/ObjectAbstractions/Common/Slider/SliderStep.fs new file mode 100644 index 000000000..65c0571ad --- /dev/null +++ b/src/Plotly.NET/Layout/ObjectAbstractions/Common/Slider/SliderStep.fs @@ -0,0 +1,95 @@ +namespace Plotly.NET.LayoutObjects + +open Plotly.NET +open DynamicObj + +/// +/// The object including the slider steps style and update parameters +/// +type SliderStep() = + inherit DynamicObj () + + /// + /// Initializes the slider with style parameters + /// + /// Sets the arguments values to be passed to the Plotly method set in `method` on slide + /// + /// When true, the API method is executed. When false, all other behaviors are the same and command execution is skipped. + /// This may be useful when hooking into, for example, the `plotly_sliderchange` method and executing the API command manually + /// without losing the benefit of the slider automatically binding to the state of the plot through the specification of `method` and `args`. + /// + /// Sets the text label to appear on the slider + /// + /// Sets the Plotly method to be called when the slider value is changed. + /// If the `skip` method is used, the API slider will function as normal but + /// will perform no API calls and will not bind automatically to state updates. + /// This may be used to create a component interface and attach to slider events manually via JavaScript + /// + /// + /// When used in a template, named items are created in the output figure in addition to any items the figure already has in this array. + /// You can modify these items in the output figure by making your own item with `templateitemname` matching this + /// `name` alongside your modifications (including `visible: false` or `enabled: false` to hide it). + /// Has no effect outside of a template + /// + /// + /// Used to refer to a named item in this array in the template. + /// Named items from the template will be created even without a matching item in the input figure, + /// but you can modify one by making an item with `templateitemname` matching its `name`, alongside your modifications + /// (including `visible: false` or `enabled: false` to hide it). If there is no template or no matching item, + /// this item will be hidden unless you explicitly show it with `visible: true` + /// + /// Sets the value of the slider step, used to refer to the step programatically. Defaults to the slider label if not provided + /// Determines whether or not this step is included in the slider + static member init + ( + ?Args : seq<(string * obj)>, + ?Execute : bool, + ?Label : string, + ?Method : StyleParam.Method, + ?Name : string, + ?TemplateItemName : string, + ?Value : string, + ?Visible : bool + ) = + SliderStep() |> SliderStep.style + ( + ?Args=Args, + ?Execute=Execute, + ?Label=Label, + ?Method=Method, + ?Name=Name, + ?TemplateItemName=TemplateItemName, + ?Value=Value, + ?Visible=Visible + ) + + static member style + ( + ?Args : seq<(string * obj)>, + ?Execute : bool, + ?Label : string, + ?Method : StyleParam.Method, + ?Name : string, + ?TemplateItemName : string, + ?Value : string, + ?Visible : bool + ) = + (fun (step : SliderStep) -> + // A bit strange, that we create a dictionary for an every + // object, but this is that way the Plotly works + let argsAsDictionaries = + Args + |> Option.map (fun args -> + args + |> Seq.map (fun arg -> [arg] |> dict) + ) + argsAsDictionaries |> DynObj.setValueOpt step "args" + Execute |> DynObj.setValueOpt step "execute" + Label |> DynObj.setValueOpt step "label" + Method |> DynObj.setValueOptBy step "method" StyleParam.Method.convert + Name |> DynObj.setValueOpt step "name" + TemplateItemName |> DynObj.setValueOpt step "templateitemname" + Value |> DynObj.setValueOpt step "value" + Visible |> DynObj.setValueOpt step "visible" + step + ) \ No newline at end of file diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index 48efcb5dc..843a609aa 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -39,6 +39,7 @@ #load "Rangebreak.fs" #load "LinearAxis.fs" #load "ColorAxis.fs" +#load "Padding.fs" #I "Layout/ObjectAbstractions/Map" @@ -64,6 +65,12 @@ #load "Ternary.fs" +#I "Layout/ObjectAbstractions/Common/Slider" + +#load "SliderCurrentValue.fs" +#load "SliderStep.fs" +#load "Slider.fs" + #load "Layout/Layout.fs" #I "Traces/ObjectAbstractions" diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index cfa048f99..f35e38d39 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -42,6 +42,7 @@ + @@ -63,6 +64,9 @@ + + + diff --git a/src/Plotly.NET/Traces/Trace.fs b/src/Plotly.NET/Traces/Trace.fs index 562f6b225..b93d89c4f 100644 --- a/src/Plotly.NET/Traces/Trace.fs +++ b/src/Plotly.NET/Traces/Trace.fs @@ -36,7 +36,7 @@ type TraceStyle() = ) = (fun (trace:('T :> Trace)) -> Name |> DynObj.setValueOpt trace "name" - Visible |> DynObj.setValueOptBy trace "visible" StyleParam.Visible.toString + Visible |> DynObj.setValueOptBy trace "visible" StyleParam.Visible.toObject ShowLegend |> DynObj.setValueOpt trace "showlegend" LegendGroup |> DynObj.setValueOpt trace "legendgroup" Opacity |> DynObj.setValueOpt trace "opacity" diff --git a/tests/Plotly.NET.Tests/LayoutObjects/Slider.fs b/tests/Plotly.NET.Tests/LayoutObjects/Slider.fs new file mode 100644 index 000000000..d99eae0f6 --- /dev/null +++ b/tests/Plotly.NET.Tests/LayoutObjects/Slider.fs @@ -0,0 +1,83 @@ +module Tests.LayoutObjects.Slider + +open Expecto +open Plotly.NET +open Plotly.NET.LayoutObjects + +open TestUtils.LayoutObjects + +let slider = + Slider.init( + Active=1, + ActiveBgColor=Color.fromRGB 1 2 3, + BgColor=Color.fromRGB 2 3 4, + BorderColor=Color.fromRGB 3 4 5, + BorderWidth=2, + CurrentValue=SliderCurrentValue.init( + Font=Font.init(StyleParam.FontFamily.Arial, Size=1., Color=Color.fromRGB 4 5 6), + Offset=1, + Prefix="prefix", + Suffix="suffix", + Visible=false, + XAnchor=StyleParam.XAnchorPosition.Center + ), + Font=Font.init(StyleParam.FontFamily.Balto, Size=2., Color=Color.fromRGB 5 6 7), + Len=0.4, + LenMode=StyleParam.UnitMode.Fraction, + MinorTickLen=6, + Name="SliderName", + Padding=Padding.init(1, 2, 3, 4), + Steps= + [SliderStep.init( + Args=["visible", box(false); "title", box("stepTitle")], + Execute=true, + Label="stepLabel", + Method=StyleParam.Method.Update, + Name="stepName", + TemplateItemName="stepTemplateItemName", + Value="stepValue", + Visible=true + )], + TemplateItemName="TemplateItemName", + TickColor=Color.fromRGB 6 7 8, + TickLen=7, + TickWidth=8, + Transition=Transition.init( + Duration=1, + Easing=StyleParam.TransitionEasing.Back, + Ordering=StyleParam.TransitionOrdering.LayoutFirst + ), + Visible=true, + X=9, + XAnchor=StyleParam.XAnchorPosition.Left, + Y=10, + YAnchor=StyleParam.YAnchorPosition.Middle + ) + +[] +let ``Slider tests`` = + testList "LayoutObjects.Slider JSON field tests" [ + slider |> createJsonFieldTest "active" "1" + slider |> createJsonFieldTest "activebgcolor" "\"rgba(1, 2, 3, 1.0)\"" + slider |> createJsonFieldTest "bgcolor" "\"rgba(2, 3, 4, 1.0)\"" + slider |> createJsonFieldTest "bordercolor" "\"rgba(3, 4, 5, 1.0)\"" + slider |> createJsonFieldTest "borderwidth" "2" + slider |> createJsonFieldTest "currentvalue" "{\"font\":{\"family\":\"Arial\",\"size\":1.0,\"color\":\"rgba(4, 5, 6, 1.0)\"},\"offset\":1,\"prefix\":\"prefix\",\"suffix\":\"suffix\",\"visible\":false,\"xanchor\":\"center\"}" + slider |> createJsonFieldTest "font" "{\"family\":\"Balto\",\"size\":2.0,\"color\":\"rgba(5, 6, 7, 1.0)\"}" + slider |> createJsonFieldTest "len" "0.4" + slider |> createJsonFieldTest "lenmode" "\"fraction\"" + slider |> createJsonFieldTest "minorticklen" "6" + slider |> createJsonFieldTest "name" "\"SliderName\"" + slider |> createJsonFieldTest "pad" "{\"b\":1,\"l\":2,\"r\":3,\"t\":4}" + slider |> createJsonFieldTest "templateitemname" "\"TemplateItemName\"" + slider |> createJsonFieldTest "tickcolor" "\"rgba(6, 7, 8, 1.0)\"" + slider |> createJsonFieldTest "ticklen" "7" + slider |> createJsonFieldTest "tickwidth" "8" + slider |> createJsonFieldTest "transition" "{\"duration\":1,\"easing\":\"back\",\"ordering\":\"layout first\"}" + slider |> createJsonFieldTest "visible" "true" + slider |> createJsonFieldTest "x" "9" + slider |> createJsonFieldTest "xanchor" "\"left\"" + slider |> createJsonFieldTest "y" "10" + slider |> createJsonFieldTest "yanchor" "\"middle\"" + slider |> createJsonFieldTest "steps" "[{\"args\":[{\"visible\":false},{\"title\":\"stepTitle\"}],\"execute\":true,\"label\":\"stepLabel\",\"method\":\"update\",\"name\":\"stepName\",\"templateitemname\":\"stepTemplateItemName\",\"value\":\"stepValue\",\"visible\":true}]" + ] \ No newline at end of file diff --git a/tests/Plotly.NET.Tests/Plotly.NET.Tests.fsproj b/tests/Plotly.NET.Tests/Plotly.NET.Tests.fsproj index 2216fd5b0..4a862749a 100644 --- a/tests/Plotly.NET.Tests/Plotly.NET.Tests.fsproj +++ b/tests/Plotly.NET.Tests/Plotly.NET.Tests.fsproj @@ -9,6 +9,7 @@ +