Skip to content

Commit

Permalink
plotlyjs 2.26: Add "false" option to scaleanchor
Browse files Browse the repository at this point in the history
- Add proper StyleParam for `ScaleAnchor`
  • Loading branch information
kMutagene committed Dec 7, 2023
1 parent bebe507 commit bad6d53
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 19 deletions.
14 changes: 14 additions & 0 deletions src/Plotly.NET/CommonAbstractions/StyleParams.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2661,6 +2661,20 @@ module StyleParam =
// #S#
//--------------------------

[<RequireQualifiedAccess>]
type ScaleAnchor =
| False
| X of int
| Y of int

static member convert =
function
| False -> box false
| X id -> (if id < 2 then "x" else sprintf "x%i" id) |> box
| Y id -> (if id < 2 then "y" else sprintf "y%i" id) |> box

member this.Convert() = this |> ScaleAnchor.convert

[<RequireQualifiedAccess>]
type ScrollZoom =
| Cartesian
Expand Down
14 changes: 7 additions & 7 deletions src/Plotly.NET/Layout/ObjectAbstractions/Common/LinearAxis.fs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type LinearAxis() =
/// <param name="RangeMode">If "normal", the range is computed in relation to the extrema of the input data. If "tozero"`, the range extends to 0, regardless of the input data If "nonnegative", the range is non-negative, regardless of the input data. Applies only to linear axes.</param>
/// <param name="Range">Sets the range of this axis. If the axis `type` is "log", then you must take the log of your desired range (e.g. to set the range from 1 to 100, set the range from 0 to 2). If the axis `type` is "date", it should be date strings, like date data, though Date objects and unix milliseconds will be accepted and converted to strings. If the axis `type` is "category", it should be numbers, using the scale where each category is assigned a serial number from zero in the order it appears.</param>
/// <param name="FixedRange">Determines whether or not this axis is zoom-able. If true, then zoom is disabled.</param>
/// <param name="ScaleAnchor">If set to another axis id (e.g. `x2`, `y`), the range of this axis changes together with the range of the corresponding axis such that the scale of pixels per unit is in a constant ratio. Both axes are still zoomable, but when you zoom one, the other will zoom the same amount, keeping a fixed midpoint. `constrain` and `constraintoward` determine how we enforce the constraint. You can chain these, ie `yaxis: {scaleanchor: "x"}, xaxis2: {scaleanchor: "y"}` but you can only link axes of the same `type`. The linked axis can have the opposite letter (to constrain the aspect ratio) or the same letter (to match scales across subplots). Loops (`yaxis: {scaleanchor: "x"}, xaxis: {scaleanchor: "y"}` or longer) are redundant and the last constraint encountered will be ignored to avoid possible inconsistent constraints via `scaleratio`. Note that setting axes simultaneously in both a `scaleanchor` and a `matches` constraint is currently forbidden.</param>
/// <param name="ScaleAnchor">If set to another axis id (e.g. `x2`, `y`), the range of this axis changes together with the range of the corresponding axis such that the scale of pixels per unit is in a constant ratio. Both axes are still zoomable, but when you zoom one, the other will zoom the same amount, keeping a fixed midpoint. `constrain` and `constraintoward` determine how we enforce the constraint. You can chain these, ie `yaxis: {scaleanchor: "x"}, xaxis2: {scaleanchor: "y"}` but you can only link axes of the same `type`. The linked axis can have the opposite letter (to constrain the aspect ratio) or the same letter (to match scales across subplots). Loops (`yaxis: {scaleanchor: "x"}, xaxis: {scaleanchor: "y"}` or longer) are redundant and the last constraint encountered will be ignored to avoid possible inconsistent constraints via `scaleratio`. Note that setting axes simultaneously in both a `scaleanchor` and a `matches` constraint is currently forbidden. Setting `false` allows to remove a default constraint (occasionally, you may need to prevent a default `scaleanchor` constraint from being applied, eg. when having an image trace `yaxis: {scaleanchor: "x"}` is set automatically in order for pixels to be rendered as squares, setting `yaxis: {scaleanchor: false}` allows to remove the constraint).</param>
/// <param name="ScaleRatio">If this axis is linked to another by `scaleanchor`, this determines the pixel to unit scale ratio. For example, if this value is 10, then every unit on this axis spans 10 times the number of pixels as a unit on the linked axis. Use this for example to create an elevation profile where the vertical scale is exaggerated a fixed amount with respect to the horizontal.</param>
/// <param name="Constrain">If this axis needs to be compressed (either due to its own `scaleanchor` and `scaleratio` or those of the other axis), determines how that happens: by increasing the "range", or by decreasing the "domain". Default is "domain" for axes containing image traces, "range" otherwise.</param>
/// <param name="ConstrainToward">If this axis needs to be compressed (either due to its own `scaleanchor` and `scaleratio` or those of the other axis), determines which direction we push the originally specified plot area. Options are "left", "center" (default), and "right" for x axes, and "top", "middle" (default), and "bottom" for y axes.</param>
Expand Down Expand Up @@ -111,7 +111,7 @@ type LinearAxis() =
[<Optional; DefaultParameterValue(null)>] ?RangeMode: StyleParam.RangeMode,
[<Optional; DefaultParameterValue(null)>] ?Range: StyleParam.Range,
[<Optional; DefaultParameterValue(null)>] ?FixedRange: bool,
[<Optional; DefaultParameterValue(null)>] ?ScaleAnchor: StyleParam.LinearAxisId,
[<Optional; DefaultParameterValue(null)>] ?ScaleAnchor: StyleParam.ScaleAnchor,
[<Optional; DefaultParameterValue(null)>] ?ScaleRatio: float,
[<Optional; DefaultParameterValue(null)>] ?Constrain: StyleParam.AxisConstraint,
[<Optional; DefaultParameterValue(null)>] ?ConstrainToward: StyleParam.AxisConstraintDirection,
Expand Down Expand Up @@ -290,7 +290,7 @@ type LinearAxis() =
/// <param name="RangeMode">If "normal", the range is computed in relation to the extrema of the input data. If "tozero"`, the range extends to 0, regardless of the input data If "nonnegative", the range is non-negative, regardless of the input data. Applies only to linear axes.</param>
/// <param name="Range">Sets the range of this axis. If the axis `type` is "log", then you must take the log of your desired range (e.g. to set the range from 1 to 100, set the range from 0 to 2). If the axis `type` is "date", it should be date strings, like date data, though Date objects and unix milliseconds will be accepted and converted to strings. If the axis `type` is "category", it should be numbers, using the scale where each category is assigned a serial number from zero in the order it appears.</param>
/// <param name="FixedRange">Determines whether or not this axis is zoom-able. If true, then zoom is disabled.</param>
/// <param name="ScaleAnchor">If set to another axis id (e.g. `x2`, `y`), the range of this axis changes together with the range of the corresponding axis such that the scale of pixels per unit is in a constant ratio. Both axes are still zoomable, but when you zoom one, the other will zoom the same amount, keeping a fixed midpoint. `constrain` and `constraintoward` determine how we enforce the constraint. You can chain these, ie `yaxis: {scaleanchor: "x"}, xaxis2: {scaleanchor: "y"}` but you can only link axes of the same `type`. The linked axis can have the opposite letter (to constrain the aspect ratio) or the same letter (to match scales across subplots). Loops (`yaxis: {scaleanchor: "x"}, xaxis: {scaleanchor: "y"}` or longer) are redundant and the last constraint encountered will be ignored to avoid possible inconsistent constraints via `scaleratio`. Note that setting axes simultaneously in both a `scaleanchor` and a `matches` constraint is currently forbidden.</param>
/// <param name="ScaleAnchor">If set to another axis id (e.g. `x2`, `y`), the range of this axis changes together with the range of the corresponding axis such that the scale of pixels per unit is in a constant ratio. Both axes are still zoomable, but when you zoom one, the other will zoom the same amount, keeping a fixed midpoint. `constrain` and `constraintoward` determine how we enforce the constraint. You can chain these, ie `yaxis: {scaleanchor: "x"}, xaxis2: {scaleanchor: "y"}` but you can only link axes of the same `type`. The linked axis can have the opposite letter (to constrain the aspect ratio) or the same letter (to match scales across subplots). Loops (`yaxis: {scaleanchor: "x"}, xaxis: {scaleanchor: "y"}` or longer) are redundant and the last constraint encountered will be ignored to avoid possible inconsistent constraints via `scaleratio`. Note that setting axes simultaneously in both a `scaleanchor` and a `matches` constraint is currently forbidden. Setting `false` allows to remove a default constraint (occasionally, you may need to prevent a default `scaleanchor` constraint from being applied, eg. when having an image trace `yaxis: {scaleanchor: "x"}` is set automatically in order for pixels to be rendered as squares, setting `yaxis: {scaleanchor: false}` allows to remove the constraint).</param>
/// <param name="ScaleRatio">If this axis is linked to another by `scaleanchor`, this determines the pixel to unit scale ratio. For example, if this value is 10, then every unit on this axis spans 10 times the number of pixels as a unit on the linked axis. Use this for example to create an elevation profile where the vertical scale is exaggerated a fixed amount with respect to the horizontal.</param>
/// <param name="Constrain">If this axis needs to be compressed (either due to its own `scaleanchor` and `scaleratio` or those of the other axis), determines how that happens: by increasing the "range", or by decreasing the "domain". Default is "domain" for axes containing image traces, "range" otherwise.</param>
/// <param name="ConstrainToward">If this axis needs to be compressed (either due to its own `scaleanchor` and `scaleratio` or those of the other axis), determines which direction we push the originally specified plot area. Options are "left", "center" (default), and "right" for x axes, and "top", "middle" (default), and "bottom" for y axes.</param>
Expand Down Expand Up @@ -371,7 +371,7 @@ type LinearAxis() =
[<Optional; DefaultParameterValue(null)>] ?RangeMode: StyleParam.RangeMode,
[<Optional; DefaultParameterValue(null)>] ?Range: StyleParam.Range,
[<Optional; DefaultParameterValue(null)>] ?FixedRange: bool,
[<Optional; DefaultParameterValue(null)>] ?ScaleAnchor: StyleParam.LinearAxisId,
[<Optional; DefaultParameterValue(null)>] ?ScaleAnchor: StyleParam.ScaleAnchor,
[<Optional; DefaultParameterValue(null)>] ?ScaleRatio: float,
[<Optional; DefaultParameterValue(null)>] ?Constrain: StyleParam.AxisConstraint,
[<Optional; DefaultParameterValue(null)>] ?ConstrainToward: StyleParam.AxisConstraintDirection,
Expand Down Expand Up @@ -802,7 +802,7 @@ type LinearAxis() =
/// <param name="RangeMode">If "normal", the range is computed in relation to the extrema of the input data. If "tozero"`, the range extends to 0, regardless of the input data If "nonnegative", the range is non-negative, regardless of the input data. Applies only to linear axes.</param>
/// <param name="Range">Sets the range of this axis. If the axis `type` is "log", then you must take the log of your desired range (e.g. to set the range from 1 to 100, set the range from 0 to 2). If the axis `type` is "date", it should be date strings, like date data, though Date objects and unix milliseconds will be accepted and converted to strings. If the axis `type` is "category", it should be numbers, using the scale where each category is assigned a serial number from zero in the order it appears.</param>
/// <param name="FixedRange">Determines whether or not this axis is zoom-able. If true, then zoom is disabled.</param>
/// <param name="ScaleAnchor">If set to another axis id (e.g. `x2`, `y`), the range of this axis changes together with the range of the corresponding axis such that the scale of pixels per unit is in a constant ratio. Both axes are still zoomable, but when you zoom one, the other will zoom the same amount, keeping a fixed midpoint. `constrain` and `constraintoward` determine how we enforce the constraint. You can chain these, ie `yaxis: {scaleanchor: "x"}, xaxis2: {scaleanchor: "y"}` but you can only link axes of the same `type`. The linked axis can have the opposite letter (to constrain the aspect ratio) or the same letter (to match scales across subplots). Loops (`yaxis: {scaleanchor: "x"}, xaxis: {scaleanchor: "y"}` or longer) are redundant and the last constraint encountered will be ignored to avoid possible inconsistent constraints via `scaleratio`. Note that setting axes simultaneously in both a `scaleanchor` and a `matches` constraint is currently forbidden.</param>
/// <param name="ScaleAnchor">If set to another axis id (e.g. `x2`, `y`), the range of this axis changes together with the range of the corresponding axis such that the scale of pixels per unit is in a constant ratio. Both axes are still zoomable, but when you zoom one, the other will zoom the same amount, keeping a fixed midpoint. `constrain` and `constraintoward` determine how we enforce the constraint. You can chain these, ie `yaxis: {scaleanchor: "x"}, xaxis2: {scaleanchor: "y"}` but you can only link axes of the same `type`. The linked axis can have the opposite letter (to constrain the aspect ratio) or the same letter (to match scales across subplots). Loops (`yaxis: {scaleanchor: "x"}, xaxis: {scaleanchor: "y"}` or longer) are redundant and the last constraint encountered will be ignored to avoid possible inconsistent constraints via `scaleratio`. Note that setting axes simultaneously in both a `scaleanchor` and a `matches` constraint is currently forbidden. Setting `false` allows to remove a default constraint (occasionally, you may need to prevent a default `scaleanchor` constraint from being applied, eg. when having an image trace `yaxis: {scaleanchor: "x"}` is set automatically in order for pixels to be rendered as squares, setting `yaxis: {scaleanchor: false}` allows to remove the constraint).</param>
/// <param name="ScaleRatio">If this axis is linked to another by `scaleanchor`, this determines the pixel to unit scale ratio. For example, if this value is 10, then every unit on this axis spans 10 times the number of pixels as a unit on the linked axis. Use this for example to create an elevation profile where the vertical scale is exaggerated a fixed amount with respect to the horizontal.</param>
/// <param name="Constrain">If this axis needs to be compressed (either due to its own `scaleanchor` and `scaleratio` or those of the other axis), determines how that happens: by increasing the "range", or by decreasing the "domain". Default is "domain" for axes containing image traces, "range" otherwise.</param>
/// <param name="ConstrainToward">If this axis needs to be compressed (either due to its own `scaleanchor` and `scaleratio` or those of the other axis), determines which direction we push the originally specified plot area. Options are "left", "center" (default), and "right" for x axes, and "top", "middle" (default), and "bottom" for y axes.</param>
Expand Down Expand Up @@ -907,7 +907,7 @@ type LinearAxis() =
[<Optional; DefaultParameterValue(null)>] ?RangeMode: StyleParam.RangeMode,
[<Optional; DefaultParameterValue(null)>] ?Range: StyleParam.Range,
[<Optional; DefaultParameterValue(null)>] ?FixedRange: bool,
[<Optional; DefaultParameterValue(null)>] ?ScaleAnchor: StyleParam.LinearAxisId,
[<Optional; DefaultParameterValue(null)>] ?ScaleAnchor: StyleParam.ScaleAnchor,
[<Optional; DefaultParameterValue(null)>] ?ScaleRatio: float,
[<Optional; DefaultParameterValue(null)>] ?Constrain: StyleParam.AxisConstraint,
[<Optional; DefaultParameterValue(null)>] ?ConstrainToward: StyleParam.AxisConstraintDirection,
Expand Down Expand Up @@ -1013,7 +1013,7 @@ type LinearAxis() =
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.LinearAxisId.convert
ScaleAnchor |> DynObj.setValueOptBy axis "scaleanchor" StyleParam.ScaleAnchor.convert
ScaleRatio |> DynObj.setValueOpt axis "scaleratio"
Constrain |> DynObj.setValueOptBy axis "constrain" StyleParam.AxisConstraint.convert
ConstrainToward |> DynObj.setValueOptBy axis "constraintoward" StyleParam.AxisConstraintDirection.convert
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,11 @@ module ``New Side options for (legend) titles`` =
)


