Skip to content

Commit 1042e9a

Browse files
committed
plotlyjs v2.13: Add selections, newselection and activeselection layout attributes to have
persistent and editable selections over cartesian subplots (plotly/plotly.js#6243)
1 parent 9590940 commit 1042e9a

File tree

9 files changed

+268
-5
lines changed

9 files changed

+268
-5
lines changed

src/Plotly.NET/ChartAPI/Chart.fs

+27
Original file line numberDiff line numberDiff line change
@@ -2735,6 +2735,33 @@ type Chart =
27352735
static member withShape(shape: Shape, [<Optional; DefaultParameterValue(true)>] ?Append: bool) =
27362736
Chart.withShapes ([ shape ], ?Append = Append)
27372737

2738+
/// <summary>
2739+
///
2740+
/// </summary>
2741+
/// <param name="selections">The selections to add to the input charts layout</param>
2742+
/// <param name="Append">If true, the input selections will be appended to existing annotations, otherwise existing annotations will be removed (default: true)</param>
2743+
[<CompiledName("WithSelections")>]
2744+
static member withSelections(selections: seq<Selection>, [<Optional; DefaultParameterValue(true)>] ?Append: bool) =
2745+
let append = defaultArg Append true
2746+
2747+
fun (ch: GenericChart) ->
2748+
2749+
let selections' =
2750+
2751+
if append then
2752+
2753+
let layout = GenericChart.getLayout ch
2754+
2755+
layout.TryGetTypedValue<seq<Selection>>("selections") |> Option.defaultValue Seq.empty |> Seq.append selections
2756+
2757+
else
2758+
selections
2759+
2760+
ch |> GenericChart.mapLayout (Layout.style (Selections = selections'))
2761+
2762+
[<CompiledName("WithSelection")>]
2763+
static member withSelection(selection: Selection, [<Optional; DefaultParameterValue(true)>] ?Append: bool) =
2764+
Chart.withSelections([ selection ], ?Append = Append)
27382765

27392766
//==============================================================================================================
27402767
//======================================= General Config object styling ========================================

src/Plotly.NET/ChartAPI/GenericChart.fs

+8-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module HTML =
1515
<head>
1616
<!-- Plotly.js -->
1717
<meta http-equiv="X-UA-Compatible" content="IE=11" >
18-
<script src="https://cdn.plot.ly/plotly-2.12.1.min.js"></script>
18+
<script src="https://cdn.plot.ly/plotly-2.13.3.min.js"></script>
1919
[ADDITIONAL_HEAD_TAGS]
2020
<style>
2121
.container {
@@ -58,7 +58,7 @@ module HTML =
5858
newScript.AppendLine(
5959
@"
6060
var renderPlotly_[SCRIPTID] = function() {
61-
var fsharpPlotlyRequire = requirejs.config({context:'fsharp-plotly',paths:{plotly:'https://cdn.plot.ly/plotly-2.12.1.min'}}) || require;
61+
var fsharpPlotlyRequire = requirejs.config({context:'fsharp-plotly',paths:{plotly:'https://cdn.plot.ly/plotly-2.13.3.min'}}) || require;
6262
fsharpPlotlyRequire(['plotly'], function(Plotly) {"
6363
)
6464
|> ignore
@@ -252,6 +252,11 @@ module GenericChart =
252252
(first.TryGetTypedValue<seq<Shape>>("shapes"))
253253
(second.TryGetTypedValue<seq<Shape>>("shapes"))
254254

255+
let selections =
256+
combineOptSeqs
257+
(first.TryGetTypedValue<seq<Selection>>("selections"))
258+
(second.TryGetTypedValue<seq<Selection>>("selections"))
259+
255260
let images =
256261
combineOptSeqs
257262
(first.TryGetTypedValue<seq<LayoutImage>>("images"))
@@ -277,6 +282,7 @@ module GenericChart =
277282
|> Layout.style (
278283
?Annotations = annotations,
279284
?Shapes = shapes,
285+
?Selections = selections,
280286
?Images = images,
281287
?Sliders = sliders,
282288
?HiddenLabels = hiddenLabels,

src/Plotly.NET/CommonAbstractions/StyleParams.fs

+28
Original file line numberDiff line numberDiff line change
@@ -2194,6 +2194,20 @@ module StyleParam =
21942194
// #N#
21952195
//--------------------------
21962196

2197+
[<RequireQualifiedAccess>]
2198+
type NewSelectionMode =
2199+
| Immediate
2200+
| Gradual
2201+
2202+
static member toString =
2203+
function
2204+
| Immediate -> "immediate"
2205+
| Gradual -> "gradual"
2206+
2207+
static member convert = NewSelectionMode.toString >> box
2208+
override this.ToString() = this |> NewSelectionMode.toString
2209+
member this.Convert() = this |> NewSelectionMode.convert
2210+
21972211
//--------------------------
21982212
// #O#
21992213
//--------------------------
@@ -2515,6 +2529,20 @@ module StyleParam =
25152529
override this.ToString() = this |> ShapeType.toString
25162530
member this.Convert() = this |> ShapeType.convert
25172531

2532+
[<RequireQualifiedAccess>]
2533+
type SelectionType =
2534+
| Rectangle
2535+
| SvgPath
2536+
2537+
static member toString =
2538+
function
2539+
| Rectangle -> "rect"
2540+
| SvgPath -> "path"
2541+
2542+
static member convert = SelectionType.toString >> box
2543+
override this.ToString() = this |> SelectionType.toString
2544+
member this.Convert() = this |> SelectionType.convert
2545+
25182546
[<RequireQualifiedAccess>]
25192547
type SymbolStyle =
25202548
| Open

src/Plotly.NET/Layout/Layout.fs

+15
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ type Layout() =
3232
/// <param name="ClickMode">Determines the mode of single click interactions. "event" is the default value and emits the `plotly_click` event. In addition this mode emits the `plotly_selected` event in drag modes "lasso" and "select", but with no event data attached (kept for compatibility reasons). The "select" flag enables selecting single data points via click. This mode also supports persistent selections, meaning that pressing Shift while clicking, adds to / subtracts from an existing selection. "select" with `hovermode`: "x" can be confusing, consider explicitly setting `hovermode`: "closest" when using this feature. Selection events are sent accordingly as long as "event" flag is set as well. When the "event" flag is missing, `plotly_click` and `plotly_selected` events are not fired.</param>
3333
/// <param name="DragMode">Determines the mode of drag interactions. "select" and "lasso" apply only to scatter traces with markers or text. "orbit" and "turntable" apply only to 3D scenes.</param>
3434
/// <param name="SelectDirection">When `dragmode` is set to "select", this limits the selection of the drag to horizontal, vertical or diagonal. "h" only allows horizontal selection, "v" only vertical, "d" only diagonal and "any" sets no limit.</param>
35+
/// <param name="ActiveSelection">Sets the styling of the active selection</param>
36+
/// <param name="NewSelection">Controls the behavior of newly drawn selections</param>
3537
/// <param name="HoverDistance">Sets the default distance (in pixels) to look for data to add hover labels (-1 means no cutoff, 0 means no looking for data). This is only a real distance for hovering on point-like objects, like scatter points. For area-like objects (bars, scatter fills, etc) hovering is on inside the area and off outside, but these objects will not supersede hover on point-like objects in case of conflict.</param>
3638
/// <param name="SpikeDistance">Sets the default distance (in pixels) to look for data to draw spikelines to (-1 means no cutoff, 0 means no looking for data). As with hoverdistance, distance does not apply to area-like objects. In addition, some objects can be hovered on but will not generate spikelines, such as scatter fills.</param>
3739
/// <param name="Hoverlabel">Sets the style ov hover labels.</param>
@@ -77,6 +79,7 @@ type Layout() =
7779
/// <param name="IcicleColorWay">Sets the default icicle slice colors. Defaults to the main `colorway` used for trace colors. If you specify a new list here it can still be extended with lighter and darker colors, see `extendiciclecolors`.</param>
7880
/// <param name="Annotations">A collection containing all Annotations of this layout. An annotation is a text element that can be placed anywhere in the plot. It can be positioned with respect to relative coordinates in the plot or with respect to the actual data coordinates of the graph. Annotations can be shown with or without an arrow.</param>
7981
/// <param name="Shapes">A collection containing all Shapes of this layout.</param>
82+
/// <param name="Selections">A collection containing all Selections of this layout.</param>
8083
/// <param name="Images">A collection containing all Images of this layout. </param>
8184
/// <param name="Sliders">A collection containing all Sliders of this layout. </param>
8285
/// <param name="UpdateMenus">A collection containing all UpdateMenus of this layout. </param>
@@ -102,6 +105,8 @@ type Layout() =
102105
[<Optional; DefaultParameterValue(null)>] ?ClickMode: StyleParam.ClickMode,
103106
[<Optional; DefaultParameterValue(null)>] ?DragMode: StyleParam.DragMode,
104107
[<Optional; DefaultParameterValue(null)>] ?SelectDirection: StyleParam.SelectDirection,
108+
[<Optional; DefaultParameterValue(null)>] ?ActiveSelection: ActiveSelection,
109+
[<Optional; DefaultParameterValue(null)>] ?NewSelection: NewSelection,
105110
[<Optional; DefaultParameterValue(null)>] ?HoverDistance: int,
106111
[<Optional; DefaultParameterValue(null)>] ?SpikeDistance: int,
107112
[<Optional; DefaultParameterValue(null)>] ?Hoverlabel: Hoverlabel,
@@ -147,6 +152,7 @@ type Layout() =
147152
[<Optional; DefaultParameterValue(null)>] ?IcicleColorWay: Color,
148153
[<Optional; DefaultParameterValue(null)>] ?Annotations: seq<Annotation>,
149154
[<Optional; DefaultParameterValue(null)>] ?Shapes: seq<Shape>,
155+
[<Optional; DefaultParameterValue(null)>] ?Selections: seq<Selection>,
150156
[<Optional; DefaultParameterValue(null)>] ?Images: seq<LayoutImage>,
151157
[<Optional; DefaultParameterValue(null)>] ?Sliders: seq<Slider>,
152158
[<Optional; DefaultParameterValue(null)>] ?UpdateMenus: seq<UpdateMenu>
@@ -246,6 +252,8 @@ type Layout() =
246252
/// <param name="ClickMode">Determines the mode of single click interactions. "event" is the default value and emits the `plotly_click` event. In addition this mode emits the `plotly_selected` event in drag modes "lasso" and "select", but with no event data attached (kept for compatibility reasons). The "select" flag enables selecting single data points via click. This mode also supports persistent selections, meaning that pressing Shift while clicking, adds to / subtracts from an existing selection. "select" with `hovermode`: "x" can be confusing, consider explicitly setting `hovermode`: "closest" when using this feature. Selection events are sent accordingly as long as "event" flag is set as well. When the "event" flag is missing, `plotly_click` and `plotly_selected` events are not fired.</param>
247253
/// <param name="DragMode">Determines the mode of drag interactions. "select" and "lasso" apply only to scatter traces with markers or text. "orbit" and "turntable" apply only to 3D scenes.</param>
248254
/// <param name="SelectDirection">When `dragmode` is set to "select", this limits the selection of the drag to horizontal, vertical or diagonal. "h" only allows horizontal selection, "v" only vertical, "d" only diagonal and "any" sets no limit.</param>
255+
/// <param name="ActiveSelection">Sets the styling of the active selection</param>
256+
/// <param name="NewSelection">Controls the behavior of newly drawn selections</param>
249257
/// <param name="HoverDistance">Sets the default distance (in pixels) to look for data to add hover labels (-1 means no cutoff, 0 means no looking for data). This is only a real distance for hovering on point-like objects, like scatter points. For area-like objects (bars, scatter fills, etc) hovering is on inside the area and off outside, but these objects will not supersede hover on point-like objects in case of conflict.</param>
250258
/// <param name="SpikeDistance">Sets the default distance (in pixels) to look for data to draw spikelines to (-1 means no cutoff, 0 means no looking for data). As with hoverdistance, distance does not apply to area-like objects. In addition, some objects can be hovered on but will not generate spikelines, such as scatter fills.</param>
251259
/// <param name="Hoverlabel">Sets the style ov hover labels.</param>
@@ -291,6 +299,7 @@ type Layout() =
291299
/// <param name="IcicleColorWay">Sets the default icicle slice colors. Defaults to the main `colorway` used for trace colors. If you specify a new list here it can still be extended with lighter and darker colors, see `extendiciclecolors`.</param>
292300
/// <param name="Annotations">A collection containing all Annotations of this layout. An annotation is a text element that can be placed anywhere in the plot. It can be positioned with respect to relative coordinates in the plot or with respect to the actual data coordinates of the graph. Annotations can be shown with or without an arrow.</param>
293301
/// <param name="Shapes">A collection containing all Shapes of this layout.</param>
302+
/// <param name="Selections">A collection containing all Selections of this layout.</param>
294303
/// <param name="Images">A collection containing all Images of this layout. </param>
295304
/// <param name="Sliders">A collection containing all Sliders of this layout. </param>
296305
/// <param name="UpdateMenus">A collection containing all UpdateMenus of this layout. </param>
@@ -316,6 +325,8 @@ type Layout() =
316325
[<Optional; DefaultParameterValue(null)>] ?ClickMode: StyleParam.ClickMode,
317326
[<Optional; DefaultParameterValue(null)>] ?DragMode: StyleParam.DragMode,
318327
[<Optional; DefaultParameterValue(null)>] ?SelectDirection: StyleParam.SelectDirection,
328+
[<Optional; DefaultParameterValue(null)>] ?ActiveSelection: ActiveSelection,
329+
[<Optional; DefaultParameterValue(null)>] ?NewSelection: NewSelection,
319330
[<Optional; DefaultParameterValue(null)>] ?HoverDistance: int,
320331
[<Optional; DefaultParameterValue(null)>] ?SpikeDistance: int,
321332
[<Optional; DefaultParameterValue(null)>] ?Hoverlabel: Hoverlabel,
@@ -361,6 +372,7 @@ type Layout() =
361372
[<Optional; DefaultParameterValue(null)>] ?IcicleColorWay: Color,
362373
[<Optional; DefaultParameterValue(null)>] ?Annotations: seq<Annotation>,
363374
[<Optional; DefaultParameterValue(null)>] ?Shapes: seq<Shape>,
375+
[<Optional; DefaultParameterValue(null)>] ?Selections: seq<Selection>,
364376
[<Optional; DefaultParameterValue(null)>] ?Images: seq<LayoutImage>,
365377
[<Optional; DefaultParameterValue(null)>] ?Sliders: seq<Slider>,
366378
[<Optional; DefaultParameterValue(null)>] ?UpdateMenus: seq<UpdateMenu>
@@ -387,6 +399,8 @@ type Layout() =
387399
ClickMode |> DynObj.setValueOptBy layout "clickmode" StyleParam.ClickMode.convert
388400
DragMode |> DynObj.setValueOptBy layout "dragmode" StyleParam.DragMode.convert
389401
SelectDirection |> DynObj.setValueOptBy layout "selectdirection" StyleParam.SelectDirection.convert
402+
ActiveSelection |> DynObj.setValueOpt layout "activeselection"
403+
NewSelection |> DynObj.setValueOpt layout "newselection"
390404
HoverDistance |> DynObj.setValueOpt layout "hoverdistance"
391405
SpikeDistance |> DynObj.setValueOpt layout "spikedistance"
392406
Hoverlabel |> DynObj.setValueOpt layout "hoverlabel"
@@ -432,6 +446,7 @@ type Layout() =
432446
IcicleColorWay |> DynObj.setValueOpt layout "iciclecolorway"
433447
Annotations |> DynObj.setValueOpt layout "annotations"
434448
Shapes |> DynObj.setValueOpt layout "shapes"
449+
Selections |> DynObj.setValueOpt layout "selections"
435450
Images |> DynObj.setValueOpt layout "images"
436451
Sliders |> DynObj.setValueOpt layout "sliders"
437452
UpdateMenus |> DynObj.setValueOpt layout "updatemenus"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
namespace Plotly.NET.LayoutObjects
2+
3+
open Plotly.NET
4+
open DynamicObj
5+
open System
6+
open System.Runtime.InteropServices
7+
8+
type ActiveSelection() =
9+
inherit DynamicObj()
10+
11+
static member init
12+
(
13+
[<Optional; DefaultParameterValue(null)>] ?FillColor: Color,
14+
[<Optional; DefaultParameterValue(null)>] ?Opacity: float
15+
) =
16+
ActiveSelection() |> ActiveSelection.style (?FillColor = FillColor, ?Opacity = Opacity)
17+
18+
static member style
19+
(
20+
[<Optional; DefaultParameterValue(null)>] ?FillColor: Color,
21+
[<Optional; DefaultParameterValue(null)>] ?Opacity: float
22+
) =
23+
(fun (activeSelection: ActiveSelection) ->
24+
25+
FillColor |> DynObj.setValueOpt activeSelection "fillcolor"
26+
Opacity |> DynObj.setValueOpt activeSelection "opacity"
27+
28+
activeSelection)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
namespace Plotly.NET.LayoutObjects
2+
3+
open Plotly.NET
4+
open DynamicObj
5+
open System
6+
open System.Runtime.InteropServices
7+
8+
type NewSelection() =
9+
inherit DynamicObj()
10+
11+
/// <summary>
12+
/// Returns a new NewSelection object with the given styles
13+
/// </summary>
14+
/// <param name="LineColor">Sets the line color. By default uses either dark grey or white to increase contrast with background color.</param>
15+
/// <param name="LineDash">Sets the dash style of lines. Set to a dash type string ("solid", "dot", "dash", "longdash", "dashdot", or "longdashdot") or a dash length list in px (eg "5px,10px,2px,2px").</param>
16+
/// <param name="LineWidth">Sets the line width (in px).</param>
17+
/// <param name="Mode">Describes how a new selection is created. If `immediate`, a new selection is created after first mouse up. If `gradual`, a new selection is not created after first mouse. By adding to and subtracting from the initial selection, this option allows declaring extra outlines of the selection.</param>
18+
static member init
19+
(
20+
[<Optional; DefaultParameterValue(null)>] ?LineColor: Color,
21+
[<Optional; DefaultParameterValue(null)>] ?LineDash: StyleParam.DrawingStyle,
22+
[<Optional; DefaultParameterValue(null)>] ?LineWidth: float,
23+
[<Optional; DefaultParameterValue(null)>] ?Mode: StyleParam.NewSelectionMode
24+
) =
25+
NewSelection()
26+
|> NewSelection.style (
27+
?LineColor = LineColor,
28+
?LineDash = LineDash,
29+
?LineWidth = LineWidth,
30+
?Mode = Mode
31+
)
32+
33+
/// <summary>
34+
/// Returns a function that applies the given styles to a NewSelection object
35+
/// </summary>
36+
/// <param name="LineColor">Sets the line color. By default uses either dark grey or white to increase contrast with background color.</param>
37+
/// <param name="LineDash">Sets the dash style of lines. Set to a dash type string ("solid", "dot", "dash", "longdash", "dashdot", or "longdashdot") or a dash length list in px (eg "5px,10px,2px,2px").</param>
38+
/// <param name="LineWidth">Sets the line width (in px).</param>
39+
/// <param name="Mode">Describes how a new selection is created. If `immediate`, a new selection is created after first mouse up. If `gradual`, a new selection is not created after first mouse. By adding to and subtracting from the initial selection, this option allows declaring extra outlines of the selection.</param>
40+
static member style
41+
(
42+
[<Optional; DefaultParameterValue(null)>] ?LineColor: Color,
43+
[<Optional; DefaultParameterValue(null)>] ?LineDash: StyleParam.DrawingStyle,
44+
[<Optional; DefaultParameterValue(null)>] ?LineWidth: float,
45+
[<Optional; DefaultParameterValue(null)>] ?Mode: StyleParam.NewSelectionMode
46+
) =
47+
(fun (newSelection: NewSelection) ->
48+
49+
let line = Line.init(?Color = LineColor, ?Dash = LineDash, ?Width = LineWidth)
50+
51+
line |> DynObj.setValue newSelection "line"
52+
Mode |> DynObj.setValueOptBy newSelection "mode" StyleParam.NewSelectionMode.convert
53+
54+
NewSelection)

0 commit comments

Comments
 (0)