From ae0bf7ec37c443c0b7020d20092e17632e06520e Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Sat, 14 Aug 2021 18:10:08 +0200 Subject: [PATCH 01/21] Add Lighting and Lightposition objects --- src/Plotly.NET/Lighting.fs | 115 +++++++++++++++++++++++++++++++ src/Plotly.NET/Plotly.NET.fsproj | 1 + 2 files changed, 116 insertions(+) create mode 100644 src/Plotly.NET/Lighting.fs diff --git a/src/Plotly.NET/Lighting.fs b/src/Plotly.NET/Lighting.fs new file mode 100644 index 000000000..1547e454e --- /dev/null +++ b/src/Plotly.NET/Lighting.fs @@ -0,0 +1,115 @@ +namespace Plotly.NET + +open DynamicObj +open System + +/// An object to set the Lighting of a 3D Scene +type Lighting() = + inherit DynamicObj () + + /// + /// Initialize a Lighting object + /// + /// Ambient light increases overall color visibility but can wash out the image. + /// Represents the extent that incident rays are reflected in a range of angles. + /// Epsilon for face normals calculation avoids math issues arising from degenerate geometry. + /// Represents the reflectance as a dependency of the viewing angle; e.g. paper is reflective when viewing it from the edge of the paper (almost 90 degrees), causing shine. + /// Alters specular reflection; the rougher the surface, the wider and less contrasty the shine. + /// Represents the level that incident rays are reflected in a single direction, causing shine. + /// Epsilon for vertex normals calculation avoids math issues arising from degenerate geometry. + static member init + ( + ?Ambient : float, + ?Diffuse : float, + ?FaceNormalEpsilon : float, + ?Fresnel : float, + ?Roughness : float, + ?Specular : float, + ?VertexNormalEpsilon: float + ) = + Lighting() + |> Lighting.style + ( + ?Ambient = Ambient , + ?Diffuse = Diffuse , + ?FaceNormalEpsilon = FaceNormalEpsilon , + ?Fresnel = Fresnel , + ?Roughness = Roughness , + ?Specular = Specular , + ?VertexNormalEpsilon= VertexNormalEpsilon + ) + + /// + /// Creates a function that applies the given style parameters to a Lighting object + /// + /// Ambient light increases overall color visibility but can wash out the image. + /// Represents the extent that incident rays are reflected in a range of angles. + /// Epsilon for face normals calculation avoids math issues arising from degenerate geometry. + /// Represents the reflectance as a dependency of the viewing angle; e.g. paper is reflective when viewing it from the edge of the paper (almost 90 degrees), causing shine. + /// Alters specular reflection; the rougher the surface, the wider and less contrasty the shine. + /// Represents the level that incident rays are reflected in a single direction, causing shine. + /// Epsilon for vertex normals calculation avoids math issues arising from degenerate geometry. + static member style + ( + ?Ambient : float, + ?Diffuse : float, + ?FaceNormalEpsilon : float, + ?Fresnel : float, + ?Roughness : float, + ?Specular : float, + ?VertexNormalEpsilon : float + ) = + fun (l:Lighting) -> + + Ambient |> DynObj.setValueOpt l "ambient" + Diffuse |> DynObj.setValueOpt l "diffuse" + FaceNormalEpsilon |> DynObj.setValueOpt l "facenormalepsilon" + Fresnel |> DynObj.setValueOpt l "fresnel" + Roughness |> DynObj.setValueOpt l "roughness" + Specular |> DynObj.setValueOpt l "specular" + VertexNormalEpsilon |> DynObj.setValueOpt l "vertexnormalepsilon" + + l + +type LightPosition() = + inherit DynamicObj () + + /// + /// Initialize a LightPosition object + /// + /// + /// + /// + static member init + ( + ?X: float, + ?Y: float, + ?Z: float + ) = + LightPosition() + |> LightPosition.style + ( + ?X= X, + ?Y= Y, + ?Z= Z + ) + + /// + /// Creates a function that applies the given style parameters to a LightPosition object + /// + /// + /// + /// + static member style + ( + ?X: float, + ?Y: float, + ?Z: float + ) = + fun (lp: LightPosition) -> + + X |> DynObj.setValueOpt lp "x" + Y |> DynObj.setValueOpt lp "y" + Z |> DynObj.setValueOpt lp "z" + + lp \ No newline at end of file diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index 176f67d05..ba1ce0347 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -36,6 +36,7 @@ + From ae9a2ddda94fe4dbc233b37dc35ff92ba57089c1 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Sun, 15 Aug 2021 08:33:40 +0200 Subject: [PATCH 02/21] Extend ColorBar with all available params and fix casing --- docs/2_7_heatmaps.fsx | 2 +- src/Plotly.NET.ImageExport/Playground.fsx | 2 +- src/Plotly.NET/Chart.fs | 58 +-- src/Plotly.NET/ChartExtensions.fs | 6 +- src/Plotly.NET/Colorbar.fs | 436 +++++++++++------- src/Plotly.NET/GenericChartExtensions.fs | 6 +- src/Plotly.NET/Marker.fs | 8 +- src/Plotly.NET/Playground.fsx | 2 +- src/Plotly.NET/Plotly.NET.fsproj | 2 +- src/Plotly.NET/Trace.fs | 32 +- src/Plotly.NET/Trace3d.fs | 32 +- .../HtmlCodegen/GeoMapCharts.fs | 5 +- .../HtmlCodegen/SimpleCharts.fs | 8 +- 13 files changed, 338 insertions(+), 261 deletions(-) diff --git a/docs/2_7_heatmaps.fsx b/docs/2_7_heatmaps.fsx index e0a57fffd..c6a2ddf14 100644 --- a/docs/2_7_heatmaps.fsx +++ b/docs/2_7_heatmaps.fsx @@ -80,7 +80,7 @@ Here is an example that adds a title to the colorbar: let heat2 = heat1 |> Chart.withColorBarStyle( - "Im the Colorbar", + "Im the ColorBar", TitleSide = StyleParam.Side.Right, TitleFont = Font.init(Size=20.) ) diff --git a/src/Plotly.NET.ImageExport/Playground.fsx b/src/Plotly.NET.ImageExport/Playground.fsx index ba2e41f9b..4e7a6b3c1 100644 --- a/src/Plotly.NET.ImageExport/Playground.fsx +++ b/src/Plotly.NET.ImageExport/Playground.fsx @@ -15,7 +15,7 @@ #load "../Plotly.NET/Title.fs" #load "../Plotly.NET/Pathbar.fs" #load "../Plotly.NET/TreemapTiling.fs" -#load "../Plotly.NET/Colorbar.fs" +#load "../Plotly.NET/ColorBar.fs" #load "../Plotly.NET/RangeSlider.fs" #load "../Plotly.NET/Button.fs" #load "../Plotly.NET/RangeSelector.fs" diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index 5f726347b..bd961d919 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -1144,12 +1144,12 @@ type Chart = [] ?Xgap, [] ?Ygap, [] ?zSmooth, - [] ?Colorbar, + [] ?ColorBar, []?UseWebGL : bool) = let style = TraceStyle.Heatmap(Z=data,?X=ColNames, ?Y=RowNames, - ?Xgap=Xgap,?Ygap=Ygap,?Colorscale=Colorscale,?Showscale=Showscale,?zSmooth=zSmooth,?Colorbar=Colorbar) + ?Xgap=Xgap,?Ygap=Ygap,?Colorscale=Colorscale,?Showscale=Showscale,?zSmooth=zSmooth,?ColorBar=ColorBar) >> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity) let useWebGL = defaultArg UseWebGL false @@ -1167,9 +1167,9 @@ type Chart = [] ?Colorscale, [] ?Showscale, [] ?zSmooth, - [] ?Colorbar) = + [] ?ColorBar) = Trace.initContour (TraceStyle.Contour(Z=data,?X=X, ?Y=Y, - ?Colorscale=Colorscale,?Showscale=Showscale,?zSmooth=zSmooth,?Colorbar=Colorbar) ) + ?Colorscale=Colorscale,?Showscale=Showscale,?zSmooth=zSmooth,?ColorBar=ColorBar) ) |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity) |> GenericChart.ofTraceObject @@ -1638,7 +1638,7 @@ type Chart = [] ?Colorscale, [] ?Showscale, [] ?zSmooth, - [] ?Colorbar, + [] ?ColorBar, [] ?zAuto, [] ?zMin, [] ?zMax, @@ -1656,7 +1656,7 @@ type Chart = ?Colorscale=Colorscale, ?Showscale=Showscale, ?zSmooth=zSmooth, - ?Colorbar=Colorbar, + ?ColorBar=ColorBar, ?zAuto=zAuto, ?zMin=zMin, ?zMax=zMax, @@ -1672,10 +1672,10 @@ type Chart = // // /// Computes the bi-dimensional histogram of two data samples and auto-determines the bin size. -// // static member Histogram2d(xy,?Name,?HistNorm,?HistFunc,?Colorscale,?Showscale,?zSmooth,?Colorbar,?zAuto,?zMin,?zMax,?nBinsx,?nBinsy,?Xbins,?Ybins) = +// // static member Histogram2d(xy,?Name,?HistNorm,?HistFunc,?Colorscale,?Showscale,?zSmooth,?ColorBar,?zAuto,?zMin,?zMax,?nBinsx,?nBinsy,?Xbins,?Ybins) = // // let x,y = Seq.unzip xy // // Chart.Histogram2d(x,y,?Name=Name,?HistNorm=HistNorm,?HistFunc=HistFunc,?Colorscale=Colorscale, -// // ?Showscale=Showscale,?Colorbar=Colorbar,?zSmooth=zSmooth,?zAuto=zAuto,?zMin=zMin,?zMax=zMax, +// // ?Showscale=Showscale,?ColorBar=ColorBar,?zSmooth=zSmooth,?zAuto=zAuto,?zMin=zMin,?zMax=zMax, // // ?nBinsx=nBinsx,?nBinsy=nBinsy,?Xbins=Xbins,?Ybins=Ybins // // ) @@ -1687,7 +1687,7 @@ type Chart = [] ?Showscale, [] ?Line, [] ?zSmooth, - [] ?Colorbar, + [] ?ColorBar, [] ?zAuto, [] ?zMin, [] ?zMax, @@ -1702,7 +1702,7 @@ type Chart = ?Colorscale=Colorscale, ?Showscale=Showscale, ?zSmooth=zSmooth, - ?Colorbar=Colorbar, + ?ColorBar=ColorBar, ?zAuto=zAuto, ?zMin=zMin, ?zMax=zMax, @@ -1802,7 +1802,7 @@ type Chart = [] ?Locationmode, [] ?Autocolorscale, [] ?Colorscale, - [] ?Colorbar, + [] ?ColorBar, [] ?Marker, [] ?GeoJson, [] ?FeatureIdKey: string, @@ -1810,7 +1810,7 @@ type Chart = [] ?Zmax) = Trace.initChoroplethMap ( TraceStyle.ChoroplethMap (Locations=locations,Z=z,?Text=Text,?Locationmode=Locationmode,?Autocolorscale=Autocolorscale, - ?Colorscale=Colorscale,?Colorbar=Colorbar,?Marker=Marker,?Zmin=Zmin,?Zmax=Zmax,?GeoJson=GeoJson,?FeatureIdKey=FeatureIdKey) + ?Colorscale=Colorscale,?ColorBar=ColorBar,?Marker=Marker,?Zmin=Zmin,?Zmax=Zmax,?GeoJson=GeoJson,?FeatureIdKey=FeatureIdKey) ) |> GenericChart.ofTraceObject @@ -1899,10 +1899,10 @@ type Chart = [] ?Contours, [] ?Colorscale, [] ?Showscale, - [] ?Colorbar) = + [] ?ColorBar) = Trace3d.initSurface ( Trace3dStyle.Surface (Z=data,?X=X, ?Y=Y,?Contours=Contours, - ?Colorscale=Colorscale,?Showscale=Showscale,?Colorbar=Colorbar ) ) + ?Colorscale=Colorscale,?Showscale=Showscale,?ColorBar=ColorBar ) ) |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity) //|> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont) |> GenericChart.ofTraceObject @@ -1981,7 +1981,7 @@ type Chart = /// /// Maxdepth: Sets the number of rendered sectors from any given `level`. Set `maxdepth` to "-1" to render all the levels in the hierarchy. /// - /// Colorbar: Sets the Colorbar for the chart + /// ColorBar: Sets the ColorBar for the chart /// ///Colors: Sets the color of each sector of this trace. If not specified, the default trace color set is used to pick the sector colors. static member Sunburst(labels,parents, @@ -1992,7 +1992,7 @@ type Chart = []?Level , []?Maxdepth , []?Colors: seq, - []?Colorbar:Colorbar + []?ColorBar:ColorBar ) = Trace.initSunburst( TraceStyle.Sunburst( @@ -2006,7 +2006,7 @@ type Chart = ?Maxdepth = Maxdepth ) ) - |> TraceStyle.Marker(?Colors=Colors,?Colorbar=Colorbar) + |> TraceStyle.Marker(?Colors=Colors,?ColorBar=ColorBar) |> GenericChart.ofTraceObject @@ -2030,7 +2030,7 @@ type Chart = /// /// Maxdepth: Sets the number of rendered sectors from any given `level`. Set `maxdepth` to "-1" to render all the levels in the hierarchy. /// - /// Colorbar: Sets the Colorbar for the chart + /// ColorBar: Sets the ColorBar for the chart /// ///Colors: Sets the color of each sector of this trace. If not specified, the default trace color set is used to pick the sector colors. static member Treemap(labels,parents, @@ -2043,7 +2043,7 @@ type Chart = []?Level , []?Maxdepth , []?Colors: seq, - []?Colorbar:Colorbar + []?ColorBar:ColorBar ) = Trace.initTreemap( TraceStyle.Treemap( @@ -2059,7 +2059,7 @@ type Chart = ?Maxdepth = Maxdepth ) ) - |> TraceStyle.Marker(?Colors=Colors,?Colorbar=Colorbar) + |> TraceStyle.Marker(?Colors=Colors,?ColorBar=ColorBar) |> GenericChart.ofTraceObject /// Creates an OHLC (open-high-low-close) chart. OHLC charts are typically used to illustrate movements in the price of a financial instrument over time. @@ -3530,7 +3530,7 @@ type Chart = /// Sets the text elements associated with each location. /// Determines if the choropleth polygons will be inserted before the layer with the specified ID. By default, choroplethmapbox traces are placed above the water layers. If set to '', the layer will be inserted above every existing layer. /// Sets the colorscale. - /// Sets the Colorbar object asociated with this trace + /// Sets the ColorBar object asociated with this trace /// Determines whether or not the color domain is computed with respect to the input data (here in `z`) or the bounds set in `zmin` and `zmax` Defaults to `false` when `zmin` and `zmax` are set by the user. /// Sets the lower bound of the color domain. Value should have the same units as in `z` and if set, `zmax` must be set as well. /// Sets the mid-point of the color domain by scaling `zmin` and/or `zmax` to be equidistant to this point. Value should have the same units as in `z`. Has no effect when `zauto` is `false`. @@ -3540,7 +3540,7 @@ type Chart = [] ?Text, [] ?Below, [] ?Colorscale, - [] ?Colorbar, + [] ?ColorBar, [] ?ZAuto, [] ?ZMin, [] ?ZMid, @@ -3556,7 +3556,7 @@ type Chart = ?Text = Text, ?Below = Below, ?Colorscale = Colorscale, - ?Colorbar = Colorbar, + ?ColorBar = ColorBar, ?ZAuto = ZAuto, ?ZMin = ZMin, ?ZMid = ZMid, @@ -3576,7 +3576,7 @@ type Chart = /// Sets text elements associated with each (lon,lat) pair If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (lon,lat) coordinates. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. /// Determines if the densitymapbox trace will be inserted before the layer with the specified ID. By default, densitymapbox traces are placed below the first layer of type symbol If set to '', the layer will be inserted above every existing layer. /// Sets the colorscale. - /// Sets the Colorbar object asociated with this trace + /// Sets the ColorBar object asociated with this trace /// Determines whether or not a colorbar is displayed for this trace. /// Determines whether or not the color domain is computed with respect to the input data (here in `z`) or the bounds set in `zmin` and `zmax` Defaults to `false` when `zmin` and `zmax` are set by the user. /// Sets the lower bound of the color domain. Value should have the same units as in `z` and if set, `zmax` must be set as well. @@ -3589,7 +3589,7 @@ type Chart = [] ?Text, [] ?Below, [] ?Colorscale, - [] ?Colorbar, + [] ?ColorBar, [] ?Showscale , [] ?ZAuto, [] ?ZMin, @@ -3606,7 +3606,7 @@ type Chart = ?Text = Text, ?Below = Below, ?Colorscale = Colorscale, - ?Colorbar = Colorbar, + ?ColorBar = ColorBar, ?Showscale = Showscale, ?ZAuto = ZAuto, ?ZMin = ZMin, @@ -3626,7 +3626,7 @@ type Chart = /// Sets text elements associated with each (lon,lat) pair If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (lon,lat) coordinates. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. /// Determines if the densitymapbox trace will be inserted before the layer with the specified ID. By default, densitymapbox traces are placed below the first layer of type symbol If set to '', the layer will be inserted above every existing layer. /// Sets the colorscale. - /// Sets the Colorbar object asociated with this trace + /// Sets the ColorBar object asociated with this trace /// Determines whether or not a colorbar is displayed for this trace. /// Determines whether or not the color domain is computed with respect to the input data (here in `z`) or the bounds set in `zmin` and `zmax` Defaults to `false` when `zmin` and `zmax` are set by the user. /// Sets the lower bound of the color domain. Value should have the same units as in `z` and if set, `zmax` must be set as well. @@ -3639,7 +3639,7 @@ type Chart = [] ?Text, [] ?Below, [] ?Colorscale, - [] ?Colorbar, + [] ?ColorBar, [] ?Showscale , [] ?ZAuto, [] ?ZMin, @@ -3658,7 +3658,7 @@ type Chart = ?Text = Text, ?Below = Below, ?Colorscale = Colorscale, - ?Colorbar = Colorbar, + ?ColorBar = ColorBar, ?Showscale = Showscale, ?ZAuto = ZAuto, ?ZMin = ZMin, diff --git a/src/Plotly.NET/ChartExtensions.fs b/src/Plotly.NET/ChartExtensions.fs index 7ba1004ab..06f65f34d 100644 --- a/src/Plotly.NET/ChartExtensions.fs +++ b/src/Plotly.NET/ChartExtensions.fs @@ -408,7 +408,7 @@ module ChartExtensions = Chart.withZ_Axis(zaxis) [] - static member withColorBar(colorbar:Colorbar) = + static member withColorBar(colorbar:ColorBar) = (fun (ch:GenericChart) -> ch |> GenericChart.mapTrace(fun t -> @@ -420,13 +420,11 @@ module ChartExtensions = [] static member withColorBarStyle(title, - [] ?TitleSide: StyleParam.Side, - [] ?TitleFont: Font, [] ?Length, [] ?OutlineColor, [] ?BorderColor, [] ?BGColor) = - let colorbar = Colorbar.init(Title=title,?Titleside=TitleSide,?Titlefont=TitleFont,?Len = Length,?Outlinecolor=OutlineColor,?Bgcolor=BGColor,?Bordercolor=BorderColor) + let colorbar = ColorBar.init(Title=title,?Len = Length,?OutlineColor=OutlineColor,?BGColor=BGColor,?BorderColor=BorderColor) Chart.withColorBar(colorbar) //// Sets second x-Axis of 2d- Charts //static member withX_Axis2(xAxis2:Axis.LinearAxis) = diff --git a/src/Plotly.NET/Colorbar.fs b/src/Plotly.NET/Colorbar.fs index 7966c41b4..5527a9ba7 100644 --- a/src/Plotly.NET/Colorbar.fs +++ b/src/Plotly.NET/Colorbar.fs @@ -3,196 +3,280 @@ namespace Plotly.NET open DynamicObj open System -/// Colorbar type inherits from dynamic object -type Colorbar () = +/// The ColorBar object to be used with ColorAxes. +type ColorBar () = inherit DynamicObj () - /// Initialized Colorbar object - //[] + /// + /// Initializes a ColorBar object. + /// + /// Sets the color of padded area. + /// Sets the axis line color. + /// Sets the width (in px) or the border enclosing this color bar. + /// Sets the step in-between ticks on this axis. Use with `tick0`. Must be a positive number, or special strings available to "log" and "date" axes. If the axis `type` is "log", then ticks are set every 10^(n"dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. "log" has several special values; "L<f>", where `f` is a positive number, gives ticks linearly spaced in value (but not position). For example `tick0` = 0.1, `dtick` = "L0.5" will put ticks at 0.1, 0.6, 1.1, 1.6 etc. To show powers of 10 plus small digits between, use "D1" (all digits) or "D2" (only 2 and 5). `tick0` is ignored for "D1" and "D2". If the axis `type` is "date", then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0. "date" also has special values "M<n>" gives ticks spaced by a number of months. `n` must be a positive integer. To set ticks on the 15th of every third month, set `tick0` to "2000-01-15" and `dtick` to "M3". To set ticks every 4 years, set `dtick` to "M48" + /// Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If "none", it appears as 1,000,000,000. If "e", 1e+9. If "E", 1E+9. If "power", 1x10^9 (with 9 in a super script). If "SI", 1G. If "B", 1B. + /// Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends. + /// Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot "fraction" or in "pixels. Use `len` to set the value. + /// Hide SI prefix for 10^n if |n| is below this number. This only has an effect when `tickformat` is "SI" or "B". + /// Specifies the maximum number of ticks for the particular axis. The actual number of ticks will be chosen automatically to be less than or equal to `nticks`. Has an effect only if `tickmode` is set to "auto". + /// Sets the axis line color. + /// Sets the width (in px) of the axis line. + /// If "true", even 4-digit integers are separated + /// If "all", all exponents are shown besides their significands. If "first", only the exponent of the first tick is shown. If "last", only the exponent of the last tick is shown. If "none", no exponents appear. + /// Determines whether or not the tick labels are drawn. + /// If "all", all tick labels are displayed with a prefix. If "first", only the first tick is displayed with a prefix. If "last", only the last tick is displayed with a suffix. If "none", tick prefixes are hidden. + /// Same as `showtickprefix` but for tick suffixes. + /// Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels. + /// Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot "fraction" or in "pixels". Use `thickness` to set the value. + /// Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is "log", then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2) except when `dtick`="L>f<" (see `dtick` for more info). If the axis `type` is "date", it should be a date string, like date data. If the axis `type` is "category", it should be a number, using the scale where each category is assigned a serial number from zero in the order it appears. + /// Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically. + /// Sets the tick color. + /// Sets the color bar's tick label font + /// Sets the tick label formatting rule using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46" + /// Set rules for customizing TickFormat on different zoom levels + /// Determines how we handle tick labels that would overflow either the graph div or the domain of the axis. The default value for inside tick labels is "hide past domain". In other cases the default is "hide past div". + /// Determines where tick labels are drawn. + /// Sets the tick length (in px). + /// Sets the tick mode for this axis. If "auto", the number of ticks is set via `nticks`. If "linear", the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` ("linear" is the default value if `tick0` and `dtick` are provided). If "array", the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. ("array" is the default value if `tickvals` is provided). + /// Sets a tick label prefix. + /// Determines whether ticks are drawn or not. If "", this axis' ticks are not drawn. If "outside" ("inside"), this axis' are drawn outside (inside) the axis lines. + /// Sets a tick label suffix. + /// Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to "array". Used with `tickvals`. + /// Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to "array". Used with `ticktext`. + /// Sets the tick width (in px). + /// Sets the ColorBar title. + /// Sets the x position of the color bar (in plot fraction). + /// Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the "left", "center" or "right" of the color bar. + /// Sets the amount of padding (in px) along the x direction. + /// Sets the y position of the color bar (in plot fraction). + /// Sets this color bar's vertical position anchor This anchor binds the `y` position to the "top", "middle" or "bottom" of the color bar. + /// Sets the amount of padding (in px) along the y direction. static member init ( - ?Thicknessmode: StyleParam.UnitMode, - ?Thickness: int, - ?Lenmode: StyleParam.UnitMode, - ?Len: float, - ?X: float, - ?Xanchor: StyleParam.HorizontalAlign, - ?Xpad: float, - ?Y: float, - ?Yanchor: StyleParam.VerticalAlign, - ?Ypad: float, - ?Outlinecolor: string, - ?Outlinewidth: float, - ?Bordercolor: string, - ?Borderwidth: float, - ?Bgcolor: string, - ?Tickmode: StyleParam.TickMode, - ?nTicks: int, - ?Tick0: IConvertible, - ?dTick: IConvertible, - ?Tickvals: seq<#IConvertible>, - ?Ticktext: seq<#IConvertible>, - ?Ticks: StyleParam.TickOptions, - ?Ticklen: float, - ?Tickwidth: float, - ?Tickcolor: string, - ?Showticklabels: bool, - ?Tickfont: Font, - ?Tickangle: int, - ?Tickformat: string, - ?Tickprefix: string, - ?Showtickprefix: StyleParam.ShowTickOption, - ?Ticksuffix: string, - ?Showticksuffix: StyleParam.ShowTickOption, - ?Exponentformat: StyleParam.ExponentFormat, - ?Showexponent: StyleParam.ShowExponent, - ?Title: string, - ?Titlefont: Font, - ?Titleside: StyleParam.Side + ?BGColor : string, + ?BorderColor : string, + ?BorderWidth : float, + ?DTick : IConvertible, + ?ExponentFormat : StyleParam.ExponentFormat, + ?Len : float, + ?LenMode : StyleParam.UnitMode, + ?MinExponent : float, + ?NTicks : int, + ?OutlineColor : string, + ?OutlineWidth : float, + ?SeparateThousands : bool, + ?ShowExponent : StyleParam.ShowExponent, + ?ShowTickLabels : bool, + ?ShowTickPrefix : StyleParam.ShowTickOption, + ?ShowTickSuffix : StyleParam.ShowTickOption, + ?Thickness : float, + ?ThicknessMode : StyleParam.UnitMode, + ?Tick0 : IConvertible, + ?TickAngle : int, + ?TickColor : string, + ?TickFont : Font, + ?TickFormat : string, + ?TickFormatStops : seq, + ?TickLabelOverflow : StyleParam.TickLabelOverflow, + ?TickLabelPosition : StyleParam.TickLabelPosition, + ?TickLen : float, + ?TickMode : StyleParam.TickMode, + ?TickPrefix : string, + ?Ticks : StyleParam.TickOptions, + ?TickSuffix : string, + ?TickText : seq<#IConvertible>, + ?TickVals : seq<#IConvertible>, + ?TickWidth : float, + ?Title : Title, + ?X : float, + ?XAnchor : StyleParam.HorizontalAlign, + ?XPad : float, + + ?Y : float, + ?YAnchor : StyleParam.VerticalAlign, + ?YPad : float ) = - Colorbar() - |> Colorbar.style + ColorBar() + |> ColorBar.style ( - ?Thicknessmode = Thicknessmode , - ?Thickness = Thickness , - ?Lenmode = Lenmode , - ?Len = Len , - ?X = X , - ?Xanchor = Xanchor , - ?Xpad = Xpad , - ?Y = Y , - ?Yanchor = Yanchor , - ?Ypad = Ypad , - ?Outlinecolor = Outlinecolor , - ?Outlinewidth = Outlinewidth , - ?Bordercolor = Bordercolor , - ?Borderwidth = Borderwidth , - ?Bgcolor = Bgcolor , - ?Tickmode = Tickmode , - ?nTicks = nTicks , - ?Tick0 = Tick0 , - ?dTick = dTick , - ?Tickvals = Tickvals , - ?Ticktext = Ticktext , - ?Ticks = Ticks , - ?Ticklen = Ticklen , - ?Tickwidth = Tickwidth , - ?Tickcolor = Tickcolor , - ?Showticklabels = Showticklabels, - ?Tickfont = Tickfont , - ?Tickangle = Tickangle , - ?Tickformat = Tickformat , - ?Tickprefix = Tickprefix , - ?Showtickprefix = Showtickprefix, - ?Ticksuffix = Ticksuffix , - ?Showticksuffix = Showticksuffix, - ?Exponentformat = Exponentformat, - ?Showexponent = Showexponent , - ?Title = Title , - ?Titlefont = Titlefont , - ?Titleside = Titleside - + ?BGColor = BGColor , + ?BorderColor = BorderColor , + ?BorderWidth = BorderWidth , + ?DTick = DTick , + ?ExponentFormat = ExponentFormat , + ?Len = Len , + ?LenMode = LenMode , + ?MinExponent = MinExponent , + ?NTicks = NTicks , + ?OutlineColor = OutlineColor , + ?OutlineWidth = OutlineWidth , + ?SeparateThousands = SeparateThousands , + ?ShowExponent = ShowExponent , + ?ShowTickLabels = ShowTickLabels , + ?ShowTickPrefix = ShowTickPrefix , + ?ShowTickSuffix = ShowTickSuffix , + ?Thickness = Thickness , + ?ThicknessMode = ThicknessMode , + ?Tick0 = Tick0 , + ?TickAngle = TickAngle , + ?TickColor = TickColor , + ?TickFont = TickFont , + ?TickFormat = TickFormat , + ?TickFormatStops = TickFormatStops , + ?TickLabelOverflow = TickLabelOverflow , + ?TickLabelPosition = TickLabelPosition , + ?TickLen = TickLen , + ?TickMode = TickMode , + ?TickPrefix = TickPrefix , + ?Ticks = Ticks , + ?TickSuffix = TickSuffix , + ?TickText = TickText , + ?TickVals = TickVals , + ?TickWidth = TickWidth , + ?Title = Title , + ?X = X , + ?XAnchor = XAnchor , + ?XPad = XPad , + ?Y = Y , + ?YAnchor = YAnchor , + ?YPad = YPad ) - /// Applies the styles to Lighting() - //[] + /// + /// Create a function that applies the given style parameters to a ColorBar object + /// + /// Sets the color of padded area. + /// Sets the axis line color. + /// Sets the width (in px) or the border enclosing this color bar. + /// Sets the step in-between ticks on this axis. Use with `tick0`. Must be a positive number, or special strings available to "log" and "date" axes. If the axis `type` is "log", then ticks are set every 10^(n"dtick) where n is the tick number. For example, to set a tick mark at 1, 10, 100, 1000, ... set dtick to 1. To set tick marks at 1, 100, 10000, ... set dtick to 2. To set tick marks at 1, 5, 25, 125, 625, 3125, ... set dtick to log_10(5), or 0.69897000433. "log" has several special values; "L<f>", where `f` is a positive number, gives ticks linearly spaced in value (but not position). For example `tick0` = 0.1, `dtick` = "L0.5" will put ticks at 0.1, 0.6, 1.1, 1.6 etc. To show powers of 10 plus small digits between, use "D1" (all digits) or "D2" (only 2 and 5). `tick0` is ignored for "D1" and "D2". If the axis `type` is "date", then you must convert the time to milliseconds. For example, to set the interval between ticks to one day, set `dtick` to 86400000.0. "date" also has special values "M<n>" gives ticks spaced by a number of months. `n` must be a positive integer. To set ticks on the 15th of every third month, set `tick0` to "2000-01-15" and `dtick` to "M3". To set ticks every 4 years, set `dtick` to "M48" + /// Determines a formatting rule for the tick exponents. For example, consider the number 1,000,000,000. If "none", it appears as 1,000,000,000. If "e", 1e+9. If "E", 1E+9. If "power", 1x10^9 (with 9 in a super script). If "SI", 1G. If "B", 1B. + /// Sets the length of the color bar This measure excludes the padding of both ends. That is, the color bar length is this length minus the padding on both ends. + /// Determines whether this color bar's length (i.e. the measure in the color variation direction) is set in units of plot "fraction" or in "pixels. Use `len` to set the value. + /// Hide SI prefix for 10^n if |n| is below this number. This only has an effect when `tickformat` is "SI" or "B". + /// Specifies the maximum number of ticks for the particular axis. The actual number of ticks will be chosen automatically to be less than or equal to `nticks`. Has an effect only if `tickmode` is set to "auto". + /// Sets the axis line color. + /// Sets the width (in px) of the axis line. + /// If "true", even 4-digit integers are separated + /// If "all", all exponents are shown besides their significands. If "first", only the exponent of the first tick is shown. If "last", only the exponent of the last tick is shown. If "none", no exponents appear. + /// Determines whether or not the tick labels are drawn. + /// If "all", all tick labels are displayed with a prefix. If "first", only the first tick is displayed with a prefix. If "last", only the last tick is displayed with a suffix. If "none", tick prefixes are hidden. + /// Same as `showtickprefix` but for tick suffixes. + /// Sets the thickness of the color bar This measure excludes the size of the padding, ticks and labels. + /// Determines whether this color bar's thickness (i.e. the measure in the constant color direction) is set in units of plot "fraction" or in "pixels". Use `thickness` to set the value. + /// Sets the placement of the first tick on this axis. Use with `dtick`. If the axis `type` is "log", then you must take the log of your starting tick (e.g. to set the starting tick to 100, set the `tick0` to 2) except when `dtick`="L>f<" (see `dtick` for more info). If the axis `type` is "date", it should be a date string, like date data. If the axis `type` is "category", it should be a number, using the scale where each category is assigned a serial number from zero in the order it appears. + /// Sets the angle of the tick labels with respect to the horizontal. For example, a `tickangle` of -90 draws the tick labels vertically. + /// Sets the tick color. + /// Sets the color bar's tick label font + /// Sets the tick label formatting rule using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46" + /// Set rules for customizing TickFormat on different zoom levels + /// Determines how we handle tick labels that would overflow either the graph div or the domain of the axis. The default value for inside tick labels is "hide past domain". In other cases the default is "hide past div". + /// Determines where tick labels are drawn. + /// Sets the tick length (in px). + /// Sets the tick mode for this axis. If "auto", the number of ticks is set via `nticks`. If "linear", the placement of the ticks is determined by a starting position `tick0` and a tick step `dtick` ("linear" is the default value if `tick0` and `dtick` are provided). If "array", the placement of the ticks is set via `tickvals` and the tick text is `ticktext`. ("array" is the default value if `tickvals` is provided). + /// Sets a tick label prefix. + /// Determines whether ticks are drawn or not. If "", this axis' ticks are not drawn. If "outside" ("inside"), this axis' are drawn outside (inside) the axis lines. + /// Sets a tick label suffix. + /// Sets the text displayed at the ticks position via `tickvals`. Only has an effect if `tickmode` is set to "array". Used with `tickvals`. + /// Sets the values at which ticks on this axis appear. Only has an effect if `tickmode` is set to "array". Used with `ticktext`. + /// Sets the tick width (in px). + /// Sets the ColorBar title. + /// Sets the x position of the color bar (in plot fraction). + /// Sets this color bar's horizontal position anchor. This anchor binds the `x` position to the "left", "center" or "right" of the color bar. + /// Sets the amount of padding (in px) along the x direction. + /// Sets the y position of the color bar (in plot fraction). + /// Sets this color bar's vertical position anchor This anchor binds the `y` position to the "top", "middle" or "bottom" of the color bar. + /// Sets the amount of padding (in px) along the y direction. static member style ( - ?Thicknessmode: StyleParam.UnitMode, - ?Thickness: int, - ?Lenmode: StyleParam.UnitMode, - ?Len: float, - ?X: float, - ?Xanchor: StyleParam.HorizontalAlign, - ?Xpad: float, - ?Y: float, - ?Yanchor: StyleParam.VerticalAlign, - ?Ypad: float, - ?Outlinecolor: string, - ?Outlinewidth: float, - ?Bordercolor: string, - ?Borderwidth: float, - ?Bgcolor: string, - ?Tickmode: StyleParam.TickMode, - ?nTicks: int, - ?Tick0: IConvertible, - ?dTick: IConvertible, - ?Tickvals: seq<#IConvertible>, - ?Ticktext: seq<#IConvertible>, - ?Ticks: StyleParam.TickOptions, - ?Ticklen: float, - ?Tickwidth: float, - ?Tickcolor: string, - ?Showticklabels: bool, - ?Tickfont: Font, - ?Tickangle: int, - ?Tickformat: string, - ?Tickprefix: string, - ?Showtickprefix: StyleParam.ShowTickOption, - ?Ticksuffix: string, - ?Showticksuffix: StyleParam.ShowTickOption, - ?Exponentformat: StyleParam.ExponentFormat, - ?Showexponent: StyleParam.ShowExponent, - ?Title: string, - ?Titlefont: Font, - ?Titleside: StyleParam.Side + ?BGColor : string, + ?BorderColor : string, + ?BorderWidth : float, + ?DTick : IConvertible, + ?ExponentFormat : StyleParam.ExponentFormat, + ?Len : float, + ?LenMode : StyleParam.UnitMode, + ?MinExponent : float, + ?NTicks : int, + ?OutlineColor : string, + ?OutlineWidth : float, + ?SeparateThousands : bool, + ?ShowExponent : StyleParam.ShowExponent, + ?ShowTickLabels : bool, + ?ShowTickPrefix : StyleParam.ShowTickOption, + ?ShowTickSuffix : StyleParam.ShowTickOption, + ?Thickness : float, + ?ThicknessMode : StyleParam.UnitMode, + ?Tick0 : IConvertible, + ?TickAngle : int, + ?TickColor : string, + ?TickFont : Font, + ?TickFormat : string, + ?TickFormatStops : seq, + ?TickLabelOverflow : StyleParam.TickLabelOverflow, + ?TickLabelPosition : StyleParam.TickLabelPosition, + ?TickLen : float, + ?TickMode : StyleParam.TickMode, + ?TickPrefix : string, + ?Ticks : StyleParam.TickOptions, + ?TickSuffix : string, + ?TickText : seq<#IConvertible>, + ?TickVals : seq<#IConvertible>, + ?TickWidth : float, + ?Title : Title, + ?X : float, + ?XAnchor : StyleParam.HorizontalAlign, + ?XPad : float, + ?Y : float, + ?YAnchor : StyleParam.VerticalAlign, + ?YPad : float ) = - (fun (colorbar:Colorbar) -> - Thicknessmode |> DynObj.setValueOptBy colorbar "thicknessmode" StyleParam.UnitMode.convert - Thickness |> DynObj.setValueOpt colorbar "thickness" - Lenmode |> DynObj.setValueOptBy colorbar "lenmode" StyleParam.UnitMode.convert - Len |> DynObj.setValueOpt colorbar "len" - X |> DynObj.setValueOpt colorbar "x" - Xanchor |> DynObj.setValueOpt colorbar "xanchor" - Xpad |> DynObj.setValueOpt colorbar "xpad" - Y |> DynObj.setValueOpt colorbar "y" - Yanchor |> DynObj.setValueOpt colorbar "yanchor" - Ypad |> DynObj.setValueOpt colorbar "ypad" - Outlinecolor |> DynObj.setValueOpt colorbar "outlinecolor" - Outlinewidth |> DynObj.setValueOpt colorbar "outlinewidth" - Bordercolor |> DynObj.setValueOpt colorbar "bordercolor" - Borderwidth |> DynObj.setValueOpt colorbar "borderwidth" - Bgcolor |> DynObj.setValueOpt colorbar "bgcolor" - Tickmode |> DynObj.setValueOpt colorbar "tickmode" - nTicks |> DynObj.setValueOpt colorbar "nticks" - Tick0 |> DynObj.setValueOpt colorbar "tick0" - dTick |> DynObj.setValueOpt colorbar "dtick" - Tickvals |> DynObj.setValueOpt colorbar "tickvals" - Ticktext |> DynObj.setValueOpt colorbar "ticktext" - Ticks |> DynObj.setValueOpt colorbar "ticks" - Ticklen |> DynObj.setValueOpt colorbar "ticklen" - Tickwidth |> DynObj.setValueOpt colorbar "tickwidth" - Tickcolor |> DynObj.setValueOpt colorbar "tickcolor" - Showticklabels |> DynObj.setValueOpt colorbar "showticklabels" - Tickfont |> DynObj.setValueOpt colorbar "tickfont" - Tickangle |> DynObj.setValueOpt colorbar "tickangle" - Tickformat |> DynObj.setValueOpt colorbar "tickformat" - Tickprefix |> DynObj.setValueOpt colorbar "tickprefix" - Showtickprefix |> DynObj.setValueOpt colorbar "showtickprefix" - Ticksuffix |> DynObj.setValueOpt colorbar "ticksuffix" - Showticksuffix |> DynObj.setValueOpt colorbar "showticksuffix" - Exponentformat |> DynObj.setValueOpt colorbar "exponentformat" - Showexponent |> DynObj.setValueOpt colorbar "showexponent" - Title |> DynObj.setValueOpt colorbar "title" - Titlefont |> DynObj.setValueOpt colorbar "titlefont" - Titleside |> DynObj.setValueOptBy colorbar "titleside" (StyleParam.Side.convert) - - colorbar - ) - - -//[] -//module Colorbar = -// -// let initColorbar (applyStyle:Colorbar->Colorbar) = -// Colorbar() |> applyStyle -// -// -// /// Functions provide the styling of the Colorbar object -// type ColorbarStyle() = + (fun (colorBar:ColorBar) -> + BGColor |> DynObj.setValueOpt colorBar "bgcolor" + BorderColor |> DynObj.setValueOpt colorBar "bordercolor" + BorderWidth |> DynObj.setValueOpt colorBar "borderwidth" + DTick |> DynObj.setValueOpt colorBar "dtick" + ExponentFormat |> DynObj.setValueOpt colorBar "exponentformat" + Len |> DynObj.setValueOpt colorBar "len" + LenMode |> DynObj.setValueOpt colorBar "lenmode" + MinExponent |> DynObj.setValueOpt colorBar "min3xponent" + NTicks |> DynObj.setValueOpt colorBar "nticks" + OutlineColor |> DynObj.setValueOpt colorBar "outlinecolor" + OutlineWidth |> DynObj.setValueOpt colorBar "outlinewidth" + SeparateThousands |> DynObj.setValueOpt colorBar "separatethousands" + ShowExponent |> DynObj.setValueOpt colorBar "showexponent" + ShowTickLabels |> DynObj.setValueOpt colorBar "showticklabels" + ShowTickPrefix |> DynObj.setValueOpt colorBar "showtickprefix" + ShowTickSuffix |> DynObj.setValueOpt colorBar "showticksuffix" + Thickness |> DynObj.setValueOpt colorBar "thickness" + ThicknessMode |> DynObj.setValueOpt colorBar "thicknessmode" + Tick0 |> DynObj.setValueOpt colorBar "tick0" + TickAngle |> DynObj.setValueOpt colorBar "tickangle" + TickColor |> DynObj.setValueOpt colorBar "tickcolor" + TickFont |> DynObj.setValueOpt colorBar "tickfont" + TickFormat |> DynObj.setValueOpt colorBar "tickformat" + TickFormatStops |> DynObj.setValueOpt colorBar "tickformatstops" + TickLabelOverflow |> DynObj.setValueOpt colorBar "ticklabeloverflow" + TickLabelPosition |> DynObj.setValueOpt colorBar "ticklabelposition" + TickLen |> DynObj.setValueOpt colorBar "ticklen" + TickMode |> DynObj.setValueOpt colorBar "tickmode" + TickPrefix |> DynObj.setValueOpt colorBar "tickprefix" + Ticks |> DynObj.setValueOpt colorBar "ticks" + TickSuffix |> DynObj.setValueOpt colorBar "ticksuffix" + TickText |> DynObj.setValueOpt colorBar "ticktext" + TickVals |> DynObj.setValueOpt colorBar "tickvals" + TickWidth |> DynObj.setValueOpt colorBar "tickwidth" + Title |> DynObj.setValueOpt colorBar "title" + X |> DynObj.setValueOpt colorBar "x" + XAnchor |> DynObj.setValueOpt colorBar "xanchor" + XPad |> DynObj.setValueOpt colorBar "xpad" + Y |> DynObj.setValueOpt colorBar "y" + YAnchor |> DynObj.setValueOpt colorBar "yanchor" + YPad |> DynObj.setValueOpt colorBar "ypad" + colorBar + ) diff --git a/src/Plotly.NET/GenericChartExtensions.fs b/src/Plotly.NET/GenericChartExtensions.fs index 845c8ceef..d4ab49bc6 100644 --- a/src/Plotly.NET/GenericChartExtensions.fs +++ b/src/Plotly.NET/GenericChartExtensions.fs @@ -284,7 +284,7 @@ module GenericChartExtensions = [] [] - member this.withColorBar(colorbar:Colorbar) = + member this.withColorBar(colorbar:ColorBar) = this |> GenericChart.mapTrace(fun t -> colorbar |> DynObj.setValue t "colorbar" @@ -294,13 +294,11 @@ module GenericChartExtensions = [] [] member this.WithColorBarStyle(title, - [] ?TitleSide: StyleParam.Side, - [] ?TitleFont: Font, [] ?Length, [] ?OutlineColor, [] ?BorderColor, [] ?BGColor) = - let colorbar = Colorbar.init(Title=title,?Titleside=TitleSide,?Titlefont=TitleFont,?Len = Length,?Outlinecolor=OutlineColor,?Bgcolor=BGColor,?Bordercolor=BorderColor) + let colorbar = ColorBar.init(Title=title,?Len = Length,?OutlineColor=OutlineColor,?BGColor=BGColor,?BorderColor=BorderColor) this |> Chart.withColorBar(colorbar) // Set the Layout options of a Chart diff --git a/src/Plotly.NET/Marker.fs b/src/Plotly.NET/Marker.fs index 608ce9342..bf95c435d 100644 --- a/src/Plotly.NET/Marker.fs +++ b/src/Plotly.NET/Marker.fs @@ -16,7 +16,7 @@ type Marker () = ?Symbol: StyleParam.Symbol, ?MultiSizes: seq<#IConvertible>, ?Line: Line, - ?Colorbar: Colorbar, + ?ColorBar: ColorBar, ?Colorscale : StyleParam.Colorscale, ?Colors: seq, ?OutlierColor:string, @@ -43,7 +43,7 @@ type Marker () = ?Opacity = Opacity , ?MultiSizes = MultiSizes , ?Line = Line , - ?Colorbar = Colorbar , + ?ColorBar = ColorBar , ?Colorscale = Colorscale , ?Colors = Colors , ?OutlierColor = OutlierColor , @@ -70,7 +70,7 @@ type Marker () = ?Symbol: StyleParam.Symbol, ?MultiSizes: seq<#IConvertible>, ?Line: Line, - ?Colorbar: Colorbar, + ?ColorBar: ColorBar, ?Colorscale : StyleParam.Colorscale, ?Colors: seq, ?OutlierColor:string, @@ -94,7 +94,7 @@ type Marker () = Opacity |> DynObj.setValueOpt marker "opacity" MultiSizes |> DynObj.setValueOpt marker "size" Line |> DynObj.setValueOpt marker "line" - Colorbar |> DynObj.setValueOpt marker "colorbar" + ColorBar |> DynObj.setValueOpt marker "colorbar" Colorscale |> DynObj.setValueOptBy marker "colorscale" StyleParam.Colorscale.convert Colors |> DynObj.setValueOpt marker "colors" OutlierColor |> DynObj.setValueOpt marker "outliercolor" diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index 19b432f24..ec538daff 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -15,7 +15,7 @@ #load "Title.fs" #load "Pathbar.fs" #load "TreemapTiling.fs" -#load "Colorbar.fs" +#load "ColorBar.fs" #load "RangeSlider.fs" #load "Button.fs" #load "RangeSelector.fs" diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index ba1ce0347..0be99e736 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -46,7 +46,7 @@ - + diff --git a/src/Plotly.NET/Trace.fs b/src/Plotly.NET/Trace.fs index c3b6333dd..5674ad267 100644 --- a/src/Plotly.NET/Trace.fs +++ b/src/Plotly.NET/Trace.fs @@ -338,7 +338,7 @@ module Trace = ?Symbol: StyleParam.Symbol, ?MultiSizes: seq<#IConvertible>, ?Line: Line, - ?Colorbar: Colorbar, + ?ColorBar: ColorBar, ?Colorscale : StyleParam.Colorscale, ?Colors: seq, ?OutlierColor:string, @@ -364,7 +364,7 @@ module Trace = |> Marker.style(?Size=Size,?Color=Color,?Symbol=Symbol, ?Opacity=Opacity,?MultiSizes=MultiSizes,?Line=Line, - ?Colorbar=Colorbar,?Colorscale=Colorscale,?Colors=Colors,?OutlierColor=OutlierColor, + ?ColorBar=ColorBar,?Colorscale=Colorscale,?Colors=Colors,?OutlierColor=OutlierColor, ?Maxdisplayed=Maxdisplayed,?Sizeref=Sizeref,?Sizemin=Sizemin, ?Sizemode=Sizemode,?Cauto=Cauto,?Cmax=Cmax,?Cmin=Cmin,?Cmid=Cmid, ?Autocolorscale=Autocolorscale,?Reversescale=Reversescale,?Showscale=Showscale @@ -755,7 +755,7 @@ module Trace = ?Reversescale , ?Showscale , ?zSmooth , - ?Colorbar + ?ColorBar ) = (fun (heatmap:('T :> Trace)) -> @@ -785,7 +785,7 @@ module Trace = Reversescale |> DynObj.setValueOpt heatmap "reversescale" Showscale |> DynObj.setValueOpt heatmap "showscale" zSmooth |> DynObj.setValueOptBy heatmap "zsmooth" StyleParam.SmoothAlg.convert - Colorbar |> DynObj.setValueOpt heatmap "colorbar" + ColorBar |> DynObj.setValueOpt heatmap "colorbar" // out -> heatmap @@ -819,7 +819,7 @@ module Trace = ?Reversescale , ?Showscale , ?zSmooth , - ?Colorbar + ?ColorBar ) = (fun (contour:('T :> Trace)) -> @@ -849,7 +849,7 @@ module Trace = Reversescale |> DynObj.setValueOpt contour "reversescale" Showscale |> DynObj.setValueOpt contour "showscale" zSmooth |> DynObj.setValueOptBy contour "zsmooth" StyleParam.SmoothAlg.convert - Colorbar |> DynObj.setValueOpt contour "colorbar" + ColorBar |> DynObj.setValueOpt contour "colorbar" // out -> contour @@ -960,7 +960,7 @@ module Trace = ?Reversescale , ?Showscale , ?zSmooth , - ?Colorbar + ?ColorBar ) = (fun (histogram2d:('T :> Trace)) -> @@ -1002,7 +1002,7 @@ module Trace = Reversescale |> DynObj.setValueOpt histogram2d "reversescale" Showscale |> DynObj.setValueOpt histogram2d "showscale" zSmooth |> DynObj.setValueOptBy histogram2d "zsmooth" StyleParam.SmoothAlg.convert - Colorbar |> DynObj.setValueOpt histogram2d "colorbar" + ColorBar |> DynObj.setValueOpt histogram2d "colorbar" // Update Marker |> DynObj.setValueOpt histogram2d "marker" @@ -1057,7 +1057,7 @@ module Trace = ?Reversescale , ?Showscale , ?zSmooth , - ?Colorbar + ?ColorBar ) = (fun (histogram2dContour:('T :> Trace)) -> @@ -1102,7 +1102,7 @@ module Trace = Reversescale |> DynObj.setValueOpt histogram2dContour "reversescale" Showscale |> DynObj.setValueOpt histogram2dContour "showscale" zSmooth |> DynObj.setValueOptBy histogram2dContour "zsmooth" StyleParam.SmoothAlg.convert - Colorbar |> DynObj.setValueOpt histogram2dContour "colorbar" + ColorBar |> DynObj.setValueOpt histogram2dContour "colorbar" // Update Marker |> DynObj.setValueOpt histogram2dContour "marker" @@ -1168,7 +1168,7 @@ module Trace = ?Locationmode : StyleParam.LocationFormat, ?Autocolorscale : bool, ?Colorscale : StyleParam.Colorscale, - ?Colorbar : Colorbar, + ?ColorBar : ColorBar, ?Marker : Marker, ?GeoJson, ?FeatureIdKey : string, @@ -1187,7 +1187,7 @@ module Trace = Autocolorscale |> DynObj.setValueOpt choropleth "autocolorscale" Colorscale |> DynObj.setValueOptBy choropleth "colorscale" StyleParam.Colorscale.convert - Colorbar |> DynObj.setValueOpt choropleth "colorbar" + ColorBar |> DynObj.setValueOpt choropleth "colorbar" Marker |> DynObj.setValueOpt choropleth "marker" GeoJson |> DynObj.setValueOpt choropleth "geojson" FeatureIdKey |> DynObj.setValueOpt choropleth "featureidkey" @@ -1604,7 +1604,7 @@ module Trace = ?Text : seq<#IConvertible>, ?Below : string, ?Colorscale : StyleParam.Colorscale, - ?Colorbar : Colorbar, + ?ColorBar : ColorBar, ?Showscale : bool, ?ZAuto : bool, ?ZMin : float, @@ -1620,7 +1620,7 @@ module Trace = Text |> DynObj.setValueOpt trace "text" Below |> DynObj.setValueOpt trace "below" Colorscale |> DynObj.setValueOptBy trace "colorscale" StyleParam.Colorscale.convert - Colorbar |> DynObj.setValueOpt trace "colorbar" + ColorBar |> DynObj.setValueOpt trace "colorbar" Showscale |> DynObj.setValueOpt trace "showscale" ZAuto |> DynObj.setValueOpt trace "zauto" ZMin |> DynObj.setValueOpt trace "zmin" @@ -1640,7 +1640,7 @@ module Trace = ?Text : seq<#IConvertible>, ?Below : string, ?Colorscale : StyleParam.Colorscale, - ?Colorbar : Colorbar, + ?ColorBar : ColorBar, ?Showscale : bool, ?ZAuto : bool, ?ZMin : float, @@ -1658,7 +1658,7 @@ module Trace = Text |> DynObj.setValueOpt trace "text" Below |> DynObj.setValueOpt trace "below" Colorscale |> DynObj.setValueOptBy trace "colorscale" StyleParam.Colorscale.convert - Colorbar |> DynObj.setValueOpt trace "colorbar" + ColorBar |> DynObj.setValueOpt trace "colorbar" Showscale |> DynObj.setValueOpt trace "showscale" ZAuto |> DynObj.setValueOpt trace "zauto" ZMin |> DynObj.setValueOpt trace "zmin" diff --git a/src/Plotly.NET/Trace3d.fs b/src/Plotly.NET/Trace3d.fs index 98ac283c3..a81488baa 100644 --- a/src/Plotly.NET/Trace3d.fs +++ b/src/Plotly.NET/Trace3d.fs @@ -48,8 +48,15 @@ module Trace3d = type Trace3dStyle() = // ######################## 3d-Charts - - + + static member setScene + ( + ?SceneName:string + ) = + fun (trace:Trace3d) -> + SceneName |> DynObj.setValueOpt trace "scene" + trace + // Applies the styles to Scatter3d() static member Scatter3d ( @@ -108,7 +115,7 @@ module Trace3d = ?Autocolorscale : bool, ?Reversescale : bool, ?Showscale : bool, - ?Colorbar , + ?ColorBar , ?Contours , ?Hidesurface , ?Lightposition , @@ -136,7 +143,7 @@ module Trace3d = Autocolorscale |> DynObj.setValueOpt surface "autocolorscale" Reversescale |> DynObj.setValueOpt surface "reversescale" Showscale |> DynObj.setValueOpt surface "showscale" - Colorbar |> DynObj.setValueOpt surface "colorbar" + ColorBar |> DynObj.setValueOpt surface "colorbar" Contours |> DynObj.setValueOpt surface "contours" Hidesurface |> DynObj.setValueOpt surface "Hidesurface" Lightposition |> DynObj.setValueOpt surface "Lightposition" @@ -174,7 +181,7 @@ module Trace3d = ?Autocolorscale , ?Reversescale , ?Showscale , - ?Colorbar , + ?ColorBar , ?Lightposition : Ligth.Lightposition, // Obj ?Lighting : Ligth.Lighting, // Obj ?Scene , @@ -213,7 +220,7 @@ module Trace3d = Autocolorscale |> DynObj.setValueOpt mesh3d "autocolorscale" Reversescale |> DynObj.setValueOpt mesh3d "reversescale" Showscale |> DynObj.setValueOpt mesh3d "showscale" - Colorbar |> DynObj.setValueOpt mesh3d "colorbar" + ColorBar |> DynObj.setValueOpt mesh3d "colorbar" Lightposition |> DynObj.setValueOpt mesh3d "lightposition" Lighting |> DynObj.setValueOpt mesh3d "lighting" Scene |> DynObj.setValueOpt mesh3d "scene" @@ -236,16 +243,3 @@ module Trace3d = // out -> mesh3d ) - - static member setScene - ( - ?SceneName:string - ) = - fun (trace:Trace3d) -> - SceneName |> DynObj.setValueOpt trace "scene" - trace - - - - - diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/GeoMapCharts.fs b/tests/Plotly.NET.Tests/HtmlCodegen/GeoMapCharts.fs index f2ecd8afc..0a1d09917 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/GeoMapCharts.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/GeoMapCharts.fs @@ -236,7 +236,10 @@ let choroplethMap2Chart = ShowOcean=true, OceanColor="lightblue", ShowRivers=true) - |> Chart.withColorBarStyle ("Alcohol consumption[l/y]",Length=0.5) + |> Chart.withColorBarStyle ( + Title.init(Text="Alcohol consumption[l/y]") + ,Length=0.5 + ) [] let ``Choropleth maps charts`` = diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/SimpleCharts.fs b/tests/Plotly.NET.Tests/HtmlCodegen/SimpleCharts.fs index e3922dccd..2a959a21d 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/SimpleCharts.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/SimpleCharts.fs @@ -482,9 +482,9 @@ let heatmapStyledChart = |> Chart.withSize(700.,500.) |> Chart.withMarginSize(Left=200.) |> Chart.withColorBarStyle( - "Im the Colorbar", - TitleSide = StyleParam.Side.Right, - TitleFont = Font.init(Size=20.) + Title.init( + Text = "Im the Colorbar" + ) ) @@ -500,7 +500,7 @@ let ``Heatmap charts`` = |> chartGeneratedContains heatmap1Chart ); testCase "Heatmap styled data" ( fun () -> - "var data = [{\"type\":\"heatmap\",\"z\":[[1.0,1.5,0.7,2.7],[2.0,0.5,1.2,1.4],[0.1,2.6,2.4,3.0]],\"x\":[\"Tp0\",\"Tp30\",\"Tp60\",\"Tp160\"],\"y\":[\"p3\",\"p2\",\"p1\"],\"colorscale\":[[0.0,\"#3D9970\"],[1.0,\"#001f3f\"]],\"showscale\":true,\"colorbar\":{\"title\":\"Im the Colorbar\",\"titlefont\":{\"size\":20.0},\"titleside\":\"right\"}}];" + """var data = [{"type":"heatmap","z":[[1.0,1.5,0.7,2.7],[2.0,0.5,1.2,1.4],[0.1,2.6,2.4,3.0]],"x":["Tp0","Tp30","Tp60","Tp160"],"y":["p3","p2","p1"],"colorscale":[[0.0,"#3D9970"],[1.0,"#001f3f"]],"showscale":true,"colorbar":{"title":{"text":"Im the Colorbar"}}}]""" |> chartGeneratedContains heatmapStyledChart ); testCase "Heatmap styled layout" ( fun () -> From 79d517fe6d84457b8e5dc8ab4893cc1ec41be4a5 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Sun, 15 Aug 2021 08:42:13 +0200 Subject: [PATCH 03/21] Rename Colorbar.fs to ColorBar.fs I dont know how this happened but well --- src/Plotly.NET/{Colorbar.fs => ColorBar.fs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Plotly.NET/{Colorbar.fs => ColorBar.fs} (100%) diff --git a/src/Plotly.NET/Colorbar.fs b/src/Plotly.NET/ColorBar.fs similarity index 100% rename from src/Plotly.NET/Colorbar.fs rename to src/Plotly.NET/ColorBar.fs From e1d2073b691b8fca91e1063a8e9d7264127a63e0 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Sun, 15 Aug 2021 08:49:51 +0200 Subject: [PATCH 04/21] Fix heatmap docs --- docs/2_7_heatmaps.fsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/2_7_heatmaps.fsx b/docs/2_7_heatmaps.fsx index c6a2ddf14..ad2956ae4 100644 --- a/docs/2_7_heatmaps.fsx +++ b/docs/2_7_heatmaps.fsx @@ -80,9 +80,7 @@ Here is an example that adds a title to the colorbar: let heat2 = heat1 |> Chart.withColorBarStyle( - "Im the ColorBar", - TitleSide = StyleParam.Side.Right, - TitleFont = Font.init(Size=20.) + Title.init("Im the ColorBar") ) (*** condition: ipynb ***) From 940121ffad772b1e9ad112d1d5123e38070f72c5 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Sun, 15 Aug 2021 08:54:53 +0200 Subject: [PATCH 05/21] Add ColorAxis object and related layout functions --- src/Plotly.NET/Axis.fs | 79 ++++++++++++++++++++++++ src/Plotly.NET/ChartExtensions.fs | 11 ++++ src/Plotly.NET/GenericChartExtensions.fs | 20 +++++- src/Plotly.NET/Layout.fs | 27 ++++++++ 4 files changed, 136 insertions(+), 1 deletion(-) diff --git a/src/Plotly.NET/Axis.fs b/src/Plotly.NET/Axis.fs index 2980f4d17..a6ca1766a 100644 --- a/src/Plotly.NET/Axis.fs +++ b/src/Plotly.NET/Axis.fs @@ -1291,3 +1291,82 @@ module Axis = Layer |> DynObj.setValueOptBy angularAxis "layer" StyleParam.Layer.convert angularAxis + + type ColorAxis() = + inherit DynamicObj() + + /// + /// Initializes a ColorAxis object + /// + /// Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `colorscale`. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed. + /// Determines whether or not the color domain is computed with respect to the input data (here corresponding trace color array(s)) or the bounds set in `cmin` and `cmax` Defaults to `false` when `cmin` and `cmax` are set by the user. + /// Sets the lower bound of the color domain. Value should have the same units as corresponding trace color array(s) and if set, `cmax` must be set as well. + /// Sets the mid-point of the color domain by scaling `cmin` and/or `cmax` to be equidistant to this point. Value should have the same units as corresponding trace color array(s). Has no effect when `cauto` is `false`. + /// Sets the upper bound of the color domain. Value should have the same units as corresponding trace color array(s) and if set, `cmin` must be set as well. + /// Sets the colorbar associated with this color axis. + /// Sets the colorscale. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]`. To control the bounds of the colorscale in color space, use`cmin` and `cmax`. Alternatively, `colorscale` may be a palette name string of the following list: Blackbody,Bluered,Blues,Cividis,Earth,Electric,Greens,Greys,Hot,Jet,Picnic,Portland,Rainbow,RdBu,Reds,Viridis,YlGnBu,YlOrRd. + /// Reverses the color mapping if true. If true, `cmin` will correspond to the last color in the array and `cmax` will correspond to the first color. + /// Determines whether or not a colorbar is displayed for this trace. + static member init + ( + ?AutoColorScale : bool, + ?CAuto : float, + ?CMin : float, + ?CMid : float, + ?CMax : float, + ?ColorBar : ColorBar, + ?ColorScale : StyleParam.Colorscale, + ?ShowScale : bool, + ?ReverseScale : bool + ) = + + ColorAxis() + |> ColorAxis.style + ( + ?AutoColorScale = AutoColorScale, + ?CAuto = CAuto , + ?CMin = CMin , + ?CMid = CMid , + ?CMax = CMax , + ?ColorBar = ColorBar , + ?ColorScale = ColorScale , + ?ShowScale = ShowScale , + ?ReverseScale = ReverseScale + ) + /// + /// Creates a function that applies the given style parameters to a ColorAxis object + /// + /// Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `colorscale`. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed. + /// Determines whether or not the color domain is computed with respect to the input data (here corresponding trace color array(s)) or the bounds set in `cmin` and `cmax` Defaults to `false` when `cmin` and `cmax` are set by the user. + /// Sets the lower bound of the color domain. Value should have the same units as corresponding trace color array(s) and if set, `cmax` must be set as well. + /// Sets the mid-point of the color domain by scaling `cmin` and/or `cmax` to be equidistant to this point. Value should have the same units as corresponding trace color array(s). Has no effect when `cauto` is `false`. + /// Sets the upper bound of the color domain. Value should have the same units as corresponding trace color array(s) and if set, `cmin` must be set as well. + /// Sets the colorbar associated with this color axis. + /// Sets the colorscale. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]`. To control the bounds of the colorscale in color space, use`cmin` and `cmax`. Alternatively, `colorscale` may be a palette name string of the following list: Blackbody,Bluered,Blues,Cividis,Earth,Electric,Greens,Greys,Hot,Jet,Picnic,Portland,Rainbow,RdBu,Reds,Viridis,YlGnBu,YlOrRd. + /// Reverses the color mapping if true. If true, `cmin` will correspond to the last color in the array and `cmax` will correspond to the first color. + /// Determines whether or not a colorbar is displayed for this trace. + static member style + ( + ?AutoColorScale : bool, + ?CAuto : float, + ?CMin : float, + ?CMid : float, + ?CMax : float, + ?ColorBar : ColorBar, + ?ColorScale : StyleParam.Colorscale, + ?ShowScale : bool, + ?ReverseScale : bool + ) = + fun (ca:ColorAxis) -> + + AutoColorScale |> DynObj.setValueOpt ca "autocolorscale" + CAuto |> DynObj.setValueOpt ca "cauto" + CMin |> DynObj.setValueOpt ca "cmin" + CMid |> DynObj.setValueOpt ca "cmid" + CMax |> DynObj.setValueOpt ca "cmax" + ColorBar |> DynObj.setValueOpt ca "colorbar" + ColorScale |> DynObj.setValueOpt ca "colorscale" + ShowScale |> DynObj.setValueOpt ca "showscale" + ReverseScale |> DynObj.setValueOpt ca "reversescale" + + ca \ No newline at end of file diff --git a/src/Plotly.NET/ChartExtensions.fs b/src/Plotly.NET/ChartExtensions.fs index 06f65f34d..80dbbfb61 100644 --- a/src/Plotly.NET/ChartExtensions.fs +++ b/src/Plotly.NET/ChartExtensions.fs @@ -1291,4 +1291,15 @@ module ChartExtensions = GenericChart.setLayout updatedLayout ch ) + /// Sets the color axis of the color axis with the given id on the chart layout + [] + static member withColorAxis(colorAxis:Axis.ColorAxis, [] ?Id) = + (fun (ch:GenericChart) -> + let layout = + let id = defaultArg Id 1 + GenericChart.getLayout ch + |> Layout.updateColorAxisById(id,colorAxis) + GenericChart.setLayout layout ch + ) + diff --git a/src/Plotly.NET/GenericChartExtensions.fs b/src/Plotly.NET/GenericChartExtensions.fs index d4ab49bc6..b88317fa2 100644 --- a/src/Plotly.NET/GenericChartExtensions.fs +++ b/src/Plotly.NET/GenericChartExtensions.fs @@ -690,4 +690,22 @@ module GenericChartExtensions = member this.ShowAsImage (format:StyleParam.ImageFormat) = this |> Chart.showAsImage format - \ No newline at end of file + /// Sets the polar object with the given id on the chart layout + [] + member this.WithPolar(polar:Polar, [] ?Id) = + this |> Chart.withPolar(polar,?Id=Id) + + /// Sets the angular axis of the polar object with the given id on the chart layout + [] + member this.WithAngularAxis(angularAxis:Axis.AngularAxis, [] ?Id) = + this |> Chart.withAngularAxis(angularAxis,?Id=Id) + + /// Sets the radial axis of the polar object with the given id on the chart layout + [] + member this.WithRadialAxis(radialAxis:Axis.RadialAxis, [] ?Id) = + this |> Chart.withRadialAxis(radialAxis,?Id=Id) + + /// Sets the color axis of the color axis with the given id on the chart layout + [] + member this.WithColorAxis(colorAxis:Axis.ColorAxis, [] ?Id) = + this |> Chart.withColorAxis(colorAxis,?Id=Id) \ No newline at end of file diff --git a/src/Plotly.NET/Layout.fs b/src/Plotly.NET/Layout.fs index d88ad5ce4..9ab9c1bf6 100644 --- a/src/Plotly.NET/Layout.fs +++ b/src/Plotly.NET/Layout.fs @@ -364,6 +364,33 @@ type Layout() = layout ) + static member tryGetColorAxisById (id:int) = + (fun (layout:Layout) -> + let key = if id < 2 then "coloraxis" else sprintf "coloraxis%i" id + layout.TryGetTypedValue(key) + ) + + /// Updates the style of current ColorAxis object with given Id. + /// If there does not exist a ColorAxis object with the given id, sets it with the given ColorAxis object + static member updateColorAxisById + ( + id : int, + colorAxis: Axis.ColorAxis + ) = + (fun (layout:Layout) -> + + let key = if id < 2 then "coloraxis" else sprintf "coloraxis%i" id + + let colorAxis' = + match layout |> Layout.tryGetColorAxisById(id) with + | Some a -> DynObj.combine (unbox a) colorAxis + | None -> colorAxis :> DynamicObj + + colorAxis |> DynObj.setValue layout key + + layout + ) + static member setLegend(legend:Legend) = (fun (layout:Layout) -> From e49ebbcd1b23947dc8f117bf8e7eed53ad885ce9 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Sun, 15 Aug 2021 08:57:39 +0200 Subject: [PATCH 06/21] fix choropleth docs --- docs/5_2_choropleth-map.fsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/5_2_choropleth-map.fsx b/docs/5_2_choropleth-map.fsx index ca415541b..7ec17de96 100644 --- a/docs/5_2_choropleth-map.fsx +++ b/docs/5_2_choropleth-map.fsx @@ -123,7 +123,7 @@ let choroplethMap2 = ShowOcean=true, OceanColor="lightblue", ShowRivers=true) - |> Chart.withColorBarStyle ("Alcohol consumption[l/y]",Length=0.5) + |> Chart.withColorBarStyle (Title.init("Alcohol consumption[l/y]"),Length=0.5) (*** condition: ipynb ***) #if IPYNB From 07c93012bbea1885f80bc6bd58c099d1cbd14e05 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Sun, 15 Aug 2021 09:52:00 +0200 Subject: [PATCH 07/21] Add Chart.Cone and associated params --- src/Plotly.NET/Chart.fs | 73 ++++++++++++--- src/Plotly.NET/Light.fs | 102 --------------------- src/Plotly.NET/Marker.fs | 6 +- src/Plotly.NET/Playground.fsx | 14 ++- src/Plotly.NET/Plotly.NET.fsproj | 2 - src/Plotly.NET/Selected.fs | 66 -------------- src/Plotly.NET/StyleParams.fs | 60 ++++++++++--- src/Plotly.NET/Title.fs | 18 ++-- src/Plotly.NET/Trace.fs | 2 +- src/Plotly.NET/Trace3d.fs | 148 ++++++++++++++++++++++++++++++- 10 files changed, 284 insertions(+), 207 deletions(-) delete mode 100644 src/Plotly.NET/Light.fs delete mode 100644 src/Plotly.NET/Selected.fs diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index bd961d919..033ce557b 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -1910,21 +1910,74 @@ type Chart = /// Uses points, line or both depending on the mode to represent 3d-data points static member Mesh3d(x, y, z, mode, - ?Name, - ?Showlegend, - ?MarkerSymbol, - ?Color, - ?Opacity, - ?Labels, - ?TextPosition, - ?TextFont, - ?Dash, - ?Width) = + [] ?Name, + [] ?Showlegend, + [] ?MarkerSymbol, + [] ?Color, + [] ?Opacity, + [] ?Labels, + [] ?TextPosition, + [] ?TextFont, + [] ?Dash, + [] ?Width) = Trace3d.initMesh3d (Trace3dStyle.Mesh3d(X = x,Y = y,Z=z) ) |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity) |> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont) |> GenericChart.ofTraceObject + static member Cone + ( + x, y, z, u, v, w, + [] ?Name, + [] ?ShowLegend, + [] ?Opacity, + [] ?ColorScale, + [] ?ShowScale, + [] ?ColorBar + ) = + + Trace3d.initCone( + Trace3dStyle.Cone( + X = x, + Y = y, + Z = z, + U = u, + V = v, + W = w, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Opacity = Opacity, + ?ColorScale = ColorScale, + ?ShowScale = ShowScale, + ?ColorBar = ColorBar + ) + ) + |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=ShowLegend,?Opacity=Opacity) + |> GenericChart.ofTraceObject + + static member Cone + ( + coneXYZ, coneUVW, + [] ?Name, + [] ?ShowLegend, + [] ?Opacity, + [] ?ColorScale, + [] ?ShowScale, + [] ?ColorBar + ) = + let x, y, z = Seq.unzip3 coneXYZ + let u, v, w = Seq.unzip3 coneUVW + + Chart.Cone( + x, y, z, u, v, w, + ?Name = Name , + ?ShowLegend = ShowLegend , + ?Opacity = Opacity , + ?ColorScale = ColorScale , + ?ShowScale = ShowScale , + ?ColorBar = ColorBar + ) + /// creates table out of header sequence and row sequences static member Table(headerValues, cellValues, [] ?AlignHeader, diff --git a/src/Plotly.NET/Light.fs b/src/Plotly.NET/Light.fs deleted file mode 100644 index ac85c716e..000000000 --- a/src/Plotly.NET/Light.fs +++ /dev/null @@ -1,102 +0,0 @@ -namespace Plotly.NET - -open DynamicObj - -/// Module containing plotly light modulation for 3d -module Ligth = - - /// Lighting type inherits from dynamic object - type Lighting () = - inherit DynamicObj () - - /// Initialized Lighting object - //[] - static member init - ( - /// Epsilon for vertex normals calculation avoids math issues arising from degenerate geometry. Default 1e-12. - ?Vertexnormalsepsilon : float, - ?Facenormalsepsilon : float, - ?Ambient : float, - ?Diffuse : float, - ?Specular : float, - ?Roughness : float, - ?Fresnel : float - ) = - Lighting () - |> Lighting.style - ( - ?Vertexnormalsepsilon = Vertexnormalsepsilon, - ?Facenormalsepsilon = Facenormalsepsilon , - ?Ambient = Ambient , - ?Diffuse = Diffuse , - ?Specular = Specular , - ?Roughness = Roughness , - ?Fresnel = Fresnel - ) - - // [] - /// Applies the styles to Lighting() - //[] - static member style - ( - /// Epsilon for vertex normals calculation avoids math issues arising from degenerate geometry. Default 1e-12. - ?Vertexnormalsepsilon : float, - ?Facenormalsepsilon : float, - ?Ambient : float, - ?Diffuse : float, - ?Specular : float, - ?Roughness : float, - ?Fresnel : float - ) = - - (fun (lighting:Lighting) -> - Vertexnormalsepsilon |> DynObj.setValueOpt lighting "vertexnormalsepsilon" - Facenormalsepsilon |> DynObj.setValueOpt lighting "facenormalsepsilon" - Ambient |> DynObj.setValueOpt lighting "ambient" - Diffuse |> DynObj.setValueOpt lighting "diffuse" - Specular |> DynObj.setValueOpt lighting "specular" - Roughness |> DynObj.setValueOpt lighting "roughness" - Fresnel |> DynObj.setValueOpt lighting "fresnel" - - lighting - ) - - - - /// Lighting type inherits from dynamic object - type Lightposition () = - inherit DynamicObj () - - /// Initialized Lightposition object - //[] - static member init - ( - ?X : int, - ?Y : int, - ?Z : int - ) = - Lightposition () - |> Lightposition.style - ( - ?X = X, - ?Y = Y, - ?Z = Z - ) - - /// Applies the styles to Lightposition() - //[] - static member style - ( - ?X : int, - ?Y : int, - ?Z : int - ) = - - (fun (lightposition: Lightposition) -> - X |> DynObj.setValueOpt lightposition "x" - Y |> DynObj.setValueOpt lightposition "y" - Z |> DynObj.setValueOpt lightposition "z" - - lightposition - ) - diff --git a/src/Plotly.NET/Marker.fs b/src/Plotly.NET/Marker.fs index bf95c435d..07dd90de4 100644 --- a/src/Plotly.NET/Marker.fs +++ b/src/Plotly.NET/Marker.fs @@ -24,7 +24,7 @@ type Marker () = ?Maxdisplayed: int, ?Sizeref: float, ?Sizemin: float, - ?Sizemode: StyleParam.SizeMode, + ?Sizemode: StyleParam.MarkerSizeMode, ?Cauto: bool, ?Cmax: float, ?Cmin: float, @@ -78,7 +78,7 @@ type Marker () = ?Maxdisplayed: int, ?Sizeref: float, ?Sizemin: float, - ?Sizemode: StyleParam.SizeMode, + ?Sizemode: StyleParam.MarkerSizeMode, ?Cauto: bool, ?Cmax: float, ?Cmin: float, @@ -102,7 +102,7 @@ type Marker () = Maxdisplayed |> DynObj.setValueOpt marker "maxdisplayed" Sizeref |> DynObj.setValueOpt marker "sizeref" Sizemin |> DynObj.setValueOpt marker "sizemin" - Sizemode |> DynObj.setValueOpt marker "sizemode" + Sizemode |> DynObj.setValueOptBy marker "sizemode" StyleParam.MarkerSizeMode.convert Cauto |> DynObj.setValueOpt marker "cauto" Cmax |> DynObj.setValueOpt marker "cmax" Cmin |> DynObj.setValueOpt marker "cmin" diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index ec538daff..af43617d7 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -6,6 +6,7 @@ #load "StyleParams.fs" #load "Colors.fs" +#load "Lighting.fs" #load "Rangebreak.fs" #load "TickFormatStop.fs" #load "Selection.fs" @@ -19,7 +20,6 @@ #load "RangeSlider.fs" #load "Button.fs" #load "RangeSelector.fs" -#load "Light.fs" #load "Legend.fs" #load "Contours.fs" #load "Dimensions.fs" @@ -36,7 +36,6 @@ #load "Bins.fs" #load "Cumulative.fs" #load "Scene.fs" -#load "Selected.fs" #load "Shape.fs" #load "Error.fs" #load "Table.fs" @@ -72,6 +71,17 @@ open FSharpAux open System +Chart.Cone( + x = [1; 1; 1], + y = [1; 2; 3], + z = [1; 1; 1], + u = [1; 2; 3], + v = [1; 1; 2], + w = [4; 4; 1] +) +|> Chart.show + + let r = [ 1; 2; 3; 4; 5; 6; 7;] |> List.map ((*) 10000) let r2 = [ 5; 6; 7; 1; 2; 3; 4;] |> List.map ((*) 10000) let r3 = [ 3; 1; 5; 2; 8; 7; 5;] |> List.map ((*) 10000) diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index 0be99e736..91c96d365 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -50,7 +50,6 @@ - @@ -67,7 +66,6 @@ - diff --git a/src/Plotly.NET/Selected.fs b/src/Plotly.NET/Selected.fs deleted file mode 100644 index 0a630b189..000000000 --- a/src/Plotly.NET/Selected.fs +++ /dev/null @@ -1,66 +0,0 @@ -namespace Plotly.NET - -open DynamicObj -open System - -/// Selected type inherits from dynamic object -type Selected () = - inherit DynamicObj () - - /// Initialized Line object - static member init - ( - ?Marker - ) = - Selected () - |> Selected.style - ( - ?Marker = Marker - ) - - - // Applies the styles to Line() - static member style - ( - ?Marker - ) = - (fun (seletion:Selected) -> - Marker |> DynObj.setValueOpt seletion "marker" - - // out -> - seletion - ) - - -// +++ -// +++ - -/// Selected type inherits from dynamic object -type UnSelected () = - inherit DynamicObj () - - /// Initialized Line object - static member init - ( - ?Marker - ) = - UnSelected () - |> UnSelected.style - ( - ?Marker = Marker - ) - - - // Applies the styles to Line() - static member style - ( - ?Marker - ) = - (fun (seletion:UnSelected) -> - Marker |> DynObj.setValueOpt seletion "marker" - - // out -> - seletion - ) - - \ No newline at end of file diff --git a/src/Plotly.NET/StyleParams.fs b/src/Plotly.NET/StyleParams.fs index 714d7bcc3..ee1fcf86e 100644 --- a/src/Plotly.NET/StyleParams.fs +++ b/src/Plotly.NET/StyleParams.fs @@ -69,12 +69,17 @@ module StyleParam = /// [] type AxisAnchorId = - | X of int | Y of int | Z of int | Free + | X of int + | Y of int + | Z of int + | Color of int + | Free static member toString = function | X id -> if id < 2 then "x" else sprintf "x%i" id | Y id -> if id < 2 then "y" else sprintf "y%i" id | Z id -> if id < 2 then "z" else sprintf "z%i" id + | Color id -> if id < 2 then "coloraxis" else sprintf "coloraxis%i" id | Free -> "free" static member convert = AxisAnchorId.toString >> box @@ -378,7 +383,37 @@ module StyleParam = | Boundaries-> "boundaries" static member convert = CategoryTickAnchor.toString >> box + + /// Sets the cones' anchor with respect to their x/y/z positions. Note that "cm" denote the cone's center of mass which corresponds to 1/4 from the tail to tip. + [] + type ConeAnchor = + | Tip + | Tail + | CenterOfMass + | Center + + static member toString = function + | Tip -> "tip" + | Tail -> "tail" + | CenterOfMass -> "cm" + | Center -> "center" + + static member convert = ConeAnchor.toString >> box + + + /// Sets the cones' anchor with respect to their x/y/z positions. Note that "cm" denote the cone's center of mass which corresponds to 1/4 from the tail to tip. + [] + type ConeSizeMode = + | Scaled + | Absolute + + static member toString = function + | Scaled -> "scaled" + | Absolute -> "absolute" + static member convert = ConeSizeMode.toString >> box + + //-------------------------- // #D# @@ -443,6 +478,8 @@ module StyleParam = static member convert = DrawingStyle.toString >> box + + //-------------------------- // #E# //-------------------------- @@ -1024,6 +1061,16 @@ module StyleParam = static member convert = MapboxLayerSymbolPlacement.toString >> box + + [] + type MarkerSizeMode = + | Diameter | Area + + static member toString = function + | Diameter -> "diameter" + | Area -> "area" + + static member convert = MarkerSizeMode.toString >> box //-------------------------- // #N# @@ -1260,17 +1307,6 @@ module StyleParam = static member convert = Side.toString >> box - [] - type SizeMode = - | Diameter | Area - - static member toString = function - | Diameter -> "diameter" - | Area -> "area" - - static member convert = SizeMode.toString >> box - - /// Choose between algorithms ('best' or 'fast') to smooth data linked to 'z'. The default value is false corresponding to no smoothing. [] type SmoothAlg = diff --git a/src/Plotly.NET/Title.fs b/src/Plotly.NET/Title.fs index 720e960c4..a922eb601 100644 --- a/src/Plotly.NET/Title.fs +++ b/src/Plotly.NET/Title.fs @@ -7,29 +7,33 @@ type Title() = static member init ( - ?Text : string, - ?Font : Font, - ?Standoff : int + ?Text : string, + ?Font : Font, + ?Standoff : int, + ?Side : StyleParam.Side ) = Title() |> Title.style ( ?Text = Text, ?Font = Font, - ?Standoff = Standoff + ?Standoff = Standoff, + ?Side = Side ) static member style ( - ?Text : string, - ?Font : Font, - ?Standoff : int + ?Text : string, + ?Font : Font, + ?Standoff : int, + ?Side : StyleParam.Side ) = (fun (title:Title) -> Text |> DynObj.setValueOpt title "text" Font |> DynObj.setValueOpt title "font" Standoff|> DynObj.setValueOpt title "standoff" + Side |> DynObj.setValueOpt title "side" title ) diff --git a/src/Plotly.NET/Trace.fs b/src/Plotly.NET/Trace.fs index 5674ad267..ff5455606 100644 --- a/src/Plotly.NET/Trace.fs +++ b/src/Plotly.NET/Trace.fs @@ -345,7 +345,7 @@ module Trace = ?Maxdisplayed: int, ?Sizeref: float, ?Sizemin: float, - ?Sizemode: StyleParam.SizeMode, + ?Sizemode: StyleParam.MarkerSizeMode, ?Cauto: bool, ?Cmax: float, ?Cmin: float, diff --git a/src/Plotly.NET/Trace3d.fs b/src/Plotly.NET/Trace3d.fs index a81488baa..a0c2abd1f 100644 --- a/src/Plotly.NET/Trace3d.fs +++ b/src/Plotly.NET/Trace3d.fs @@ -182,8 +182,8 @@ module Trace3d = ?Reversescale , ?Showscale , ?ColorBar , - ?Lightposition : Ligth.Lightposition, // Obj - ?Lighting : Ligth.Lighting, // Obj + ?Lightposition : LightPosition, + ?Lighting : Lighting, // Obj ?Scene , ?Xcalendar , ?Ycalendar , @@ -243,3 +243,147 @@ module Trace3d = // out -> mesh3d ) + + /// + /// Applies the style parameters of the cone chart to the given trace + /// + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not this trace is visible. If "legendonly", the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible). + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Sets the legend rank for this trace. Items and groups with smaller ranks are presented on top/left side while with `"reversed" `legend.traceorder` they are on bottom/right side. The default legendrank is 1000, so that you can use ranks less than 1000 to place certain items before all unranked items, and ranks greater than 1000 to go after all unranked items. + /// Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items. + /// Sets the legend group title for this trace. + /// Sets the opacity of the surface. Please note that in the case of using high `opacity` values for example a value greater than or equal to 0.5 on two surfaces (and 0.25 with four surfaces), an overlay of multiple transparent surfaces may not perfectly be sorted in depth by the webgl API. This behavior may be improved in the near future and is subject to change. + /// Assigns id labels to each datum. These ids for object constancy of data points during animation. Should be an array of strings, not numbers or any other type. + /// Sets the x coordinates of the vector field and of the displayed cones. + /// Sets the y coordinates of the vector field and of the displayed cones. + /// Sets the z coordinates of the vector field and of the displayed cones. + /// Sets the x components of the vector field. + /// Sets the y components of the vector field. + /// Sets the z components of the vector field. + /// Sets the text elements associated with the cones. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Same as `text`. + /// Determines which trace information appear on hover. If `none` or `skip` are set, no information is displayed upon hovering. But, if `none` is set, click and hover events are still fired. + /// Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example "y: %{y}" as well as %{xother}, {%_xother}, {%_xother_}, {%xother_}. When showing info for several points, "xother" will be added to those with different x positions from the first point. An underscore before or after "(x|y)other" will add a space on that side, only when this field is shown. Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. variable `norm` Anything contained in tag `<extra>` is displayed in the secondary box, for example "<extra>{fullData.name}</extra>". To hide the secondary box completely, use an empty tag `<extra></extra>`. + /// Sets the hover text formatting rulefor `x` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `xaxis.hoverformat`. + /// Sets the hover text formatting rulefor `y` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `yaxis.hoverformat`. + /// Sets the hover text formatting rulefor `z` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `zaxis.hoverformat` + /// Sets the hover text formatting rulefor `u` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format.By default the values are formatted using generic number format. + /// Sets the hover text formatting rulefor `v` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format.By default the values are formatted using generic number format. + /// Sets the hover text formatting rulefor `w` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format.By default the values are formatted using generic number format. + /// Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index. + /// Assigns extra data each datum. This may be useful when listening to hover, click and selection events. Note that, "scatter" traces also appends customdata items in the markers DOM elements + /// Sets a reference between this trace's 3D coordinate system and a 3D scene. If "scene" (the default value), the (x,y,z) coordinates refer to `layout.scene`. If "scene2", the (x,y,z) coordinates refer to `layout.scene2`, and so on. + /// Sets a reference to a shared color axis. References to these shared color axes are "coloraxis", "coloraxis2", "coloraxis3", etc. Settings for these shared color axes are set in the layout, under `layout.coloraxis`, `layout.coloraxis2`, etc. Note that multiple color scales can be linked to the same color axis. + /// Sets the ColorBar object associated with the color scale of the cones + /// Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `colorscale`. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed. + /// Sets the colorscale. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]`. To control the bounds of the colorscale in color space, use`cmin` and `cmax`. Alternatively, `colorscale` may be a palette name string of the following list: Blackbody,Bluered,Blues,Cividis,Earth,Electric,Greens,Greys,Hot,Jet,Picnic,Portland,Rainbow,RdBu,Reds,Viridis,YlGnBu,YlOrRd. + /// Determines whether or not a colorbar is displayed for this trace. + /// Reverses the color mapping if true. If true, `cmin` will correspond to the last color in the array and `cmax` will correspond to the first color. + /// Determines whether or not the color domain is computed with respect to the input data (here u/v/w norm) or the bounds set in `cmin` and `cmax` Defaults to `false` when `cmin` and `cmax` are set by the user. + /// Sets the upper bound of the color domain. Value should have the same units as u/v/w norm and if set, `cmin` must be set as well. + /// Sets the mid-point of the color domain by scaling `cmin` and/or `cmax` to be equidistant to this point. Value should have the same units as u/v/w norm. Has no effect when `cauto` is `false`. + /// Sets the lower bound of the color domain. Value should have the same units as u/v/w norm and if set, `cmax` must be set as well. + /// Sets the cones' anchor with respect to their x/y/z positions. Note that "cm" denote the cone's center of mass which corresponds to 1/4 from the tail to tip. + /// Sets the hover labels of this cone trace. + /// Sets the Lighting of this cone trace. + /// Sets the LightPosition of this cone trace. + /// Determines whether `sizeref` is set as a "scaled" (i.e unitless) scalar (normalized by the max u/v/w norm in the vector field) or as "absolute" value (in the same units as the vector field). + /// Adjusts the cone size scaling. The size of the cones is determined by their u/v/w norm multiplied a factor and `sizeref`. This factor (computed internally) corresponds to the minimum "time" to travel across two successive x/y/z positions at the average velocity of those two successive positions. All cones in a given trace use the same factor. With `sizemode` set to "scaled", `sizeref` is unitless, its default value is "0.5" With `sizemode` set to "absolute", `sizeref` has the same units as the u/v/w vector field, its the default value is half the sample's maximum vector norm. + /// Controls persistence of some user-driven changes to the trace: `constraintrange` in `parcoords` traces, as well as some `editable: true` modifications such as `name` and `colorbar.title`. Defaults to `layout.uirevision`. Note that other user-driven trace attribute changes are controlled by `layout` attributes: `trace.visible` is controlled by `layout.legend.uirevision`, `selectedpoints` is controlled by `layout.selectionrevision`, and `colorbar.(x|y)` (accessible with `config: {editable: true}`) is controlled by `layout.editrevision`. Trace changes are tracked by `uid`, which only falls back on trace index if no `uid` is provided. So if your app can add/remove traces before the end of the `data` array, such that the same trace has a different index, you can still preserve user-driven changes if you give each trace a `uid` that stays with it as it moves. + static member Cone + ( + ?Name : string, + ?Visible : StyleParam.Visible, + ?ShowLegend : bool, + ?LegendRank : int, + ?LegendGroup : string, + ?LegendGroupTitle : Title, + ?Opacity : float, + ?Ids : seq<#IConvertible>, + ?X : seq<#IConvertible>, + ?Y : seq<#IConvertible>, + ?Z : seq<#IConvertible>, + ?U : seq<#IConvertible>, + ?V : seq<#IConvertible>, + ?W : seq<#IConvertible>, + ?Text : seq<#IConvertible>, + ?HoverText : seq<#IConvertible>, + ?HoverInfo : string, + ?HoverTemplate : string, + ?XHoverFormat : string, + ?YHoverFormat : string, + ?ZHoverFormat : string, + ?UHoverFormat : string, + ?VHoverFormat : string, + ?WHoverFormat : string, + ?Meta : seq<#IConvertible>, + ?CustomData : seq<#IConvertible>, + ?Scene : Scene, + ?ColorAxis : StyleParam.AxisAnchorId, + ?ColorBar : ColorBar, + ?AutoColorScale : bool, + ?ColorScale : StyleParam.Colorscale, + ?ShowScale : bool, + ?ReverseScale : bool, + ?CAuto : bool, + ?CMin : float, + ?CMid : float, + ?CMax : float, + ?Anchor : StyleParam.ConeAnchor, + ?HoverLabel : Hoverlabel, + ?Lighting : Lighting, + ?LightPosition : LightPosition, + ?SizeMode : StyleParam.ConeSizeMode, + ?SizeRef : float, + ?UIRevision : seq<#IConvertible> + + ) = + (fun (cone: Trace3d) -> + Name |> DynObj.setValueOpt cone "name" + Visible |> DynObj.setValueOptBy cone "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt cone "showlegend" + LegendRank |> DynObj.setValueOpt cone "legendrank" + LegendGroup |> DynObj.setValueOpt cone "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt cone "legendgrouptitle" + Opacity |> DynObj.setValueOpt cone "opacity" + Ids |> DynObj.setValueOpt cone "ids" + X |> DynObj.setValueOpt cone "x" + Y |> DynObj.setValueOpt cone "y" + Z |> DynObj.setValueOpt cone "z" + U |> DynObj.setValueOpt cone "u" + V |> DynObj.setValueOpt cone "v" + W |> DynObj.setValueOpt cone "w" + Text |> DynObj.setValueOpt cone "text" + HoverText |> DynObj.setValueOpt cone "hovertext" + HoverInfo |> DynObj.setValueOpt cone "hoverinfo" + HoverTemplate |> DynObj.setValueOpt cone "hovertemplate" + XHoverFormat |> DynObj.setValueOpt cone "xhoverformat" + YHoverFormat |> DynObj.setValueOpt cone "yhoverformat" + ZHoverFormat |> DynObj.setValueOpt cone "zhoverformat" + UHoverFormat |> DynObj.setValueOpt cone "uhoverformat" + VHoverFormat |> DynObj.setValueOpt cone "vhoverformat" + WHoverFormat |> DynObj.setValueOpt cone "whoverformat" + Meta |> DynObj.setValueOpt cone "meta" + CustomData |> DynObj.setValueOpt cone "customdata" + Scene |> DynObj.setValueOpt cone "scene" + ColorAxis |> DynObj.setValueOptBy cone "scene" StyleParam.AxisAnchorId.convert + ColorBar |> DynObj.setValueOpt cone "colorbar" + AutoColorScale |> DynObj.setValueOpt cone "autocolorscale" + ColorScale |> DynObj.setValueOptBy cone "colorscale" StyleParam.Colorscale.convert + ShowScale |> DynObj.setValueOpt cone "showscale" + ReverseScale |> DynObj.setValueOpt cone "reversescale" + CAuto |> DynObj.setValueOpt cone "cauto" + CMin |> DynObj.setValueOpt cone "cmin" + CMid |> DynObj.setValueOpt cone "cmid" + CMax |> DynObj.setValueOpt cone "cmax" + Anchor |> DynObj.setValueOptBy cone "anchor" StyleParam.ConeAnchor.convert + HoverLabel |> DynObj.setValueOpt cone "hoverlabel" + Lighting |> DynObj.setValueOpt cone "lighting" + LightPosition |> DynObj.setValueOpt cone "lightposition" + SizeMode |> DynObj.setValueOptBy cone "sizemode" StyleParam.ConeSizeMode.convert + SizeRef |> DynObj.setValueOpt cone "sizeref" + UIRevision |> DynObj.setValueOpt cone "uirevision" + + cone + ) \ No newline at end of file From b2e740ddc5d1c974ca57ee976d445f31aaba4bb3 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Sun, 15 Aug 2021 16:37:08 +0200 Subject: [PATCH 08/21] Add more Scene support, Unify SubPlotId handling --- docs/5_0_geo-vs-mapbox.fsx | 4 +- docs/5_1_geo-plots.fsx | 4 +- docs/5_2_choropleth-map.fsx | 6 +- src/Plotly.NET/Axis.fs | 32 +-- src/Plotly.NET/Chart.fs | 4 +- src/Plotly.NET/ChartExtensions.fs | 228 ++++++++++-------- src/Plotly.NET/GenericChartExtensions.fs | 184 +++++--------- src/Plotly.NET/Layout.fs | 135 +++++++---- src/Plotly.NET/LayoutGrid.fs | 18 +- src/Plotly.NET/Playground.fsx | 44 +++- src/Plotly.NET/Plotly.NET.fsproj | 2 +- src/Plotly.NET/Scene.fs | 124 +++++++--- src/Plotly.NET/StyleParams.fs | 72 +++--- src/Plotly.NET/Template.fs | 24 +- src/Plotly.NET/Trace.fs | 10 +- src/Plotly.NET/Trace3d.fs | 8 +- .../HtmlCodegen/ChartLayout.fs | 10 +- .../Plotly.NET.Tests/HtmlCodegen/Charts3D.fs | 8 +- .../HtmlCodegen/GeoMapCharts.fs | 10 +- 19 files changed, 505 insertions(+), 422 deletions(-) diff --git a/docs/5_0_geo-vs-mapbox.fsx b/docs/5_0_geo-vs-mapbox.fsx index 7fc0c9f29..c5a9c6938 100644 --- a/docs/5_0_geo-vs-mapbox.fsx +++ b/docs/5_0_geo-vs-mapbox.fsx @@ -84,7 +84,7 @@ let myGeo = let moreFeaturesBaseMap = Chart.PointGeo([]) - |> Chart.withMap myGeo + |> Chart.withGeo myGeo |> Chart.withMarginSize(0,0,0,0) (*** condition: ipynb ***) @@ -119,7 +119,7 @@ let countryGeo = let countryBaseMap = Chart.PointGeo([]) - |> Chart.withMap countryGeo + |> Chart.withGeo countryGeo |> Chart.withMarginSize(0,0,0,0) (*** condition: ipynb ***) diff --git a/docs/5_1_geo-plots.fsx b/docs/5_1_geo-plots.fsx index 72966cf33..71086dba7 100644 --- a/docs/5_1_geo-plots.fsx +++ b/docs/5_1_geo-plots.fsx @@ -59,7 +59,7 @@ let pointGeo = Labels=cityNames, TextPosition=StyleParam.TextPosition.TopCenter ) - |> Chart.withMapStyle( + |> Chart.withGeoStyle( Scope=StyleParam.GeoScope.NorthAmerica, Projection=GeoProjection.init(StyleParam.GeoProjectionType.AzimuthalEqualArea), CountryColor = "lightgrey" @@ -109,7 +109,7 @@ let flights = ) |> Chart.combine |> Chart.withLegend(false) - |> Chart.withMapStyle( + |> Chart.withGeoStyle( Scope=StyleParam.GeoScope.NorthAmerica, Projection=GeoProjection.init(StyleParam.GeoProjectionType.AzimuthalEqualArea), ShowLand=true, diff --git a/docs/5_2_choropleth-map.fsx b/docs/5_2_choropleth-map.fsx index 7ec17de96..e5057251b 100644 --- a/docs/5_2_choropleth-map.fsx +++ b/docs/5_2_choropleth-map.fsx @@ -110,14 +110,14 @@ choroplethMap1 |> GenericChart.toChartHTML (** ## Map styling -you can access various map styles via `Chart.withMapStyle`, such as the projection type, lake/ocean color, and so on. +you can access various map styles via `Chart.withGeoStyle`, such as the projection type, lake/ocean color, and so on. *) let choroplethMap2 = Chart.ChoroplethMap( locations,z, Locationmode=StyleParam.LocationFormat.CountryNames ) - |> Chart.withMapStyle( + |> Chart.withGeoStyle( Projection=GeoProjection.init(projectionType=StyleParam.GeoProjectionType.Mollweide), ShowLakes=true, ShowOcean=true, @@ -236,7 +236,7 @@ let choroplethGeoJSON = GeoJson = geoJson, FeatureIdKey="id" ) - |> Chart.withMap( + |> Chart.withGeo( Geo.init( Scope=StyleParam.GeoScope.NorthAmerica, Projection=GeoProjection.init(StyleParam.GeoProjectionType.AzimuthalEqualArea), diff --git a/src/Plotly.NET/Axis.fs b/src/Plotly.NET/Axis.fs index a6ca1766a..91848b25a 100644 --- a/src/Plotly.NET/Axis.fs +++ b/src/Plotly.NET/Axis.fs @@ -99,11 +99,11 @@ module Axis = ?RangeMode : StyleParam.RangeMode, ?Range : StyleParam.Range, ?FixedRange : bool, - ?ScaleAnchor : StyleParam.AxisAnchorId, + ?ScaleAnchor : StyleParam.LinearAxisId, ?ScaleRatio : float, ?Constrain : StyleParam.AxisConstraint, ?ConstrainToward : StyleParam.AxisConstraintDirection, - ?Matches : StyleParam.AxisAnchorId, + ?Matches : StyleParam.LinearAxisId, ?Rangebreaks : seq, ?TickMode : StyleParam.TickMode, ?NTicks : int, @@ -153,9 +153,9 @@ module Axis = ?ShowDividers : bool, ?DividerColor : string, ?DividerWidth : int, - ?Anchor : StyleParam.AxisAnchorId, + ?Anchor : StyleParam.LinearAxisId, ?Side : StyleParam.Side, - ?Overlaying : StyleParam.AxisAnchorId, + ?Overlaying : StyleParam.LinearAxisId, ?Layer : StyleParam.Layer, ?Domain : StyleParam.Range, ?Position : float, @@ -335,11 +335,11 @@ module Axis = ?RangeMode : StyleParam.RangeMode, ?Range : StyleParam.Range, ?FixedRange : bool, - ?ScaleAnchor : StyleParam.AxisAnchorId, + ?ScaleAnchor : StyleParam.LinearAxisId, ?ScaleRatio : float, ?Constrain : StyleParam.AxisConstraint, ?ConstrainToward : StyleParam.AxisConstraintDirection, - ?Matches : StyleParam.AxisAnchorId, + ?Matches : StyleParam.LinearAxisId, ?Rangebreaks : seq, ?TickMode : StyleParam.TickMode, ?NTicks : int, @@ -389,9 +389,9 @@ module Axis = ?ShowDividers : bool, ?DividerColor : string, ?DividerWidth : int, - ?Anchor : StyleParam.AxisAnchorId, + ?Anchor : StyleParam.LinearAxisId, ?Side : StyleParam.Side, - ?Overlaying : StyleParam.AxisAnchorId, + ?Overlaying : StyleParam.LinearAxisId, ?Layer : StyleParam.Layer, ?Domain : StyleParam.Range, ?Position : float, @@ -570,11 +570,11 @@ module Axis = ?RangeMode : StyleParam.RangeMode, ?Range : StyleParam.Range, ?FixedRange : bool, - ?ScaleAnchor : StyleParam.AxisAnchorId, + ?ScaleAnchor : StyleParam.LinearAxisId, ?ScaleRatio : float, ?Constrain : StyleParam.AxisConstraint, ?ConstrainToward : StyleParam.AxisConstraintDirection, - ?Matches : StyleParam.AxisAnchorId, + ?Matches : StyleParam.LinearAxisId, ?Rangebreaks : seq, ?TickMode : StyleParam.TickMode, ?NTicks : int, @@ -624,9 +624,9 @@ module Axis = ?ShowDividers : bool, ?DividerColor : string, ?DividerWidth : int, - ?Anchor : StyleParam.AxisAnchorId, + ?Anchor : StyleParam.LinearAxisId, ?Side : StyleParam.Side, - ?Overlaying : StyleParam.AxisAnchorId, + ?Overlaying : StyleParam.LinearAxisId, ?Layer : StyleParam.Layer, ?Domain : StyleParam.Range, ?Position : float, @@ -648,11 +648,11 @@ module Axis = RangeMode |> DynObj.setValueOptBy axis "rangemode" StyleParam.RangeMode.convert Range |> DynObj.setValueOptBy axis "range" StyleParam.Range.convert FixedRange |> DynObj.setValueOpt axis "fixedrange" - ScaleAnchor |> DynObj.setValueOptBy axis "scaleanchor" StyleParam.AxisAnchorId.convert + ScaleAnchor |> DynObj.setValueOptBy axis "scaleanchor" StyleParam.LinearAxisId.convert ScaleRatio |> DynObj.setValueOpt axis "scaleratio" Constrain |> DynObj.setValueOptBy axis "constrain" StyleParam.AxisConstraint.convert ConstrainToward |> DynObj.setValueOptBy axis "constraitoward" StyleParam.AxisConstraintDirection.convert - Matches |> DynObj.setValueOptBy axis "matches" StyleParam.AxisAnchorId.convert + Matches |> DynObj.setValueOptBy axis "matches" StyleParam.LinearAxisId.convert Rangebreaks |> DynObj.setValueOpt axis "rangebreaks" TickMode |> DynObj.setValueOptBy axis "tickmode" StyleParam.TickMode.convert NTicks |> DynObj.setValueOpt axis "nticks" @@ -702,9 +702,9 @@ module Axis = ShowDividers |> DynObj.setValueOpt axis "showdividers" DividerColor |> DynObj.setValueOpt axis "dividercolor" DividerWidth |> DynObj.setValueOpt axis "dividerwidth" - Anchor |> DynObj.setValueOptBy axis "anchor" StyleParam.AxisAnchorId.convert + Anchor |> DynObj.setValueOptBy axis "anchor" StyleParam.LinearAxisId.convert Side |> DynObj.setValueOptBy axis "side" StyleParam.Side.convert - Overlaying |> DynObj.setValueOptBy axis "overlaying" StyleParam.AxisAnchorId.convert + Overlaying |> DynObj.setValueOptBy axis "overlaying" StyleParam.LinearAxisId.convert Layer |> DynObj.setValueOptBy axis "layer" StyleParam.Layer.convert Domain |> DynObj.setValueOptBy axis "domain" StyleParam.Range.convert Position |> DynObj.setValueOpt axis "position" diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index 033ce557b..a8cb358fb 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -65,8 +65,8 @@ type Chart = GenericChart.ofTraceObject trace |> GenericChart.mapLayout ( fun l -> l - |> Layout.AddLinearAxis(AxisId.X 1,hiddenAxis()) - |> Layout.AddLinearAxis(AxisId.Y 1,hiddenAxis()) + |> Layout.AddLinearAxis(StyleParam.SubPlotId.XAxis 1,hiddenAxis()) + |> Layout.AddLinearAxis(StyleParam.SubPlotId.YAxis 1,hiddenAxis()) ) diff --git a/src/Plotly.NET/ChartExtensions.fs b/src/Plotly.NET/ChartExtensions.fs index 80dbbfb61..1c0af34d1 100644 --- a/src/Plotly.NET/ChartExtensions.fs +++ b/src/Plotly.NET/ChartExtensions.fs @@ -54,27 +54,24 @@ module ChartExtensions = static member withAxisAnchor ( [] ?X, - [] ?Y, - [] ?Z + [] ?Y ) = - let idx = if X.IsSome then Some (StyleParam.AxisAnchorId.X X.Value) else None - let idy = if Y.IsSome then Some (StyleParam.AxisAnchorId.Y Y.Value) else None - let idz = if Z.IsSome then Some (StyleParam.AxisAnchorId.Z Z.Value) else None + let idx = X |> Option.map StyleParam.LinearAxisId.X + let idy = Y |> Option.map StyleParam.LinearAxisId.Y fun (ch:GenericChart) -> ch |> mapTrace (fun trace -> trace - |> TraceStyle.SetAxisAnchor(?X=idx,?Y=idy,?Z=idz) + |> TraceStyle.SetAxisAnchor(?X=idx,?Y=idy) ) [] static member withAxisAnchor ( (ch:GenericChart), [] ?X, - [] ?Y, - [] ?Z + [] ?Y ) = - ch |> Chart.withAxisAnchor(?X=X,?Y=Y,?Z=Z) + ch |> Chart.withAxisAnchor(?X=X,?Y=Y) /// Apply styling to the Marker(s) of the chart as Object. [] @@ -191,33 +188,41 @@ module ChartExtensions = [] [] - static member withX_Axis(xAxis:Axis.LinearAxis,[] ?Id : int) = + static member withX_Axis(xAxis:Axis.LinearAxis,[] ?Id : StyleParam.SubPlotId) = Chart.withXAxis(xAxis, ?Id = Id) // Sets x-Axis of 2d and 3d- Charts [] - static member withXAxis(xAxis:Axis.LinearAxis,[] ?Id) = - (fun (ch:GenericChart) -> - let contains3d = - ch - |> existsTrace (fun t -> - match t with - | :? Trace3d -> true - | _ -> false) + static member withXAxis(xAxis:Axis.LinearAxis,[] ?Id: StyleParam.SubPlotId) = + fun (ch:GenericChart) -> + + let id = defaultArg Id (StyleParam.SubPlotId.XAxis 1) - match contains3d with - | false -> + match id with + | StyleParam.SubPlotId.XAxis _ -> let layout = - let id = if Id.IsSome then StyleParam.AxisId.X Id.Value else StyleParam.AxisId.X 1 GenericChart.getLayout ch |> Layout.UpdateLinearAxisById(id,axis=xAxis) GenericChart.setLayout layout ch - | true -> - let layout = - Layout() - |> Layout.style (Scene=Scene.init( xAxis=xAxis) ) - GenericChart.addLayout layout ch - ) + + | StyleParam.SubPlotId.Scene _ -> + + let layout = GenericChart.getLayout ch + + let updatedScene = + layout + |> Layout.tryGetSceneById(id) + |> Option.defaultValue (Scene.init()) + |> Scene.style(XAxis = xAxis) + + let updatedLayout = + layout + |> Layout.updateSceneById(id,updatedScene) + + GenericChart.addLayout updatedLayout ch + + | _ -> failwith $"{StyleParam.SubPlotId.toString id} is an invalid subplot id for setting a xaxis" + [] @@ -283,33 +288,40 @@ module ChartExtensions = [] [] - static member withY_Axis(yAxis:Axis.LinearAxis,[] ?Id : int) = + static member withY_Axis(yAxis:Axis.LinearAxis,[] ?Id: StyleParam.SubPlotId) = Chart.withYAxis(yAxis, ?Id = Id) // Sets y-Axis of 2d and 3d- Charts [] - static member withYAxis(yAxis:Axis.LinearAxis,[] ?Id) = - (fun (ch:GenericChart) -> - let contains3d = - ch - |> existsTrace (fun t -> - match t with - | :? Trace3d -> true - | _ -> false) + static member withYAxis(yAxis:Axis.LinearAxis,[] ?Id: StyleParam.SubPlotId) = + fun (ch:GenericChart) -> + + let id = defaultArg Id (StyleParam.SubPlotId.YAxis 1) - match contains3d with - | false -> - let layout = - let id = if Id.IsSome then StyleParam.AxisId.Y Id.Value else StyleParam.AxisId.Y 1 - GenericChart.getLayout ch - |> Layout.UpdateLinearAxisById(id,axis=yAxis) - GenericChart.setLayout layout ch - | true -> - let layout = - Layout() - |> Layout.style(Scene=Scene.init(yAxis=yAxis) ) - GenericChart.addLayout layout ch - ) + match id with + | StyleParam.SubPlotId.YAxis _ -> + let layout = + GenericChart.getLayout ch + |> Layout.UpdateLinearAxisById(id,axis=yAxis) + GenericChart.setLayout layout ch + + | StyleParam.SubPlotId.Scene sceneId -> + + let layout = GenericChart.getLayout ch + + let updatedScene = + layout + |> Layout.tryGetSceneById(id) + |> Option.defaultValue (Scene.init()) + |> Scene.style(YAxis = yAxis) + + let updatedLayout = + layout + |> Layout.updateSceneById(id,updatedScene) + + GenericChart.addLayout updatedLayout ch + + | _ -> failwith $"{StyleParam.SubPlotId.toString id} is an invalid subplot id for setting a xaxis" [] @@ -366,13 +378,29 @@ module ChartExtensions = // Sets z-Axis of 3d- Charts [] - static member withZAxis(zAxis:Axis.LinearAxis) = - (fun (ch:GenericChart) -> - let layout = - Layout() - |> Layout.style(Scene=Scene.init(zAxis=zAxis) ) - GenericChart.addLayout layout ch - ) + static member withZAxis(zAxis:Axis.LinearAxis,[] ?Id: StyleParam.SubPlotId) = + fun (ch:GenericChart) -> + + let id = defaultArg Id (StyleParam.SubPlotId.Scene 1) + + match id with + | StyleParam.SubPlotId.Scene sceneId -> + + let layout = GenericChart.getLayout ch + + let updatedScene = + layout + |> Layout.tryGetSceneById(id) + |> Option.defaultValue (Scene.init()) + |> Scene.style(ZAxis = zAxis) + + let updatedLayout = + layout + |> Layout.updateSceneById(id,updatedScene) + + GenericChart.addLayout updatedLayout ch + + | _ -> failwith $"{StyleParam.SubPlotId.toString id} is an invalid subplot id for setting a xaxis" @@ -485,22 +513,22 @@ module ChartExtensions = GenericChart.setLayout layout ch) /// Sets a map for the given chart (will only work with traces supporting geo, e.g. choropleth, scattergeo) - [] - static member withMap(map:Geo,[] ?Id ) = + [] + static member withGeo(map:Geo,[] ?Id:StyleParam.SubPlotId ) = (fun (ch:GenericChart) -> let layout = - let id = defaultArg Id 1 + let id = defaultArg Id (StyleParam.SubPlotId.Geo 1) GenericChart.getLayout ch - |> Layout.UpdateMapById(id,map) + |> Layout.UpdateGeoById(id,map) GenericChart.setLayout layout ch ) /// Sets a mapbox for the given chart (will only work with traces supporting mapboxes, e.g. choroplethmapbox, scattermapbox) [] - static member withMapbox(mapBox:Mapbox,[] ?Id ) = + static member withMapbox(mapBox:Mapbox,[] ?Id:StyleParam.SubPlotId ) = (fun (ch:GenericChart) -> let layout = - let id = defaultArg Id 1 + let id = defaultArg Id (StyleParam.SubPlotId.MapBox 1) GenericChart.getLayout ch |> Layout.UpdateMapboxById(id,mapBox) GenericChart.setLayout layout ch @@ -571,8 +599,8 @@ module ChartExtensions = /// LatAxis : Sets the latitudinal axis for this geo trace /// /// LonAxis : Sets the longitudinal axis for this geo trace - [] - static member withMapStyle([] ?Id, + [] + static member withGeoStyle([] ?Id: StyleParam.SubPlotId, []?FitBounds : StyleParam.GeoFitBounds, []?Resolution : StyleParam.GeoResolution, []?Scope : StyleParam.GeoScope, @@ -641,16 +669,16 @@ module ChartExtensions = ?LatAxis = LatAxis , ?LonAxis = LonAxis ) - let id = defaultArg Id 1 - ch |> Chart.withMap(map,id) + let id = defaultArg Id (StyleParam.SubPlotId.Geo 1) + ch |> Chart.withGeo(map,id) ) - [] - static member withMapProjection(projectionType : StyleParam.GeoProjectionType, + [] + static member withGeoProjection(projectionType : StyleParam.GeoProjectionType, []?Rotation , []?Parallels, []?Scale , - []?Id + []?Id: StyleParam.SubPlotId ) = (fun (ch:GenericChart) -> @@ -663,8 +691,8 @@ module ChartExtensions = ) let map = Geo.init(Projection = projection) - let id = defaultArg Id 1 - ch |> Chart.withMap(map,id) + let id = defaultArg Id (StyleParam.SubPlotId.Geo 1) + ch |> Chart.withGeo(map,id) ) /// Set the LayoutGrid options of a Chart @@ -681,9 +709,9 @@ module ChartExtensions = /// Sets where the x axis labels and titles go. "bottom" means the very bottom of the grid. "bottom plot" is the lowest plot that each x axis is used in. "top" and "top plot" are similar. /// Sets where the y axis labels and titles go. "left" means the very left edge of the grid. "left plot" is the leftmost plot that each y axis is used in. "right" and "right plot" are similar. [] - static member withLayoutGridStyle([]?SubPlots : (StyleParam.AxisId * StyleParam.AxisId) [] [], - []?XAxes : StyleParam.AxisId [], - []?YAxes : StyleParam.AxisId [], + static member withLayoutGridStyle([]?SubPlots : (StyleParam.LinearAxisId * StyleParam.LinearAxisId) [] [], + []?XAxes : StyleParam.LinearAxisId [], + []?YAxes : StyleParam.LinearAxisId [], []?Rows : int, []?Columns : int, []?RowOrder : StyleParam.LayoutGridRowOrder, @@ -849,9 +877,9 @@ module ChartExtensions = /// Sets where the y axis labels and titles go. "left" means the very left edge of the grid. "left plot" is the leftmost plot that each y axis is used in. "right" and "right plot" are similar. [] static member Grid (nRows: int, nCols: int, - []?SubPlots : (StyleParam.AxisId*StyleParam.AxisId) [] [], - []?XAxes : StyleParam.AxisId [], - []?YAxes : StyleParam.AxisId [], + []?SubPlots : (StyleParam.LinearAxisId*StyleParam.LinearAxisId) [] [], + []?XAxes : StyleParam.LinearAxisId [], + []?YAxes : StyleParam.LinearAxisId [], []?RowOrder : StyleParam.LayoutGridRowOrder, []?Pattern : StyleParam.LayoutGridPattern, []?XGap : float, @@ -902,8 +930,8 @@ module ChartExtensions = gChart |> Chart.withAxisAnchor(xAnchor,yAnchor) // set adapted axis anchors - |> Chart.withXAxis(xAxis,i+1) // set previous axis with adapted id (one individual axis for each subplot, wether or not they will be used later) - |> Chart.withYAxis(yAxis,i+1) // set previous axis with adapted id (one individual axis for each subplot, wether or not they will be used later) + |> Chart.withXAxis(xAxis,(StyleParam.SubPlotId.XAxis (i+1))) // set previous axis with adapted id (one individual axis for each subplot, wether or not they will be used later) + |> Chart.withYAxis(yAxis,(StyleParam.SubPlotId.YAxis (i+1))) // set previous axis with adapted id (one individual axis for each subplot, wether or not they will be used later) |> GenericChart.mapLayout (fun l -> if i > 0 then // remove default axes from consecutive charts, otherwise they will override the first one @@ -950,9 +978,9 @@ module ChartExtensions = [] static member Grid ( - []?SubPlots : (StyleParam.AxisId*StyleParam.AxisId) [] [], - []?XAxes : StyleParam.AxisId [], - []?YAxes : StyleParam.AxisId [], + []?SubPlots : (StyleParam.LinearAxisId*StyleParam.LinearAxisId) [] [], + []?XAxes : StyleParam.LinearAxisId [], + []?YAxes : StyleParam.LinearAxisId [], []?RowOrder : StyleParam.LayoutGridRowOrder, []?Pattern : StyleParam.LayoutGridPattern, []?XGap : float, @@ -1033,9 +1061,9 @@ module ChartExtensions = [] static member SingleStack ( - []?SubPlots : (StyleParam.AxisId*StyleParam.AxisId) [] [], - []?XAxes : StyleParam.AxisId [], - []?YAxes : StyleParam.AxisId [], + []?SubPlots : (StyleParam.LinearAxisId*StyleParam.LinearAxisId) [] [], + []?XAxes : StyleParam.LinearAxisId [], + []?YAxes : StyleParam.LinearAxisId [], []?RowOrder : StyleParam.LayoutGridRowOrder, []?Pattern : StyleParam.LayoutGridPattern, []?XGap : float, @@ -1098,7 +1126,7 @@ module ChartExtensions = let ydomain = (1. - ((rowWidth * float rowI) - space ),1. - (rowWidth * float (rowI-1))) if contains3d ch then - let sceneName = sprintf "scene%i" (i+1) + let sceneId = StyleParam.SubPlotId.Scene (i+1) let scene = Scene.init ( @@ -1107,14 +1135,14 @@ module ChartExtensions = ) let layout = GenericChart.getLayout ch - |> Layout.AddScene ( - sceneName, + |> Layout.addScene ( + sceneId, scene ) ch |> mapTrace (fun t -> - t?scene <- sceneName + t?scene <- (StyleParam.SubPlotId.toString sceneId) t ) |> GenericChart.setLayout layout @@ -1123,38 +1151,38 @@ module ChartExtensions = let xaxis,yaxis,layout = let layout = GenericChart.getLayout ch - let xName, yName = StyleParam.AxisId.X 1 |> StyleParam.AxisId.toString, StyleParam.AxisId.Y 1 |> StyleParam.AxisId.toString + let xName, yName = StyleParam.LinearAxisId.X 1 |> StyleParam.LinearAxisId.toString, StyleParam.LinearAxisId.Y 1 |> StyleParam.LinearAxisId.toString match (layout.TryGetTypedValue xName),(layout.TryGetTypedValue yName) with | Some x, Some y -> // remove axis DynObj.remove layout xName DynObj.remove layout yName - x |> Axis.LinearAxis.style(Anchor=StyleParam.AxisAnchorId.Y index,Domain=StyleParam.Range.MinMax xdomain), - y |> Axis.LinearAxis.style(Anchor=StyleParam.AxisAnchorId.X index,Domain=StyleParam.Range.MinMax ydomain), + x |> Axis.LinearAxis.style(Anchor=StyleParam.LinearAxisId.Y index,Domain=StyleParam.Range.MinMax xdomain), + y |> Axis.LinearAxis.style(Anchor=StyleParam.LinearAxisId.X index,Domain=StyleParam.Range.MinMax ydomain), layout | Some x, None -> // remove x - axis DynObj.remove layout xName - x |> Axis.LinearAxis.style(Anchor=StyleParam.AxisAnchorId.Y index,Domain=StyleParam.Range.MinMax xdomain), - Axis.LinearAxis.init(Anchor=StyleParam.AxisAnchorId.X index,Domain=StyleParam.Range.MinMax ydomain), + x |> Axis.LinearAxis.style(Anchor=StyleParam.LinearAxisId.Y index,Domain=StyleParam.Range.MinMax xdomain), + Axis.LinearAxis.init(Anchor=StyleParam.LinearAxisId.X index,Domain=StyleParam.Range.MinMax ydomain), layout | None, Some y -> // remove y - axis DynObj.remove layout yName - Axis.LinearAxis.init(Anchor=StyleParam.AxisAnchorId.Y index,Domain=StyleParam.Range.MinMax xdomain), - y |> Axis.LinearAxis.style(Anchor=StyleParam.AxisAnchorId.X index,Domain=StyleParam.Range.MinMax ydomain), + Axis.LinearAxis.init(Anchor=StyleParam.LinearAxisId.Y index,Domain=StyleParam.Range.MinMax xdomain), + y |> Axis.LinearAxis.style(Anchor=StyleParam.LinearAxisId.X index,Domain=StyleParam.Range.MinMax ydomain), layout | None, None -> - Axis.LinearAxis.init(Anchor=StyleParam.AxisAnchorId.Y index,Domain=StyleParam.Range.MinMax xdomain), - Axis.LinearAxis.init(Anchor=StyleParam.AxisAnchorId.X index,Domain=StyleParam.Range.MinMax ydomain), + Axis.LinearAxis.init(Anchor=StyleParam.LinearAxisId.Y index,Domain=StyleParam.Range.MinMax xdomain), + Axis.LinearAxis.init(Anchor=StyleParam.LinearAxisId.X index,Domain=StyleParam.Range.MinMax ydomain), layout ch |> GenericChart.setLayout layout |> Chart.withAxisAnchor(X=index,Y=index) - |> Chart.withXAxis(xaxis,index) - |> Chart.withYAxis(yaxis,index) + |> Chart.withXAxis(xaxis,StyleParam.SubPlotId.YAxis index) + |> Chart.withYAxis(yaxis,StyleParam.SubPlotId.XAxis index) ) |> Chart.combine diff --git a/src/Plotly.NET/GenericChartExtensions.fs b/src/Plotly.NET/GenericChartExtensions.fs index b88317fa2..78664bdf4 100644 --- a/src/Plotly.NET/GenericChartExtensions.fs +++ b/src/Plotly.NET/GenericChartExtensions.fs @@ -31,18 +31,9 @@ module GenericChartExtensions = member this.WithAxisAnchor ( [] ?X, - [] ?Y, - [] ?Z + [] ?Y ) = - let idx = if X.IsSome then Some (StyleParam.AxisAnchorId.X X.Value) else None - let idy = if Y.IsSome then Some (StyleParam.AxisAnchorId.Y Y.Value) else None - let idz = if Z.IsSome then Some (StyleParam.AxisAnchorId.Z Z.Value) else None - - this - |> mapTrace (fun trace -> - trace - |> Trace.TraceStyle.SetAxisAnchor(?X=idx,?Y=idy,?Z=idz) - ) + this |> Chart.withAxisAnchor(?X = X,?Y = Y) /// Apply styling to the Marker(s) of the chart as Object. [] @@ -161,27 +152,8 @@ module GenericChartExtensions = // Sets x-Axis of 2d and 3d- Charts [] [] - member this.WithXAxis(xAxis:Axis.LinearAxis,[] ?Id) = - - let contains3d = - this - |> existsTrace (fun t -> - match t with - | :? Trace3d -> true - | _ -> false) - - match contains3d with - | false -> - let layout = - let id = if Id.IsSome then StyleParam.AxisId.X Id.Value else StyleParam.AxisId.X 1 - GenericChart.getLayout this - |> Layout.UpdateLinearAxisById(id,axis=xAxis) - GenericChart.setLayout layout this - | true -> - let layout = - Layout() - |> Layout.style (Scene=Scene.init( xAxis=xAxis) ) - GenericChart.addLayout layout this + member this.WithXAxis(xAxis:Axis.LinearAxis,[] ?Id: StyleParam.SubPlotId) = + this |> Chart.withXAxis(xAxis, ?Id = Id) // Sets x-Axis of 2d and 3d- Charts [] @@ -214,27 +186,8 @@ module GenericChartExtensions = // Sets y-Axis of 2d and 3d- Charts [] [] - member this.WithYAxis(yAxis:Axis.LinearAxis,[] ?Id) = - - let contains3d = - this - |> existsTrace (fun t -> - match t with - | :? Trace3d -> true - | _ -> false) - - match contains3d with - | false -> - let layout = - let id = if Id.IsSome then StyleParam.AxisId.Y Id.Value else StyleParam.AxisId.Y 1 - GenericChart.getLayout this - |> Layout.UpdateLinearAxisById(id,axis=yAxis) - GenericChart.setLayout layout this - | true -> - let layout = - Layout() - |> Layout.style(Scene=Scene.init(yAxis=yAxis) ) - GenericChart.addLayout layout this + member this.WithYAxis(yAxis:Axis.LinearAxis,[] ?Id: StyleParam.SubPlotId) = + this |> Chart.withYAxis(yAxis, ?Id = Id) // Sets y-Axis of 3d- Charts [] @@ -260,11 +213,8 @@ module GenericChartExtensions = // Sets z-Axis of 3d- Charts [] [] - member this.WithZAxis(zAxis:Axis.LinearAxis) = - let layout = - Layout() - |> Layout.style(Scene=Scene.init(zAxis=zAxis)) - GenericChart.addLayout layout this + member this.WithZAxis(zAxis:Axis.LinearAxis, [] ?Id: StyleParam.SubPlotId) = + this |> Chart.withZAxis(zAxis, ?Id=Id) @@ -327,22 +277,14 @@ module GenericChartExtensions = /// Sets a map for the given chart (will only work with traces supporting geo, e.g. choropleth, scattergeo) [] [] - member this.WithMap(map:Geo,[] ?Id ) = - let layout = - let id = defaultArg Id 1 - GenericChart.getLayout this - |> Layout.UpdateMapById(id,map) - GenericChart.setLayout layout this + member this.WithGeo(geo:Geo,[] ?Id:StyleParam.SubPlotId ) = + this |> Chart.withGeo(geo, ?Id = Id) /// Sets a mapbox for the given chart (will only work with traces supporting mapboxes, e.g. choroplethmapbox, scattermapbox) [] [] - member this.withMapbox(mapBox:Mapbox,[] ?Id ) = - let layout = - let id = defaultArg Id 1 - GenericChart.getLayout this - |> Layout.UpdateMapboxById(id,mapBox) - GenericChart.setLayout layout this + member this.withMapbox(mapBox:Mapbox,[] ?Id: StyleParam.SubPlotId ) = + this |> Chart.withMapbox(mapBox, ?Id = Id) /// Sets the map style for the given chart (will only work with traces supporting geo, e.g. choropleth, scattergeo) @@ -410,9 +352,9 @@ module GenericChartExtensions = /// LatAxis : Sets the latitudinal axis for this geo trace /// /// LonAxis : Sets the longitudinal axis for this geo trace - [] + [] [] - member this.WithMapStyle([] ?Id, + member this.WithGeoStyle([] ?Id : StyleParam.SubPlotId, []?FitBounds : StyleParam.GeoFitBounds, []?Resolution : StyleParam.GeoResolution, []?Scope : StyleParam.GeoScope, @@ -445,44 +387,42 @@ module GenericChartExtensions = []?LatAxis : Axis.LinearAxis, []?LonAxis : Axis.LinearAxis ) = - let map = - Geo.init( - ?FitBounds = FitBounds , - ?Resolution = Resolution , - ?Scope = Scope , - ?Projection = Projection , - ?Center = Center , - ?Visible = Visible , - ?Domain = Domain , - ?ShowCoastLines = ShowCoastLines, - ?CoastLineColor = CoastLineColor, - ?CoastLineWidth = CoastLineWidth, - ?ShowLand = ShowLand , - ?LandColor = LandColor , - ?ShowOcean = ShowOcean , - ?OceanColor = OceanColor , - ?ShowLakes = ShowLakes , - ?LakeColor = LakeColor , - ?ShowRivers = ShowRivers , - ?RiverColor = RiverColor , - ?RiverWidth = RiverWidth , - ?ShowCountries = ShowCountries , - ?CountryColor = CountryColor , - ?CountryWidth = CountryWidth , - ?ShowSubunits = ShowSubunits , - ?SubunitColor = SubunitColor , - ?SubunitWidth = SubunitWidth , - ?ShowFrame = ShowFrame , - ?FrameColor = FrameColor , - ?FrameWidth = FrameWidth , - ?BgColor = BgColor , - ?LatAxis = LatAxis , - ?LonAxis = LonAxis - ) in - let id = defaultArg Id 1 in - this |> Chart.withMap(map,id) - - [] + this + |> Chart.withGeoStyle( + ?FitBounds = FitBounds , + ?Resolution = Resolution , + ?Scope = Scope , + ?Projection = Projection , + ?Center = Center , + ?Visible = Visible , + ?Domain = Domain , + ?ShowCoastLines = ShowCoastLines, + ?CoastLineColor = CoastLineColor, + ?CoastLineWidth = CoastLineWidth, + ?ShowLand = ShowLand , + ?LandColor = LandColor , + ?ShowOcean = ShowOcean , + ?OceanColor = OceanColor , + ?ShowLakes = ShowLakes , + ?LakeColor = LakeColor , + ?ShowRivers = ShowRivers , + ?RiverColor = RiverColor , + ?RiverWidth = RiverWidth , + ?ShowCountries = ShowCountries , + ?CountryColor = CountryColor , + ?CountryWidth = CountryWidth , + ?ShowSubunits = ShowSubunits , + ?SubunitColor = SubunitColor , + ?SubunitWidth = SubunitWidth , + ?ShowFrame = ShowFrame , + ?FrameColor = FrameColor , + ?FrameWidth = FrameWidth , + ?BgColor = BgColor , + ?LatAxis = LatAxis , + ?LonAxis = LonAxis + ) + + [] [] member this.WithMapProjection(projectionType : StyleParam.GeoProjectionType, []?Rotation , @@ -490,25 +430,21 @@ module GenericChartExtensions = []?Scale , []?Id ) = - let projection = - GeoProjection.init( - projectionType = projectionType, - ?Rotation = Rotation , - ?Parallels = Parallels , - ?Scale = Scale - ) - - let map = Geo.init(Projection = projection) - let id = defaultArg Id 1 - this |> Chart.withMap(map,id) + this + |> Chart.withGeoProjection( + projectionType = projectionType, + ?Rotation = Rotation , + ?Parallels = Parallels , + ?Scale = Scale + ) // Set the LayoutGrid options of a Chart [] [] - member this.WithLayoutGridStyle([]?SubPlots : (StyleParam.AxisId * StyleParam.AxisId)[] [], - []?XAxes : StyleParam.AxisId [], - []?YAxes : StyleParam.AxisId [], + member this.WithLayoutGridStyle([]?SubPlots : (StyleParam.LinearAxisId * StyleParam.LinearAxisId)[] [], + []?XAxes : StyleParam.LinearAxisId [], + []?YAxes : StyleParam.LinearAxisId [], []?Rows : int, []?Columns : int, []?RowOrder : StyleParam.LayoutGridRowOrder, diff --git a/src/Plotly.NET/Layout.fs b/src/Plotly.NET/Layout.fs index 9ab9c1bf6..fb0879855 100644 --- a/src/Plotly.NET/Layout.fs +++ b/src/Plotly.NET/Layout.fs @@ -144,8 +144,8 @@ type Layout() = ?Paper_bgcolor, ?Plot_bgcolor, - ?Hovermode:StyleParam.Hovermode, - ?Dragmode:StyleParam.Dragmode, + ?Hovermode:StyleParam.HoverMode, + ?Dragmode:StyleParam.DragMode, ?Separators, ?Barmode:StyleParam.Barmode, @@ -177,8 +177,8 @@ type Layout() = Hidesources |> DynObj.setValueOpt layout "hidesources" Smith |> DynObj.setValueOpt layout "smith" Showlegend |> DynObj.setValueOpt layout "showlegend" - Hovermode |> DynObj.setValueOptBy layout "hovermode" StyleParam.Hovermode.toString - Dragmode |> DynObj.setValueOptBy layout "dragmode" StyleParam.Dragmode.toString + Hovermode |> DynObj.setValueOptBy layout "hovermode" StyleParam.HoverMode.toString + Dragmode |> DynObj.setValueOptBy layout "dragmode" StyleParam.DragMode.toString Geo |> DynObj.setValueOpt layout "geo" Polar |> DynObj.setValueOpt layout "polar" @@ -230,91 +230,107 @@ type Layout() = static member AddLinearAxis ( - id : StyleParam.AxisId, + id : StyleParam.SubPlotId, axis : Axis.LinearAxis ) = (fun (layout:Layout) -> - axis |> DynObj.setValue layout (StyleParam.AxisId.toString id) + match id with + | StyleParam.SubPlotId.XAxis _ | StyleParam.SubPlotId.YAxis _ -> + axis |> DynObj.setValue layout (StyleParam.SubPlotId.toString id) + layout - layout + | _ -> failwith $"{StyleParam.SubPlotId.toString id} is an invalid subplot id for setting a linear axis on layout" ) // Updates the style of current axis with given AxisId static member UpdateLinearAxisById ( - id : StyleParam.AxisId, + id : StyleParam.SubPlotId, axis : Axis.LinearAxis ) = (fun (layout:Layout) -> - let axis' = - match layout.TryGetValue (StyleParam.AxisId.toString id) with - | Some a -> DynObj.combine (unbox a) axis - | None -> axis :> DynamicObj + match id with + | StyleParam.SubPlotId.XAxis _ | StyleParam.SubPlotId.YAxis _ -> + + let axis' = + match layout.TryGetValue (StyleParam.SubPlotId.toString id) with + | Some a -> DynObj.combine (unbox a) axis + | None -> axis :> DynamicObj - axis' |> DynObj.setValue layout (StyleParam.AxisId.toString id) + axis' |> DynObj.setValue layout (StyleParam.SubPlotId.toString id) - layout + layout + | _ -> failwith $"{StyleParam.SubPlotId.toString id} is an invalid subplot id for setting a linear axis on layout" ) - static member AddScene + static member addScene ( - name: string, - scene:Scene + id : StyleParam.SubPlotId, + scene : Scene ) = (fun (layout:Layout) -> - scene |> DynObj.setValue layout name + scene |> DynObj.setValue layout (StyleParam.SubPlotId.toString id) layout ) - static member SetLayoutGrid + static member updateSceneById ( - grid: LayoutGrid + id : StyleParam.SubPlotId, + scene : Scene ) = - (fun (layout:Layout) -> - grid |> DynObj.setValue layout "grid" - layout - ) + (fun (layout:Layout) -> + let scene' = + match layout.TryGetValue (StyleParam.SubPlotId.toString id) with + | Some a -> DynObj.combine (unbox a) scene + | None -> scene :> DynamicObj - - static member GetLayoutGrid - ( - grid: LayoutGrid - ) = - (fun (layout:Layout) -> - grid |> DynObj.setValue layout "grid" + scene' |> DynObj.setValue layout (StyleParam.SubPlotId.toString id) layout ) + static member tryGetSceneById (id:StyleParam.SubPlotId) = + (fun (layout:Layout) -> + layout.TryGetTypedValue(StyleParam.SubPlotId.toString id) + ) - static member AddMap + static member AddGeo ( - id : int, - map : Geo + id : StyleParam.SubPlotId, + geo : Geo ) = (fun (layout:Layout) -> - let key = if id < 2 then "geo" else sprintf "geo%i" id - map |> DynObj.setValue layout key + geo |> DynObj.setValue layout (StyleParam.SubPlotId.toString id) layout ) // Updates the style of current geo map with given Id - static member UpdateMapById + static member UpdateGeoById ( - id : int, - map : Geo + id : StyleParam.SubPlotId, + geo : Geo ) = (fun (layout:Layout) -> - let key = if id < 2 then "geo" else sprintf "geo%i" id let geo' = - match layout.TryGetTypedValue(key) with - | Some a -> DynObj.combine (unbox a) map - | None -> map :> DynamicObj - - geo'|> DynObj.setValue layout key + match layout.TryGetValue (StyleParam.SubPlotId.toString id) with + | Some a -> DynObj.combine (unbox a) geo + | None -> geo :> DynamicObj + + geo' |> DynObj.setValue layout (StyleParam.SubPlotId.toString id) + layout + ) + + static member AddMapbox + ( + id : StyleParam.SubPlotId, + mapbox : Mapbox + ) = + (fun (layout:Layout) -> + + mapbox |> DynObj.setValue layout (StyleParam.SubPlotId.toString id) layout ) @@ -322,18 +338,16 @@ type Layout() = // Updates the style of current geo map with given Id static member UpdateMapboxById ( - id : int, + id : StyleParam.SubPlotId, mapbox : Mapbox ) = (fun (layout:Layout) -> - let key = if id < 2 then "mapbox" else sprintf "mapbox%i" id let mapbox' = - match layout.TryGetTypedValue(key) with - | Some a -> DynObj.combine (unbox a) mapbox - | None -> mapbox :> DynamicObj - - mapbox' |> DynObj.setValue layout key + match layout.TryGetValue (StyleParam.SubPlotId.toString id) with + | Some a -> DynObj.combine (unbox a) mapbox + | None -> mapbox :> DynamicObj + mapbox' |> DynObj.setValue layout (StyleParam.SubPlotId.toString id) layout ) @@ -391,6 +405,23 @@ type Layout() = layout ) + static member SetLayoutGrid + ( + grid: LayoutGrid + ) = + (fun (layout:Layout) -> + grid |> DynObj.setValue layout "grid" + layout + ) + + static member GetLayoutGrid + ( + grid: LayoutGrid + ) = + (fun (layout:Layout) -> + grid |> DynObj.setValue layout "grid" + layout + ) static member setLegend(legend:Legend) = (fun (layout:Layout) -> diff --git a/src/Plotly.NET/LayoutGrid.fs b/src/Plotly.NET/LayoutGrid.fs index 55eba959b..35b56274d 100644 --- a/src/Plotly.NET/LayoutGrid.fs +++ b/src/Plotly.NET/LayoutGrid.fs @@ -25,9 +25,9 @@ type LayoutGrid () = ( ?Rows : int, ?Columns : int, - ?SubPlots : (StyleParam.AxisId * StyleParam.AxisId) [] [], - ?XAxes : StyleParam.AxisId [], - ?YAxes : StyleParam.AxisId [], + ?SubPlots : (StyleParam.LinearAxisId * StyleParam.LinearAxisId) [] [], + ?XAxes : StyleParam.LinearAxisId [], + ?YAxes : StyleParam.LinearAxisId [], ?RowOrder : StyleParam.LayoutGridRowOrder, ?Pattern : StyleParam.LayoutGridPattern, ?XGap : float, @@ -72,9 +72,9 @@ type LayoutGrid () = ( ?Rows : int, ?Columns : int, - ?SubPlots : (StyleParam.AxisId * StyleParam.AxisId) [] [], - ?XAxes : StyleParam.AxisId [], - ?YAxes : StyleParam.AxisId [], + ?SubPlots : (StyleParam.LinearAxisId * StyleParam.LinearAxisId) [] [], + ?XAxes : StyleParam.LinearAxisId [], + ?YAxes : StyleParam.LinearAxisId [], ?RowOrder : StyleParam.LayoutGridRowOrder, ?Pattern : StyleParam.LayoutGridPattern, ?XGap : float, @@ -84,9 +84,9 @@ type LayoutGrid () = ?YSide : StyleParam.LayoutGridYSide ) = (fun (layoutGrid: LayoutGrid) -> - SubPlots |> DynObj.setValueOptBy layoutGrid "subplots" (Array.map (Array.map ( fun (x,y) -> $"{StyleParam.AxisId.toString x}{StyleParam.AxisId.toString y}"))) - XAxes |> DynObj.setValueOptBy layoutGrid "xaxes" (Array.map StyleParam.AxisId.toString) - YAxes |> DynObj.setValueOptBy layoutGrid "yaxes" (Array.map StyleParam.AxisId.toString) + SubPlots |> DynObj.setValueOptBy layoutGrid "subplots" (Array.map (Array.map ( fun (x,y) -> $"{StyleParam.LinearAxisId.toString x}{StyleParam.LinearAxisId.toString y}"))) + XAxes |> DynObj.setValueOptBy layoutGrid "xaxes" (Array.map StyleParam.LinearAxisId.toString) + YAxes |> DynObj.setValueOptBy layoutGrid "yaxes" (Array.map StyleParam.LinearAxisId.toString) Rows |> DynObj.setValueOpt layoutGrid "rows" Columns |> DynObj.setValueOpt layoutGrid "columns" RowOrder |> DynObj.setValueOptBy layoutGrid "roworder" StyleParam.LayoutGridRowOrder.toString diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index af43617d7..a24798fe9 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -35,6 +35,7 @@ #load "Polar.fs" #load "Bins.fs" #load "Cumulative.fs" +#load "Annotation.fs" #load "Scene.fs" #load "Shape.fs" #load "Error.fs" @@ -47,7 +48,6 @@ #load "MapboxLayer.fs" #load "Mapbox.fs" #load "LayoutGrid.fs" -#load "Annotation.fs" #load "Layout.fs" #load "Template.fs" #load "Config.fs" @@ -71,6 +71,28 @@ open FSharpAux open System + +let singleStackChart = + let x = [1.; 2.; 3.; 4.; 5.; 6.; 7.; 8.; 9.; 10.; ] + let y = [2.; 1.5; 5.; 1.5; 3.; 2.5; 2.5; 1.5; 3.5; 1.] + [ + Chart.Point(x,y) + |> Chart.withYAxisStyle("This title must") + + Chart.Line(x,y) + |> Chart.withYAxisStyle("be set on the",ZeroLine=false) + + Chart.Spline(x,y) + |> Chart.withYAxisStyle("respective subplots",ZeroLine=false) + ] + |> Chart.SingleStack(Pattern = StyleParam.LayoutGridPattern.Coupled) + //move xAxis to bottom and increase spacing between plots by using the withLayoutGridStyle function + |> Chart.withLayoutGridStyle(XSide=StyleParam.LayoutGridXSide.Bottom,YGap= 0.1) + |> Chart.withTitle("Hi i am the new SingleStackChart") + |> Chart.withXAxisStyle("im the shared xAxis") + +singleStackChart |> Chart.show + Chart.Cone( x = [1; 1; 1], y = [1; 2; 3], @@ -81,6 +103,10 @@ Chart.Cone( ) |> Chart.show +Chart.Point([1,2]) +|> Chart.withXAxisStyle ("X axis title quack quack", MinMax = (-1.,10.)) +|> Chart.withYAxisStyle ("Y axis title boo foo", MinMax = (-1.,10.)) +|> Chart.show let r = [ 1; 2; 3; 4; 5; 6; 7;] |> List.map ((*) 10000) let r2 = [ 5; 6; 7; 1; 2; 3; 4;] |> List.map ((*) 10000) @@ -354,7 +380,7 @@ Chart.ChoroplethMap( GeoJson = geoJson, FeatureIdKey="id" ) -|> Chart.withMap( +|> Chart.withGeo( Geo.init( Scope=StyleParam.GeoScope.Usa ) @@ -370,7 +396,7 @@ Trace.initChoroplethMap(id) t?locationmode <- "geojson-id" t |> GenericChart.ofTraceObject -|> Chart.withMap( +|> Chart.withGeo( Geo.init( Scope=StyleParam.GeoScope.Usa ) @@ -557,14 +583,14 @@ Chart.ScatterGeo( ], StyleParam.Mode.Lines ) -|> Chart.withMapStyle( +|> Chart.withGeoStyle( Projection=GeoProjection.init(projectionType=StyleParam.GeoProjectionType.AzimuthalEqualArea), ShowLakes=true, ShowOcean=true, OceanColor="lightblue", ShowRivers=true) |> Chart.show -//test new withMapStyle function +//test new withGeoStyle function let locations2,z2 = [("Belarus",17.5); ("Moldova",16.8);("Lithuania",15.4);("Russia",15.1); @@ -619,13 +645,13 @@ let locations2,z2 = // Pure alcohol consumption among adults (age 15+) in 2010 Chart.ChoroplethMap(locations2,z2,Locationmode=StyleParam.LocationFormat.CountryNames,Colorscale=StyleParam.Colorscale.Electric) -|> Chart.withMapStyle( +|> Chart.withGeoStyle( Projection=GeoProjection.init(projectionType=StyleParam.GeoProjectionType.Mollweide), ShowLakes=true, ShowOcean=true, OceanColor="lightblue", ShowRivers=true) -|> Chart.withColorBarStyle ("Alcohol consumption[l/y]",Length=0.5) +|> Chart.withColorBarStyle (Title.init("Alcohol consumption[l/y]"),Length=0.5) |> Chart.withSize(1000.,1000.) |> Chart.show @@ -810,9 +836,7 @@ generateDomainRanges 8 1 ] |> Chart.Heatmap |> Chart.withColorBarStyle( - "Hallo?", - TitleSide=StyleParam.Side.Right, - TitleFont=Font.init(Size=20.) + Title.init("Hallo?",Side=StyleParam.Side.Right) ) |> Chart.show diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index 91c96d365..f17b97fe9 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -65,6 +65,7 @@ + @@ -77,7 +78,6 @@ - diff --git a/src/Plotly.NET/Scene.fs b/src/Plotly.NET/Scene.fs index 4d632f24f..532ea0a6a 100644 --- a/src/Plotly.NET/Scene.fs +++ b/src/Plotly.NET/Scene.fs @@ -2,60 +2,108 @@ namespace Plotly.NET open DynamicObj +type AspectRatio() = + inherit DynamicObj () + +type Camera() = + inherit DynamicObj () + /// Scene type Scene() = inherit DynamicObj () - /// Initialized Scene object - //[] + /// + /// Initialize a categorical Scene object that can be used as a laxout anchor for a 3D coordinate system. + /// + /// 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. + /// If "cube", this scene's axes are drawn as a cube, regardless of the axes' ranges. If "data", this scene's axes are drawn in proportion with the axes' ranges. If "manual", this scene's axes are drawn in proportion with the input of "aspectratio" (the default behavior if "aspectratio" is provided). If "auto", this scene's axes are drawn using the results of "data" except when one axis is more than four times the size of the two others, where in that case the results of "cube" are used. + /// Sets this scene's axis aspectratio. + /// Sets this scene's background color. + /// Sets this scene's camera + /// Sets this scene's domain + /// Determines the mode of drag interactions for this scene. + /// Determines the mode of hover interactions for this scene. + /// Controls persistence of user-driven changes in camera attributes. Defaults to `layout.uirevision`. + /// Sets this scene's xaxis + /// Sets this scene's yaxis + /// Sets this scene's zaxis static member init ( - ?xAxis:Axis.LinearAxis, - ?yAxis:Axis.LinearAxis, - ?zAxis:Axis.LinearAxis, - ?isSubplotObj: bool , - ?BgColor: string, - // ?Camera , - ?Domain:Domain - // ?Aspectmode , - // ?Aspectratio + ?Annotations : seq, + ?AspectMode : StyleParam.AspectMode, + ?AspectRatio : AspectRatio, + ?BGColor : string, + ?Camera : Camera, + ?Domain : Domain, + ?DragMode : StyleParam.DragMode, + ?HoverMode : StyleParam.HoverMode, + ?UIRevision : string, + ?XAxis : Axis.LinearAxis, + ?YAxis : Axis.LinearAxis, + ?ZAxis : Axis.LinearAxis ) = Scene () |> Scene.style ( - ?xAxis = xAxis , - ?yAxis = yAxis , - ?zAxis = zAxis , - ?isSubplotObj = isSubplotObj , - ?BgColor = BgColor , - ?Domain = Domain + ?Annotations = Annotations , + ?AspectMode = AspectMode , + ?AspectRatio = AspectRatio , + ?BGColor = BGColor , + ?Camera = Camera , + ?Domain = Domain , + ?DragMode = DragMode , + ?HoverMode = HoverMode , + ?UIRevision = UIRevision , + ?XAxis = XAxis , + ?YAxis = YAxis , + ?ZAxis = ZAxis ) - // [] - /// Applies the styles to Scene() - //[] + /// + /// Creates a function that applies the given style parameters to a Scene object + /// + /// 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. + /// If "cube", this scene's axes are drawn as a cube, regardless of the axes' ranges. If "data", this scene's axes are drawn in proportion with the axes' ranges. If "manual", this scene's axes are drawn in proportion with the input of "aspectratio" (the default behavior if "aspectratio" is provided). If "auto", this scene's axes are drawn using the results of "data" except when one axis is more than four times the size of the two others, where in that case the results of "cube" are used. + /// Sets this scene's axis aspectratio. + /// Sets this scene's background color. + /// Sets this scene's camera + /// Sets this scene's domain + /// Determines the mode of drag interactions for this scene. + /// Determines the mode of hover interactions for this scene. + /// Controls persistence of user-driven changes in camera attributes. Defaults to `layout.uirevision`. + /// Sets this scene's xaxis + /// Sets this scene's yaxis + /// Sets this scene's zaxis static member style ( - ?xAxis:Axis.LinearAxis, - ?yAxis:Axis.LinearAxis, - ?zAxis:Axis.LinearAxis, - ?isSubplotObj: bool , - ?BgColor: string, - // ?Camera , - ?Domain:Domain - // ?Aspectmode , - // ?Aspectratio + ?Annotations : seq, + ?AspectMode : StyleParam.AspectMode, + ?AspectRatio : AspectRatio, + ?BGColor : string, + ?Camera : Camera, + ?Domain : Domain, + ?DragMode : StyleParam.DragMode, + ?HoverMode : StyleParam.HoverMode, + ?UIRevision : string, + ?XAxis : Axis.LinearAxis, + ?YAxis : Axis.LinearAxis, + ?ZAxis : Axis.LinearAxis ) = (fun (scene:Scene) -> - isSubplotObj |> DynObj.setValueOpt scene "_isSubplotObj" - BgColor |> DynObj.setValueOpt scene "bgcolor" - Domain |> DynObj.setValueOpt scene "domain" - // Update - xAxis |> DynObj.setValueOpt scene "xaxis" - yAxis |> DynObj.setValueOpt scene "yaxis" - zAxis |> DynObj.setValueOpt scene "zaxis" - - // out -> + + Annotations |> DynObj.setValueOpt scene "annotations" + AspectMode |> DynObj.setValueOptBy scene "aspectmode" StyleParam.AspectMode.convert + AspectRatio |> DynObj.setValueOpt scene "aspectratio" + BGColor |> DynObj.setValueOpt scene "bgcolor" + Camera |> DynObj.setValueOpt scene "camera" + Domain |> DynObj.setValueOpt scene "domain" + DragMode |> DynObj.setValueOptBy scene "dragmode" StyleParam.DragMode.convert + HoverMode |> DynObj.setValueOptBy scene "hovermode" StyleParam.HoverMode.convert + UIRevision |> DynObj.setValueOpt scene "uirevision" + XAxis |> DynObj.setValueOpt scene "xaxis" + YAxis |> DynObj.setValueOpt scene "yaxis" + ZAxis |> DynObj.setValueOpt scene "zaxis" + scene ) diff --git a/src/Plotly.NET/StyleParams.fs b/src/Plotly.NET/StyleParams.fs index ee1fcf86e..153a662cc 100644 --- a/src/Plotly.NET/StyleParams.fs +++ b/src/Plotly.NET/StyleParams.fs @@ -12,6 +12,20 @@ module StyleParam = //-------------------------- // #A# //-------------------------- + + [] + type AspectMode = + | Auto | Cube | Data | Manual + + static member toString = function + | Auto -> "auto" + | Cube -> "cube" + | Data -> "data" + | Manual-> "manual" + + + static member convert = AspectMode.toString >> box + /// Sets the horizontal alignment of the text content within hover label box. Has an effect only if the hover label text spans more two or more lines [] type Align = @@ -66,34 +80,38 @@ module StyleParam = |LineOnly -> 8 static member convert = ArrowHead.toEnum >> box - /// [] - type AxisAnchorId = - | X of int - | Y of int - | Z of int - | Color of int - | Free + type LinearAxisId = + | X of int | Y of int static member toString = function | X id -> if id < 2 then "x" else sprintf "x%i" id | Y id -> if id < 2 then "y" else sprintf "y%i" id - | Z id -> if id < 2 then "z" else sprintf "z%i" id - | Color id -> if id < 2 then "coloraxis" else sprintf "coloraxis%i" id - | Free -> "free" - - static member convert = AxisAnchorId.toString >> box - - [] - type AxisId = - | X of int | Y of int | Z of int + static member convert = LinearAxisId.toString >> box + + // to-do merge with axis anchor id + [] + type SubPlotId = + | XAxis of int + | YAxis of int + | ColorAxis of int + | Geo of int + | MapBox of int + | Polar of int + | Ternary of int + | Scene of int static member toString = function - | X id -> if id < 2 then "xaxis" else sprintf "xaxis%i" id - | Y id -> if id < 2 then "yaxis" else sprintf "yaxis%i" id - | Z id -> if id < 2 then "zaxis" else sprintf "zaxis%i" id - - static member convert = AxisId.toString >> box + | XAxis id -> if id < 2 then "xaxis" else sprintf "xaxis%i" id + | YAxis id -> if id < 2 then "yaxis" else sprintf "yaxis%i" id + | ColorAxis id -> if id < 2 then "coloraxis" else sprintf "coloraxis%i" id + | Geo id -> if id < 2 then "geo" else sprintf "geo%i" id + | MapBox id -> if id < 2 then "mapbox" else sprintf "mapbox%i" id + | Polar id -> if id < 2 then "polar" else sprintf "polar%i" id + | Ternary id -> if id < 2 then "ternary" else sprintf "ternary%i" id + | Scene id -> if id < 2 then "scene" else sprintf "scene%i" id + + static member convert = SubPlotId.toString >> box [] /// Editable parts of a chart that can be set via Chart config. @@ -424,7 +442,7 @@ module StyleParam = /// dragging motions. A user can always depress the 'shift' key to access the whatever functionality has not been set as the default. In 3D plots, the /// default drag mode is 'rotate' which rotates the scene. [] - type Dragmode = + type DragMode = | Zoom | Pan | Rotate static member toString = function @@ -433,7 +451,7 @@ module StyleParam = | Rotate -> "rotate" - static member convert = Dragmode.toString >> box + static member convert = DragMode.toString >> box /// Sets the Delaunay axis, which is the axis that is perpendicular to the surface of the Delaunay triangulation. /// It has an effect if `i`, `j`, `k` are not provided and `alphahull` is set to indicate Delaunay triangulation. @@ -714,16 +732,16 @@ module StyleParam = /// with corresponding trace labels. When set to 'y' all data sharing the same 'y' coordinates will be shown on the screen with corresponding /// trace labels. When set to 'closest', information about the data point closest to where the viewer is hovering will appear. [] - type Hovermode = - | Closest | X | Y + type HoverMode = + | Closest | X | Y | False static member toString = function | Closest -> "closest" | X -> "x" | Y -> "y" + | False -> "false" - - static member convert = Hovermode.toString >> box + static member convert = HoverMode.toString >> box [] type HorizontalAlign = diff --git a/src/Plotly.NET/Template.fs b/src/Plotly.NET/Template.fs index 19f34e8c8..6e93c3636 100644 --- a/src/Plotly.NET/Template.fs +++ b/src/Plotly.NET/Template.fs @@ -95,8 +95,8 @@ module ChartTemplates = Paper_bgcolor = "white", Plot_bgcolor = "white" ) - |> Layout.AddLinearAxis((StyleParam.AxisId.X 1),(initLightAxisTemplate())) - |> Layout.AddLinearAxis((StyleParam.AxisId.Y 1),(initLightAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.XAxis 1),(initLightAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.YAxis 1),(initLightAxisTemplate())) Template.init(defaultLayout) @@ -115,8 +115,8 @@ module ChartTemplates = Paper_bgcolor = "white", Plot_bgcolor = "white" ) - |> Layout.AddLinearAxis((StyleParam.AxisId.X 1),(initLightAxisTemplate())) - |> Layout.AddLinearAxis((StyleParam.AxisId.Y 1),(initLightAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.XAxis 1),(initLightAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.YAxis 1),(initLightAxisTemplate())) Template.init(defaultLayout) @@ -139,8 +139,8 @@ module ChartTemplates = Plot_bgcolor= "rgb(55, 55, 61)", Font = Font.init(Color = "rgb(204, 204, 204)") ) - |> Layout.AddLinearAxis((StyleParam.AxisId.X 1),(initDarkAxisTemplate())) - |> Layout.AddLinearAxis((StyleParam.AxisId.Y 1),(initDarkAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.XAxis 1),(initDarkAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.YAxis 1),(initDarkAxisTemplate())) Template.init(darkLayoutTemplate) @@ -177,8 +177,8 @@ module ChartTemplates = Plot_bgcolor= "#200117", Font = Font.init(Color = "white") ) - |> Layout.AddLinearAxis((StyleParam.AxisId.X 1),(initFslabAxisTemplate())) - |> Layout.AddLinearAxis((StyleParam.AxisId.Y 1),(initFslabAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.XAxis 1),(initFslabAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.YAxis 1),(initFslabAxisTemplate())) Template.init(fslabLayoutTemplate) |> Template.withColorWay ColorWays.fslab @@ -196,8 +196,8 @@ module ChartTemplates = Paper_bgcolor = "rgba(255, 255, 255, 0)", Plot_bgcolor = "rgba(255, 255, 255, 0)" ) - |> Layout.AddLinearAxis((StyleParam.AxisId.X 1),(initTransparentAxisTemplate())) - |> Layout.AddLinearAxis((StyleParam.AxisId.Y 1),(initTransparentAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.XAxis 1),(initTransparentAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.YAxis 1),(initTransparentAxisTemplate())) Template.init(defaultLayout) @@ -215,7 +215,7 @@ module ChartTemplates = Paper_bgcolor = "rgba(255, 255, 255, 0)", Plot_bgcolor = "rgba(255, 255, 255, 0)" ) - |> Layout.AddLinearAxis((StyleParam.AxisId.X 1),(initTransparentAxisTemplate())) - |> Layout.AddLinearAxis((StyleParam.AxisId.Y 1),(initTransparentAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.XAxis 1),(initTransparentAxisTemplate())) + |> Layout.AddLinearAxis((StyleParam.SubPlotId.YAxis 1),(initTransparentAxisTemplate())) Template.init(defaultLayout) \ No newline at end of file diff --git a/src/Plotly.NET/Trace.fs b/src/Plotly.NET/Trace.fs index ff5455606..bbe496325 100644 --- a/src/Plotly.NET/Trace.fs +++ b/src/Plotly.NET/Trace.fs @@ -231,15 +231,13 @@ module Trace = /// Sets the given axis anchor id(s) on a Trace object. static member SetAxisAnchor ( - ?X:StyleParam.AxisAnchorId, - ?Y:StyleParam.AxisAnchorId, - ?Z:StyleParam.AxisAnchorId + ?X:StyleParam.LinearAxisId, + ?Y:StyleParam.LinearAxisId ) = (fun (trace:('T :> Trace)) -> - X |> DynObj.setValueOptBy trace "xaxis" StyleParam.AxisAnchorId.toString - Y |> DynObj.setValueOptBy trace "yaxis" StyleParam.AxisAnchorId.toString - Z |> DynObj.setValueOptBy trace "zaxis" StyleParam.AxisAnchorId.toString + X |> DynObj.setValueOptBy trace "xaxis" StyleParam.LinearAxisId.toString + Y |> DynObj.setValueOptBy trace "yaxis" StyleParam.LinearAxisId.toString trace ) diff --git a/src/Plotly.NET/Trace3d.fs b/src/Plotly.NET/Trace3d.fs index a0c2abd1f..173837200 100644 --- a/src/Plotly.NET/Trace3d.fs +++ b/src/Plotly.NET/Trace3d.fs @@ -319,8 +319,8 @@ module Trace3d = ?WHoverFormat : string, ?Meta : seq<#IConvertible>, ?CustomData : seq<#IConvertible>, - ?Scene : Scene, - ?ColorAxis : StyleParam.AxisAnchorId, + ?Scene : StyleParam.SubPlotId, + ?ColorAxis : StyleParam.SubPlotId, ?ColorBar : ColorBar, ?AutoColorScale : bool, ?ColorScale : StyleParam.Colorscale, @@ -366,8 +366,8 @@ module Trace3d = WHoverFormat |> DynObj.setValueOpt cone "whoverformat" Meta |> DynObj.setValueOpt cone "meta" CustomData |> DynObj.setValueOpt cone "customdata" - Scene |> DynObj.setValueOpt cone "scene" - ColorAxis |> DynObj.setValueOptBy cone "scene" StyleParam.AxisAnchorId.convert + Scene |> DynObj.setValueOptBy cone "scene" StyleParam.SubPlotId.convert + ColorAxis |> DynObj.setValueOptBy cone "scene" StyleParam.SubPlotId.convert ColorBar |> DynObj.setValueOpt cone "colorbar" AutoColorScale |> DynObj.setValueOpt cone "autocolorscale" ColorScale |> DynObj.setValueOptBy cone "colorscale" StyleParam.Colorscale.convert diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/ChartLayout.fs b/tests/Plotly.NET.Tests/HtmlCodegen/ChartLayout.fs index 960f35f28..d6203939a 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/ChartLayout.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/ChartLayout.fs @@ -46,7 +46,7 @@ let multipleAxesChart = Chart.Line (x,y',Name="anchor 2") |> Chart.withAxisAnchor(Y=2) - let twoXAxes1 = + let twoYAxes1 = [ anchoredAt1 anchoredAt2 @@ -55,15 +55,15 @@ let multipleAxesChart = |> Chart.withYAxisStyle( "axis 1", Side=StyleParam.Side.Left, - Id=1 + Id= StyleParam.SubPlotId.YAxis 1 ) |> Chart.withYAxisStyle( "axis2", Side=StyleParam.Side.Right, - Id=2, - Overlaying=StyleParam.AxisAnchorId.Y 1 + Id=StyleParam.SubPlotId.YAxis 2, + Overlaying=StyleParam.LinearAxisId.Y 1 ) - twoXAxes1 + twoYAxes1 [] let ``Multiple Axes styling`` = diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs b/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs index 657af80ae..c187cf5ba 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs @@ -12,8 +12,8 @@ let scatterChart = let z = [19; 26; 55;] Chart.Scatter3d(x,y,z,StyleParam.Mode.Markers) - |> Chart.withXAxisStyle("my x-axis") - |> Chart.withYAxisStyle("my y-axis") + |> Chart.withXAxisStyle("my x-axis", Id=StyleParam.SubPlotId.Scene 1) + |> Chart.withYAxisStyle("my y-axis", Id=StyleParam.SubPlotId.Scene 1) |> Chart.withZAxisStyle("my z-axis") |> Chart.withSize(800.,800.) @@ -43,8 +43,8 @@ let lineChart = |> List.unzip3 Chart.Scatter3d(x, y, z, StyleParam.Mode.Lines_Markers) - |> Chart.withXAxisStyle("x-axis") - |> Chart.withYAxisStyle("y-axis") + |> Chart.withXAxisStyle("x-axis", Id=StyleParam.SubPlotId.Scene 1) + |> Chart.withYAxisStyle("y-axis", Id=StyleParam.SubPlotId.Scene 1) |> Chart.withZAxisStyle("z-axis") |> Chart.withSize(800., 800.) diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/GeoMapCharts.fs b/tests/Plotly.NET.Tests/HtmlCodegen/GeoMapCharts.fs index 0a1d09917..32d9f7be7 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/GeoMapCharts.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/GeoMapCharts.fs @@ -26,7 +26,7 @@ let moreFeaturesBasemapChart = RiverColor="Blue" ) Chart.PointGeo([]) - |> Chart.withMap myGeo + |> Chart.withGeo myGeo |> Chart.withMarginSize(0, 0, 0, 0) let cultureMapChart = @@ -38,7 +38,7 @@ let cultureMapChart = CountryColor="RebeccaPurple" ) Chart.PointGeo([]) - |> Chart.withMap countryGeo + |> Chart.withGeo countryGeo |> Chart.withMarginSize(0, 0, 0, 0) [] @@ -91,7 +91,7 @@ let pointGeoChart = Labels=cityNames, TextPosition=StyleParam.TextPosition.TopCenter ) - |> Chart.withMapStyle( + |> Chart.withGeoStyle( Scope=StyleParam.GeoScope.NorthAmerica, Projection=GeoProjection.init(StyleParam.GeoProjectionType.AzimuthalEqualArea), CountryColor = "lightgrey" @@ -136,7 +136,7 @@ let flightsMapChart = ) |> Chart.combine |> Chart.withLegend(false) - |> Chart.withMapStyle( + |> Chart.withGeoStyle( Scope=StyleParam.GeoScope.NorthAmerica, Projection=GeoProjection.init(StyleParam.GeoProjectionType.AzimuthalEqualArea), ShowLand=true, @@ -230,7 +230,7 @@ let choroplethMap2Chart = locations,z, Locationmode=StyleParam.LocationFormat.CountryNames ) - |> Chart.withMapStyle( + |> Chart.withGeoStyle( Projection=GeoProjection.init(projectionType=StyleParam.GeoProjectionType.Mollweide), ShowLakes=true, ShowOcean=true, From d39816da1d33d148492ce9333299c32edce69922 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Sun, 15 Aug 2021 16:43:15 +0200 Subject: [PATCH 09/21] Fix docs after subplotid changes --- docs/1_0_axis-styling.fsx | 12 ++++++------ docs/3_0_3d-scatter-plots.fsx | 4 ++-- docs/3_1_3d-line-plots.fsx | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/1_0_axis-styling.fsx b/docs/1_0_axis-styling.fsx index e78e6ef97..7e317c37f 100644 --- a/docs/1_0_axis-styling.fsx +++ b/docs/1_0_axis-styling.fsx @@ -127,13 +127,13 @@ let twoXAxes1 = |> Chart.withYAxisStyle( "axis 1", Side=StyleParam.Side.Left, - Id=1 + Id=StyleParam.SubPlotId.YAxis 1 ) |> Chart.withYAxisStyle( "axis2", Side=StyleParam.Side.Right, - Id=2, - Overlaying=StyleParam.AxisAnchorId.Y 1 + Id=StyleParam.SubPlotId.YAxis 2, + Overlaying=StyleParam.LinearAxisId.Y 1 ) (*** condition: ipynb ***) @@ -169,10 +169,10 @@ let twoXAxes2 = |> Chart.withYAxisStyle( "second y-axis", Side=StyleParam.Side.Left, - Id=2, - Overlaying=StyleParam.AxisAnchorId.Y 1, + Id=StyleParam.SubPlotId.YAxis 2, + Overlaying=StyleParam.LinearAxisId.Y 1, Position=0.10, // position the axis beteen the leftmost edge and the firt axis at 0.3 - Anchor=StyleParam.AxisAnchorId.Free, + //Anchor=StyleParam.AxisAnchorId.Free, ShowLine=true ) diff --git a/docs/3_0_3d-scatter-plots.fsx b/docs/3_0_3d-scatter-plots.fsx index fc08aa7a8..aaa083063 100644 --- a/docs/3_0_3d-scatter-plots.fsx +++ b/docs/3_0_3d-scatter-plots.fsx @@ -41,8 +41,8 @@ let z = [19; 26; 55;] let scatter3d = Chart.Scatter3d(x,y,z,StyleParam.Mode.Markers) - |> Chart.withXAxisStyle("my x-axis") - |> Chart.withYAxisStyle("my y-axis") + |> Chart.withXAxisStyle("my x-axis", Id=StyleParam.SubPlotId.Scene 1) // in contrast to 2D plots, x and y axes of 3D charts have to be set via the scene object + |> Chart.withYAxisStyle("my y-axis", Id=StyleParam.SubPlotId.Scene 1) // in contrast to 2D plots, x and y axes of 3D charts have to be set via the scene object |> Chart.withZAxisStyle("my z-axis") |> Chart.withSize(800.,800.) diff --git a/docs/3_1_3d-line-plots.fsx b/docs/3_1_3d-line-plots.fsx index 9cb113042..708a61eca 100644 --- a/docs/3_1_3d-line-plots.fsx +++ b/docs/3_1_3d-line-plots.fsx @@ -53,8 +53,8 @@ When using `Lines_Markers` as the mode of the chart, you additionally render a l let scatter3dLine = Chart.Scatter3d(x,y,z,StyleParam.Mode.Lines_Markers) - |> Chart.withXAxisStyle("x-axis") - |> Chart.withYAxisStyle("y-axis") + |> Chart.withXAxisStyle("x-axis", Id=StyleParam.SubPlotId.Scene 1) // in contrast to 2D plots, x and y axes of 3D charts have to be set via the scene object + |> Chart.withYAxisStyle("y-axis", Id=StyleParam.SubPlotId.Scene 1) // in contrast to 2D plots, x and y axes of 3D charts have to be set via the scene object |> Chart.withZAxisStyle("z-axis") |> Chart.withSize(800.,800.) From 0c9c7071216e65000e61a87fda19b48e5162ff22 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Sun, 15 Aug 2021 18:05:21 +0200 Subject: [PATCH 10/21] Add Chart.StreamTube and related options --- src/Plotly.NET/Chart.fs | 63 +++++++++++++ src/Plotly.NET/Playground.fsx | 43 +++++---- src/Plotly.NET/Plotly.NET.fsproj | 1 + src/Plotly.NET/StreamTubeStarts.fs | 49 ++++++++++ src/Plotly.NET/Trace3d.fs | 144 +++++++++++++++++++++++++++++ 5 files changed, 280 insertions(+), 20 deletions(-) create mode 100644 src/Plotly.NET/StreamTubeStarts.fs diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index a8cb358fb..fccce027f 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -1978,6 +1978,69 @@ type Chart = ?ColorBar = ColorBar ) + + static member StreamTube + ( + x, y, z, u, v, w, + [] ?Name, + [] ?ShowLegend, + [] ?Opacity, + [] ?ColorScale, + [] ?ShowScale, + [] ?ColorBar, + [] ?MaxDisplayed: int, + [] ?Starts: StreamTubeStarts + + ) = + + Trace3d.initStreamTube( + Trace3dStyle.StreamTube( + X = x, + Y = y, + Z = z, + U = u, + V = v, + W = w, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Opacity = Opacity, + ?ColorScale = ColorScale, + ?ShowScale = ShowScale, + ?ColorBar = ColorBar, + ?MaxDisplayed = MaxDisplayed, + ?Starts = Starts + ) + ) + |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=ShowLegend,?Opacity=Opacity) + |> GenericChart.ofTraceObject + + static member StreamTube + ( + streamTubeXYZ, streamTubeUVW, + [] ?Name, + [] ?ShowLegend, + [] ?Opacity, + [] ?ColorScale, + [] ?ShowScale, + [] ?ColorBar, + [] ?MaxDisplayed: int, + [] ?Starts: StreamTubeStarts + ) = + let x, y, z = Seq.unzip3 streamTubeXYZ + let u, v, w = Seq.unzip3 streamTubeUVW + + Chart.StreamTube( + x, y, z, u, v, w, + ?Name = Name , + ?ShowLegend = ShowLegend , + ?Opacity = Opacity , + ?ColorScale = ColorScale , + ?ShowScale = ShowScale , + ?ColorBar = ColorBar , + ?MaxDisplayed = MaxDisplayed , + ?Starts = Starts + ) + /// creates table out of header sequence and row sequences static member Table(headerValues, cellValues, [] ?AlignHeader, diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index a24798fe9..42a79f867 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -6,6 +6,7 @@ #load "StyleParams.fs" #load "Colors.fs" +#load "StreamTubeStarts.fs" #load "Lighting.fs" #load "Rangebreak.fs" #load "TickFormatStop.fs" @@ -71,27 +72,29 @@ open FSharpAux open System +let tubeData = + Http.RequestString @"https://raw.githubusercontent.com/plotly/datasets/master/streamtube-wind.csv" + |> Frame.ReadCsvString + +tubeData.Print() + +Chart.StreamTube( + x = (tubeData.["x"] |> Series.values), + y = (tubeData.["y"] |> Series.values), + z = (tubeData.["z"] |> Series.values), + u = (tubeData.["u"] |> Series.values), + v = (tubeData.["v"] |> Series.values), + w = (tubeData.["w"] |> Series.values), + Starts = + StreamTubeStarts.init( + X = Array.init 16 (fun _ -> 80), + Y = [20;30;40;50;20;30;40;50;20;30;40;50;20;30;40;50], + Z = [0;0;0;0;5;5;5;5;10;10;10;10;15;15;15;15] + ), + ColorScale = StyleParam.Colorscale.Viridis +) -let singleStackChart = - let x = [1.; 2.; 3.; 4.; 5.; 6.; 7.; 8.; 9.; 10.; ] - let y = [2.; 1.5; 5.; 1.5; 3.; 2.5; 2.5; 1.5; 3.5; 1.] - [ - Chart.Point(x,y) - |> Chart.withYAxisStyle("This title must") - - Chart.Line(x,y) - |> Chart.withYAxisStyle("be set on the",ZeroLine=false) - - Chart.Spline(x,y) - |> Chart.withYAxisStyle("respective subplots",ZeroLine=false) - ] - |> Chart.SingleStack(Pattern = StyleParam.LayoutGridPattern.Coupled) - //move xAxis to bottom and increase spacing between plots by using the withLayoutGridStyle function - |> Chart.withLayoutGridStyle(XSide=StyleParam.LayoutGridXSide.Bottom,YGap= 0.1) - |> Chart.withTitle("Hi i am the new SingleStackChart") - |> Chart.withXAxisStyle("im the shared xAxis") - -singleStackChart |> Chart.show +|> Chart.show Chart.Cone( x = [1; 1; 1], diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index f17b97fe9..c3c660e04 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -36,6 +36,7 @@ + diff --git a/src/Plotly.NET/StreamTubeStarts.fs b/src/Plotly.NET/StreamTubeStarts.fs new file mode 100644 index 000000000..56f31a47d --- /dev/null +++ b/src/Plotly.NET/StreamTubeStarts.fs @@ -0,0 +1,49 @@ +namespace Plotly.NET + +open DynamicObj +open System + +/// An object to set the Lighting of a 3D Scene +type StreamTubeStarts() = + inherit DynamicObj () + + /// + /// Initializes a TubeStarts object + /// + /// Sets the x components of the starting position of the streamtubes + /// Sets the y components of the starting position of the streamtubes + /// Sets the z components of the starting position of the streamtubes + static member init + ( + ?X: seq<#IConvertible>, + ?Y: seq<#IConvertible>, + ?Z: seq<#IConvertible> + ) = + + StreamTubeStarts() + |> StreamTubeStarts.style + ( + ?X = X, + ?Y = Y, + ?Z = Z + ) + + /// + /// Creates a function that applies the given style parameters to a TubeStarts object + /// + /// Sets the x components of the starting position of the streamtubes + /// Sets the y components of the starting position of the streamtubes + /// Sets the z components of the starting position of the streamtubes + static member style + ( + ?X: seq<#IConvertible>, + ?Y: seq<#IConvertible>, + ?Z: seq<#IConvertible> + ) = + fun (streamTubeStarts: StreamTubeStarts) -> + + X |> DynObj.setValueOpt streamTubeStarts "x" + Y |> DynObj.setValueOpt streamTubeStarts "y" + Z |> DynObj.setValueOpt streamTubeStarts "z" + + streamTubeStarts \ No newline at end of file diff --git a/src/Plotly.NET/Trace3d.fs b/src/Plotly.NET/Trace3d.fs index 173837200..d32133a5d 100644 --- a/src/Plotly.NET/Trace3d.fs +++ b/src/Plotly.NET/Trace3d.fs @@ -386,4 +386,148 @@ module Trace3d = UIRevision |> DynObj.setValueOpt cone "uirevision" cone + ) + + /// + /// Applies the style parameters of the streamtube chart to the given trace + /// + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not this trace is visible. If "legendonly", the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible). + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Sets the legend rank for this trace. Items and groups with smaller ranks are presented on top/left side while with `"reversed" `legend.traceorder` they are on bottom/right side. The default legendrank is 1000, so that you can use ranks less than 1000 to place certain items before all unranked items, and ranks greater than 1000 to go after all unranked items. + /// Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items. + /// Sets the legend group title for this trace. + /// Sets the opacity of the surface. Please note that in the case of using high `opacity` values for example a value greater than or equal to 0.5 on two surfaces (and 0.25 with four surfaces), an overlay of multiple transparent surfaces may not perfectly be sorted in depth by the webgl API. This behavior may be improved in the near future and is subject to change. + /// Assigns id labels to each datum. These ids for object constancy of data points during animation. Should be an array of strings, not numbers or any other type. + /// Sets the x coordinates of the vector field. + /// Sets the y coordinates of the vector field. + /// Sets the z coordinates of the vector field. + /// Sets the x components of the vector field. + /// Sets the y components of the vector field. + /// Sets the z components of the vector field. + /// Sets a text element associated with this trace. If trace `hoverinfo` contains a "text" flag, this text element will be seen in all hover labels. Note that streamtube traces do not support array `text` values. + /// Same as `text`. + /// Determines which trace information appear on hover. If `none` or `skip` are set, no information is displayed upon hovering. But, if `none` is set, click and hover events are still fired. + /// Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example "y: %{y}" as well as %{xother}, {%_xother}, {%_xother_}, {%xother_}. When showing info for several points, "xother" will be added to those with different x positions from the first point. An underscore before or after "(x|y)other" will add a space on that side, only when this field is shown. Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. variable `norm` Anything contained in tag `<extra>` is displayed in the secondary box, for example "<extra>{fullData.name}</extra>". To hide the secondary box completely, use an empty tag `<extra></extra>`. + /// Sets the hover text formatting rulefor `x` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `xaxis.hoverformat`. + /// Sets the hover text formatting rulefor `y` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `yaxis.hoverformat`. + /// Sets the hover text formatting rulefor `z` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `zaxis.hoverformat` + /// Sets the hover text formatting rulefor `u` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format.By default the values are formatted using generic number format. + /// Sets the hover text formatting rulefor `v` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format.By default the values are formatted using generic number format. + /// Sets the hover text formatting rulefor `w` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format.By default the values are formatted using generic number format. + /// Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index. + /// Assigns extra data each datum. This may be useful when listening to hover, click and selection events. Note that, "scatter" traces also appends customdata items in the markers DOM elements + /// Sets a reference between this trace's 3D coordinate system and a 3D scene. If "scene" (the default value), the (x,y,z) coordinates refer to `layout.scene`. If "scene2", the (x,y,z) coordinates refer to `layout.scene2`, and so on. + /// Sets a reference to a shared color axis. References to these shared color axes are "coloraxis", "coloraxis2", "coloraxis3", etc. Settings for these shared color axes are set in the layout, under `layout.coloraxis`, `layout.coloraxis2`, etc. Note that multiple color scales can be linked to the same color axis. + /// Sets the ColorBar object associated with the color scale of the streamtubes + /// Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `colorscale`. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed. + /// Sets the colorscale. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]`. To control the bounds of the colorscale in color space, use`cmin` and `cmax`. Alternatively, `colorscale` may be a palette name string of the following list: Blackbody,Bluered,Blues,Cividis,Earth,Electric,Greens,Greys,Hot,Jet,Picnic,Portland,Rainbow,RdBu,Reds,Viridis,YlGnBu,YlOrRd. + /// Determines whether or not a colorbar is displayed for this trace. + /// Reverses the color mapping if true. If true, `cmin` will correspond to the last color in the array and `cmax` will correspond to the first color. + /// Determines whether or not the color domain is computed with respect to the input data (here u/v/w norm) or the bounds set in `cmin` and `cmax` Defaults to `false` when `cmin` and `cmax` are set by the user. + /// Sets the upper bound of the color domain. Value should have the same units as u/v/w norm and if set, `cmin` must be set as well. + /// Sets the mid-point of the color domain by scaling `cmin` and/or `cmax` to be equidistant to this point. Value should have the same units as u/v/w norm. Has no effect when `cauto` is `false`. + /// Sets the lower bound of the color domain. Value should have the same units as u/v/w norm and if set, `cmax` must be set as well. + /// Sets the hover labels of this streamtube trace. + /// Sets the Lighting of this streamtube trace. + /// Sets the LightPosition of this streamtube trace. + /// The maximum number of displayed segments in a streamtube. + /// The scaling factor for the streamtubes. The default is 1, which avoids two max divergence tubes from touching at adjacent starting positions. + /// Sets the streamtube starting positions + /// Controls persistence of some user-driven changes to the trace: `constraintrange` in `parcoords` traces, as well as some `editable: true` modifications such as `name` and `colorbar.title`. Defaults to `layout.uirevision`. Note that other user-driven trace attribute changes are controlled by `layout` attributes: `trace.visible` is controlled by `layout.legend.uirevision`, `selectedpoints` is controlled by `layout.selectionrevision`, and `colorbar.(x|y)` (accessible with `config: {editable: true}`) is controlled by `layout.editrevision`. Trace changes are tracked by `uid`, which only falls back on trace index if no `uid` is provided. So if your app can add/remove traces before the end of the `data` array, such that the same trace has a different index, you can still preserve user-driven changes if you give each trace a `uid` that stays with it as it moves. + static member StreamTube + ( + ?Name : string, + ?Visible : StyleParam.Visible, + ?ShowLegend : bool, + ?LegendRank : int, + ?LegendGroup : string, + ?LegendGroupTitle : Title, + ?Opacity : float, + ?Ids : seq<#IConvertible>, + ?X : seq<#IConvertible>, + ?Y : seq<#IConvertible>, + ?Z : seq<#IConvertible>, + ?U : seq<#IConvertible>, + ?V : seq<#IConvertible>, + ?W : seq<#IConvertible>, + ?Text : seq<#IConvertible>, + ?HoverText : seq<#IConvertible>, + ?HoverInfo : string, + ?HoverTemplate : string, + ?XHoverFormat : string, + ?YHoverFormat : string, + ?ZHoverFormat : string, + ?UHoverFormat : string, + ?VHoverFormat : string, + ?WHoverFormat : string, + ?Meta : seq<#IConvertible>, + ?CustomData : seq<#IConvertible>, + ?Scene : StyleParam.SubPlotId, + ?ColorAxis : StyleParam.SubPlotId, + ?ColorBar : ColorBar, + ?AutoColorScale : bool, + ?ColorScale : StyleParam.Colorscale, + ?ShowScale : bool, + ?ReverseScale : bool, + ?CAuto : bool, + ?CMin : float, + ?CMid : float, + ?CMax : float, + ?HoverLabel : Hoverlabel, + ?Lighting : Lighting, + ?LightPosition : LightPosition, + ?MaxDisplayed : int, + ?SizeRef : float, + ?Starts : StreamTubeStarts, + ?UIRevision : seq<#IConvertible> + + ) = + (fun (streamTube: Trace3d) -> + Name |> DynObj.setValueOpt streamTube "name" + Visible |> DynObj.setValueOptBy streamTube "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt streamTube "showlegend" + LegendRank |> DynObj.setValueOpt streamTube "legendrank" + LegendGroup |> DynObj.setValueOpt streamTube "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt streamTube "legendgrouptitle" + Opacity |> DynObj.setValueOpt streamTube "opacity" + Ids |> DynObj.setValueOpt streamTube "ids" + X |> DynObj.setValueOpt streamTube "x" + Y |> DynObj.setValueOpt streamTube "y" + Z |> DynObj.setValueOpt streamTube "z" + U |> DynObj.setValueOpt streamTube "u" + V |> DynObj.setValueOpt streamTube "v" + W |> DynObj.setValueOpt streamTube "w" + Text |> DynObj.setValueOpt streamTube "text" + HoverText |> DynObj.setValueOpt streamTube "hovertext" + HoverInfo |> DynObj.setValueOpt streamTube "hoverinfo" + HoverTemplate |> DynObj.setValueOpt streamTube "hovertemplate" + XHoverFormat |> DynObj.setValueOpt streamTube "xhoverformat" + YHoverFormat |> DynObj.setValueOpt streamTube "yhoverformat" + ZHoverFormat |> DynObj.setValueOpt streamTube "zhoverformat" + UHoverFormat |> DynObj.setValueOpt streamTube "uhoverformat" + VHoverFormat |> DynObj.setValueOpt streamTube "vhoverformat" + WHoverFormat |> DynObj.setValueOpt streamTube "whoverformat" + Meta |> DynObj.setValueOpt streamTube "meta" + CustomData |> DynObj.setValueOpt streamTube "customdata" + Scene |> DynObj.setValueOptBy streamTube "scene" StyleParam.SubPlotId.convert + ColorAxis |> DynObj.setValueOptBy streamTube "scene" StyleParam.SubPlotId.convert + ColorBar |> DynObj.setValueOpt streamTube "colorbar" + AutoColorScale |> DynObj.setValueOpt streamTube "autocolorscale" + ColorScale |> DynObj.setValueOptBy streamTube "colorscale" StyleParam.Colorscale.convert + ShowScale |> DynObj.setValueOpt streamTube "showscale" + ReverseScale |> DynObj.setValueOpt streamTube "reversescale" + CAuto |> DynObj.setValueOpt streamTube "cauto" + CMin |> DynObj.setValueOpt streamTube "cmin" + CMid |> DynObj.setValueOpt streamTube "cmid" + CMax |> DynObj.setValueOpt streamTube "cmax" + HoverLabel |> DynObj.setValueOpt streamTube "hoverlabel" + Lighting |> DynObj.setValueOpt streamTube "lighting" + LightPosition |> DynObj.setValueOpt streamTube "lightposition" + MaxDisplayed |> DynObj.setValueOpt streamTube "maxdisplayed" + SizeRef |> DynObj.setValueOpt streamTube "sizeref" + Starts |> DynObj.setValueOpt streamTube "starts" + UIRevision |> DynObj.setValueOpt streamTube "uirevision" + + streamTube ) \ No newline at end of file From b2ddcb3e97213ded64081380e233219003d3b15b Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Mon, 16 Aug 2021 11:17:16 +0200 Subject: [PATCH 11/21] Add Chart.Volume and associated objects/styling --- src/Plotly.NET/Caps.fs | 63 ++++++++++++ src/Plotly.NET/Chart.fs | 38 ++++++++ src/Plotly.NET/Playground.fsx | 44 ++++++++- src/Plotly.NET/Plotly.NET.fsproj | 4 + src/Plotly.NET/Slices.fs | 67 +++++++++++++ src/Plotly.NET/SpaceFrame.fs | 30 ++++++ src/Plotly.NET/StyleParams.fs | 44 +++++++++ src/Plotly.NET/Surface.fs | 40 ++++++++ src/Plotly.NET/Trace3d.fs | 159 ++++++++++++++++++++++++++++++- 9 files changed, 483 insertions(+), 6 deletions(-) create mode 100644 src/Plotly.NET/Caps.fs create mode 100644 src/Plotly.NET/Slices.fs create mode 100644 src/Plotly.NET/SpaceFrame.fs create mode 100644 src/Plotly.NET/Surface.fs diff --git a/src/Plotly.NET/Caps.fs b/src/Plotly.NET/Caps.fs new file mode 100644 index 000000000..dd4ee5d5f --- /dev/null +++ b/src/Plotly.NET/Caps.fs @@ -0,0 +1,63 @@ +namespace Plotly.NET + +open DynamicObj +open System + +type CapFill () = + inherit DynamicObj () + + static member init + ( + ?Fill: float, + ?Show: bool + ) = + CapFill() + |> CapFill.style + ( + ?Fill = Fill, + ?Show = Show + ) + + static member style + ( + ?Fill: float, + ?Show: bool + ) = + + fun (capFill: CapFill) -> + + Fill |> DynObj.setValueOpt capFill "fill" + Show |> DynObj.setValueOpt capFill "show" + + +type Caps() = + inherit DynamicObj () + + static member init + ( + ?X: CapFill, + ?Y: CapFill, + ?Z: CapFill + ) = + + Caps() + |> Caps.style + ( + ?X = X, + ?Y = Y, + ?Z = Z + ) + + static member style + ( + ?X: CapFill, + ?Y: CapFill, + ?Z: CapFill + ) = + fun (caps: Caps) -> + + X |> DynObj.setValueOpt caps "x" + Y |> DynObj.setValueOpt caps "y" + Z |> DynObj.setValueOpt caps "z" + + caps \ No newline at end of file diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index fccce027f..621784994 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -2040,6 +2040,44 @@ type Chart = ?MaxDisplayed = MaxDisplayed , ?Starts = Starts ) + + static member Volume + ( + x,y,z,value, + [] ?Name, + [] ?ShowLegend, + [] ?Opacity, + [] ?ColorScale, + [] ?ShowScale, + [] ?ColorBar, + [] ?IsoMin, + [] ?IsoMax, + [] ?Caps : Caps, + [] ?Slices : Slices, + [] ?Surface : Surface + ) = + Trace3d.initVolume( + Trace3dStyle.Volume( + X = x, + Y = y, + Z = z, + Value = value, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Opacity = Opacity, + ?ColorScale = ColorScale, + ?ShowScale = ShowScale, + ?ColorBar = ColorBar, + ?IsoMin = IsoMin, + ?IsoMax = IsoMax, + ?Caps = Caps, + ?Slices = Slices, + ?Surface = Surface + ) + ) + |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=ShowLegend,?Opacity=Opacity) + |> GenericChart.ofTraceObject + /// creates table out of header sequence and row sequences static member Table(headerValues, cellValues, diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index 42a79f867..5063730b3 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -6,6 +6,10 @@ #load "StyleParams.fs" #load "Colors.fs" +#load "Surface.fs" +#load "SpaceFrame.fs" +#load "Slices.fs" +#load "Caps.fs" #load "StreamTubeStarts.fs" #load "Lighting.fs" #load "Rangebreak.fs" @@ -72,6 +76,45 @@ open FSharpAux open System +let linspace (min,max,n) = + if n <= 2 then failwithf "n needs to be larger then 2" + let bw = float (max - min) / (float n - 1.) + Array.init n (fun i -> min + (bw * float i)) + +let mgrid (min,max,n) = + + let data = linspace(min,max,n) + + let z = [|for i in 1 .. n do [|for i in 1 .. n do yield data|]|] + let x = [|for i in 1 .. n do [|for j in 1 .. n do yield [|for k in 1 .. n do yield data.[i-1]|]|]|] + let y = [|for i in 1 .. n do [|for j in 1 .. n do yield [|for k in 1 .. n do yield data.[j-1]|]|]|] + + x,y,z + +let x,y,z = + mgrid(-8.,8.,40) + |> fun (x,y,z) -> + (x |> Array.concat |> Array.concat), + (y |> Array.concat |> Array.concat), + (z |> Array.concat |> Array.concat) + +let values = + Array.map3 (fun x y z -> + sin(x*y*z) / (x*y*z) + ) x y z + + +Chart.Volume( + x, y, z, values, + Opacity=0.1, + Surface=(Surface.init(Count=17)), + IsoMin=0.1, + IsoMax=0.8, + ColorScale = StyleParam.Colorscale.Viridis + +) +|> Chart.show + let tubeData = Http.RequestString @"https://raw.githubusercontent.com/plotly/datasets/master/streamtube-wind.csv" |> Frame.ReadCsvString @@ -93,7 +136,6 @@ Chart.StreamTube( ), ColorScale = StyleParam.Colorscale.Viridis ) - |> Chart.show Chart.Cone( diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index c3c660e04..9fd688bed 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -36,6 +36,10 @@ + + + + diff --git a/src/Plotly.NET/Slices.fs b/src/Plotly.NET/Slices.fs new file mode 100644 index 000000000..90ea2a7b4 --- /dev/null +++ b/src/Plotly.NET/Slices.fs @@ -0,0 +1,67 @@ +namespace Plotly.NET + +open DynamicObj +open System + +type SlicesFill () = + inherit DynamicObj () + + static member init + ( + ?Fill: float, + ?Locations: seq<#IConvertible>, + ?Show: bool + ) = + SlicesFill() + |> SlicesFill.style + ( + ?Fill = Fill, + ?Locations = Locations, + ?Show = Show + ) + + static member style + ( + ?Fill: float, + ?Locations: seq<#IConvertible>, + ?Show: bool + ) = + + fun (slicesFill: SlicesFill) -> + + Fill |> DynObj.setValueOpt slicesFill "fill" + Locations |> DynObj.setValueOpt slicesFill "locations" + Show |> DynObj.setValueOpt slicesFill "show" + + +type Slices() = + inherit DynamicObj () + + static member init + ( + ?X: SlicesFill, + ?Y: SlicesFill, + ?Z: SlicesFill + ) = + + Slices() + |> Slices.style + ( + ?X = X, + ?Y = Y, + ?Z = Z + ) + + static member style + ( + ?X: SlicesFill, + ?Y: SlicesFill, + ?Z: SlicesFill + ) = + fun (slices: Slices) -> + + X |> DynObj.setValueOpt slices "x" + Y |> DynObj.setValueOpt slices "y" + Z |> DynObj.setValueOpt slices "z" + + slices \ No newline at end of file diff --git a/src/Plotly.NET/SpaceFrame.fs b/src/Plotly.NET/SpaceFrame.fs new file mode 100644 index 000000000..9d9211ff5 --- /dev/null +++ b/src/Plotly.NET/SpaceFrame.fs @@ -0,0 +1,30 @@ +namespace Plotly.NET + +open DynamicObj +open System + +type Spaceframe () = + inherit DynamicObj () + + static member init + ( + ?Fill: float, + ?Show: bool + ) = + Spaceframe() + |> Spaceframe.style + ( + ?Fill = Fill, + ?Show = Show + ) + + static member style + ( + ?Fill: float, + ?Show: bool + ) = + + fun (spaceframe: Spaceframe) -> + + Fill |> DynObj.setValueOpt spaceframe "fill" + Show |> DynObj.setValueOpt spaceframe "show" \ No newline at end of file diff --git a/src/Plotly.NET/StyleParams.fs b/src/Plotly.NET/StyleParams.fs index 153a662cc..f0811f35a 100644 --- a/src/Plotly.NET/StyleParams.fs +++ b/src/Plotly.NET/StyleParams.fs @@ -1380,6 +1380,50 @@ module StyleParam = static member convert = TimeStepMode.toString >> box + /// Sets the surface pattern of the iso-surface 3-D sections. The default pattern of the surface is `all` meaning that the rest of surface elements would be shaded. The check options (either 1 or 2) could be used to draw half of the squares on the surface. Using various combinations of capital `A`, `B`, `C`, `D` and `E` may also be used to reduce the number of triangles on the iso-surfaces and creating other patterns of interest. + [] + type SurfacePattern = + | A | B | C | D | E + | AB | AC | AD | AE + | BC | BD | BE + | CD | CE + | ABC | ABD | ABE + | BCD | BDE + | ABCD | BCDE + | Odd + | Even + | All + + static member toString = function + | A -> "A" + | B -> "B" + | C -> "C" + | D -> "D" + | E -> "E" + | AB -> "A+B" + | AC -> "A+C" + | AD -> "A+D" + | AE -> "A+E" + | BC -> "B+C" + | BD -> "B+D" + | BE -> "B+E" + | CD -> "C+D" + | CE -> "C+E" + | ABC -> "A+B+C" + | ABD -> "A+B+D" + | ABE -> "A+B+E" + | BCD -> "B+C+D" + | BDE -> "B+D+E" + | ABCD -> "A+B+C+D" + | BCDE -> "B+C+D+E" + | Odd -> "odd" + | Even -> "even" + | All -> "all" + + static member convert = SurfacePattern.toString >> box + + + //-------------------------- // #T# //-------------------------- diff --git a/src/Plotly.NET/Surface.fs b/src/Plotly.NET/Surface.fs new file mode 100644 index 000000000..54939d219 --- /dev/null +++ b/src/Plotly.NET/Surface.fs @@ -0,0 +1,40 @@ +namespace Plotly.NET + +open DynamicObj +open System + +type Surface () = + inherit DynamicObj () + + static member init + ( + ?Count: int, + ?Fill: float, + ?Pattern: StyleParam.SurfacePattern, + ?Show: bool + ) = + Surface() + |> Surface.style + ( + ?Count = Count, + ?Fill = Fill, + ?Pattern = Pattern, + ?Show = Show + ) + + static member style + ( + ?Count: int, + ?Fill: float, + ?Pattern: StyleParam.SurfacePattern, + ?Show: bool + ) = + + fun (surface: Surface) -> + + Count |> DynObj.setValueOpt surface "count" + Fill |> DynObj.setValueOpt surface "fill" + Pattern |> DynObj.setValueOptBy surface "pattern" StyleParam.SurfacePattern.convert + Show |> DynObj.setValueOpt surface "show" + + surface \ No newline at end of file diff --git a/src/Plotly.NET/Trace3d.fs b/src/Plotly.NET/Trace3d.fs index d32133a5d..3e0ed6eb9 100644 --- a/src/Plotly.NET/Trace3d.fs +++ b/src/Plotly.NET/Trace3d.fs @@ -387,7 +387,7 @@ module Trace3d = cone ) - + /// /// Applies the style parameters of the streamtube chart to the given trace /// @@ -428,9 +428,9 @@ module Trace3d = /// Sets the upper bound of the color domain. Value should have the same units as u/v/w norm and if set, `cmin` must be set as well. /// Sets the mid-point of the color domain by scaling `cmin` and/or `cmax` to be equidistant to this point. Value should have the same units as u/v/w norm. Has no effect when `cauto` is `false`. /// Sets the lower bound of the color domain. Value should have the same units as u/v/w norm and if set, `cmax` must be set as well. - /// Sets the hover labels of this streamtube trace. - /// Sets the Lighting of this streamtube trace. - /// Sets the LightPosition of this streamtube trace. + /// Sets the hover labels of this trace. + /// Sets the Lighting of this trace. + /// Sets the LightPosition of this trace. /// The maximum number of displayed segments in a streamtube. /// The scaling factor for the streamtubes. The default is 1, which avoids two max divergence tubes from touching at adjacent starting positions. /// Sets the streamtube starting positions @@ -530,4 +530,153 @@ module Trace3d = UIRevision |> DynObj.setValueOpt streamTube "uirevision" streamTube - ) \ No newline at end of file + ) + + /// + /// Applies the style parameters of the volume chart to the given trace + /// + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not this trace is visible. If "legendonly", the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible). + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Sets the legend rank for this trace. Items and groups with smaller ranks are presented on top/left side while with `"reversed" `legend.traceorder` they are on bottom/right side. The default legendrank is 1000, so that you can use ranks less than 1000 to place certain items before all unranked items, and ranks greater than 1000 to go after all unranked items. + /// Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items. + /// Sets the title of the legendgroup + /// Sets the opacity of the surface. Please note that in the case of using high `opacity` values for example a value greater than or equal to 0.5 on two surfaces (and 0.25 with four surfaces), an overlay of multiple transparent surfaces may not perfectly be sorted in depth by the webgl API. This behavior may be improved in the near future and is subject to change. + /// Assigns id labels to each datum. These ids for object constancy of data points during animation. Should be an array of strings, not numbers or any other type. + /// Sets the X coordinates of the vertices on X axis. + /// Sets the Y coordinates of the vertices on Y axis. + /// Sets the Z coordinates of the vertices on Z axis. + /// Sets the 4th dimension (value) of the vertices. + /// Sets the text elements associated with the vertices. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Same as `text`. + /// Determines which trace information appear on hover. If `none` or `skip` are set, no information is displayed upon hovering. But, if `none` is set, click and hover events are still fired. + /// Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example "y: %{y}" as well as %{xother}, {%_xother}, {%_xother_}, {%xother_}. When showing info for several points, "xother" will be added to those with different x positions from the first point. An underscore before or after "(x|y)other" will add a space on that side, only when this field is shown. Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. variable `norm` Anything contained in tag `<extra>` is displayed in the secondary box, for example "<extra>{fullData.name}</extra>". To hide the secondary box completely, use an empty tag `<extra></extra>`. + /// Sets the hover text formatting rulefor `x` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `xaxis.hoverformat`. + /// Sets the hover text formatting rulefor `y` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `yaxis.hoverformat`. + /// Sets the hover text formatting rulefor `z` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `zaxis.hoverformat` + /// Sets the hover text formatting rulefor `value` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format.By default the values are formatted using generic number format. + /// Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index. + /// Assigns extra data each datum. This may be useful when listening to hover, click and selection events. Note that, "scatter" traces also appends customdata items in the markers DOM elements + /// Sets a reference between this trace's 3D coordinate system and a 3D scene. If "scene" (the default value), the (x,y,z) coordinates refer to `layout.scene`. If "scene2", the (x,y,z) coordinates refer to `layout.scene2`, and so on. + /// Sets a reference to a shared color axis. References to these shared color axes are "coloraxis", "coloraxis2", "coloraxis3", etc. Settings for these shared color axes are set in the layout, under `layout.coloraxis`, `layout.coloraxis2`, etc. Note that multiple color scales can be linked to the same color axis. + /// Sets the colorbar of this trace + /// Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `colorscale`. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed. + /// Sets the colorscale. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]`. To control the bounds of the colorscale in color space, use`cmin` and `cmax`. Alternatively, `colorscale` may be a palette name string of the following list: Blackbody,Bluered,Blues,Cividis,Earth,Electric,Greens,Greys,Hot,Jet,Picnic,Portland,Rainbow,RdBu,Reds,Viridis,YlGnBu,YlOrRd. + /// Determines whether or not a colorbar is displayed for this trace. + /// Reverses the color mapping if true. If true, `cmin` will correspond to the last color in the array and `cmax` will correspond to the first color. + /// Determines whether or not the color domain is computed with respect to the input data (here `value`) or the bounds set in `cmin` and `cmax` Defaults to `false` when `cmin` and `cmax` are set by the user. + /// Sets the lower bound of the color domain. Value should have the same units as `value` and if set, `cmax` must be set as well. + /// Sets the mid-point of the color domain by scaling `cmin` and/or `cmax` to be equidistant to this point. Value should have the same units as `value`. Has no effect when `cauto` is `false`. + /// Sets the upper bound of the color domain. Value should have the same units as `value` and if set, `cmin` must be set as well. + /// Sets the caps of this trace caps (color-coded surfaces on the sides of the visualization domain) + /// Sets the contour of this trace. + /// Determines whether or not normal smoothing is applied to the meshes, creating meshes with an angular, low-poly look via flat reflections. + /// Sets the hover labels of this trace. + /// Sets the maximum boundary for iso-surface plot. + /// Sets the minimum boundary for iso-surface plot. + /// Sets the Lighting of this trace. + /// Sets the LightPosition of this trace. + /// Sets the opacityscale. The opacityscale must be an array containing arrays mapping a normalized value to an opacity value. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 1], [0.5, 0.2], [1, 1]]` means that higher/lower values would have higher opacity values and those in the middle would be more transparent Alternatively, `opacityscale` may be a palette name string of the following list: 'min', 'max', 'extremes' and 'uniform'. The default is 'uniform'. + /// Sets slices through the volume + /// Sets the SpaceFrame of this trace. + /// Sets the Surface of this trace. + /// Controls persistence of some user-driven changes to the trace: `constraintrange` in `parcoords` traces, as well as some `editable: true` modifications such as `name` and `colorbar.title`. Defaults to `layout.uirevision`. Note that other user-driven trace attribute changes are controlled by `layout` attributes: `trace.visible` is controlled by `layout.legend.uirevision`, `selectedpoints` is controlled by `layout.selectionrevision`, and `colorbar.(x|y)` (accessible with `config: {editable: true}`) is controlled by `layout.editrevision`. Trace changes are tracked by `uid`, which only falls back on trace index if no `uid` is provided. So if your app can add/remove traces before the end of the `data` array, such that the same trace has a different index, you can still preserve user-driven changes if you give each trace a `uid` that stays with it as it moves. + static member Volume + ( + ?Name : string, + ?Visible : StyleParam.Visible, + ?ShowLegend : bool, + ?LegendRank : int, + ?LegendGroup : string, + ?LegendGroupTitle : Title, + ?Opacity : float, + ?Ids : seq<#IConvertible>, + ?X : seq<#IConvertible>, + ?Y : seq<#IConvertible>, + ?Z : seq<#IConvertible>, + ?Value : seq<#IConvertible>, + ?Text : seq<#IConvertible>, + ?HoverText : seq<#IConvertible>, + ?HoverInfo : string, + ?HoverTemplate : string, + ?XHoverFormat : string, + ?YHoverFormat : string, + ?ZHoverFormat : string, + ?ValueHoverFormat : string, + ?Meta : seq<#IConvertible>, + ?CustomData : seq<#IConvertible>, + ?Scene : StyleParam.SubPlotId, + ?ColorAxis : StyleParam.SubPlotId, + ?ColorBar : ColorBar, + ?AutoColorScale : bool, + ?ColorScale : StyleParam.Colorscale, + ?ShowScale : bool, + ?ReverseScale : bool, + ?CAuto : bool, + ?CMin : float, + ?CMid : float, + ?CMax : float, + ?Caps : Caps, + ?Contour : Contour, + ?FlatShading : bool, + ?HoverLabel : Hoverlabel, + ?IsoMax : float, + ?IsoMin : float, + ?Lighting : Lighting, + ?LightPosition : LightPosition, + ?OpacityScale : seq<#seq<#IConvertible>>, + ?Slices : Slices, + ?SpaceFrame : Spaceframe, + ?Surface : Surface, + ?UIRevision : seq<#IConvertible> + ) = + fun (volume: Trace3d) -> + + Name |> DynObj.setValueOpt volume "name" + Visible |> DynObj.setValueOptBy volume "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt volume "showlegend" + LegendRank |> DynObj.setValueOpt volume "legendrank" + LegendGroup |> DynObj.setValueOpt volume "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt volume "legendgrouptitle" + Opacity |> DynObj.setValueOpt volume "opacity" + Ids |> DynObj.setValueOpt volume "ids" + X |> DynObj.setValueOpt volume "x" + Y |> DynObj.setValueOpt volume "y" + Z |> DynObj.setValueOpt volume "z" + Value |> DynObj.setValueOpt volume "value" + Text |> DynObj.setValueOpt volume "text" + HoverText |> DynObj.setValueOpt volume "hovertext" + HoverInfo |> DynObj.setValueOpt volume "hoverinfo" + HoverTemplate |> DynObj.setValueOpt volume "hovertemplate" + XHoverFormat |> DynObj.setValueOpt volume "xhoverformat" + YHoverFormat |> DynObj.setValueOpt volume "yhoverformat" + ZHoverFormat |> DynObj.setValueOpt volume "zhoverformat" + ValueHoverFormat |> DynObj.setValueOpt volume "valuehoverformat" + Meta |> DynObj.setValueOpt volume "meta" + CustomData |> DynObj.setValueOpt volume "customdata" + Scene |> DynObj.setValueOptBy volume "scene" StyleParam.SubPlotId.convert + ColorAxis |> DynObj.setValueOptBy volume "scene" StyleParam.SubPlotId.convert + ColorBar |> DynObj.setValueOpt volume "colorbar" + AutoColorScale |> DynObj.setValueOpt volume "autocolorscale" + ColorScale |> DynObj.setValueOptBy volume "colorscale" StyleParam.Colorscale.convert + ShowScale |> DynObj.setValueOpt volume "showscale" + ReverseScale |> DynObj.setValueOpt volume "reversescale" + CAuto |> DynObj.setValueOpt volume "cauto" + CMin |> DynObj.setValueOpt volume "cmin" + CMid |> DynObj.setValueOpt volume "cmid" + CMax |> DynObj.setValueOpt volume "cmax" + Caps |> DynObj.setValueOpt volume "caps" + Contour |> DynObj.setValueOpt volume "contour" + FlatShading |> DynObj.setValueOpt volume "flatshading" + HoverLabel |> DynObj.setValueOpt volume "hoverlabel" + IsoMax |> DynObj.setValueOpt volume "isomax" + IsoMin |> DynObj.setValueOpt volume "isomin" + Lighting |> DynObj.setValueOpt volume "lighting" + LightPosition |> DynObj.setValueOpt volume "lightposition" + OpacityScale |> DynObj.setValueOpt volume "opacityscale" + Slices |> DynObj.setValueOpt volume "slices" + SpaceFrame |> DynObj.setValueOpt volume "spaceframe" + Surface |> DynObj.setValueOpt volume "surface" + UIRevision |> DynObj.setValueOpt volume "uirevision" + + volume From ff6a4f8b4d629dd4f78225b44a82b2ae68e44862 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Wed, 18 Aug 2021 11:17:00 +0200 Subject: [PATCH 12/21] Add Chart.IsoSurface --- src/Plotly.NET/Caps.fs | 2 + src/Plotly.NET/Chart.fs | 39 +++++++++ src/Plotly.NET/Playground.fsx | 27 ++++++ src/Plotly.NET/Slices.fs | 2 + src/Plotly.NET/SpaceFrame.fs | 4 +- src/Plotly.NET/Trace3d.fs | 149 ++++++++++++++++++++++++++++++++++ 6 files changed, 222 insertions(+), 1 deletion(-) diff --git a/src/Plotly.NET/Caps.fs b/src/Plotly.NET/Caps.fs index dd4ee5d5f..c1d1eaeb3 100644 --- a/src/Plotly.NET/Caps.fs +++ b/src/Plotly.NET/Caps.fs @@ -29,6 +29,8 @@ type CapFill () = Fill |> DynObj.setValueOpt capFill "fill" Show |> DynObj.setValueOpt capFill "show" + capFill + type Caps() = inherit DynamicObj () diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index 621784994..a778af69f 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -2078,6 +2078,45 @@ type Chart = |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=ShowLegend,?Opacity=Opacity) |> GenericChart.ofTraceObject + + static member IsoSurface + ( + x,y,z,value, + [] ?Name, + [] ?ShowLegend, + [] ?Opacity, + [] ?ColorScale, + [] ?ShowScale, + [] ?ColorBar, + [] ?IsoMin, + [] ?IsoMax, + [] ?Caps : Caps, + [] ?Slices : Slices, + [] ?Surface : Surface + ) = + Trace3d.initIsoSurface( + Trace3dStyle.IsoSurface( + X = x, + Y = y, + Z = z, + Value = value, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Opacity = Opacity, + ?ColorScale = ColorScale, + ?ShowScale = ShowScale, + ?ColorBar = ColorBar, + ?IsoMin = IsoMin, + ?IsoMax = IsoMax, + ?Caps = Caps, + ?Slices = Slices, + ?Surface = Surface + ) + ) + |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=ShowLegend,?Opacity=Opacity) + |> GenericChart.ofTraceObject + + /// creates table out of header sequence and row sequences static member Table(headerValues, cellValues, diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index 5063730b3..375fd0c10 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -91,6 +91,33 @@ let mgrid (min,max,n) = x,y,z + +let xIso,yIso,zIso = + mgrid(-5.,5.,40) + |> fun (x,y,z) -> + (x |> Array.concat |> Array.concat), + (y |> Array.concat |> Array.concat), + (z |> Array.concat |> Array.concat) + +let valueIso = + Array.map3 (fun x y z -> + x * x * 0.5 + y * y + z * z * 2. + ) xIso yIso zIso + + +Chart.IsoSurface( + xIso,yIso,zIso,valueIso, + IsoMin = 10., + IsoMax = 40., + Caps = Caps.init( + X = (CapFill.init(Show=false)), + Y = (CapFill.init(Show=false)) + ), + Surface = Surface.init(Count=5), + ColorScale = StyleParam.Colorscale.Viridis +) +|> Chart.show + let x,y,z = mgrid(-8.,8.,40) |> fun (x,y,z) -> diff --git a/src/Plotly.NET/Slices.fs b/src/Plotly.NET/Slices.fs index 90ea2a7b4..b6932e319 100644 --- a/src/Plotly.NET/Slices.fs +++ b/src/Plotly.NET/Slices.fs @@ -33,6 +33,8 @@ type SlicesFill () = Locations |> DynObj.setValueOpt slicesFill "locations" Show |> DynObj.setValueOpt slicesFill "show" + slicesFill + type Slices() = inherit DynamicObj () diff --git a/src/Plotly.NET/SpaceFrame.fs b/src/Plotly.NET/SpaceFrame.fs index 9d9211ff5..61121d408 100644 --- a/src/Plotly.NET/SpaceFrame.fs +++ b/src/Plotly.NET/SpaceFrame.fs @@ -27,4 +27,6 @@ type Spaceframe () = fun (spaceframe: Spaceframe) -> Fill |> DynObj.setValueOpt spaceframe "fill" - Show |> DynObj.setValueOpt spaceframe "show" \ No newline at end of file + Show |> DynObj.setValueOpt spaceframe "show" + + spaceframe \ No newline at end of file diff --git a/src/Plotly.NET/Trace3d.fs b/src/Plotly.NET/Trace3d.fs index 3e0ed6eb9..1ef3c2c01 100644 --- a/src/Plotly.NET/Trace3d.fs +++ b/src/Plotly.NET/Trace3d.fs @@ -680,3 +680,152 @@ module Trace3d = UIRevision |> DynObj.setValueOpt volume "uirevision" volume + + /// + /// Applies the style parameters of the isosurface chart to the given trace + /// + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not this trace is visible. If "legendonly", the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible). + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Sets the legend rank for this trace. Items and groups with smaller ranks are presented on top/left side while with `"reversed" `legend.traceorder` they are on bottom/right side. The default legendrank is 1000, so that you can use ranks less than 1000 to place certain items before all unranked items, and ranks greater than 1000 to go after all unranked items. + /// Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items. + /// Sets the title of the legendgroup + /// Sets the opacity of the surface. Please note that in the case of using high `opacity` values for example a value greater than or equal to 0.5 on two surfaces (and 0.25 with four surfaces), an overlay of multiple transparent surfaces may not perfectly be sorted in depth by the webgl API. This behavior may be improved in the near future and is subject to change. + /// Assigns id labels to each datum. These ids for object constancy of data points during animation. Should be an array of strings, not numbers or any other type. + /// Sets the X coordinates of the vertices on X axis. + /// Sets the Y coordinates of the vertices on Y axis. + /// Sets the Z coordinates of the vertices on Z axis. + /// Sets the 4th dimension (value) of the vertices. + /// Sets the text elements associated with the vertices. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Same as `text`. + /// Determines which trace information appear on hover. If `none` or `skip` are set, no information is displayed upon hovering. But, if `none` is set, click and hover events are still fired. + /// Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example "y: %{y}" as well as %{xother}, {%_xother}, {%_xother_}, {%xother_}. When showing info for several points, "xother" will be added to those with different x positions from the first point. An underscore before or after "(x|y)other" will add a space on that side, only when this field is shown. Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. variable `norm` Anything contained in tag `<extra>` is displayed in the secondary box, for example "<extra>{fullData.name}</extra>". To hide the secondary box completely, use an empty tag `<extra></extra>`. + /// Sets the hover text formatting rulefor `x` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `xaxis.hoverformat`. + /// Sets the hover text formatting rulefor `y` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `yaxis.hoverformat`. + /// Sets the hover text formatting rulefor `z` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `zaxis.hoverformat` + /// Sets the hover text formatting rulefor `value` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format.By default the values are formatted using generic number format. + /// Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index. + /// Assigns extra data each datum. This may be useful when listening to hover, click and selection events. Note that, "scatter" traces also appends customdata items in the markers DOM elements + /// Sets a reference between this trace's 3D coordinate system and a 3D scene. If "scene" (the default value), the (x,y,z) coordinates refer to `layout.scene`. If "scene2", the (x,y,z) coordinates refer to `layout.scene2`, and so on. + /// Sets a reference to a shared color axis. References to these shared color axes are "coloraxis", "coloraxis2", "coloraxis3", etc. Settings for these shared color axes are set in the layout, under `layout.coloraxis`, `layout.coloraxis2`, etc. Note that multiple color scales can be linked to the same color axis. + /// Sets the colorbar of this trace + /// Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `colorscale`. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed. + /// Sets the colorscale. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]`. To control the bounds of the colorscale in color space, use`cmin` and `cmax`. Alternatively, `colorscale` may be a palette name string of the following list: Blackbody,Bluered,Blues,Cividis,Earth,Electric,Greens,Greys,Hot,Jet,Picnic,Portland,Rainbow,RdBu,Reds,Viridis,YlGnBu,YlOrRd. + /// Determines whether or not a colorbar is displayed for this trace. + /// Reverses the color mapping if true. If true, `cmin` will correspond to the last color in the array and `cmax` will correspond to the first color. + /// Determines whether or not the color domain is computed with respect to the input data (here `value`) or the bounds set in `cmin` and `cmax` Defaults to `false` when `cmin` and `cmax` are set by the user. + /// Sets the lower bound of the color domain. Value should have the same units as `value` and if set, `cmax` must be set as well. + /// Sets the mid-point of the color domain by scaling `cmin` and/or `cmax` to be equidistant to this point. Value should have the same units as `value`. Has no effect when `cauto` is `false`. + /// Sets the upper bound of the color domain. Value should have the same units as `value` and if set, `cmin` must be set as well. + /// Sets the caps of this trace caps (color-coded surfaces on the sides of the visualization domain) + /// Sets the contour of this trace. + /// Determines whether or not normal smoothing is applied to the meshes, creating meshes with an angular, low-poly look via flat reflections. + /// Sets the hover labels of this trace. + /// Sets the maximum boundary for iso-surface plot. + /// Sets the minimum boundary for iso-surface plot. + /// Sets the Lighting of this trace. + /// Sets the LightPosition of this trace. + /// Sets the opacityscale. The opacityscale must be an array containing arrays mapping a normalized value to an opacity value. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 1], [0.5, 0.2], [1, 1]]` means that higher/lower values would have higher opacity values and those in the middle would be more transparent Alternatively, `opacityscale` may be a palette name string of the following list: 'min', 'max', 'extremes' and 'uniform'. The default is 'uniform'. + /// Sets slices through the volume + /// Sets the SpaceFrame of this trace. + /// Sets the Surface of this trace. + /// Controls persistence of some user-driven changes to the trace: `constraintrange` in `parcoords` traces, as well as some `editable: true` modifications such as `name` and `colorbar.title`. Defaults to `layout.uirevision`. Note that other user-driven trace attribute changes are controlled by `layout` attributes: `trace.visible` is controlled by `layout.legend.uirevision`, `selectedpoints` is controlled by `layout.selectionrevision`, and `colorbar.(x|y)` (accessible with `config: {editable: true}`) is controlled by `layout.editrevision`. Trace changes are tracked by `uid`, which only falls back on trace index if no `uid` is provided. So if your app can add/remove traces before the end of the `data` array, such that the same trace has a different index, you can still preserve user-driven changes if you give each trace a `uid` that stays with it as it moves. + static member IsoSurface + ( + ?Name : string, + ?Visible : StyleParam.Visible, + ?ShowLegend : bool, + ?LegendRank : int, + ?LegendGroup : string, + ?LegendGroupTitle : Title, + ?Opacity : float, + ?Ids : seq<#IConvertible>, + ?X : seq<#IConvertible>, + ?Y : seq<#IConvertible>, + ?Z : seq<#IConvertible>, + ?Value : seq<#IConvertible>, + ?Text : seq<#IConvertible>, + ?HoverText : seq<#IConvertible>, + ?HoverInfo : string, + ?HoverTemplate : string, + ?XHoverFormat : string, + ?YHoverFormat : string, + ?ZHoverFormat : string, + ?ValueHoverFormat : string, + ?Meta : seq<#IConvertible>, + ?CustomData : seq<#IConvertible>, + ?Scene : StyleParam.SubPlotId, + ?ColorAxis : StyleParam.SubPlotId, + ?ColorBar : ColorBar, + ?AutoColorScale : bool, + ?ColorScale : StyleParam.Colorscale, + ?ShowScale : bool, + ?ReverseScale : bool, + ?CAuto : bool, + ?CMin : float, + ?CMid : float, + ?CMax : float, + ?Caps : Caps, + ?Contour : Contour, + ?FlatShading : bool, + ?HoverLabel : Hoverlabel, + ?IsoMax : float, + ?IsoMin : float, + ?Lighting : Lighting, + ?LightPosition : LightPosition, + ?OpacityScale : seq<#seq<#IConvertible>>, + ?Slices : Slices, + ?SpaceFrame : Spaceframe, + ?Surface : Surface, + ?UIRevision : seq<#IConvertible> + ) = + fun (volume: Trace3d) -> + + Name |> DynObj.setValueOpt volume "name" + Visible |> DynObj.setValueOptBy volume "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt volume "showlegend" + LegendRank |> DynObj.setValueOpt volume "legendrank" + LegendGroup |> DynObj.setValueOpt volume "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt volume "legendgrouptitle" + Opacity |> DynObj.setValueOpt volume "opacity" + Ids |> DynObj.setValueOpt volume "ids" + X |> DynObj.setValueOpt volume "x" + Y |> DynObj.setValueOpt volume "y" + Z |> DynObj.setValueOpt volume "z" + Value |> DynObj.setValueOpt volume "value" + Text |> DynObj.setValueOpt volume "text" + HoverText |> DynObj.setValueOpt volume "hovertext" + HoverInfo |> DynObj.setValueOpt volume "hoverinfo" + HoverTemplate |> DynObj.setValueOpt volume "hovertemplate" + XHoverFormat |> DynObj.setValueOpt volume "xhoverformat" + YHoverFormat |> DynObj.setValueOpt volume "yhoverformat" + ZHoverFormat |> DynObj.setValueOpt volume "zhoverformat" + ValueHoverFormat |> DynObj.setValueOpt volume "valuehoverformat" + Meta |> DynObj.setValueOpt volume "meta" + CustomData |> DynObj.setValueOpt volume "customdata" + Scene |> DynObj.setValueOptBy volume "scene" StyleParam.SubPlotId.convert + ColorAxis |> DynObj.setValueOptBy volume "scene" StyleParam.SubPlotId.convert + ColorBar |> DynObj.setValueOpt volume "colorbar" + AutoColorScale |> DynObj.setValueOpt volume "autocolorscale" + ColorScale |> DynObj.setValueOptBy volume "colorscale" StyleParam.Colorscale.convert + ShowScale |> DynObj.setValueOpt volume "showscale" + ReverseScale |> DynObj.setValueOpt volume "reversescale" + CAuto |> DynObj.setValueOpt volume "cauto" + CMin |> DynObj.setValueOpt volume "cmin" + CMid |> DynObj.setValueOpt volume "cmid" + CMax |> DynObj.setValueOpt volume "cmax" + Caps |> DynObj.setValueOpt volume "caps" + Contour |> DynObj.setValueOpt volume "contour" + FlatShading |> DynObj.setValueOpt volume "flatshading" + HoverLabel |> DynObj.setValueOpt volume "hoverlabel" + IsoMax |> DynObj.setValueOpt volume "isomax" + IsoMin |> DynObj.setValueOpt volume "isomin" + Lighting |> DynObj.setValueOpt volume "lighting" + LightPosition |> DynObj.setValueOpt volume "lightposition" + OpacityScale |> DynObj.setValueOpt volume "opacityscale" + Slices |> DynObj.setValueOpt volume "slices" + SpaceFrame |> DynObj.setValueOpt volume "spaceframe" + Surface |> DynObj.setValueOpt volume "surface" + UIRevision |> DynObj.setValueOpt volume "uirevision" + + volume From e19a91d516e398263aa741753c1da483eff9c290 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Thu, 19 Aug 2021 19:55:01 +0200 Subject: [PATCH 13/21] Add all params for scatter3d traces --- src/Plotly.NET/GenericChart.fs | 36 ++-- src/Plotly.NET/Playground.fsx | 63 +++++-- src/Plotly.NET/Plotly.NET.fsproj | 1 + src/Plotly.NET/Projection.fs | 69 +++++++ src/Plotly.NET/StyleParams.fs | 14 ++ src/Plotly.NET/Trace3d.fs | 169 +++++++++++++----- .../Plotly.NET.Tests/HtmlCodegen/Charts3D.fs | 13 +- 7 files changed, 287 insertions(+), 78 deletions(-) create mode 100644 src/Plotly.NET/Projection.fs diff --git a/src/Plotly.NET/GenericChart.fs b/src/Plotly.NET/GenericChart.fs index ebb4b3ed6..eba26ef45 100644 --- a/src/Plotly.NET/GenericChart.fs +++ b/src/Plotly.NET/GenericChart.fs @@ -119,6 +119,10 @@ module HTML = [] module GenericChart = + + let internal jsonConfig = JsonSerializerSettings() + jsonConfig.ReferenceLoopHandling <- ReferenceLoopHandling.Serialize + open Trace type Figure = @@ -252,14 +256,14 @@ module GenericChart = let toChartHTML gChart = let guid = Guid.NewGuid().ToString() let tracesJson = - getTraces gChart - |> JsonConvert.SerializeObject + let traces = getTraces gChart + JsonConvert.SerializeObject(traces, jsonConfig) let layoutJson = - getLayout gChart - |> JsonConvert.SerializeObject + let layout = getLayout gChart + JsonConvert.SerializeObject(layout, jsonConfig) let configJson = - getConfig gChart - |> JsonConvert.SerializeObject + let config = getConfig gChart + JsonConvert.SerializeObject(config, jsonConfig) let displayOpts = getDisplayOptions gChart @@ -291,14 +295,14 @@ module GenericChart = let toChartHtmlWithSize (width:int) (height:int) (gChart:GenericChart) = let guid = Guid.NewGuid().ToString() let tracesJson = - getTraces gChart - |> JsonConvert.SerializeObject + let traces = getTraces gChart + JsonConvert.SerializeObject(traces, jsonConfig) let layoutJson = - getLayout gChart - |> JsonConvert.SerializeObject + let layout = getLayout gChart + JsonConvert.SerializeObject(layout, jsonConfig) let configJson = - getConfig gChart - |> JsonConvert.SerializeObject + let config = getConfig gChart + JsonConvert.SerializeObject(config, jsonConfig) let displayOpts = getDisplayOptions gChart @@ -327,11 +331,11 @@ module GenericChart = let toChartImage (format:StyleParam.ImageFormat) gChart = let guid = Guid.NewGuid().ToString() let tracesJson = - getTraces gChart - |> JsonConvert.SerializeObject + let traces = getTraces gChart + JsonConvert.SerializeObject(traces, jsonConfig) let layoutJson = - getLayout gChart - |> JsonConvert.SerializeObject + let layout = getLayout gChart + JsonConvert.SerializeObject(layout, jsonConfig) let html = HTML.staticChart diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index 375fd0c10..fde1b3a04 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -2,10 +2,11 @@ #r "nuget: Deedle" #r "nuget: FSharpAux" #r "nuget: DynamicObj" -#r "nuget: Newtonsoft.Json, 12.0.3" +#r "nuget: Newtonsoft.Json, 13.0.1" #load "StyleParams.fs" #load "Colors.fs" +#load "Projection.fs" #load "Surface.fs" #load "SpaceFrame.fs" #load "Slices.fs" @@ -64,6 +65,8 @@ #load "CandelstickExtension.fs" #load "SankeyExtension.fs" +open DynamicObj + open Plotly.NET open GenericChart @@ -75,6 +78,26 @@ open Deedle open FSharpAux open System +let lineChart = + let c = [0. .. 0.5 .. 15.] + + let x, y, z = + c + |> List.map (fun i -> + let i' = float i + let r = 10. * Math.Cos (i' / 10.) + (r * Math.Cos i', r * Math.Sin i', i') + ) + |> List.unzip3 + + Chart.Scatter3d(x, y, z, StyleParam.Mode.Lines_Markers) + |> Chart.withXAxisStyle("x-axis", Id=StyleParam.SubPlotId.Scene 1) + |> Chart.withYAxisStyle("y-axis", Id=StyleParam.SubPlotId.Scene 1) + |> Chart.withZAxisStyle("z-axis") + |> Chart.withSize(800., 800.) + +lineChart +|> Chart.show let linspace (min,max,n) = if n <= 2 then failwithf "n needs to be larger then 2" @@ -104,19 +127,33 @@ let valueIso = x * x * 0.5 + y * y + z * z * 2. ) xIso yIso zIso +let contains3d ch= + ch + |> existsTrace (fun t -> + match t with + | :? Trace3d -> true + | _ -> false) + +let iso = + Chart.IsoSurface( + xIso,yIso,zIso,valueIso, + IsoMin = 10., + IsoMax = 40., + Caps = Caps.init( + X = (CapFill.init(Show=false)), + Y = (CapFill.init(Show=false)) + ), + Surface = Surface.init(Count=5), + ColorScale = StyleParam.Colorscale.Viridis + ) + |> GenericChart.mapTrace(fun t -> + t + |> Trace3d.Trace3dStyle.Cone(Name="soos") + ) -Chart.IsoSurface( - xIso,yIso,zIso,valueIso, - IsoMin = 10., - IsoMax = 40., - Caps = Caps.init( - X = (CapFill.init(Show=false)), - Y = (CapFill.init(Show=false)) - ), - Surface = Surface.init(Count=5), - ColorScale = StyleParam.Colorscale.Viridis -) -|> Chart.show +contains3d iso + +iso |> Chart.show let x,y,z = mgrid(-8.,8.,40) diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index 9fd688bed..34469cead 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -36,6 +36,7 @@ + diff --git a/src/Plotly.NET/Projection.fs b/src/Plotly.NET/Projection.fs new file mode 100644 index 000000000..4c3e592e1 --- /dev/null +++ b/src/Plotly.NET/Projection.fs @@ -0,0 +1,69 @@ +namespace Plotly.NET + +open DynamicObj +open System + + +type ProjectionDimension () = + inherit DynamicObj () + + static member init + ( + ?Opacity : float, + ?Scale : float, + ?Show : bool + ) = + ProjectionDimension() + |> ProjectionDimension.style + ( + ?Opacity = Opacity, + ?Scale = Scale , + ?Show = Show + ) + + static member style + ( + ?Opacity : float, + ?Scale : float, + ?Show : bool + ) = + + fun (projectionDimension: ProjectionDimension) -> + + Opacity |> DynObj.setValueOpt projectionDimension "opacity" + Scale |> DynObj.setValueOpt projectionDimension "scale" + Show |> DynObj.setValueOpt projectionDimension "show" + + projectionDimension + +type Projection () = + inherit DynamicObj () + + static member init + ( + ?X: ProjectionDimension, + ?Y: ProjectionDimension, + ?Z: ProjectionDimension + ) = + Projection() + |> Projection.style + ( + ?X = X, + ?Y = Y, + ?Z = Z + ) + + static member style + ( + ?X: ProjectionDimension, + ?Y: ProjectionDimension, + ?Z: ProjectionDimension + ) = + + fun (projection: Projection) -> + + X |> DynObj.setValueOpt projection "x" + Y |> DynObj.setValueOpt projection "y" + Z |> DynObj.setValueOpt projection "z" + + projection \ No newline at end of file diff --git a/src/Plotly.NET/StyleParams.fs b/src/Plotly.NET/StyleParams.fs index f0811f35a..07af2ff7b 100644 --- a/src/Plotly.NET/StyleParams.fs +++ b/src/Plotly.NET/StyleParams.fs @@ -1422,6 +1422,20 @@ module StyleParam = static member convert = SurfacePattern.toString >> box + [] + type SurfaceAxis = + | NoSurfaceAxis + | X + | Y + | Z + + static member toString = function + | NoSurfaceAxis -> "-1" + | X -> "0" + | Y -> "1" + | Z -> "2" + + static member convert = SurfaceAxis.toString >> box //-------------------------- diff --git a/src/Plotly.NET/Trace3d.fs b/src/Plotly.NET/Trace3d.fs index 1ef3c2c01..f387cb7d8 100644 --- a/src/Plotly.NET/Trace3d.fs +++ b/src/Plotly.NET/Trace3d.fs @@ -57,46 +57,133 @@ module Trace3d = SceneName |> DynObj.setValueOpt trace "scene" trace - // Applies the styles to Scatter3d() + /// + /// Applies the style parameters of the Scatter3d chart to the given trace + /// + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not this trace is visible. If "legendonly", the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible). + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Sets the legend rank for this trace. Items and groups with smaller ranks are presented on top/left side while with `"reversed" `legend.traceorder` they are on bottom/right side. The default legendrank is 1000, so that you can use ranks less than 1000 to place certain items before all unranked items, and ranks greater than 1000 to go after all unranked items. + /// Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items. + /// Sets the legend group title + /// Sets the opacity of the trace. + /// Determines the drawing mode for this scatter trace. If the provided `mode` includes "text" then the `text` elements appear at the coordinates. Otherwise, the `text` elements appear on hover. If there are less than 20 points and the trace is not stacked then the default is "lines+markers". Otherwise, "lines". + /// Assigns id labels to each datum. These ids for object constancy of data points during animation. Should be an array of strings, not numbers or any other type. + /// Sets the x coordinates. + /// Sets the y coordinates. + /// Sets the z coordinates. + /// Sets the surface fill color. + /// Sets text elements associated with each (x,y,z) triplet. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y,z) coordinates. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Sets the positions of the `text` elements with respects to the (x,y) coordinates. + /// Template string used for rendering the information text that appear on points. Note that this will override `textinfo`. Variables are inserted using %{variable}, for example "y: %{y}". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. Every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. + /// Sets text elements associated with each (x,y,z) triplet. If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (x,y,z) coordinates. To be seen, trace `hoverinfo` must contain a "text" flag. + /// Determines which trace information appear on hover. If `none` or `skip` are set, no information is displayed upon hovering. But, if `none` is set, click and hover events are still fired. + /// Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example "y: %{y}" as well as %{xother}, {%_xother}, {%_xother_}, {%xother_}. When showing info for several points, "xother" will be added to those with different x positions from the first point. An underscore before or after "(x|y)other" will add a space on that side, only when this field is shown. Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. variable `norm` Anything contained in tag `<extra>` is displayed in the secondary box, for example "<extra>{fullData.name}</extra>". To hide the secondary box completely, use an empty tag `<extra></extra>`. + /// Sets the hover text formatting rulefor `x` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `xaxis.hoverformat`. + /// Sets the hover text formatting rulefor `y` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `yaxis.hoverformat`. + /// Sets the hover text formatting rulefor `z` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `zaxis.hoverformat`. + /// Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index. + /// Assigns extra data each datum. This may be useful when listening to hover, click and selection events. Note that, "scatter" traces also appends customdata items in the markers DOM elements + /// Sets a reference between this trace's 3D coordinate system and a 3D scene. If "scene" (the default value), the (x,y,z) coordinates refer to `layout.scene`. If "scene2", the (x,y,z) coordinates refer to `layout.scene2`, and so on. + /// Sets the marker of this trace. + /// Sets the line of this trace. + /// Sets the text font of this trace. + /// Sets the x Error of this trace. + /// Sets the y Error of this trace. + /// Sets the z Error of this trace. + /// Determines whether or not gaps (i.e. {nan} or missing values) in the provided data arrays are connected. + /// Sets the hoverlabel of this trace. + /// Sets the projection of this trace. + /// If "-1", the scatter points are not fill with a surface If "0", "1", "2", the scatter points are filled with a Delaunay surface about the x, y, z respectively. + /// Sets the calendar system to use with `x` date data. + /// Sets the calendar system to use with `y` date data. + /// Sets the calendar system to use with `z` date data. + /// Controls persistence of some user-driven changes to the trace: `constraintrange` in `parcoords` traces, as well as some `editable: true` modifications such as `name` and `colorbar.title`. Defaults to `layout.uirevision`. Note that other user-driven trace attribute changes are controlled by `layout` attributes: `trace.visible` is controlled by `layout.legend.uirevision`, `selectedpoints` is controlled by `layout.selectionrevision`, and `colorbar.(x|y)` (accessible with `config: {editable: true}`) is controlled by `layout.editrevision`. Trace changes are tracked by `uid`, which only falls back on trace index if no `uid` is provided. So if your app can add/remove traces before the end of the `data` array, such that the same trace has a different index, you can still preserve user-driven changes if you give each trace a `uid` that stays with it as it moves. static member Scatter3d ( - ?X : seq<#IConvertible>, - ?Y : seq<#IConvertible>, - ?Z : seq<#IConvertible>, - ?Mode : StyleParam.Mode, - ?Surfaceaxis, - ?Surfacecolor, - //?Projection : Projection, - ?Scene : string, - ?Error_y: Error, - ?Error_x: Error, - ?Error_z: Error, - ?Xsrc : string, - ?Ysrc : string, - ?Zsrc : string + ?Name : string, + ?Visible : StyleParam.Visible, + ?ShowLegend : bool, + ?LegendRank : int, + ?LegendGroup : string, + ?LegendGroupTitle : Title, + ?Mode : StyleParam.Mode, + ?Opacity : float, + ?Ids : seq<#IConvertible>, + ?X : seq<#IConvertible>, + ?Y : seq<#IConvertible>, + ?Z : seq<#IConvertible>, + ?SurfaceColor : string, + ?Text : seq<#IConvertible>, + ?TextPosition : StyleParam.TextPosition, + ?TextTemplate : string, + ?HoverText : seq<#IConvertible>, + ?HoverInfo : string, + ?HoverTemplate : string, + ?XHoverFormat : string, + ?YHoverFormat : string, + ?ZHoverFormat : string, + ?Meta : string, + ?CustomData : seq<#IConvertible>, + ?Scene : StyleParam.SubPlotId, + ?Marker : Marker, + ?Line : Line, + ?TextFont : Font, + ?ErrorX : Error, + ?ErrorY : Error, + ?ErrorZ : Error, + ?ConnectGaps : bool, + ?Hoverlabel : Hoverlabel, + ?Projection : Projection, + ?Surfaceaxis : StyleParam.SurfaceAxis, + ?XCalendar : StyleParam.Calendar, + ?YCalendar : StyleParam.Calendar, + ?ZCalendar : StyleParam.Calendar, + ?UIRevision : string ) = - //(fun (scatter:('T :> Trace3d)) -> - (fun (scatter: Trace3d) -> - //scatter.set_type plotType - X |> DynObj.setValueOpt scatter "x" - Y |> DynObj.setValueOpt scatter "y" - Z |> DynObj.setValueOpt scatter "z" - Mode |> DynObj.setValueOptBy scatter "mode" StyleParam.Mode.toString - - Surfaceaxis |> DynObj.setValueOpt scatter "xsrc" - Surfacecolor |> DynObj.setValueOpt scatter "xsrc" - Scene |> DynObj.setValueOpt scatter "xsrc" - Xsrc |> DynObj.setValueOpt scatter "xsrc" - Ysrc |> DynObj.setValueOpt scatter "ysrc" - Zsrc |> DynObj.setValueOpt scatter "zsrc" - - // Update - Error_x |> DynObj.setValueOpt scatter "error_x" - Error_y |> DynObj.setValueOpt scatter "error_y" - Error_z |> DynObj.setValueOpt scatter "error_z" - //Projection |> DynObj.setValueOpt scatter "projecton" - // out -> + (fun (scatter: #Trace) -> + + Name |> DynObj.setValueOpt scatter "name" + Visible |> DynObj.setValueOptBy scatter "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt scatter "showlegend" + LegendRank |> DynObj.setValueOpt scatter "legendrank" + LegendGroup |> DynObj.setValueOpt scatter "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt scatter "legendgrouptitle" + Mode |> DynObj.setValueOptBy scatter "mode" StyleParam.Mode.convert + Opacity |> DynObj.setValueOpt scatter "opacity" + Ids |> DynObj.setValueOpt scatter "ids" + X |> DynObj.setValueOpt scatter "x" + Y |> DynObj.setValueOpt scatter "y" + Z |> DynObj.setValueOpt scatter "z" + SurfaceColor |> DynObj.setValueOpt scatter "surfacecolor" + Text |> DynObj.setValueOpt scatter "text" + TextPosition |> DynObj.setValueOptBy scatter "textposition" StyleParam.TextPosition.convert + TextTemplate |> DynObj.setValueOpt scatter "texttemplate" + HoverText |> DynObj.setValueOpt scatter "hovertext" + HoverInfo |> DynObj.setValueOpt scatter "hoverinfo" + HoverTemplate |> DynObj.setValueOpt scatter "hovertemplate" + XHoverFormat |> DynObj.setValueOpt scatter "xhoverformat" + YHoverFormat |> DynObj.setValueOpt scatter "yhoverformat" + ZHoverFormat |> DynObj.setValueOpt scatter "zhoverformat" + Meta |> DynObj.setValueOpt scatter "meta" + CustomData |> DynObj.setValueOpt scatter "customdata" + Scene |> DynObj.setValueOptBy scatter "scene" StyleParam.SubPlotId.convert + Marker |> DynObj.setValueOpt scatter "marker" + Line |> DynObj.setValueOpt scatter "line" + TextFont |> DynObj.setValueOpt scatter "textfont" + ErrorX |> DynObj.setValueOpt scatter "errorx" + ErrorY |> DynObj.setValueOpt scatter "errory" + ErrorZ |> DynObj.setValueOpt scatter "errorz" + ConnectGaps |> DynObj.setValueOpt scatter "connectgaps" + Hoverlabel |> DynObj.setValueOpt scatter "hoverlabel" + Projection |> DynObj.setValueOpt scatter "projection" + Surfaceaxis |> DynObj.setValueOptBy scatter "surfaceaxis" StyleParam.SurfaceAxis.convert + XCalendar |> DynObj.setValueOptBy scatter "xcalendar" StyleParam.Calendar.convert + YCalendar |> DynObj.setValueOptBy scatter "ycalendar" StyleParam.Calendar.convert + ZCalendar |> DynObj.setValueOptBy scatter "zcalendar" StyleParam.Calendar.convert + UIRevision |> DynObj.setValueOpt scatter "uirevision" + scatter ) @@ -130,7 +217,7 @@ module Trace3d = ?Surfacecolorsrc ) = - (fun (surface:('T :> Trace)) -> + (fun (surface: #Trace) -> Z |> DynObj.setValueOpt surface "z" X |> DynObj.setValueOpt surface "x" @@ -200,9 +287,9 @@ module Trace3d = ) = - //(fun (scatter:('T :> Trace3d)) -> - (fun (mesh3d: Trace3d) -> - //scatter.set_type plotType + + (fun (mesh3d: #Trace) -> + X |> DynObj.setValueOpt mesh3d "x" Y |> DynObj.setValueOpt mesh3d "y" Z |> DynObj.setValueOpt mesh3d "z" @@ -339,7 +426,7 @@ module Trace3d = ?UIRevision : seq<#IConvertible> ) = - (fun (cone: Trace3d) -> + (fun (cone: #Trace) -> Name |> DynObj.setValueOpt cone "name" Visible |> DynObj.setValueOptBy cone "visible" StyleParam.Visible.convert ShowLegend |> DynObj.setValueOpt cone "showlegend" diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs b/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs index c187cf5ba..b95542e27 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs @@ -21,11 +21,11 @@ let scatterChart = let ``3D Scatter charts`` = testList "Charts3D.3D Scatter charts" [ testCase "3D Scatter charts data" ( fun () -> - "var data = [{\"type\":\"scatter3d\",\"x\":[19,26,55],\"y\":[19,26,55],\"z\":[19,26,55],\"mode\":\"markers\",\"line\":{},\"marker\":{}}];" + """var data = [{"type":"scatter3d","mode":"markers","x":[19,26,55],"y":[19,26,55],"z":[19,26,55],"line":{},"marker":{}}]""" |> chartGeneratedContains scatterChart ); testCase "3D Scatter charts layout" ( fun () -> - "var layout = {\"scene\":{\"xaxis\":{\"title\":{\"text\":\"my x-axis\"}},\"yaxis\":{\"title\":{\"text\":\"my y-axis\"}},\"zaxis\":{\"title\":{\"text\":\"my z-axis\"}}},\"width\":800.0,\"height\":800.0};" + """var layout = {"scene":{"xaxis":{"title":{"text":"my x-axis"}},"yaxis":{"title":{"text":"my y-axis"}},"zaxis":{"title":{"text":"my z-axis"}}},"width":800.0,"height":800.0};""" |> chartGeneratedContains scatterChart ); ] @@ -53,14 +53,11 @@ let lineChart = let ``Line charts`` = testList "Charts3D.Line charts" [ testCase "Line data" ( fun () -> - [ - "var data = [{\"type\":\"scatter3d\",\"x\":[10.0,8.764858122060915,5.3760304484812105,0.699428991431538," - ",0.4599954209124893],\"z\":[0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5,11.0,11.5,12.0,12.5,13.0,13.5,14.0,14.5,15.0],\"mode\":\"lines+markers\",\"line\":{},\"marker\":{}}];" - ] - |> chartGeneratedContainsList lineChart + """var data = [{"type":"scatter3d","mode":"lines+markers","x":[10.0,8.764858122060915,5.3760304484812105,0.699428991431538,-4.078516059742164,-7.762380006776013,-9.457759559629629,-8.796818588044248,-6.020456431562834,-1.8981046678556164,2.4893698743024015,6.041583606256742,7.924627339505819,7.774455867055686,5.766162492106399,2.5362920361842747,-1.0137084976470045,-3.9731770939413367,-5.663676531805762,-5.800381805436716,-4.533522819483132,-2.3661340757417872,0.020074794419808174,1.9742392407015044,3.0577702559255746,3.1462811058452385,2.427409510770794,1.302916035546942,0.23240834306912295,-0.42769357063721014,-0.5373819709641076],"y":[0.0,4.788263815209447,8.372671348444594,9.862941931402888,8.911720173488927,5.798670944701264,1.3481709304529075,-3.2951619221615798,-6.970612585921842,-8.802141619140079,-8.415352216177444,-6.014904288506064,-2.306115620213046,1.7125353726077581,5.024910671806752,6.86324142009979,6.892925283704576,5.269880365378672,2.561769585348826,-0.43714135926897707,-2.9393586065447344,-4.37711141115013,-4.535916791549611,-3.576112184549465,-1.9443135767963393,-0.2091277735131711,1.123941901777903,1.7603416439605064,1.6837070198341995,1.1265744325858227,0.4599954209124893],"z":[0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5,11.0,11.5,12.0,12.5,13.0,13.5,14.0,14.5,15.0],"line":{},"marker":{}}];""" + |> chartGeneratedContains lineChart ); testCase "Line layout" ( fun () -> - "var layout = {\"scene\":{\"xaxis\":{\"title\":{\"text\":\"x-axis\"}},\"yaxis\":{\"title\":{\"text\":\"y-axis\"}},\"zaxis\":{\"title\":{\"text\":\"z-axis\"}}},\"width\":800.0,\"height\":800.0};" + """var layout = {"scene":{"xaxis":{"title":{"text":"x-axis"}},"yaxis":{"title":{"text":"y-axis"}},"zaxis":{"title":{"text":"z-axis"}}},"width":800.0,"height":800.0};""" |> chartGeneratedContains lineChart ); ] From 7187d07761a6916e7ba0ce6c66783fb73fa0298b Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Fri, 20 Aug 2021 17:33:36 +0200 Subject: [PATCH 14/21] Add Chart.Point3d, Chart.Line3d, Chart.Bubble3d --- src/Plotly.NET/Chart.fs | 189 ++++++++++++++++++++++++++++++++++ src/Plotly.NET/Playground.fsx | 38 ++++--- 2 files changed, 210 insertions(+), 17 deletions(-) diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index a778af69f..02d5d18f5 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -1889,6 +1889,195 @@ type Chart = let x,y,z = Seq.unzip3 xyz Chart.Scatter3d(x, y, z, mode, ?Name=Name,?Showlegend=Showlegend,?MarkerSymbol=MarkerSymbol,?Color=Color,?Opacity=Opacity,?Labels=Labels,?TextPosition=TextPosition,?TextFont=TextFont,?Dash=Dash,?Width=Width) + /// + static member Point3d + ( + x, y, z, + [] ?Name, + [] ?Showlegend, + [] ?MarkerSymbol, + [] ?Color, + [] ?Opacity, + [] ?Labels, + [] ?TextPosition, + [] ?TextFont + ) = + // if text position or font is set, then show labels (not only when hovering) + let changeMode = StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome) + + Chart.Scatter3d( + x = x, + y = y, + z = z, + mode = changeMode StyleParam.Mode.Markers, + ?Name = Name, + ?Showlegend = Showlegend, + ?MarkerSymbol = MarkerSymbol, + ?Color = Color, + ?Opacity = Opacity, + ?Labels = Labels, + ?TextPosition = TextPosition, + ?TextFont = TextFont + ) + + /// + static member Point3d + ( + xyz, + [] ?Name, + [] ?Showlegend, + [] ?MarkerSymbol, + [] ?Color, + [] ?Opacity, + [] ?Labels, + [] ?TextPosition, + [] ?TextFont + ) = + let x, y, z = Seq.unzip3 xyz + + Chart.Point3d( + x, y, z, + ?Name = Name, + ?Showlegend = Showlegend, + ?MarkerSymbol = MarkerSymbol, + ?Color = Color, + ?Opacity = Opacity, + ?Labels = Labels, + ?TextPosition = TextPosition, + ?TextFont = TextFont + ) + + + /// Uses points, line or both depending on the mode to represent 3d-data points + static member Line3d + ( + x, y, z, + [] ?Name, + [] ?ShowMarkers, + [] ?Showlegend, + [] ?MarkerSymbol, + [] ?Color, + [] ?Opacity, + [] ?Labels, + [] ?TextPosition, + [] ?TextFont, + [] ?Dash, + [] ?Width + ) = + let changeMode = + let isShowMarker = + match ShowMarkers with + | Some isShow -> isShow + | Option.None -> false + StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome) + >> StyleParam.ModeUtils.showMarker (isShowMarker) + + Chart.Scatter3d( + x = x, + y = y, + z = z, + mode = changeMode StyleParam.Mode.Lines, + ?Name = Name , + ?Showlegend = Showlegend , + ?MarkerSymbol = MarkerSymbol, + ?Color = Color , + ?Opacity = Opacity , + ?Labels = Labels , + ?TextPosition = TextPosition, + ?TextFont = TextFont , + ?Dash = Dash , + ?Width = Width + ) + + /// Uses points, line or both depending on the mode to represent 3d-data points + static member Line3d + ( + xyz, + [] ?Name, + [] ?ShowMarkers, + [] ?Showlegend, + [] ?MarkerSymbol, + [] ?Color, + [] ?Opacity, + [] ?Labels, + [] ?TextPosition, + [] ?TextFont, + [] ?Dash, + [] ?Width + ) = + let x, y, z = Seq.unzip3 xyz + + Chart.Line3d( + x, y, z, + ?Name = Name , + ?ShowMarkers = ShowMarkers , + ?Showlegend = Showlegend , + ?MarkerSymbol = MarkerSymbol, + ?Color = Color , + ?Opacity = Opacity , + ?Labels = Labels , + ?TextPosition = TextPosition, + ?TextFont = TextFont , + ?Dash = Dash , + ?Width = Width + ) + + /// + static member Bubble3d + ( + x, y, z, sizes, + [] ?Name, + [] ?Showlegend, + [] ?MarkerSymbol, + [] ?Color, + [] ?Opacity, + [] ?Labels, + [] ?TextPosition, + [] ?TextFont + ) = + let changeMode = StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome) + + Trace3d.initScatter3d ( + Trace3dStyle.Scatter3d( + X = x, + Y = y, + Z = z, + Mode=changeMode StyleParam.Mode.Markers + ) + ) + |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity) + |> TraceStyle.Marker(?Color=Color,?Symbol=MarkerSymbol, MultiSizes=sizes) + |> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont) + |> GenericChart.ofTraceObject + + /// + static member Bubble3d + ( + xyz, sizes, + [] ?Name, + [] ?Showlegend, + [] ?MarkerSymbol, + [] ?Color, + [] ?Opacity, + [] ?Labels, + [] ?TextPosition, + [] ?TextFont + ) = + let x, y, z = Seq.unzip3 xyz + + Chart.Bubble3d( + x, y, z, sizes, + ?Name = Name, + ?Showlegend = Showlegend, + ?MarkerSymbol = MarkerSymbol, + ?Color = Color, + ?Opacity = Opacity, + ?Labels = Labels, + ?TextPosition = TextPosition, + ?TextFont = TextFont + ) + + /// Uses points, line or both depending on the mode to represent 3d-data points static member Surface(data:seq<#seq<#IConvertible>>, [] ?X, diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index fde1b3a04..f31c41e66 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -78,27 +78,31 @@ open Deedle open FSharpAux open System -let lineChart = - let c = [0. .. 0.5 .. 15.] - - let x, y, z = - c - |> List.map (fun i -> - let i' = float i - let r = 10. * Math.Cos (i' / 10.) - (r * Math.Cos i', r * Math.Sin i', i') - ) - |> List.unzip3 - Chart.Scatter3d(x, y, z, StyleParam.Mode.Lines_Markers) - |> Chart.withXAxisStyle("x-axis", Id=StyleParam.SubPlotId.Scene 1) - |> Chart.withYAxisStyle("y-axis", Id=StyleParam.SubPlotId.Scene 1) - |> Chart.withZAxisStyle("z-axis") - |> Chart.withSize(800., 800.) +Chart.Point3d( + [1,2,3; 4,5,6; 7,8,9], + Labels = ["A"; "B"; "C"], + TextPosition = StyleParam.TextPosition.BottomCenter +) +|> Chart.show -lineChart +Chart.Line3d( + [1,3,2; 6,5,4; 7,9,8], + Labels = ["A"; "B"; "C"], + TextPosition = StyleParam.TextPosition.BottomCenter, + ShowMarkers = true +) |> Chart.show +Chart.Bubble3d( + [1,3,2; 6,5,4; 7,9,8], + [20; 40; 30], + Labels = ["A"; "B"; "C"], + TextPosition = StyleParam.TextPosition.TopLeft +) +|> Chart.show + + let linspace (min,max,n) = if n <= 2 then failwithf "n needs to be larger then 2" let bw = float (max - min) / (float n - 1.) From 4dc71c0a5b922d128711a9c8db25fdeb449c128b Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Fri, 20 Aug 2021 17:41:22 +0200 Subject: [PATCH 15/21] Round 3d Line data for stable testing --- tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs b/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs index b95542e27..37cbf5d09 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs @@ -39,6 +39,10 @@ let lineChart = let i' = float i let r = 10. * Math.Cos (i' / 10.) (r * Math.Cos i', r * Math.Sin i', i') + |> fun (x,y,z) -> + Math.Round(x,3), + Math.Round(y,3), + Math.Round(z,3) ) |> List.unzip3 @@ -53,7 +57,7 @@ let lineChart = let ``Line charts`` = testList "Charts3D.Line charts" [ testCase "Line data" ( fun () -> - """var data = [{"type":"scatter3d","mode":"lines+markers","x":[10.0,8.764858122060915,5.3760304484812105,0.699428991431538,-4.078516059742164,-7.762380006776013,-9.457759559629629,-8.796818588044248,-6.020456431562834,-1.8981046678556164,2.4893698743024015,6.041583606256742,7.924627339505819,7.774455867055686,5.766162492106399,2.5362920361842747,-1.0137084976470045,-3.9731770939413367,-5.663676531805762,-5.800381805436716,-4.533522819483132,-2.3661340757417872,0.020074794419808174,1.9742392407015044,3.0577702559255746,3.1462811058452385,2.427409510770794,1.302916035546942,0.23240834306912295,-0.42769357063721014,-0.5373819709641076],"y":[0.0,4.788263815209447,8.372671348444594,9.862941931402888,8.911720173488927,5.798670944701264,1.3481709304529075,-3.2951619221615798,-6.970612585921842,-8.802141619140079,-8.415352216177444,-6.014904288506064,-2.306115620213046,1.7125353726077581,5.024910671806752,6.86324142009979,6.892925283704576,5.269880365378672,2.561769585348826,-0.43714135926897707,-2.9393586065447344,-4.37711141115013,-4.535916791549611,-3.576112184549465,-1.9443135767963393,-0.2091277735131711,1.123941901777903,1.7603416439605064,1.6837070198341995,1.1265744325858227,0.4599954209124893],"z":[0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5,11.0,11.5,12.0,12.5,13.0,13.5,14.0,14.5,15.0],"line":{},"marker":{}}];""" + """var data = [{"type":"scatter3d","mode":"lines+markers","x":[10.0,8.765,5.376,0.699,-4.079,-7.762,-9.458,-8.797,-6.02,-1.898,2.489,6.042,7.925,7.774,5.766,2.536,-1.014,-3.973,-5.664,-5.8,-4.534,-2.366,0.02,1.974,3.058,3.146,2.427,1.303,0.232,-0.428,-0.537],"y":[0.0,4.788,8.373,9.863,8.912,5.799,1.348,-3.295,-6.971,-8.802,-8.415,-6.015,-2.306,1.713,5.025,6.863,6.893,5.27,2.562,-0.437,-2.939,-4.377,-4.536,-3.576,-1.944,-0.209,1.124,1.76,1.684,1.127,0.46],"z":[0.0,0.5,1.0,1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,8.5,9.0,9.5,10.0,10.5,11.0,11.5,12.0,12.5,13.0,13.5,14.0,14.5,15.0],"line":{},"marker":{}}];""" |> chartGeneratedContains lineChart ); testCase "Line layout" ( fun () -> From b48e9aa49811ba6d294c1c80e0ebcc210cd5b185 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Fri, 20 Aug 2021 18:22:23 +0200 Subject: [PATCH 16/21] Add all Surface trace parameters --- src/Plotly.NET/Chart.fs | 6 +- src/Plotly.NET/Contours.fs | 190 ++++++++++++------ src/Plotly.NET/Trace3d.fs | 183 ++++++++++++----- .../Plotly.NET.Tests/HtmlCodegen/Charts3D.fs | 2 +- 4 files changed, 260 insertions(+), 121 deletions(-) diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index 02d5d18f5..7ce3dcf6c 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -2086,12 +2086,12 @@ type Chart = [] ?Showlegend, [] ?Opacity, [] ?Contours, - [] ?Colorscale, - [] ?Showscale, + [] ?ColorScale, + [] ?ShowScale, [] ?ColorBar) = Trace3d.initSurface ( Trace3dStyle.Surface (Z=data,?X=X, ?Y=Y,?Contours=Contours, - ?Colorscale=Colorscale,?Showscale=Showscale,?ColorBar=ColorBar ) ) + ?ColorScale=ColorScale,?ShowScale=ShowScale,?ColorBar=ColorBar ) ) |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity) //|> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont) |> GenericChart.ofTraceObject diff --git a/src/Plotly.NET/Contours.fs b/src/Plotly.NET/Contours.fs index e39864592..bdb60ab2e 100644 --- a/src/Plotly.NET/Contours.fs +++ b/src/Plotly.NET/Contours.fs @@ -2,6 +2,38 @@ namespace Plotly.NET open DynamicObj +type ContourProject () = + inherit DynamicObj () + + static member init + ( + ?X: bool, + ?Y: bool, + ?Z: bool + ) = + ContourProject() + |> ContourProject.style + ( + ?X = X, + ?Y = Y, + ?Z = Z + ) + + static member style + ( + ?X: bool, + ?Y: bool, + ?Z: bool + ) = + + fun (contourProject: ContourProject) -> + + X |> DynObj.setValueOpt contourProject "x" + Y |> DynObj.setValueOpt contourProject "y" + Z |> DynObj.setValueOpt contourProject "z" + + contourProject + /// Contour object inherits from dynamic object type Contour () = inherit DynamicObj () @@ -10,28 +42,32 @@ type Contour () = //[] static member init ( - ?Show: bool, - ?Start: float, - ?End: float, - ?Size: float, - ?Color: string, - ?UseColorMap: bool, - ?Width: float, - ?Highlight: bool, - ?Highlightcolor: string , - ?Highlightwidth : float + ?Color : string, + ?End : float, + ?Highlight : bool, + ?HighlightColor : string , + ?HighlightWidth : float, + ?Project : ContourProject, + ?Show : bool, + ?Size : float, + ?Start : float, + ?UseColorMap : bool, + ?Width : float ) = Contour () |> Contour.style ( - ?Show = Show , - //?Project = Project , - ?Color = Color , - ?UseColorMap = UseColorMap , - ?Width = Width , - ?Highlight = Highlight , - ?Highlightcolor = Highlightcolor , - ?Highlightwidth = Highlightwidth + ?Color = Color , + ?End = End , + ?Highlight = Highlight , + ?HighlightColor = HighlightColor, + ?HighlightWidth = HighlightWidth, + ?Project = Project , + ?Show = Show , + ?Size = Size , + ?Start = Start , + ?UseColorMap = UseColorMap , + ?Width = Width ) @@ -39,29 +75,32 @@ type Contour () = //[] static member style ( - ?Show: bool, - ?Start: float, - ?End: float, - ?Size: float, - ?Color: string, - ?UseColorMap: bool, - ?Width: float, - ?Highlight: bool, - ?Highlightcolor: string , - ?Highlightwidth : float + ?Color : string, + ?End : float, + ?Highlight : bool, + ?HighlightColor : string , + ?HighlightWidth : float, + ?Project : ContourProject, + ?Show : bool, + ?Size : float, + ?Start : float, + ?UseColorMap : bool, + ?Width : float ) = (fun (contour:Contour) -> - Show |> DynObj.setValueOpt contour "show" - Color |> DynObj.setValueOpt contour "color" - Start |> DynObj.setValueOpt contour "start" - End |> DynObj.setValueOpt contour "end" - Size |> DynObj.setValueOpt contour "size" - UseColorMap |> DynObj.setValueOpt contour "usecolormap" - Width |> DynObj.setValueOpt contour "width" - Highlight |> DynObj.setValueOpt contour "highlight" - Highlightcolor |> DynObj.setValueOpt contour "highlightcolor" - Highlightwidth |> DynObj.setValueOpt contour "highlightwidth" + Color |> DynObj.setValueOpt contour "color" + End |> DynObj.setValueOpt contour "end" + Highlight |> DynObj.setValueOpt contour "highlight" + HighlightColor |> DynObj.setValueOpt contour "highlightcolor" + HighlightWidth |> DynObj.setValueOpt contour "highlightwidth" + Project |> DynObj.setValueOpt contour "project" + Show |> DynObj.setValueOpt contour "show" + Size |> DynObj.setValueOpt contour "size" + Start |> DynObj.setValueOpt contour "start" + UseColorMap |> DynObj.setValueOpt contour "usecolormap" + Width |> DynObj.setValueOpt contour "width" + contour ) @@ -74,9 +113,9 @@ type Contours () = //[] static member init ( - ?X , - ?Y , - ?Z + ?X : Contour, + ?Y : Contour, + ?Z : Contour ) = Contours () |> Contours.style @@ -107,48 +146,65 @@ type Contours () = // Initialized x-y-z-Contours with the same properties static member initXyz ( - ?Show , - //?Project , - ?Color, - ?UseColorMap , - ?Width , - ?Highlight , - ?Highlightcolor , - ?Highlightwidth + ?Color : string, + ?End : float, + ?Highlight : bool, + ?HighlightColor : string , + ?HighlightWidth : float, + ?Project : ContourProject, + ?Show : bool, + ?Size : float, + ?Start : float, + ?UseColorMap : bool, + ?Width : float ) = Contours () |> Contours.styleXyz ( - ?Show=Show , - //?Project , - ?Color=Color , - ?UseColorMap=UseColorMap , - ?Width=Width , - ?Highlight=Highlight , - ?Highlightcolor=Highlightcolor, - ?Highlightwidth=Highlightwidth + ?Color = Color , + ?End = End , + ?Highlight = Highlight , + ?HighlightColor = HighlightColor, + ?HighlightWidth = HighlightWidth, + ?Project = Project , + ?Show = Show , + ?Size = Size , + ?Start = Start , + ?UseColorMap = UseColorMap , + ?Width = Width ) // Applies the styles to Contours() //[] static member styleXyz ( - ?Show , - //?Project , - ?Color, - ?UseColorMap , - ?Width , - ?Highlight , - ?Highlightcolor , - ?Highlightwidth + ?Color : string, + ?End : float, + ?Highlight : bool, + ?HighlightColor : string , + ?HighlightWidth : float, + ?Project : ContourProject, + ?Show : bool, + ?Size : float, + ?Start : float, + ?UseColorMap : bool, + ?Width : float ) = (fun (contours: Contours) -> let xyzContour = - Contour.init (?Show=Show,?Color=Color,?UseColorMap=UseColorMap, ?Width=Width, - ?Highlight=Highlight, ?Highlightcolor=Highlightcolor, ?Highlightwidth=Highlightwidth) + Contour.init ( + ?Show=Show, + ?Color=Color, + ?UseColorMap=UseColorMap, + ?Width=Width, + ?Highlight=Highlight, + ?HighlightColor=HighlightColor, + ?HighlightWidth=HighlightWidth, + ?Project = Project + ) contours |> Contours.style(X=xyzContour,Y=xyzContour,Z=xyzContour) ) diff --git a/src/Plotly.NET/Trace3d.fs b/src/Plotly.NET/Trace3d.fs index f387cb7d8..8d6c57e4d 100644 --- a/src/Plotly.NET/Trace3d.fs +++ b/src/Plotly.NET/Trace3d.fs @@ -189,61 +189,144 @@ module Trace3d = - /// Applies the styles of 3d-surface to TraceObjects + /// + /// Applies the style parameters of the surface chart to the given trace + /// + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not this trace is visible. If "legendonly", the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible). + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Sets the legend rank for this trace. Items and groups with smaller ranks are presented on top/left side while with `"reversed" `legend.traceorder` they are on bottom/right side. The default legendrank is 1000, so that you can use ranks less than 1000 to place certain items before all unranked items, and ranks greater than 1000 to go after all unranked items. + /// Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items. + /// Sets the legend group title for this trace. + /// Sets the opacity of the surface. Please note that in the case of using high `opacity` values for example a value greater than or equal to 0.5 on two surfaces (and 0.25 with four surfaces), an overlay of multiple transparent surfaces may not perfectly be sorted in depth by the webgl API. This behavior may be improved in the near future and is subject to change. + /// Assigns id labels to each datum. These ids for object constancy of data points during animation. Should be an array of strings, not numbers or any other type. + /// Sets the x coordinates. + /// Sets the y coordinates. + /// Sets the z coordinates. + /// Sets the surface color values, used for setting a color scale independent of `z`. + /// Sets the text elements associated with each z value. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Same as `text`. + /// Determines which trace information appear on hover. If `none` or `skip` are set, no information is displayed upon hovering. But, if `none` is set, click and hover events are still fired. + /// Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example "y: %{y}" as well as %{xother}, {%_xother}, {%_xother_}, {%xother_}. When showing info for several points, "xother" will be added to those with different x positions from the first point. An underscore before or after "(x|y)other" will add a space on that side, only when this field is shown. Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. variable `norm` Anything contained in tag `<extra>` is displayed in the secondary box, for example "<extra>{fullData.name}</extra>". To hide the secondary box completely, use an empty tag `<extra></extra>`. + /// Sets the hover text formatting rulefor `x` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `xaxis.hoverformat`. + /// Sets the hover text formatting rulefor `y` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `yaxis.hoverformat`. + /// Sets the hover text formatting rulefor `z` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `zaxis.hoverformat`. + /// Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index. + /// Assigns extra data each datum. This may be useful when listening to hover, click and selection events. Note that, "scatter" traces also appends customdata items in the markers DOM elements + /// Sets a reference between this trace's 3D coordinate system and a 3D scene. If "scene" (the default value), the (x,y,z) coordinates refer to `layout.scene`. If "scene2", the (x,y,z) coordinates refer to `layout.scene2`, and so on. + /// Sets a reference to a shared color axis. References to these shared color axes are "coloraxis", "coloraxis2", "coloraxis3", etc. Settings for these shared color axes are set in the layout, under `layout.coloraxis`, `layout.coloraxis2`, etc. Note that multiple color scales can be linked to the same color axis. + /// Sets the colorbar of this trace. + /// Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `colorscale`. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed. + /// Sets the colorscale. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]`. To control the bounds of the colorscale in color space, use`cmin` and `cmax`. Alternatively, `colorscale` may be a palette name string of the following list: Blackbody,Bluered,Blues,Cividis,Earth,Electric,Greens,Greys,Hot,Jet,Picnic,Portland,Rainbow,RdBu,Reds,Viridis,YlGnBu,YlOrRd. + /// Determines whether or not a colorbar is displayed for this trace. + /// Reverses the color mapping if true. If true, `cmin` will correspond to the last color in the array and `cmax` will correspond to the first color. + /// Determines whether or not the color domain is computed with respect to the input data (here z or surfacecolor) or the bounds set in `cmin` and `cmax` Defaults to `false` when `cmin` and `cmax` are set by the user. + /// Sets the lower bound of the color domain. Value should have the same units as z or surfacecolor and if set, `cmax` must be set as well. + /// Sets the mid-point of the color domain by scaling `cmin` and/or `cmax` to be equidistant to this point. Value should have the same units as z or surfacecolor. Has no effect when `cauto` is `false`. + /// Sets the upper bound of the color domain. Value should have the same units as z or surfacecolor and if set, `cmin` must be set as well. + /// Determines whether or not gaps (i.e. {nan} or missing values) in the `z` data are filled in. + /// Sets the contours of this trace. + /// Determines whether or not a surface is drawn. For example, set `hidesurface` to "false" `contours.x.show` to "true" and `contours.y.show` to "true" to draw a wire frame plot. + /// Sets the hoverlabel style of this trace. + /// Sets the Lighting style of this trace. + /// Sets the LightPosition style of this trace. + /// Sets the opacityscale. The opacityscale must be an array containing arrays mapping a normalized value to an opacity value. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 1], [0.5, 0.2], [1, 1]]` means that higher/lower values would have higher opacity values and those in the middle would be more transparent Alternatively, `opacityscale` may be a palette name string of the following list: 'min', 'max', 'extremes' and 'uniform'. The default is 'uniform'. + /// Sets the calendar system to use with `x` date data. + /// Sets the calendar system to use with `y` date data. + /// Sets the calendar system to use with `z` date data. + /// Controls persistence of some user-driven changes to the trace: `constraintrange` in `parcoords` traces, as well as some `editable: true` modifications such as `name` and `colorbar.title`. Defaults to `layout.uirevision`. Note that other user-driven trace attribute changes are controlled by `layout` attributes: `trace.visible` is controlled by `layout.legend.uirevision`, `selectedpoints` is controlled by `layout.selectionrevision`, and `colorbar.(x|y)` (accessible with `config: {editable: true}`) is controlled by `layout.editrevision`. Trace changes are tracked by `uid`, which only falls back on trace index if no `uid` is provided. So if your app can add/remove traces before the end of the `data` array, such that the same trace has a different index, you can still preserve user-driven changes if you give each trace a `uid` that stays with it as it moves. static member Surface ( - ?Z : seq<#seq<#IConvertible>>, - ?X : seq<#IConvertible>, - ?Y : seq<#IConvertible>, - ?cAuto , - ?cMin , - ?cMax , - ?Colorscale , - ?Autocolorscale : bool, - ?Reversescale : bool, - ?Showscale : bool, - ?ColorBar , - ?Contours , - ?Hidesurface , - ?Lightposition , - ?Lighting , - ?Xcalendar , - ?Ycalendar , - ?Zcalendar , - - ?Zsrc , - ?Xsrc , - ?Ysrc , - ?Surfacecolorsrc - + ?Name : string, + ?Visible : StyleParam.Visible, + ?ShowLegend : bool, + ?LegendRank : int, + ?LegendGroup : string, + ?LegendGroupTitle : Title, + ?Opacity : float, + ?Ids : seq<#IConvertible>, + ?X : seq<#IConvertible>, + ?Y : seq<#IConvertible>, + ?Z : seq<#seq<#IConvertible>>, + ?SurfaceColor : string, + ?Text : seq<#IConvertible>, + ?HoverText : seq<#IConvertible>, + ?HoverInfo : string, + ?HoverTemplate : string, + ?XHoverFormat : string, + ?YHoverFormat : string, + ?ZHoverFormat : string, + ?Meta : string, + ?CustomData : seq<#IConvertible>, + ?Scene : StyleParam.SubPlotId, + ?ColorAxis : StyleParam.SubPlotId, + ?ColorBar : ColorBar, + ?AutoColorScale : bool, + ?ColorScale : StyleParam.Colorscale, + ?ShowScale : bool, + ?ReverseScale : bool, + ?CAuto : bool, + ?CMin : float, + ?CMid : float, + ?CMax : float, + ?ConnectGaps : bool, + ?Contours : Contours, + ?HideSurface : bool, + ?Hoverlabel : Hoverlabel, + ?Lighting : Lighting, + ?LightPosition : LightPosition, + ?OpacityScale : seq<#seq<#IConvertible>>, + ?XCalendar : StyleParam.Calendar, + ?YCalendar : StyleParam.Calendar, + ?ZCalendar : StyleParam.Calendar, + ?UIRevision : string ) = (fun (surface: #Trace) -> - - Z |> DynObj.setValueOpt surface "z" - X |> DynObj.setValueOpt surface "x" - Y |> DynObj.setValueOpt surface "y" - - cAuto |> DynObj.setValueOpt surface "cauto" - cMin |> DynObj.setValueOpt surface "cmin" - cMax |> DynObj.setValueOpt surface "cmax" - Colorscale |> DynObj.setValueOptBy surface "colorscale" StyleParam.Colorscale.convert - Autocolorscale |> DynObj.setValueOpt surface "autocolorscale" - Reversescale |> DynObj.setValueOpt surface "reversescale" - Showscale |> DynObj.setValueOpt surface "showscale" - ColorBar |> DynObj.setValueOpt surface "colorbar" - Contours |> DynObj.setValueOpt surface "contours" - Hidesurface |> DynObj.setValueOpt surface "Hidesurface" - Lightposition |> DynObj.setValueOpt surface "Lightposition" - Lighting |> DynObj.setValueOpt surface "Lighting" - Xcalendar |> DynObj.setValueOpt surface "Xcalendar" - Ycalendar |> DynObj.setValueOpt surface "Ycalendar" - Zcalendar |> DynObj.setValueOpt surface "Zcalendar" - Zsrc |> DynObj.setValueOpt surface "zsrc" - Xsrc |> DynObj.setValueOpt surface "xsrc" - Ysrc |> DynObj.setValueOpt surface "ysrc" - Surfacecolorsrc|> DynObj.setValueOpt surface "surfacecolorsrc" + + Name |> DynObj.setValueOpt surface "name" + Visible |> DynObj.setValueOptBy surface "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt surface "showlegend" + LegendRank |> DynObj.setValueOpt surface "legendrank" + LegendGroup |> DynObj.setValueOpt surface "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt surface "legendgrouptitle" + Opacity |> DynObj.setValueOpt surface "opacity" + Ids |> DynObj.setValueOpt surface "ids" + X |> DynObj.setValueOpt surface "x" + Y |> DynObj.setValueOpt surface "y" + Z |> DynObj.setValueOpt surface "z" + SurfaceColor |> DynObj.setValueOpt surface "surfacecolor" + Text |> DynObj.setValueOpt surface "text" + HoverText |> DynObj.setValueOpt surface "hovertext" + HoverInfo |> DynObj.setValueOpt surface "hoverinfo" + HoverTemplate |> DynObj.setValueOpt surface "hovertemplate" + XHoverFormat |> DynObj.setValueOpt surface "xhoverformat" + YHoverFormat |> DynObj.setValueOpt surface "yhoverformat" + ZHoverFormat |> DynObj.setValueOpt surface "zhoverformat" + Meta |> DynObj.setValueOpt surface "meta" + CustomData |> DynObj.setValueOpt surface "customdata" + Scene |> DynObj.setValueOptBy surface "scene" StyleParam.SubPlotId.convert + ColorAxis |> DynObj.setValueOptBy surface "coloraxis" StyleParam.SubPlotId.convert + ColorBar |> DynObj.setValueOpt surface "colorbar" + AutoColorScale |> DynObj.setValueOpt surface "autocolorscale" + ColorScale |> DynObj.setValueOptBy surface "colorscale" StyleParam.Colorscale.convert + ShowScale |> DynObj.setValueOpt surface "showscale" + ReverseScale |> DynObj.setValueOpt surface "reversescale" + CAuto |> DynObj.setValueOpt surface "cauto" + CMin |> DynObj.setValueOpt surface "cmin" + CMid |> DynObj.setValueOpt surface "cmid" + CMax |> DynObj.setValueOpt surface "cmax" + ConnectGaps |> DynObj.setValueOpt surface "connectgaps" + Contours |> DynObj.setValueOpt surface "contours" + HideSurface |> DynObj.setValueOpt surface "hidesurface" + Hoverlabel |> DynObj.setValueOpt surface "hoverlabel" + Lighting |> DynObj.setValueOpt surface "lighting" + LightPosition |> DynObj.setValueOpt surface "lightposition" + OpacityScale |> DynObj.setValueOpt surface "opacityscale" + XCalendar |> DynObj.setValueOptBy surface "xcalendar" StyleParam.Calendar.convert + YCalendar |> DynObj.setValueOptBy surface "ycalendar" StyleParam.Calendar.convert + ZCalendar |> DynObj.setValueOptBy surface "zcalendar" StyleParam.Calendar.convert + UIRevision |> DynObj.setValueOpt surface "uirevision" - // out -> surface ) diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs b/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs index 37cbf5d09..f3be717d5 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs @@ -117,7 +117,7 @@ let ``Surface charts`` = emptyLayout firstSurfaceChart ); testCase "Second surface data" ( fun () -> - "var data = [{\"type\":\"surface\",\"z\":[[1.0,1.0],[1.0,2.0]],\"x\":[0.0,2.5],\"y\":[0.0,2.5],\"contours\":{\"x\":{\"show\":true},\"y\":{\"show\":true},\"z\":{\"show\":true}},\"opacity\":0.5}];" + """var data = [{"type":"surface","x":[0.0,2.5],"y":[0.0,2.5],"z":[[1.0,1.0],[1.0,2.0]],"contours":{"x":{"show":true},"y":{"show":true},"z":{"show":true}},"opacity":0.5}];""" |> chartGeneratedContains secondSurfaceChart ); testCase "Second surface layout" ( fun () -> From 8b55f510fd095ab65cc581fa5d1888557c63e65d Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Fri, 20 Aug 2021 18:45:29 +0200 Subject: [PATCH 17/21] Add all mesh3d trace parameters --- src/Plotly.NET/Chart.fs | 51 +++++--- src/Plotly.NET/StyleParams.fs | 11 ++ src/Plotly.NET/Trace3d.fs | 233 ++++++++++++++++++++++------------ 3 files changed, 202 insertions(+), 93 deletions(-) diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index 7ce3dcf6c..18d7f697f 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -2079,7 +2079,9 @@ type Chart = /// Uses points, line or both depending on the mode to represent 3d-data points - static member Surface(data:seq<#seq<#IConvertible>>, + static member Surface + ( + zData, [] ?X, [] ?Y, [] ?Name, @@ -2088,30 +2090,49 @@ type Chart = [] ?Contours, [] ?ColorScale, [] ?ShowScale, - [] ?ColorBar) = + [] ?ColorBar + ) = Trace3d.initSurface ( - Trace3dStyle.Surface (Z=data,?X=X, ?Y=Y,?Contours=Contours, - ?ColorScale=ColorScale,?ShowScale=ShowScale,?ColorBar=ColorBar ) ) + Trace3dStyle.Surface( + ?X=X, + ?Y=Y, + Z=zData, + ?Contours=Contours, + ?ColorScale=ColorScale, + ?ShowScale=ShowScale, + ?ColorBar=ColorBar + ) + ) |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity) - //|> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont) |> GenericChart.ofTraceObject /// Uses points, line or both depending on the mode to represent 3d-data points - static member Mesh3d(x, y, z, mode, + static member Mesh3d + ( + x, y, z, + [] ?I, + [] ?J, + [] ?K, [] ?Name, [] ?Showlegend, - [] ?MarkerSymbol, - [] ?Color, [] ?Opacity, - [] ?Labels, - [] ?TextPosition, - [] ?TextFont, - [] ?Dash, - [] ?Width) = - Trace3d.initMesh3d (Trace3dStyle.Mesh3d(X = x,Y = y,Z=z) ) + [] ?Contours, + [] ?ColorScale, + [] ?ShowScale, + [] ?ColorBar + ) = + Trace3d.initMesh3d ( + Trace3dStyle.Mesh3d( + X = x, + Y = y, + Z = z, + ?I = I, + ?J = J, + ?K = K + ) + ) |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity) - |> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont) |> GenericChart.ofTraceObject static member Cone diff --git a/src/Plotly.NET/StyleParams.fs b/src/Plotly.NET/StyleParams.fs index 07af2ff7b..f13804466 100644 --- a/src/Plotly.NET/StyleParams.fs +++ b/src/Plotly.NET/StyleParams.fs @@ -766,6 +766,17 @@ module StyleParam = | JPEG -> "jpeg" static member convert = ImageFormat.toString >> box + + [] + type IntensityMode = + | Vertex | Cell + static member toString = function + | Vertex -> "vertex" + | Cell -> "cell" + + + static member convert = IntensityMode.toString >> box + //-------------------------- // #J# diff --git a/src/Plotly.NET/Trace3d.fs b/src/Plotly.NET/Trace3d.fs index 8d6c57e4d..40f24ef62 100644 --- a/src/Plotly.NET/Trace3d.fs +++ b/src/Plotly.NET/Trace3d.fs @@ -331,88 +331,165 @@ module Trace3d = ) - // Applies the styles to Scatter3d() + /// + /// Applies the style parameters of the mesh3d chart to the given trace + /// + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not this trace is visible. If "legendonly", the trace is not drawn, but can appear as a legend item (provided that the legend itself is visible). + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Sets the legend rank for this trace. Items and groups with smaller ranks are presented on top/left side while with `"reversed" `legend.traceorder` they are on bottom/right side. The default legendrank is 1000, so that you can use ranks less than 1000 to place certain items before all unranked items, and ranks greater than 1000 to go after all unranked items. + /// Sets the legend group for this trace. Traces part of the same legend group hide/show at the same time when toggling legend items. + /// Sets the legend group title for this trace. + /// Sets the opacity of the surface. Please note that in the case of using high `opacity` values for example a value greater than or equal to 0.5 on two surfaces (and 0.25 with four surfaces), an overlay of multiple transparent surfaces may not perfectly be sorted in depth by the webgl API. This behavior may be improved in the near future and is subject to change. + /// Assigns id labels to each datum. These ids for object constancy of data points during animation. Should be an array of strings, not numbers or any other type. + /// Sets the X coordinates of the vertices. The nth element of vectors `x`, `y` and `z` jointly represent the X, Y and Z coordinates of the nth vertex. + /// Sets the Y coordinates of the vertices. The nth element of vectors `x`, `y` and `z` jointly represent the X, Y and Z coordinates of the nth vertex. + /// Sets the Z coordinates of the vertices. The nth element of vectors `x`, `y` and `z` jointly represent the X, Y and Z coordinates of the nth vertex. + /// A vector of vertex indices, i.e. integer values between 0 and the length of the vertex vectors, representing the "first" vertex of a triangle. For example, `{i[m], j[m], k[m]}` together represent face m (triangle m) in the mesh, where `i[m] = n` points to the triplet `{x[n], y[n], z[n]}` in the vertex arrays. Therefore, each element in `i` represents a point in space, which is the first vertex of a triangle. + /// A vector of vertex indices, i.e. integer values between 0 and the length of the vertex vectors, representing the "second" vertex of a triangle. For example, `{i[m], j[m], k[m]}` together represent face m (triangle m) in the mesh, where `j[m] = n` points to the triplet `{x[n], y[n], z[n]}` in the vertex arrays. Therefore, each element in `j` represents a point in space, which is the second vertex of a triangle. + /// A vector of vertex indices, i.e. integer values between 0 and the length of the vertex vectors, representing the "third" vertex of a triangle. For example, `{i[m], j[m], k[m]}` together represent face m (triangle m) in the mesh, where `k[m] = n` points to the triplet `{x[n], y[n], z[n]}` in the vertex arrays. Therefore, each element in `k` represents a point in space, which is the third vertex of a triangle. + /// Sets the color of each face Overrides "color" and "vertexcolor". + /// Sets the intensity values for vertices or cells as defined by `intensitymode`. It can be used for plotting fields on meshes. + /// Determines the source of `intensity` values. + /// Sets the color of each vertex Overrides "color". While Red, green and blue colors are in the range of 0 and 255; in the case of having vertex color data in RGBA format, the alpha color should be normalized to be between 0 and 1. + /// Sets the text elements associated with the vertices. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Same as `text`. + /// Determines which trace information appear on hover. If `none` or `skip` are set, no information is displayed upon hovering. But, if `none` is set, click and hover events are still fired. + /// Template string used for rendering the information that appear on hover box. Note that this will override `hoverinfo`. Variables are inserted using %{variable}, for example "y: %{y}" as well as %{xother}, {%_xother}, {%_xother_}, {%xother_}. When showing info for several points, "xother" will be added to those with different x positions from the first point. An underscore before or after "(x|y)other" will add a space on that side, only when this field is shown. Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example "Price: %{y:$.2f}". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax. The variables available in `hovertemplate` are the ones emitted as event data described at this link https://plotly.com/javascript/plotlyjs-events/#event-data. Additionally, every attributes that can be specified per-point (the ones that are `arrayOk: true`) are available. variable `norm` Anything contained in tag `<extra>` is displayed in the secondary box, for example "<extra>{fullData.name}</extra>". To hide the secondary box completely, use an empty tag `<extra></extra>`. + /// Sets the hover text formatting rulefor `x` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `xaxis.hoverformat`. + /// Sets the hover text formatting rulefor `y` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `yaxis.hoverformat`. + /// Sets the hover text formatting rulefor `z` using d3 formatting mini-languages which are very similar to those in Python. For numbers, see: https://github.com/d3/d3-format/tree/v1.4.5#d3-format. And for dates see: https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format. We add two items to d3's date formatter: "%h" for half of the year as a decimal number as well as "%{n}f" for fractional seconds with n digits. For example, "2016-10-13 09:15:23.456" with tickformat "%H~%M~%S.%2f" would display "09~15~23.46"By default the values are formatted using `zaxis.hoverformat`. + /// Assigns extra meta information associated with this trace that can be used in various text attributes. Attributes such as trace `name`, graph, axis and colorbar `title.text`, annotation `text` `rangeselector`, `updatemenues` and `sliders` `label` text all support `meta`. To access the trace `meta` values in an attribute in the same trace, simply use `%{meta[i]}` where `i` is the index or key of the `meta` item in question. To access trace `meta` in layout attributes, use `%{data[n[.meta[i]}` where `i` is the index or key of the `meta` and `n` is the trace index. + /// Assigns extra data each datum. This may be useful when listening to hover, click and selection events. Note that, "scatter" traces also appends customdata items in the markers DOM elements + /// Sets a reference between this trace's 3D coordinate system and a 3D scene. If "scene" (the default value), the (x,y,z) coordinates refer to `layout.scene`. If "scene2", the (x,y,z) coordinates refer to `layout.scene2`, and so on. + /// Sets a reference to a shared color axis. References to these shared color axes are "coloraxis", "coloraxis2", "coloraxis3", etc. Settings for these shared color axes are set in the layout, under `layout.coloraxis`, `layout.coloraxis2`, etc. Note that multiple color scales can be linked to the same color axis. + /// Sets the colorbar of this trace. + /// Determines whether the colorscale is a default palette (`autocolorscale: true`) or the palette determined by `colorscale`. In case `colorscale` is unspecified or `autocolorscale` is true, the default palette will be chosen according to whether numbers in the `color` array are all positive, all negative or mixed. + /// Sets the colorscale. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, `[[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]`. To control the bounds of the colorscale in color space, use`cmin` and `cmax`. Alternatively, `colorscale` may be a palette name string of the following list: Blackbody,Bluered,Blues,Cividis,Earth,Electric,Greens,Greys,Hot,Jet,Picnic,Portland,Rainbow,RdBu,Reds,Viridis,YlGnBu,YlOrRd. + /// Determines whether or not a colorbar is displayed for this trace. + /// Reverses the color mapping if true. If true, `cmin` will correspond to the last color in the array and `cmax` will correspond to the first color. + /// Determines whether or not the color domain is computed with respect to the input data (here z or surfacecolor) or the bounds set in `cmin` and `cmax` Defaults to `false` when `cmin` and `cmax` are set by the user. + /// Sets the lower bound of the color domain. Value should have the same units as z or surfacecolor and if set, `cmax` must be set as well. + /// Sets the mid-point of the color domain by scaling `cmin` and/or `cmax` to be equidistant to this point. Value should have the same units as z or surfacecolor. Has no effect when `cauto` is `false`. + /// Sets the upper bound of the color domain. Value should have the same units as z or surfacecolor and if set, `cmin` must be set as well. + /// Determines how the mesh surface triangles are derived from the set of vertices (points) represented by the `x`, `y` and `z` arrays, if the `i`, `j`, `k` arrays are not supplied. For general use of `mesh3d` it is preferred that `i`, `j`, `k` are supplied. If "-1", Delaunay triangulation is used, which is mainly suitable if the mesh is a single, more or less layer surface that is perpendicular to `delaunayaxis`. In case the `delaunayaxis` intersects the mesh surface at more than one point it will result triangles that are very long in the dimension of `delaunayaxis`. If ">0", the alpha-shape algorithm is used. In this case, the positive `alphahull` value signals the use of the alpha-shape algorithm, _and_ its value acts as the parameter for the mesh fitting. If "0", the convex-hull algorithm is used. It is suitable for convex bodies or if the intention is to enclose the `x`, `y` and `z` point set into a convex hull. + /// Sets the Delaunay axis, which is the axis that is perpendicular to the surface of the Delaunay triangulation. It has an effect if `i`, `j`, `k` are not provided and `alphahull` is set to indicate Delaunay triangulation. + /// Sets the contour of this trace + /// Determines whether or not normal smoothing is applied to the meshes, creating meshes with an angular, low-poly look via flat reflections. + /// Sets the hoverlabel style of this trace. + /// Sets the Lighting style of this trace. + /// Sets the LightPosition style of this trace. + /// Sets the calendar system to use with `x` date data. + /// Sets the calendar system to use with `y` date data. + /// Sets the calendar system to use with `z` date data. + /// Controls persistence of some user-driven changes to the trace: `constraintrange` in `parcoords` traces, as well as some `editable: true` modifications such as `name` and `colorbar.title`. Defaults to `layout.uirevision`. Note that other user-driven trace attribute changes are controlled by `layout` attributes: `trace.visible` is controlled by `layout.legend.uirevision`, `selectedpoints` is controlled by `layout.selectionrevision`, and `colorbar.(x|y)` (accessible with `config: {editable: true}`) is controlled by `layout.editrevision`. Trace changes are tracked by `uid`, which only falls back on trace index if no `uid` is provided. So if your app can add/remove traces before the end of the `data` array, such that the same trace has a different index, you can still preserve user-driven changes if you give each trace a `uid` that stays with it as it moves. static member Mesh3d ( - ?X : seq<#IConvertible>, - ?Y : seq<#IConvertible>, - ?Z : seq<#IConvertible>, - ?I : seq<#IConvertible>, - ?J : seq<#IConvertible>, - ?K : seq<#IConvertible>, - ?Delaunayaxis : StyleParam.Delaunayaxis, - ?Alphahull , - ?Intensity : seq<#IConvertible>, - ?Vertexcolor , - ?Facecolor , - ?Flatshading , - ?Contour , - ?Colorscale , - ?Autocolorscale , - ?Reversescale , - ?Showscale , - ?ColorBar , - ?Lightposition : LightPosition, - ?Lighting : Lighting, // Obj - ?Scene , - ?Xcalendar , - ?Ycalendar , - ?Zcalendar , - ?Xsrc : string, - ?Ysrc : string, - ?Zsrc : string, - ?Isrc : string, - ?Jsrc : string, - ?Ksrc : string, - ?Intensityscr : string, - ?Vertexcolorscr : string, - ?Facecolorscr : string - - + ?Name : string, + ?Visible : StyleParam.Visible, + ?ShowLegend : bool, + ?LegendRank : int, + ?LegendGroup : string, + ?LegendGroupTitle : Title, + ?Opacity : float, + ?Ids : seq<#IConvertible>, + ?X : seq<#IConvertible>, + ?Y : seq<#IConvertible>, + ?Z : seq<#IConvertible>, + ?I : seq<#IConvertible>, + ?J : seq<#IConvertible>, + ?K : seq<#IConvertible>, + ?FaceColor : seq<#IConvertible>, + ?Intensity : seq<#IConvertible>, + ?IntensityMode : StyleParam.IntensityMode, + ?VertexColor : seq<#IConvertible>, + ?Text : seq<#IConvertible>, + ?HoverText : seq<#IConvertible>, + ?HoverInfo : string, + ?HoverTemplate : string, + ?XHoverFormat : string, + ?YHoverFormat : string, + ?ZHoverFormat : string, + ?Meta : string, + ?CustomData : seq<#IConvertible>, + ?Scene : StyleParam.SubPlotId, + ?ColorAxis : StyleParam.SubPlotId, + ?ColorBar : ColorBar, + ?AutoColorScale : bool, + ?ColorScale : StyleParam.Colorscale, + ?ShowScale : bool, + ?ReverseScale : bool, + ?CAuto : bool, + ?CMin : float, + ?CMid : float, + ?CMax : float, + ?AlphaHull : float, + ?Delaunayaxis : StyleParam.Delaunayaxis, + ?Contour : Contour, + ?FlatShading : bool, + ?Hoverlabel : Hoverlabel, + ?Lighting : Lighting, + ?LightPosition : LightPosition, + ?XCalendar : StyleParam.Calendar, + ?YCalendar : StyleParam.Calendar, + ?ZCalendar : StyleParam.Calendar, + ?UIRevision : string ) = - (fun (mesh3d: #Trace) -> - - X |> DynObj.setValueOpt mesh3d "x" - Y |> DynObj.setValueOpt mesh3d "y" - Z |> DynObj.setValueOpt mesh3d "z" - I |> DynObj.setValueOpt mesh3d "i" - J |> DynObj.setValueOpt mesh3d "j" - K |> DynObj.setValueOpt mesh3d "k" - Alphahull |> DynObj.setValueOpt mesh3d "alphahull " - Intensity |> DynObj.setValueOpt mesh3d "intensity " - Vertexcolor |> DynObj.setValueOpt mesh3d "vertexcolor" - Facecolor |> DynObj.setValueOpt mesh3d "facecolor " - Flatshading |> DynObj.setValueOpt mesh3d "flatshading" - Contour |> DynObj.setValueOpt mesh3d "contour " - - Colorscale |> DynObj.setValueOpt mesh3d "colorscale" - Autocolorscale |> DynObj.setValueOpt mesh3d "autocolorscale" - Reversescale |> DynObj.setValueOpt mesh3d "reversescale" - Showscale |> DynObj.setValueOpt mesh3d "showscale" - ColorBar |> DynObj.setValueOpt mesh3d "colorbar" - Lightposition |> DynObj.setValueOpt mesh3d "lightposition" - Lighting |> DynObj.setValueOpt mesh3d "lighting" - Scene |> DynObj.setValueOpt mesh3d "scene" - Xcalendar |> DynObj.setValueOpt mesh3d "xcalendar" - Ycalendar |> DynObj.setValueOpt mesh3d "ycalendar" - Zcalendar |> DynObj.setValueOpt mesh3d "zcalendar" - - Xsrc |> DynObj.setValueOpt mesh3d "xsrc" - Ysrc |> DynObj.setValueOpt mesh3d "ysrc" - Zsrc |> DynObj.setValueOpt mesh3d "zsrc" - Isrc |> DynObj.setValueOpt mesh3d "isrc" - Jsrc |> DynObj.setValueOpt mesh3d "jsrc" - Ksrc |> DynObj.setValueOpt mesh3d "ksrc" - Intensityscr |> DynObj.setValueOpt mesh3d "intensityscr" - Vertexcolorscr |> DynObj.setValueOpt mesh3d "vertexcolorscr" - Facecolorscr |> DynObj.setValueOpt mesh3d "facecolorscr" - - Delaunayaxis |> DynObj.setValueOptBy mesh3d "delaunayaxis" StyleParam.Delaunayaxis.convert - - // out -> - mesh3d - ) + fun (mesh3d: #Trace) -> + + Name |> DynObj.setValueOpt mesh3d "name" + Visible |> DynObj.setValueOptBy mesh3d "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt mesh3d "showlegend" + LegendRank |> DynObj.setValueOpt mesh3d "legendrank" + LegendGroup |> DynObj.setValueOpt mesh3d "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt mesh3d "legendgrouptitle" + Opacity |> DynObj.setValueOpt mesh3d "opacity" + Ids |> DynObj.setValueOpt mesh3d "ids" + X |> DynObj.setValueOpt mesh3d "x" + Y |> DynObj.setValueOpt mesh3d "y" + Z |> DynObj.setValueOpt mesh3d "z" + I |> DynObj.setValueOpt mesh3d "i" + J |> DynObj.setValueOpt mesh3d "j" + K |> DynObj.setValueOpt mesh3d "k" + FaceColor |> DynObj.setValueOpt mesh3d "facecolor" + Intensity |> DynObj.setValueOpt mesh3d "intensity" + IntensityMode |> DynObj.setValueOptBy mesh3d "intensitymode" StyleParam.IntensityMode.convert + VertexColor |> DynObj.setValueOpt mesh3d "vertexcolor" + Text |> DynObj.setValueOpt mesh3d "text" + HoverText |> DynObj.setValueOpt mesh3d "hovertext" + HoverInfo |> DynObj.setValueOpt mesh3d "hoverinfo" + HoverTemplate |> DynObj.setValueOpt mesh3d "hovertemplate" + XHoverFormat |> DynObj.setValueOpt mesh3d "xhoverformat" + YHoverFormat |> DynObj.setValueOpt mesh3d "yhoverformat" + ZHoverFormat |> DynObj.setValueOpt mesh3d "zhoverformat" + Meta |> DynObj.setValueOpt mesh3d "meta" + CustomData |> DynObj.setValueOpt mesh3d "customdata" + Scene |> DynObj.setValueOptBy mesh3d "scene" StyleParam.SubPlotId.convert + ColorAxis |> DynObj.setValueOptBy mesh3d "coloraxis" StyleParam.SubPlotId.convert + ColorBar |> DynObj.setValueOpt mesh3d "colorbar" + AutoColorScale |> DynObj.setValueOpt mesh3d "autocolorscale" + ColorScale |> DynObj.setValueOptBy mesh3d "colorscale" StyleParam.Colorscale.convert + ShowScale |> DynObj.setValueOpt mesh3d "showscale" + ReverseScale |> DynObj.setValueOpt mesh3d "reversescale" + CAuto |> DynObj.setValueOpt mesh3d "cauto" + CMin |> DynObj.setValueOpt mesh3d "cmin" + CMid |> DynObj.setValueOpt mesh3d "cmid" + CMax |> DynObj.setValueOpt mesh3d "cmax" + AlphaHull |> DynObj.setValueOpt mesh3d "alphahull" + Delaunayaxis |> DynObj.setValueOptBy mesh3d "delaunayaxis" StyleParam.Delaunayaxis.convert + Contour |> DynObj.setValueOpt mesh3d "contour" + FlatShading |> DynObj.setValueOpt mesh3d "flatshading" + Hoverlabel |> DynObj.setValueOpt mesh3d "hoverlabel" + Lighting |> DynObj.setValueOpt mesh3d "lighting" + LightPosition |> DynObj.setValueOpt mesh3d "lightposition" + XCalendar |> DynObj.setValueOptBy mesh3d "xcalendar" StyleParam.Calendar.convert + YCalendar |> DynObj.setValueOptBy mesh3d "ycalendar" StyleParam.Calendar.convert + ZCalendar |> DynObj.setValueOptBy mesh3d "zcalendar" StyleParam.Calendar.convert + UIRevision |> DynObj.setValueOpt mesh3d "uirevision" + + mesh3d + /// /// Applies the style parameters of the cone chart to the given trace From 9940c9ce04778c3e2c5aa8c1931e0b87c4155f2f Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Mon, 23 Aug 2021 13:59:45 +0200 Subject: [PATCH 18/21] Add functions to set the 3D scenes of layouts --- src/Plotly.NET/ChartExtensions.fs | 23 +++++++---- src/Plotly.NET/GenericChartExtensions.fs | 8 +++- src/Plotly.NET/Layout.fs | 22 ++++------ src/Plotly.NET/Playground.fsx | 51 ++++++++++++++++++++++-- 4 files changed, 78 insertions(+), 26 deletions(-) diff --git a/src/Plotly.NET/ChartExtensions.fs b/src/Plotly.NET/ChartExtensions.fs index 1c0af34d1..dc27af652 100644 --- a/src/Plotly.NET/ChartExtensions.fs +++ b/src/Plotly.NET/ChartExtensions.fs @@ -1271,7 +1271,7 @@ module ChartExtensions = static member withPolar(polar:Polar, [] ?Id) = (fun (ch:GenericChart) -> let layout = - let id = defaultArg Id 1 + let id = defaultArg Id (StyleParam.SubPlotId.Polar 1) GenericChart.getLayout ch |> Layout.updatePolarById(id,polar) GenericChart.setLayout layout ch @@ -1283,7 +1283,7 @@ module ChartExtensions = static member withAngularAxis(angularAxis:Axis.AngularAxis, [] ?Id) = (fun (ch:GenericChart) -> - let id = defaultArg Id 1 + let id = defaultArg Id (StyleParam.SubPlotId.Polar 1) let layout = GenericChart.getLayout ch let updatedPolar = @@ -1303,7 +1303,7 @@ module ChartExtensions = [] static member withRadialAxis(radialAxis:Axis.RadialAxis, [] ?Id) = (fun (ch:GenericChart) -> - let id = defaultArg Id 1 + let id = defaultArg Id (StyleParam.SubPlotId.Polar 1) let layout = GenericChart.getLayout ch let updatedPolar = @@ -1319,15 +1319,24 @@ module ChartExtensions = GenericChart.setLayout updatedLayout ch ) - /// Sets the color axis of the color axis with the given id on the chart layout + /// Sets the color axis with the given id on the chart layout [] static member withColorAxis(colorAxis:Axis.ColorAxis, [] ?Id) = (fun (ch:GenericChart) -> let layout = - let id = defaultArg Id 1 + let id = defaultArg Id (StyleParam.SubPlotId.ColorAxis 1) GenericChart.getLayout ch |> Layout.updateColorAxisById(id,colorAxis) - GenericChart.setLayout layout ch + GenericChart.setLayout layout ch ) - + /// Sets the scene with the given id on the chart layout + [] + static member withScene(scene:Scene, [] ?Id) = + (fun (ch:GenericChart) -> + let layout = + let id = defaultArg Id (StyleParam.SubPlotId.Scene 1) + GenericChart.getLayout ch + |> Layout.updateSceneById(id,scene) + GenericChart.setLayout layout ch + ) diff --git a/src/Plotly.NET/GenericChartExtensions.fs b/src/Plotly.NET/GenericChartExtensions.fs index 78664bdf4..690250235 100644 --- a/src/Plotly.NET/GenericChartExtensions.fs +++ b/src/Plotly.NET/GenericChartExtensions.fs @@ -644,4 +644,10 @@ module GenericChartExtensions = /// Sets the color axis of the color axis with the given id on the chart layout [] member this.WithColorAxis(colorAxis:Axis.ColorAxis, [] ?Id) = - this |> Chart.withColorAxis(colorAxis,?Id=Id) \ No newline at end of file + this |> Chart.withColorAxis(colorAxis,?Id=Id) + + /// Sets the scene object with the given id on the chart layout + [] + member this.WithScene(scene:Scene, [] ?Id) = + this |> Chart.withScene(scene,?Id=Id) + diff --git a/src/Plotly.NET/Layout.fs b/src/Plotly.NET/Layout.fs index fb0879855..1894a6034 100644 --- a/src/Plotly.NET/Layout.fs +++ b/src/Plotly.NET/Layout.fs @@ -351,56 +351,50 @@ type Layout() = layout ) - static member tryGetPolarById (id:int) = + static member tryGetPolarById (id:StyleParam.SubPlotId) = (fun (layout:Layout) -> - let key = if id < 2 then "polar" else sprintf "polar%i" id - layout.TryGetTypedValue(key) + layout.TryGetTypedValue(StyleParam.SubPlotId.toString id) ) /// Updates the style of current polar object with given Id. /// If there does not exist a polar object with the given id, sets it with the given polar object static member updatePolarById ( - id : int, + id : StyleParam.SubPlotId, polar : Polar ) = (fun (layout:Layout) -> - let key = if id < 2 then "polar" else sprintf "polar%i" id - let polar' = match layout |> Layout.tryGetPolarById(id) with | Some a -> DynObj.combine (unbox a) polar | None -> polar :> DynamicObj - polar' |> DynObj.setValue layout key + polar' |> DynObj.setValue layout (StyleParam.SubPlotId.toString id) layout ) - static member tryGetColorAxisById (id:int) = + static member tryGetColorAxisById (id:StyleParam.SubPlotId) = (fun (layout:Layout) -> - let key = if id < 2 then "coloraxis" else sprintf "coloraxis%i" id - layout.TryGetTypedValue(key) + layout.TryGetTypedValue(StyleParam.SubPlotId.toString id) ) /// Updates the style of current ColorAxis object with given Id. /// If there does not exist a ColorAxis object with the given id, sets it with the given ColorAxis object static member updateColorAxisById ( - id : int, + id : StyleParam.SubPlotId, colorAxis: Axis.ColorAxis ) = (fun (layout:Layout) -> - let key = if id < 2 then "coloraxis" else sprintf "coloraxis%i" id - let colorAxis' = match layout |> Layout.tryGetColorAxisById(id) with | Some a -> DynObj.combine (unbox a) colorAxis | None -> colorAxis :> DynamicObj - colorAxis |> DynObj.setValue layout key + colorAxis' |> DynObj.setValue layout (StyleParam.SubPlotId.toString id) layout ) diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index f31c41e66..23dcf4653 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -79,11 +79,54 @@ open FSharpAux open System -Chart.Point3d( - [1,2,3; 4,5,6; 7,8,9], - Labels = ["A"; "B"; "C"], - TextPosition = StyleParam.TextPosition.BottomCenter +let scene1 = + Scene.init( + Domain = Domain.init( + Row = 0, + Column = 1 + ) + ) + +let scene2 = + Scene.init( + Domain = Domain.init( + Row = 0, + Column = 3 + ) + ) + +let p1 = + Chart.Point3d( + [1,2,3; 4,5,6; 7,8,9], + Labels = ["A"; "B"; "C"], + TextPosition = StyleParam.TextPosition.BottomCenter + ) + |> GenericChart.mapTrace( + Trace3d.Trace3dStyle.Scatter3d( + Scene = StyleParam.SubPlotId.Scene 1 + ) + ) + +let p2 = + Chart.Point3d( + [1,2,3; 4,5,6; 7,8,9], + Labels = ["A2"; "B2"; "C2"], + TextPosition = StyleParam.TextPosition.BottomCenter + ) + |> GenericChart.mapTrace( + Trace3d.Trace3dStyle.Scatter3d( + Scene = StyleParam.SubPlotId.Scene 2 + ) ) + +let c1 = Chart.Line([1,2; 3,4]) +let c2 = Chart.Line([1,2; 3,4]) + +[c1;p1;c2;p2] +|> Chart.Grid(1,4,Pattern=StyleParam.LayoutGridPattern.Coupled) +|> Chart.withScene(scene1, StyleParam.SubPlotId.Scene 1) +|> Chart.withScene(scene2, StyleParam.SubPlotId.Scene 2) +|> Chart.withSize(1000.,500.) |> Chart.show Chart.Line3d( From 13c3cf2a9185a8759706ff673da2a569246ecc1e Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Mon, 23 Aug 2021 15:01:42 +0200 Subject: [PATCH 19/21] use #Trace as parameter type for all Trace3dStyle function --- src/Plotly.NET/Trace3d.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Plotly.NET/Trace3d.fs b/src/Plotly.NET/Trace3d.fs index 40f24ef62..e9e7ea11e 100644 --- a/src/Plotly.NET/Trace3d.fs +++ b/src/Plotly.NET/Trace3d.fs @@ -730,7 +730,7 @@ module Trace3d = ?UIRevision : seq<#IConvertible> ) = - (fun (streamTube: Trace3d) -> + (fun (streamTube: #Trace) -> Name |> DynObj.setValueOpt streamTube "name" Visible |> DynObj.setValueOptBy streamTube "visible" StyleParam.Visible.convert ShowLegend |> DynObj.setValueOpt streamTube "showlegend" @@ -877,7 +877,7 @@ module Trace3d = ?Surface : Surface, ?UIRevision : seq<#IConvertible> ) = - fun (volume: Trace3d) -> + fun (volume: #Trace) -> Name |> DynObj.setValueOpt volume "name" Visible |> DynObj.setValueOptBy volume "visible" StyleParam.Visible.convert @@ -1026,7 +1026,7 @@ module Trace3d = ?Surface : Surface, ?UIRevision : seq<#IConvertible> ) = - fun (volume: Trace3d) -> + fun (volume: #Trace) -> Name |> DynObj.setValueOpt volume "name" Visible |> DynObj.setValueOptBy volume "visible" StyleParam.Visible.convert From 417e1233c833ded58bdd65dc1fab7c1ffc72d95c Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Mon, 23 Aug 2021 15:02:19 +0200 Subject: [PATCH 20/21] Add 3D chart docs --- docs/3_0_3d-scatter-plots.fsx | 63 +++++++++++--- docs/3_1_3d-line-plots.fsx | 68 --------------- ...ace-plots.fsx => 3_1_3d-surface-plots.fsx} | 2 +- ...d-mesh-plots.fsx => 3_2_3d-mesh-plots.fsx} | 2 +- docs/3_3_3d-cone-charts.fsx | 55 ++++++++++++ docs/3_4_3d-streamtube-plots.fsx | 71 ++++++++++++++++ docs/3_5_3d-volume-plots.fsx | 82 ++++++++++++++++++ docs/3_6_3d-isosurface-plots .fsx | 85 +++++++++++++++++++ 8 files changed, 347 insertions(+), 81 deletions(-) delete mode 100644 docs/3_1_3d-line-plots.fsx rename docs/{3_2_3d-surface-plots.fsx => 3_1_3d-surface-plots.fsx} (99%) rename docs/{3_3_3d-mesh-plots.fsx => 3_2_3d-mesh-plots.fsx} (99%) create mode 100644 docs/3_3_3d-cone-charts.fsx create mode 100644 docs/3_4_3d-streamtube-plots.fsx create mode 100644 docs/3_5_3d-volume-plots.fsx create mode 100644 docs/3_6_3d-isosurface-plots .fsx diff --git a/docs/3_0_3d-scatter-plots.fsx b/docs/3_0_3d-scatter-plots.fsx index aaa083063..0ae0cf22d 100644 --- a/docs/3_0_3d-scatter-plots.fsx +++ b/docs/3_0_3d-scatter-plots.fsx @@ -1,6 +1,6 @@ (** --- -title: 3D Scatter charts +title: 3D point and line charts category: 3D Charts categoryindex: 4 index: 1 @@ -22,25 +22,25 @@ index: 1 #endif // IPYNB (** -# 3D Scatter charts +# 3D point plots [![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 three-dimensional scatter charts in F#. +*Summary:* This example shows how to create three-dimensional point and line charts in F#. A Scatter3d chart report shows a three-dimensional spinnable view of your data *) open Plotly.NET -let x = [19; 26; 55;] -let y = [19; 26; 55;] -let z = [19; 26; 55;] - -let scatter3d = - Chart.Scatter3d(x,y,z,StyleParam.Mode.Markers) +let point3d = + Chart.Point3d( + [1,3,2; 6,5,4; 7,9,8], + Labels = ["A"; "B"; "C"], + TextPosition = StyleParam.TextPosition.BottomCenter + ) |> Chart.withXAxisStyle("my x-axis", Id=StyleParam.SubPlotId.Scene 1) // in contrast to 2D plots, x and y axes of 3D charts have to be set via the scene object |> Chart.withYAxisStyle("my y-axis", Id=StyleParam.SubPlotId.Scene 1) // in contrast to 2D plots, x and y axes of 3D charts have to be set via the scene object |> Chart.withZAxisStyle("my z-axis") @@ -48,12 +48,53 @@ let scatter3d = (*** condition: ipynb ***) #if IPYNB -scatter3d +point3d #endif // IPYNB (***hide***) -scatter3d |> GenericChart.toChartHTML +point3d |> GenericChart.toChartHTML (*** include-it-raw ***) +(** +# 3D Line plots +*) + +let line3d = + Chart.Line3d( + [1,3,2; 6,5,4; 7,9,8], + Labels = ["A"; "B"; "C"], + TextPosition = StyleParam.TextPosition.BottomCenter, + ShowMarkers = true + ) + +(*** condition: ipynb ***) +#if IPYNB +line3d +#endif // IPYNB + +(***hide***) +line3d |> GenericChart.toChartHTML +(*** include-it-raw ***) + +(** +# 3D Bubble plots +*) + +let bubble3d = + Chart.Bubble3d( + [1,3,2; 6,5,4; 7,9,8], + [10;20;30], + Labels = ["A"; "B"; "C"], + TextPosition = StyleParam.TextPosition.BottomCenter + ) + +(*** condition: ipynb ***) +#if IPYNB +bubble3d +#endif // IPYNB + +(***hide***) +bubble3d |> GenericChart.toChartHTML +(*** include-it-raw ***) \ No newline at end of file diff --git a/docs/3_1_3d-line-plots.fsx b/docs/3_1_3d-line-plots.fsx deleted file mode 100644 index 708a61eca..000000000 --- a/docs/3_1_3d-line-plots.fsx +++ /dev/null @@ -1,68 +0,0 @@ -(** ---- -title: 3D line charts -category: 3D Charts -categoryindex: 4 -index: 2 ---- -*) - -(*** 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 - -(** -# 3D line charts - -[![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 three-dimensional scatter charts in F#. - -let's first create some data for the purpose of creating example charts: -*) - -open Plotly.NET -open System - -let c = [0. .. 0.5 .. 15.] - -let x,y,z = - c - |> List.map (fun i -> - let i' = float i - let r = 10. * Math.Cos (i' / 10.) - (r*Math.Cos i',r*Math.Sin i',i') - ) - |> List.unzip3 - -(** -A Scatter3 chart shows a three-dimensional spinnable view of your data. -When using `Lines_Markers` as the mode of the chart, you additionally render a line between the points: -*) - -let scatter3dLine = - Chart.Scatter3d(x,y,z,StyleParam.Mode.Lines_Markers) - |> Chart.withXAxisStyle("x-axis", Id=StyleParam.SubPlotId.Scene 1) // in contrast to 2D plots, x and y axes of 3D charts have to be set via the scene object - |> Chart.withYAxisStyle("y-axis", Id=StyleParam.SubPlotId.Scene 1) // in contrast to 2D plots, x and y axes of 3D charts have to be set via the scene object - |> Chart.withZAxisStyle("z-axis") - |> Chart.withSize(800.,800.) - -(*** condition: ipynb ***) -#if IPYNB -scatter3dLine -#endif // IPYNB - -(***hide***) -scatter3dLine |> GenericChart.toChartHTML -(*** include-it-raw ***) \ No newline at end of file diff --git a/docs/3_2_3d-surface-plots.fsx b/docs/3_1_3d-surface-plots.fsx similarity index 99% rename from docs/3_2_3d-surface-plots.fsx rename to docs/3_1_3d-surface-plots.fsx index 79dc6a6aa..3caac124e 100644 --- a/docs/3_2_3d-surface-plots.fsx +++ b/docs/3_1_3d-surface-plots.fsx @@ -3,7 +3,7 @@ title: 3D surface plots category: 3D Charts categoryindex: 4 -index: 3 +index: 2 --- *) diff --git a/docs/3_3_3d-mesh-plots.fsx b/docs/3_2_3d-mesh-plots.fsx similarity index 99% rename from docs/3_3_3d-mesh-plots.fsx rename to docs/3_2_3d-mesh-plots.fsx index 766573103..d45684b84 100644 --- a/docs/3_3_3d-mesh-plots.fsx +++ b/docs/3_2_3d-mesh-plots.fsx @@ -3,7 +3,7 @@ title: 3D Mesh plots category: 3D Charts categoryindex: 4 -index: 4 +index: 3 --- *) diff --git a/docs/3_3_3d-cone-charts.fsx b/docs/3_3_3d-cone-charts.fsx new file mode 100644 index 000000000..df15f75bf --- /dev/null +++ b/docs/3_3_3d-cone-charts.fsx @@ -0,0 +1,55 @@ +(** +--- +title: 3D Cone plots +category: 3D Charts +categoryindex: 4 +index: 4 +--- +*) + +(*** 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 + +(** +# 3D Cone plots + +[![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 3D-Cone charts in F#. + +*) + +open System +open Plotly.NET + + +let cone = + Chart.Cone( + x = [1; 1; 1], + y = [1; 2; 3], + z = [1; 1; 1], + u = [1; 2; 3], + v = [1; 1; 2], + w = [4; 4; 1] + ) + +(*** condition: ipynb ***) +#if IPYNB +cone +#endif // IPYNB + +(***hide***) +cone |> GenericChart.toChartHTML +(*** include-it-raw ***) diff --git a/docs/3_4_3d-streamtube-plots.fsx b/docs/3_4_3d-streamtube-plots.fsx new file mode 100644 index 000000000..ac01ef418 --- /dev/null +++ b/docs/3_4_3d-streamtube-plots.fsx @@ -0,0 +1,71 @@ +(** +--- +title: 3D streamtube plots +category: 3D Charts +categoryindex: 4 +index: 5 +--- +*) + +(*** 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 + +(** +# 3D Mesh plots + +[![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 3D-StreamTube charts in F#. + +let's first create some data for the purpose of creating example charts: +*) + +#r "nuget: Deedle" +#r "nuget: FSharp.Data" +open Deedle +open FSharp.Data +open System +open Plotly.NET + +let tubeData = + Http.RequestString @"https://raw.githubusercontent.com/plotly/datasets/master/streamtube-wind.csv" + |> Frame.ReadCsvString + +let streamTube = + Chart.StreamTube( + x = (tubeData.["x"] |> Series.values), + y = (tubeData.["y"] |> Series.values), + z = (tubeData.["z"] |> Series.values), + u = (tubeData.["u"] |> Series.values), + v = (tubeData.["v"] |> Series.values), + w = (tubeData.["w"] |> Series.values), + Starts = + StreamTubeStarts.init( + X = Array.init 16 (fun _ -> 80), + Y = [20;30;40;50;20;30;40;50;20;30;40;50;20;30;40;50], + Z = [0;0;0;0;5;5;5;5;10;10;10;10;15;15;15;15] + ), + ColorScale = StyleParam.Colorscale.Viridis + ) + + +(*** condition: ipynb ***) +#if IPYNB +streamTube +#endif // IPYNB + +(***hide***) +streamTube |> GenericChart.toChartHTML +(*** include-it-raw ***) diff --git a/docs/3_5_3d-volume-plots.fsx b/docs/3_5_3d-volume-plots.fsx new file mode 100644 index 000000000..1a1df3ba8 --- /dev/null +++ b/docs/3_5_3d-volume-plots.fsx @@ -0,0 +1,82 @@ +(** +--- +title: 3D Volume plots +category: 3D Charts +categoryindex: 4 +index: 6 +--- +*) + +(*** 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 + +(** +# 3D Volume plots + +[![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 3D-Volume charts in F#. + +let's first create some data for the purpose of creating example charts: +*) + +open System +open Plotly.NET + +let linspace (min,max,n) = + if n <= 2 then failwithf "n needs to be larger then 2" + let bw = float (max - min) / (float n - 1.) + Array.init n (fun i -> min + (bw * float i)) + +let mgrid (min,max,n) = + + let data = linspace(min,max,n) + + let z = [|for i in 1 .. n do [|for i in 1 .. n do yield data|]|] + let x = [|for i in 1 .. n do [|for j in 1 .. n do yield [|for k in 1 .. n do yield data.[i-1]|]|]|] + let y = [|for i in 1 .. n do [|for j in 1 .. n do yield [|for k in 1 .. n do yield data.[j-1]|]|]|] + + x,y,z + +let x,y,z = + mgrid(-8.,8.,40) + |> fun (x,y,z) -> + (x |> Array.concat |> Array.concat), + (y |> Array.concat |> Array.concat), + (z |> Array.concat |> Array.concat) + +let values = + Array.map3 (fun x y z -> + sin(x*y*z) / (x*y*z) + ) x y z + +let volume = + Chart.Volume( + x, y, z, values, + Opacity=0.1, + Surface=(Surface.init(Count=17)), + IsoMin=0.1, + IsoMax=0.8, + ColorScale = StyleParam.Colorscale.Viridis + ) + +(*** condition: ipynb ***) +#if IPYNB +volume +#endif // IPYNB + +(***hide***) +volume |> GenericChart.toChartHTML +(*** include-it-raw ***) diff --git a/docs/3_6_3d-isosurface-plots .fsx b/docs/3_6_3d-isosurface-plots .fsx new file mode 100644 index 000000000..bc5d98e01 --- /dev/null +++ b/docs/3_6_3d-isosurface-plots .fsx @@ -0,0 +1,85 @@ +(** +--- +title: 3D IsoSurface plots +category: 3D Charts +categoryindex: 4 +index: 7 +--- +*) + +(*** 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 + +(** +# 3D IsoSurface plots + +[![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 3D-IsoSurface charts in F#. + +let's first create some data for the purpose of creating example charts: +*) + +open System +open Plotly.NET + +let linspace (min,max,n) = + if n <= 2 then failwithf "n needs to be larger then 2" + let bw = float (max - min) / (float n - 1.) + Array.init n (fun i -> min + (bw * float i)) + +let mgrid (min,max,n) = + + let data = linspace(min,max,n) + + let z = [|for i in 1 .. n do [|for i in 1 .. n do yield data|]|] + let x = [|for i in 1 .. n do [|for j in 1 .. n do yield [|for k in 1 .. n do yield data.[i-1]|]|]|] + let y = [|for i in 1 .. n do [|for j in 1 .. n do yield [|for k in 1 .. n do yield data.[j-1]|]|]|] + + x,y,z + +let xIso,yIso,zIso = + mgrid(-5.,5.,40) + |> fun (x,y,z) -> + (x |> Array.concat |> Array.concat), + (y |> Array.concat |> Array.concat), + (z |> Array.concat |> Array.concat) + +let valueIso = + Array.map3 (fun x y z -> + x * x * 0.5 + y * y + z * z * 2. + ) xIso yIso zIso + +let isoSurface = + Chart.IsoSurface( + xIso,yIso,zIso,valueIso, + IsoMin = 10., + IsoMax = 40., + Caps = Caps.init( + X = (CapFill.init(Show=false)), + Y = (CapFill.init(Show=false)) + ), + Surface = Surface.init(Count=5), + ColorScale = StyleParam.Colorscale.Viridis + ) + +(*** condition: ipynb ***) +#if IPYNB +isoSurface +#endif // IPYNB + +(***hide***) +isoSurface |> GenericChart.toChartHTML +(*** include-it-raw ***) From b65ad7ddc291c3c1878b69bdb26dcdd0e17d1377 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Mon, 23 Aug 2021 15:44:18 +0200 Subject: [PATCH 21/21] Add 3D chart tests --- .../Plotly.NET.Tests/HtmlCodegen/Charts3D.fs | 175 ++++++++++++++++-- 1 file changed, 159 insertions(+), 16 deletions(-) diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs b/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs index f3be717d5..f9d02ea84 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/Charts3D.fs @@ -6,6 +6,23 @@ open TestUtils open Plotly.NET.GenericChart open System +//---------------------- Generate linearly spaced vector ---------------------- +let linspace (min,max,n) = + if n <= 2 then failwithf "n needs to be larger then 2" + let bw = float (max - min) / (float n - 1.) + Array.init n (fun i -> min + (bw * float i)) + +//-------------------- Generate linearly spaced mesh grid --------------------- +let mgrid (min,max,n) = + + let data = linspace(min,max,n) + + let z = [|for i in 1 .. n do [|for i in 1 .. n do yield data|]|] + let x = [|for i in 1 .. n do [|for j in 1 .. n do yield [|for k in 1 .. n do yield data.[i-1]|]|]|] + let y = [|for i in 1 .. n do [|for j in 1 .. n do yield [|for k in 1 .. n do yield data.[j-1]|]|]|] + + x,y,z + let scatterChart = let x = [19; 26; 55;] let y = [19; 26; 55;] @@ -30,6 +47,30 @@ let ``3D Scatter charts`` = ); ] +let pointChart = + let x = [19; 26; 55;] + let y = [19; 26; 55;] + let z = [19; 26; 55;] + + Chart.Point3d(x,y,z) + |> Chart.withXAxisStyle("my x-axis", Id=StyleParam.SubPlotId.Scene 1) + |> Chart.withYAxisStyle("my y-axis", Id=StyleParam.SubPlotId.Scene 1) + |> Chart.withZAxisStyle("my z-axis") + |> Chart.withSize(800.,800.) + +[] +let ``3D Point charts`` = + testList "Charts3D.3D Point charts" [ + testCase "3D Point charts data" ( fun () -> + """var data = [{"type":"scatter3d","mode":"markers","x":[19,26,55],"y":[19,26,55],"z":[19,26,55],"line":{},"marker":{}}]""" + |> chartGeneratedContains pointChart + ); + testCase "3D Point charts layout" ( fun () -> + """var layout = {"scene":{"xaxis":{"title":{"text":"my x-axis"}},"yaxis":{"title":{"text":"my y-axis"}},"zaxis":{"title":{"text":"my z-axis"}}},"width":800.0,"height":800.0};""" + |> chartGeneratedContains pointChart + ); + ] + let lineChart = let c = [0. .. 0.5 .. 15.] @@ -46,13 +87,12 @@ let lineChart = ) |> List.unzip3 - Chart.Scatter3d(x, y, z, StyleParam.Mode.Lines_Markers) + Chart.Line3d(x, y, z, ShowMarkers=true) |> Chart.withXAxisStyle("x-axis", Id=StyleParam.SubPlotId.Scene 1) |> Chart.withYAxisStyle("y-axis", Id=StyleParam.SubPlotId.Scene 1) |> Chart.withZAxisStyle("z-axis") |> Chart.withSize(800., 800.) - [] let ``Line charts`` = testList "Charts3D.Line charts" [ @@ -66,13 +106,33 @@ let ``Line charts`` = ); ] +let bubbleChart = + Chart.Bubble3d( + [1,3,2; 6,5,4; 7,9,8], + [20; 40; 30], + Labels = ["A"; "B"; "C"], + TextPosition = StyleParam.TextPosition.TopLeft + ) + |> Chart.withXAxisStyle("x-axis", Id=StyleParam.SubPlotId.Scene 1) + |> Chart.withYAxisStyle("y-axis", Id=StyleParam.SubPlotId.Scene 1) + |> Chart.withZAxisStyle("z-axis") + +[] +let ``Bubble charts`` = + testList "Charts3D.Bubble charts" [ + testCase "Bubble data" ( fun () -> + """var data = [{"type":"scatter3d","mode":"markers+text","x":[1,6,7],"y":[3,5,9],"z":[2,4,8],"marker":{"size":[20,40,30]},"text":["A","B","C"],"textposition":"top left"}];""" + |> chartGeneratedContains bubbleChart + ); + testCase "Bubble layout" ( fun () -> + """var layout = {"scene":{"xaxis":{"title":{"text":"x-axis"}},"yaxis":{"title":{"text":"y-axis"}},"zaxis":{"title":{"text":"z-axis"}}}};""" + |> chartGeneratedContains bubbleChart + ); + ] + + let firstSurfaceChart = - //---------------------- Generate linearly spaced vector ---------------------- - let linspace (min,max,n) = - if n <= 2 then failwithf "n needs to be larger then 2" - let bw = float (max - min) / (float n - 1.) - Array.init n (fun i -> min + (bw * float i)) - + //---------------------- Create example data ---------------------- let size = 100 let x = linspace(-2. * Math.PI, 2. * Math.PI, size) @@ -127,13 +187,6 @@ let ``Surface charts`` = let meshChart = - let linspace (min,max,n) = - if n <= 2 then failwithf "n needs to be larger then 2" - let bw = float (max - min) / (float n - 1.) - Array.init n (fun i -> min + (bw * float i)) - //[|min ..bw ..max|] - - //---------------------- Create example data ---------------------- let size = 100 let x = linspace(-2. * Math.PI, 2. * Math.PI, size) let y = linspace(-2. * Math.PI, 2. * Math.PI, size) @@ -173,4 +226,94 @@ let ``Mesh charts`` = testCase "Mesh layout" ( fun () -> emptyLayout meshChart ); - ] \ No newline at end of file + ] + +let coneChart = + Chart.Cone( + x = [1; 1; 1], + y = [1; 2; 3], + z = [1; 1; 1], + u = [1; 2; 3], + v = [1; 1; 2], + w = [4; 4; 1], + ColorScale = StyleParam.Colorscale.Viridis + ) + +[] +let ``Cone charts`` = + testList "Charts3D.Cone charts" [ + testCase "Cone data" ( fun () -> + """var data = [{"type":"cone","x":[1,1,1],"y":[1,2,3],"z":[1,1,1],"u":[1,2,3],"v":[1,1,2],"w":[4,4,1],"colorscale":"Viridis"}];""" + |> chartGeneratedContains coneChart + ); + testCase "Cone layout" ( fun () -> + emptyLayout coneChart + ); + ] + +let streamTubeChart = + Chart.StreamTube( + x = [0; 0; 0], + y = [0; 1; 2], + z = [0; 0; 0], + u = [0; 0; 0], + v = [1; 1; 1], + w = [0; 0; 0], + ColorScale = StyleParam.Colorscale.Viridis + ) + +[] +let ``StreamTube charts`` = + testList "StreamTube.Volume charts" [ + testCase "Volume data" ( fun () -> + """var data = [{"type":"streamtube","x":[0,0,0],"y":[0,1,2],"z":[0,0,0],"u":[0,0,0],"v":[1,1,1],"w":[0,0,0],"colorscale":"Viridis"}];""" + |> chartGeneratedContains streamTubeChart + ); + testCase "Volume layout" ( fun () -> + emptyLayout streamTubeChart + ); + ] + +let volumeChart = + let x,y,z = mgrid(1.,2.,4) + Chart.Volume( + x |> Array.concat |> Array.concat |> Array.map (fun x -> Math.Round(x,3)), + y |> Array.concat |> Array.concat |> Array.map (fun x -> Math.Round(x,3)), + z |> Array.concat |> Array.concat |> Array.map (fun x -> Math.Round(x,3)), + z |> Array.concat |> Array.concat |> Array.map (fun x -> Math.Round(x,3)), + ColorScale = StyleParam.Colorscale.Viridis + ) + +[] +let ``Volume charts`` = + testList "Charts3D.Volume charts" [ + testCase "Volume data" ( fun () -> + """var data = [{"type":"volume","x":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0],"y":[1.0,1.0,1.0,1.0,1.333,1.333,1.333,1.333,1.667,1.667,1.667,1.667,2.0,2.0,2.0,2.0,1.0,1.0,1.0,1.0,1.333,1.333,1.333,1.333,1.667,1.667,1.667,1.667,2.0,2.0,2.0,2.0,1.0,1.0,1.0,1.0,1.333,1.333,1.333,1.333,1.667,1.667,1.667,1.667,2.0,2.0,2.0,2.0,1.0,1.0,1.0,1.0,1.333,1.333,1.333,1.333,1.667,1.667,1.667,1.667,2.0,2.0,2.0,2.0],"z":[1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0],"value":[1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0],"colorscale":"Viridis"}];""" + |> chartGeneratedContains volumeChart + ); + testCase "Volume layout" ( fun () -> + emptyLayout volumeChart + ); + ] + +let isoSurfaceChart = + let x,y,z = mgrid(1.,2.,4) + Chart.IsoSurface( + x |> Array.concat |> Array.concat |> Array.map (fun x -> Math.Round(x,3)), + y |> Array.concat |> Array.concat |> Array.map (fun x -> Math.Round(x,3)), + z |> Array.concat |> Array.concat |> Array.map (fun x -> Math.Round(x,3)), + z |> Array.concat |> Array.concat |> Array.map (fun x -> Math.Round(x,3)), + ColorScale = StyleParam.Colorscale.Viridis + ) + +[] +let ``IsoSurface charts`` = + testList "Charts3D.IsoSurface charts" [ + testCase "IsoSurface data" ( fun () -> + """var data = [{"type":"isosurface","x":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.333,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,1.667,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0,2.0],"y":[1.0,1.0,1.0,1.0,1.333,1.333,1.333,1.333,1.667,1.667,1.667,1.667,2.0,2.0,2.0,2.0,1.0,1.0,1.0,1.0,1.333,1.333,1.333,1.333,1.667,1.667,1.667,1.667,2.0,2.0,2.0,2.0,1.0,1.0,1.0,1.0,1.333,1.333,1.333,1.333,1.667,1.667,1.667,1.667,2.0,2.0,2.0,2.0,1.0,1.0,1.0,1.0,1.333,1.333,1.333,1.333,1.667,1.667,1.667,1.667,2.0,2.0,2.0,2.0],"z":[1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0],"value":[1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0,1.0,1.333,1.667,2.0],"colorscale":"Viridis"}];""" + |> chartGeneratedContains isoSurfaceChart + ); + testCase "IsoSurface layout" ( fun () -> + emptyLayout isoSurfaceChart + ); + ]