module ``New scaleanchor option for linear axes`` =
let ``Point chart with scaleanchor=false`` =
Chart.Point([1,2], UseDefaults = false)
|> Chart.withXAxis(
LinearAxis.init(
ScaleAnchor = StyleParam.ScaleAnchor.False
)
)
16 changes: 5 additions & 11 deletions tests/ConsoleApps/FSharpConsole/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,11 @@ open Newtonsoft.Json

[<EntryPoint>]
let main argv =
[
Chart.Point([1,2], UseDefaults = false)
Chart.Point([3,4], UseDefaults = false)
]
|> Chart.combine
|> Chart.withLegendStyle(
Title = Title.init(
Text = "Legend title (top right)",
Side = StyleParam.Side.TopRight
),
Orientation = StyleParam.Orientation.Horizontal
Chart.Point([1,2], UseDefaults = false)
|> Chart.withXAxis(
LinearAxis.init(
ScaleAnchor = StyleParam.ScaleAnchor.False
)
)
|> Chart.show
0
2 changes: 1 addition & 1 deletion tests/CoreTests/CoreTests/LayoutObjects/LinearAxis.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ let fullAxis =
RangeMode = StyleParam.RangeMode.Normal,
Range = StyleParam.Range.MinMax (-1.,1.),
FixedRange = true ,
ScaleAnchor = StyleParam.LinearAxisId.X 1,
ScaleAnchor = StyleParam.ScaleAnchor.X 1,
ScaleRatio = 6.9,
Constrain = StyleParam.AxisConstraint.Range,
ConstrainToward = StyleParam.AxisConstraintDirection.Bottom,
Expand Down
16 changes: 16 additions & 0 deletions tests/CoreTests/CoreTests/UpstreamFeatures/2.26.fs
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,20 @@ module ``New Side options for (legend) titles`` =
|> chartGeneratedContains ``New Side options for (legend) titles``.``Point charts with horizontal legend title top right``
)
]
]

module ``New scaleanchor option for linear axes`` =
[<Tests>]
let ``New ScaleAnchor option`` =
testList "UpstreamFeatures.PlotlyJS_2_26" [
testList "New scaleanchor option for linear axes" [
testCase "scaleanchor=false data" ( fun () ->
"""var data = [{"type":"scatter","mode":"markers","x":[1],"y":[2],"marker":{},"line":{}}];"""
|> chartGeneratedContains ``New scaleanchor option for linear axes``.``Point chart with scaleanchor=false``
)
testCase "scaleanchor=false layout" ( fun () ->
"""var layout = {"xaxis":{"scaleanchor":false}};"""
|> chartGeneratedContains ``New scaleanchor option for linear axes``.``Point chart with scaleanchor=false``
)
]
]

0 comments on commit bad6d53

Please sign in to comment.