diff --git a/Plotly.NET.sln b/Plotly.NET.sln index 1b00bd96d..093037539 100644 --- a/Plotly.NET.sln +++ b/Plotly.NET.sln @@ -1,11 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 +# Visual Studio Version 18 +VisualStudioVersion = 18.5.11709.299 stable MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{BF60BC93-E09B-4E5F-9D85-95A519479D54}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + AGENTS.md = AGENTS.md CITATION.cff = CITATION.cff .config\dotnet-tools.json = .config\dotnet-tools.json LICENSE = LICENSE @@ -135,9 +136,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "04_distribution-charts", "0 docs\distribution-charts\histograms.fsx = docs\distribution-charts\histograms.fsx docs\distribution-charts\pareto-chart.fsx = docs\distribution-charts\pareto-chart.fsx docs\distribution-charts\point-density.fsx = docs\distribution-charts\point-density.fsx + docs\distribution-charts\residual.fsx = docs\distribution-charts\residual.fsx docs\distribution-charts\splom.fsx = docs\distribution-charts\splom.fsx docs\distribution-charts\violin-plots.fsx = docs\distribution-charts\violin-plots.fsx - docs\distribution-charts\residual.fsx = docs\distribution-charts\residual.fsx EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01_chart-layout", "01_chart-layout", "{C7D0EF67-9A18-49DD-AC79-944E384BD8D0}" @@ -169,6 +170,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00_general", "00_general", docs\general\chart-config.fsx = docs\general\chart-config.fsx docs\general\defaults.fsx = docs\general\defaults.fsx docs\general\display-options.fsx = docs\general\display-options.fsx + docs\general\encoded-arrays.fsx = docs\general\encoded-arrays.fsx docs\general\image-export.fsx = docs\general\image-export.fsx docs\general\multi-arguments.fsx = docs\general\multi-arguments.fsx docs\general\styling-markers.fsx = docs\general\styling-markers.fsx diff --git a/docs/3D-charts/3d-isosurface-plots.fsx b/docs/3D-charts/3d-isosurface-plots.fsx index c22436319..82ddcd12f 100644 --- a/docs/3D-charts/3d-isosurface-plots.fsx +++ b/docs/3D-charts/3d-isosurface-plots.fsx @@ -10,8 +10,8 @@ index: 7 (*** hide ***) (*** condition: prepare ***) -#r "nuget: Newtonsoft.JSON, 13.0.1" -#r "nuget: DynamicObj, 2.0.0" +#r "nuget: Newtonsoft.JSON, 13.0.3" +#r "nuget: DynamicObj, 7.0.1" #r "nuget: Giraffe.ViewEngine, 1.4.0" #r "../../src/Plotly.NET/bin/Release/netstandard2.0/Plotly.NET.dll" diff --git a/docs/_head.html b/docs/_head.html index 70ba3ddc6..c8ed8f813 100644 --- a/docs/_head.html +++ b/docs/_head.html @@ -20,6 +20,6 @@ - + \ No newline at end of file diff --git a/docs/_template.ipynb b/docs/_template.ipynb deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/categorical-charts/sankey.fsx b/docs/categorical-charts/sankey.fsx index b7d9a2fab..02e70ea0f 100644 --- a/docs/categorical-charts/sankey.fsx +++ b/docs/categorical-charts/sankey.fsx @@ -79,3 +79,31 @@ sankey1 (***hide***) sankey1 |> GenericChart.toChartHTML (***include-it-raw***) + +(** +## Node alignment + +The `NodeAlign` parameter controls how nodes are aligned horizontally. The available options are +`Left`, `Right`, `Center`, and `Justify` (the default). + +Use the `NodeAlign` parameter on `Chart.Sankey` to apply alignment via the convenience overload, +or pass `Align` to `SankeyNodes.init` directly when building nodes manually: +*) + +let sankeyAligned = + Chart.Sankey( + nodeLabels = [ "Source A"; "Source B"; "Sink" ], + linkedNodeIds = [ 0, 2; 1, 2 ], + linkValues = [ 8; 4 ], + NodeAlign = StyleParam.SankeyNodeAlign.Left, + UseDefaults = false + ) + +(*** condition: ipynb ***) +#if IPYNB +sankeyAligned +#endif // IPYNB + +(***hide***) +sankeyAligned |> GenericChart.toChartHTML +(***include-it-raw***) diff --git a/docs/general/encoded-arrays.fsx b/docs/general/encoded-arrays.fsx new file mode 100644 index 000000000..2fccbe8ff --- /dev/null +++ b/docs/general/encoded-arrays.fsx @@ -0,0 +1,279 @@ +(** +--- +title: Encoded typed arrays +category: General +categoryindex: 1 +index: 10 +--- +*) + +(*** hide ***) + +(*** condition: prepare ***) +#r "nuget: Newtonsoft.JSON, 13.0.3" +#r "nuget: DynamicObj, 7.0.1" +#r "nuget: Giraffe.ViewEngine, 1.4.0" +#r "../../src/Plotly.NET/bin/Release/netstandard2.0/Plotly.NET.dll" + +Plotly.NET.Defaults.DefaultDisplayOptions <- + Plotly.NET.DisplayOptions.init (PlotlyJSReference = Plotly.NET.PlotlyJSReference.NoReference) + +(*** condition: ipynb ***) +#if IPYNB +#r "nuget: Plotly.NET, {{fsdocs-package-version}}" +#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}" +#endif // IPYNB + +(** +# Encoded typed arrays + +[![Binder]({{root}}img/badge-binder.svg)](https://mybinder.org/v2/gh/plotly/plotly.net/gh-pages?urlpath=/tree/home/jovyan/{{fsdocs-source-basename}}.ipynb)  +[![Notebook]({{root}}img/badge-notebook.svg)]({{root}}{{fsdocs-source-basename}}.ipynb) + +*Summary:* This page explains how to use `EncodedTypedArray` for efficient data transfer with plotly.js 2.28+. + +### Table of contents + +- [What are encoded typed arrays?](#What-are-encoded-typed-arrays) +- [Creating EncodedTypedArray values](#Creating-EncodedTypedArray-values) +- [Using encoded arrays with Scatter](#Using-encoded-arrays-with-Scatter) +- [Using encoded arrays with Bar and Column charts](#Using-encoded-arrays-with-Bar-and-Column-charts) +- [Using encoded arrays with Heatmap](#Using-encoded-arrays-with-Heatmap) +- [Using encoded arrays with 3D charts](#Using-encoded-arrays-with-3D-charts) +- [Using encoded arrays with statistical charts](#Using-encoded-arrays-with-statistical-charts) +- [Using encoded arrays for error bars and trace-level styling](#Using-encoded-arrays-for-error-bars-and-trace-level-styling) + +## What are encoded typed arrays? + +plotly.js 2.28.0 introduced support for passing data arrays as **base64-encoded typed arrays** instead of plain JSON arrays. +This format (`bdata`/`dtype`/`shape`) is significantly more compact and faster to parse for large numeric datasets, +since it avoids the overhead of JSON number serialization. + +For example, a float64 array `[1.0, 2.0, 3.0]` transmitted as plain JSON looks like `[1.0,2.0,3.0]`, +while the encoded form is `{"bdata":"AAAAAAAA8D8AAAAAAAAAQA==...","dtype":"f8"}` — smaller and faster to deserialize in the browser. + +Plotly.NET exposes this via the `EncodedTypedArray` type. + +## Creating EncodedTypedArray values + +`EncodedTypedArray` can be constructed from any standard .NET typed array: +*) + +open Plotly.NET + +// Float64 (double) arrays — most common for continuous data +let xEncoded = EncodedTypedArray.ofFloat64Array [| 1.0; 2.0; 3.0; 4.0; 5.0 |] +let yEncoded = EncodedTypedArray.ofFloat64Array [| 2.0; 4.0; 1.0; 5.0; 3.0 |] + +// Int32 arrays — for integer data like indices or counts +let sourceEncoded = EncodedTypedArray.ofInt32Array [| 0; 1; 2 |] + +// Float32 arrays — smaller footprint when full precision is not needed +let valuesEncoded = EncodedTypedArray.ofFloat32Array [| 1.0f; 2.5f; 0.8f |] + +(** +Supported constructors: + +| Constructor | .NET type | plotly.js dtype | +|---|---|---| +| `EncodedTypedArray.ofFloat64Array` | `float[]` | `f8` (64-bit float) | +| `EncodedTypedArray.ofFloat32Array` | `float32[]` | `f4` (32-bit float) | +| `EncodedTypedArray.ofInt32Array` | `int[]` | `i4` (32-bit int) | +| `EncodedTypedArray.ofInt16Array` | `int16[]` | `i2` (16-bit int) | +| `EncodedTypedArray.ofInt8Array` | `sbyte[]` | `i1` (8-bit int) | +| `EncodedTypedArray.ofUInt32Array` | `uint32[]` | `u4` (unsigned 32-bit) | +| `EncodedTypedArray.ofUInt16Array` | `uint16[]` | `u2` (unsigned 16-bit) | +| `EncodedTypedArray.ofUInt8Array` | `byte[]` | `u1` (unsigned 8-bit) | + +## Using encoded arrays with Scatter + +The encoded convenience overload for `Chart.Scatter` takes `xEncoded` and `yEncoded` as required +positional arguments instead of plain `x`/`y` sequences: +*) + +let scatterEncoded = + Chart.Scatter( + xEncoded = EncodedTypedArray.ofFloat64Array [| 1.0; 2.0; 3.0; 4.0; 5.0 |], + yEncoded = EncodedTypedArray.ofFloat64Array [| 2.0; 4.0; 1.0; 5.0; 3.0 |], + mode = StyleParam.Mode.Markers, + Name = "encoded scatter", + UseDefaults = false + ) + +(*** condition: ipynb ***) +#if IPYNB +scatterEncoded +#endif // IPYNB + +(***hide***) +scatterEncoded |> GenericChart.toChartHTML +(***include-it-raw***) + +(** +The same encoded overload is available for `Chart.Point`, `Chart.Line`, `Chart.Bubble`, `Chart.Area`, `Chart.SplineArea`, and `Chart.StackedArea`. + +## Using encoded arrays with Bar and Column charts + +For bar and column charts, the main data array (`values`) is always required and encoded. +The keys array is optional: +*) + +let barEncoded = + Chart.Bar( + valuesEncoded = EncodedTypedArray.ofFloat64Array [| 5.0; 3.0; 7.0; 2.0 |], + KeysEncoded = EncodedTypedArray.ofInt32Array [| 0; 1; 2; 3 |], + Name = "encoded bar" + ) + +(*** condition: ipynb ***) +#if IPYNB +barEncoded +#endif // IPYNB + +(***hide***) +barEncoded |> GenericChart.toChartHTML +(***include-it-raw***) + +(** +The same pattern applies to `Chart.Column`, `Chart.StackedBar`, and `Chart.StackedColumn`. + +## Using encoded arrays with Heatmap + +For heatmaps, the z matrix is required and encoded; x and y axes are optional and encoded. +When `zEncoded` is given as a flat encoded array, `shape` must also be set so plotly.js can reconstruct the matrix: +*) + +let heatmapEncoded = + Chart.Heatmap( + zEncoded = EncodedTypedArray.ofFloat64Array([| 1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0; 8.0; 9.0 |], shape = [ 3; 3 ]), + Name = "encoded heatmap", + UseDefaults = false + ) + +(*** condition: ipynb ***) +#if IPYNB +heatmapEncoded +#endif // IPYNB + +(***hide***) +heatmapEncoded |> GenericChart.toChartHTML +(***include-it-raw***) +(** +Note that for heatmaps the z data is passed as a flat 1D encoded array. plotly.js uses the `shape` field +(rows × columns) to interpret the layout, so `shape` must be specified: + +``` +// Explicit 3x3 shape +let z3x3 = + EncodedTypedArray.ofFloat64Array([| 1.0 .. 9.0 |], shape = [ 3; 3 ]) +``` + +The same `shape` requirement applies to other matrix-style traces such as `Chart.Surface`, `Chart.Contour`, +`Chart.Histogram2D`, and `Chart.Histogram2DContour`. + +## Using encoded arrays with 3D charts + +Encoded typed arrays work the same way on 3D traces. For example, `Chart.Scatter3D` accepts encoded x, y, and z coordinates: +*) + +let scatter3DEncoded = + Chart.Scatter3D( + xEncoded = EncodedTypedArray.ofFloat64Array [| 1.0; 2.0; 3.0 |], + yEncoded = EncodedTypedArray.ofFloat64Array [| 4.0; 5.0; 6.0 |], + zEncoded = EncodedTypedArray.ofFloat64Array [| 7.0; 8.0; 9.0 |], + mode = StyleParam.Mode.Markers, + Name = "encoded scatter3d", + UseDefaults = false + ) + +(*** condition: ipynb ***) +#if IPYNB +scatter3DEncoded +#endif // IPYNB + +(***hide***) +scatter3DEncoded |> GenericChart.toChartHTML +(***include-it-raw***) + +(** +For matrix-based 3D traces such as `Chart.Surface` and `Chart.Volume`, encoded arrays are also supported, +and `shape` must be set wherever plotly.js needs to reconstruct multi-dimensional data from a flat payload. + +## Using encoded arrays with statistical charts + +Distribution and statistical charts support encoded sample arrays as well. Here is a histogram example: +*) + +let histogramEncoded = + Chart.Histogram( + dataEncoded = EncodedTypedArray.ofFloat64Array [| 1.0; 2.0; 2.0; 3.0; 3.0; 3.0; 4.0 |], + orientation = StyleParam.Orientation.Vertical, + Name = "encoded histogram", + UseDefaults = false + ) + +(*** condition: ipynb ***) +#if IPYNB +histogramEncoded +#endif // IPYNB + +(***hide***) +histogramEncoded |> GenericChart.toChartHTML +(***include-it-raw***) + +(** +The same pattern works for `Chart.BoxPlot`, `Chart.Violin`, and finance-style traces such as +`Chart.OHLC` and `Chart.Candlestick`. + +## Using encoded arrays for error bars and trace-level styling + +Some features are available through trace-level styling rather than only through chart-root overloads. +This is especially useful when you want encoded error bars, encoded metadata arrays, or other advanced options: +*) + +open Plotly.NET.TraceObjects + +let scatterWithEncodedErrorBars = + let xErrorEncoded = EncodedTypedArray.ofFloat64Array [| 0.1; 0.2; 0.3 |] + let yErrorEncoded = EncodedTypedArray.ofFloat64Array [| 0.4; 0.5; 0.6 |] + let yErrorMinusEncoded = EncodedTypedArray.ofFloat64Array [| 0.3; 0.2; 0.1 |] + + Trace2D.initScatter( + Trace2DStyle.Scatter( + Name = "encoded scatter + error bars", + Mode = StyleParam.Mode.Lines_Markers, + XEncoded = EncodedTypedArray.ofFloat64Array [| 1.0; 2.0; 3.0 |], + YEncoded = EncodedTypedArray.ofFloat64Array [| 4.0; 5.0; 6.0 |], + XError = + Error.init( + Type = StyleParam.ErrorType.Data, + ArrayEncoded = xErrorEncoded + ), + YError = + Error.init( + Type = StyleParam.ErrorType.Data, + ArrayEncoded = yErrorEncoded, + ArrayminusEncoded = yErrorMinusEncoded + ) + ) + ) + |> GenericChart.ofTraceObject true + |> Chart.withDisplayOptionsStyle(PlotlyJSReference = PlotlyJSReference.NoReference) + +(*** condition: ipynb ***) +#if IPYNB +scatterWithEncodedErrorBars +#endif // IPYNB + +(***hide***) +scatterWithEncodedErrorBars |> GenericChart.toChartHTML +(***include-it-raw***) + +(** +The trace-style modules (`Trace2DStyle`, `Trace3DStyle`, `TraceDomainStyle`, and others) also accept encoded arrays +for many metadata fields such as ids, custom data, selected points, text, dimensions, and trace-specific attributes. + +For more advanced usage including encoded arrays on 3D, domain, and map traces, see the trace-level +style modules (`Trace2DStyle`, `Trace3DStyle`, `TraceDomainStyle`, etc.) which accept `*Encoded` optional parameters +for most data-array fields. +*) diff --git a/docs/general/image-export.fsx b/docs/general/image-export.fsx index 5650d59eb..167cce253 100644 --- a/docs/general/image-export.fsx +++ b/docs/general/image-export.fsx @@ -14,7 +14,7 @@ index: 2 #r "nuget: Newtonsoft.JSON, 13.0.3" #r "nuget: DynamicObj, 7.0.1" #r "nuget: Giraffe.ViewEngine, 1.4.0" -#r "nuget: PuppeteerSharp, 9.0.2" +#r "nuget: PuppeteerSharp, 24.40.0" #r "../../src/Plotly.NET/bin/Release/netstandard2.0/Plotly.NET.dll" #r "../../src/Plotly.NET.ImageExport/bin/Release/netstandard2.0/Plotly.NET.ImageExport.dll" diff --git a/plans/PlotlyJS_2_28_Parity.md b/plans/PlotlyJS_2_28_Parity.md new file mode 100644 index 000000000..503df224d --- /dev/null +++ b/plans/PlotlyJS_2_28_Parity.md @@ -0,0 +1,156 @@ +# plotly.js 2.28.0 Full Parity Plan + +## Summary + +Plotly.NET has been targeting plotly.js 2.28.0 since the bundle was bumped in commit `62a96500`. The bulk of the work — encoded typed array support across all trace types and the F# Chart API — was completed in a long series of commits tracked in [EncodedArraySupport.md](EncodedArraySupport.md). The remaining C# domain-surface gaps were closed afterwards, so this document now serves as a completion record for the 2.28.0 parity work. + +## plotly.js 2.28.0 Release Features + +Source: https://github.com/plotly/plotly.js/releases/tag/v2.28.0 + +### Added + +1. **Sankey node `align`** — horizontal alignment option for sankey nodes ([#6800](https://github.com/plotly/plotly.js/pull/6800)) +2. **Virtual-WebGL** — option to load a `virtual-webgl` script for multiple WebGL 1 contexts ([#6784](https://github.com/plotly/plotly.js/pull/6784)) +3. **Encoded typed arrays** — base64 `bdata`/`dtype`/`shape` object form for data arrays ([#5230](https://github.com/plotly/plotly.js/pull/5230)) + +### Fixed (JS-only, no Plotly.NET surface needed) + +- scattergl rendering on M1 mac +- sankey hover highlighting across multiple traces +- rangeslider drag at x=0 +- duplicated major/minor ticks in calc data +- range defaults respecting `minallowed`/`maxallowed` +- `scattergl` legend with `marker.angle` array +- `scatterpolargl` `line.shape` schema cleanup + +The fixes are JS-runtime-only and do not require Plotly.NET changes — they are resolved by shipping the updated `plotly-2.28.0.min.js` bundle, which is already in place. + +## Final Implementation Status + +| Feature | F# Trace Layer | F# Chart API | C# Wrapper | Tests | Status | +|---------|:-:|:-:|:-:|:-:|---| +| Encoded typed arrays | ✅ | ✅ | ✅ | ✅ 946 passing | Done | +| Sankey node `align` | ✅ | ✅ | ✅ | ✅ | Done | +| Virtual-WebGL | N/A | N/A | N/A | N/A | No surface needed — use `DisplayOptions.AdditionalHeadTags` | +| Sankey encoded arrays (nodes + links) | ✅ | ✅ | ✅ | ✅ | Done | +| ParallelCoord/Categories `keyValuesEncoded` | ✅ | ✅ | ✅ | ✅ | Done | +| Documentation | ✅ | — | — | — | Done | +| Bundled plotly.js 2.28.0 | ✅ | — | — | — | Done | + +## Implemented Items + +### Sankey node `align` property + +Implemented across the F# trace/chart layers and the C# wrapper. + +Scope: + +- add a `SankeyNodeAlign` `StyleParam` enum with values matching plotly.js: `Left`, `Right`, `Center`, `Justify` (plotly.js values: `"left"`, `"right"`, `"center"`, `"justify"`) +- add `?Align: StyleParam.SankeyNodeAlign` to `SankeyNodes.init` and `SankeyNodes.style` +- add `?NodeAlign` to `Chart.Sankey` (F#) and `Chart.Sankey` (C#) forwarding to `SankeyNodes` +- verify the `align` property appears in the plotly.js schema for sankey nodes before settling on the exact enum values + +Files to change: + +- `src/Plotly.NET/CommonAbstractions/StyleParam.fs` — add `SankeyNodeAlign` DU +- `src/Plotly.NET/Traces/ObjectAbstractions/Sankey.fs` — add `?Align` param to `SankeyNodes` +- `src/Plotly.NET/ChartAPI/ChartDomain/ChartDomain_Relations.fs` — add `?NodeAlign` to `Chart.Sankey` +- `src/Plotly.NET.CSharp/ChartAPI/ChartDomain.cs` — expose `NodeAlign` on the higher-level C# `Chart.Sankey` helper + +Tests: + +- add a test fixture in `tests/Common/FSharpTestBase/TestCharts/UpstreamFeatures/2.28.fs` +- add assertions in `tests/CoreTests/CoreTests/UpstreamFeatures/2.28.fs` +- verify serialization produces `"node": { "align": "right" }` + +### Virtual-WebGL + +No dedicated Plotly.NET surface was needed. Users can inject the `virtual-webgl` script through `DisplayOptions.AdditionalHeadTags`, which is sufficient for the plotly.js integration model. + +### Sankey encoded arrays at Chart API level + +Implemented on the trace layer, F# chart layer, and exposed to C# through the wrapper surface. + +Scope: + +- design encoded array support for `SankeyNodes` and `SankeyLinks`: + - add `?LabelEncoded`, `?ColorEncoded`, `?XEncoded`, `?YEncoded`, `?CustomDataEncoded` to `SankeyNodes.init`/`SankeyNodes.style` + - add `?SourceEncoded`, `?TargetEncoded`, `?ValueEncoded`, `?LabelEncoded`, `?ColorEncoded`, `?CustomDataEncoded` to `SankeyLinks.init`/`SankeyLinks.style` +- add an encoded `Chart.Sankey` overload that accepts nodes/links built with encoded arrays +- add tests + +Files to change: + +- `src/Plotly.NET/Traces/ObjectAbstractions/Sankey.fs` +- `src/Plotly.NET/ChartAPI/ChartDomain/ChartDomain_Relations.fs` +- `src/Plotly.NET.CSharp/ChartAPI/ChartDomain.cs` +- test fixtures and assertions in upstream 2.28 test files + +### ParallelCoord / ParallelCategories `keyValuesEncoded` convenience + +Implemented on the F# chart layer and mirrored to C#. + +Scope: + +- add `Chart.ParallelCoord(keyValuesEncoded = ...)` and `Chart.ParallelCategories(keyValuesEncoded = ...)` overloads +- delegate to existing `Dimension.initParallel(ValuesEncoded = ...)` internally +- add tests + +### C# surface projection (Phase H3) + +Implemented. The foundational encoded chart roots were added earlier, and the missing domain helpers were completed by adding: + +- C# `Chart.Sankey(..., NodeAlign, ...)` +- C# `Chart.ParallelCoord(IEnumerable<(string, EncodedTypedArray)> keyValuesEncoded, ...)` +- C# `Chart.ParallelCategories(IEnumerable<(string, EncodedTypedArray)> keyValuesEncoded, ...)` + +Scope: + +- mirror the finalized F# encoded overloads into `Plotly.NET.CSharp` +- focus on foundational chart roots first: + - `Chart.Scatter`, `Chart.Bar`, `Chart.Histogram`, `Chart.Heatmap`, `Chart.Scatter3D`, etc. +- avoid duplicating every convenience overload — only add C# encoded overloads for the most commonly used chart types +- validate through the existing core build/test targets + +Files to change: + +- `src/Plotly.NET.CSharp/ChartAPI/Chart2D.cs` +- `src/Plotly.NET.CSharp/ChartAPI/Chart3D.cs` +- `src/Plotly.NET.CSharp/ChartAPI/ChartDomain.cs` +- `src/Plotly.NET.CSharp/ChartAPI/ChartMap.cs` +- `src/Plotly.NET.CSharp/ChartAPI/ChartPolar.cs` +- `src/Plotly.NET.CSharp/ChartAPI/ChartSmith.cs` +- `src/Plotly.NET.CSharp/ChartAPI/ChartTernary.cs` +- `src/Plotly.NET.CSharp/ChartAPI/ChartCarpet.cs` +- documentation and release notes + +### Documentation updates + +Implemented. + +Scope: + +- add a new doc page (e.g. `docs/general/encoded-arrays.fsx`) showing how to use `EncodedTypedArray` with common chart types +- update the Sankey docs page to show the `align` property +- mention 2.28.0 features in `RELEASE_NOTES.md` for the upcoming version + +## Outcome + +Plotly.NET now has full planned parity with plotly.js 2.28.0: + +- bundled plotly.js 2.28.0 runtime +- encoded typed arrays across trace layers and chart APIs +- Sankey node alignment +- encoded Sankey node/link support +- encoded ParallelCoord/ParallelCategories convenience overloads +- C# wrapper coverage for the parity surface +- docs and release notes + +## Verification + +Verified in repo: + +- `.\build.cmd runTestsCore` passes +- upstream 2.28 fixtures are present and green in the core suite +- the C# wrapper builds successfully with the completed domain bindings diff --git a/src/Plotly.NET.CSharp/ChartAPI/Chart2D.cs b/src/Plotly.NET.CSharp/ChartAPI/Chart2D.cs index c8766e6b2..4d8e110ba 100644 --- a/src/Plotly.NET.CSharp/ChartAPI/Chart2D.cs +++ b/src/Plotly.NET.CSharp/ChartAPI/Chart2D.cs @@ -2750,6 +2750,413 @@ public static GenericChart PointDensity( UseDefaults: UseDefaults.ToOption() ); + // ---- Encoded array overloads ---- + + /// Creates a Scatter plot from encoded x and y typed arrays. + /// Sets the x coordinates as an encoded typed array. + /// Sets the y coordinates as an encoded typed array. + /// Determines the drawing mode for this scatter trace. + /// If set to false, ignore the global default settings set in Defaults + public static GenericChart Scatter( + EncodedTypedArray xEncoded, + EncodedTypedArray yEncoded, + StyleParam.Mode mode, + Optional Name = default, + Optional ShowLegend = default, + Optional Opacity = default, + Optional> MultiOpacity = default, + Optional Text = default, + Optional> MultiText = default, + Optional TextPosition = default, + Optional> MultiTextPosition = default, + Optional MarkerColor = default, + Optional MarkerColorScale = default, + Optional MarkerOutline = default, + Optional MarkerSymbol = default, + Optional> MultiMarkerSymbol = default, + Optional Marker = default, + Optional LineColor = default, + Optional LineColorScale = default, + Optional LineWidth = default, + Optional LineDash = default, + Optional Line = default, + Optional AlignmentGroup = default, + Optional OffsetGroup = default, + Optional StackGroup = default, + Optional Orientation = default, + Optional GroupNorm = default, + Optional Fill = default, + Optional FillColor = default, + Optional FillPattern = default, + Optional UseWebGL = default, + Optional UseDefaults = default + ) + where TextType : IConvertible + => + Plotly.NET.Chart2D_Scatter.Chart.Scatter( + xEncoded: xEncoded, + yEncoded: yEncoded, + mode: mode, + Name: Name.ToOption(), + ShowLegend: ShowLegend.ToOption(), + Opacity: Opacity.ToOption(), + MultiOpacity: MultiOpacity.ToOption(), + Text: Text.ToOption(), + MultiText: MultiText.ToOption(), + TextPosition: TextPosition.ToOption(), + MultiTextPosition: MultiTextPosition.ToOption(), + MarkerColor: MarkerColor.ToOption(), + MarkerColorScale: MarkerColorScale.ToOption(), + MarkerOutline: MarkerOutline.ToOption(), + MarkerSymbol: MarkerSymbol.ToOption(), + MultiMarkerSymbol: MultiMarkerSymbol.ToOption(), + Marker: Marker.ToOption(), + LineColor: LineColor.ToOption(), + LineColorScale: LineColorScale.ToOption(), + LineWidth: LineWidth.ToOption(), + LineDash: LineDash.ToOption(), + Line: Line.ToOption(), + AlignmentGroup: AlignmentGroup.ToOption(), + OffsetGroup: OffsetGroup.ToOption(), + StackGroup: StackGroup.ToOption(), + Orientation: Orientation.ToOption(), + GroupNorm: GroupNorm.ToOption(), + Fill: Fill.ToOption(), + FillColor: FillColor.ToOption(), + FillPattern: FillPattern.ToOption(), + UseWebGL: UseWebGL.ToOption(), + UseDefaults: UseDefaults.ToOption() + ); + + /// Creates a bar chart from encoded values, with bars plotted horizontally. + /// Sets the bar lengths as an encoded typed array. + /// Sets the bar keys as an encoded typed array. + /// Sets where the bar base is drawn (in position axis units). + /// Sets the bar width (in position axis units) of all bars. + /// If set to false, ignore the global default settings set in Defaults + public static GenericChart Bar( + EncodedTypedArray valuesEncoded, + Optional KeysEncoded = default, + Optional Name = default, + Optional ShowLegend = default, + Optional Opacity = default, + Optional> MultiOpacity = default, + Optional Text = default, + Optional> MultiText = default, + Optional MarkerColor = default, + Optional MarkerColorScale = default, + Optional MarkerOutline = default, + Optional MarkerPatternShape = default, + Optional> MultiMarkerPatternShape = default, + Optional MarkerPattern = default, + Optional Marker = default, + Optional Base = default, + Optional Width = default, + Optional MultiWidthEncoded = default, + Optional TextPosition = default, + Optional> MultiTextPosition = default, + Optional UseDefaults = default + ) + where TextType : IConvertible + where BaseType : IConvertible + where WidthType : IConvertible + => + Plotly.NET.Chart2D_Bar.Chart.Bar( + valuesEncoded: valuesEncoded, + KeysEncoded: KeysEncoded.ToOption(), + Name: Name.ToOption(), + ShowLegend: ShowLegend.ToOption(), + Opacity: Opacity.ToOption(), + MultiOpacity: MultiOpacity.ToOption(), + Text: Text.ToOption(), + MultiText: MultiText.ToOption(), + MarkerColor: MarkerColor.ToOption(), + MarkerColorScale: MarkerColorScale.ToOption(), + MarkerOutline: MarkerOutline.ToOption(), + MarkerPatternShape: MarkerPatternShape.ToOption(), + MultiMarkerPatternShape: MultiMarkerPatternShape.ToOption(), + MarkerPattern: MarkerPattern.ToOption(), + Marker: Marker.ToOption(), + Base: Base.ToOption(), + Width: Width.ToOption(), + MultiWidthEncoded: MultiWidthEncoded.ToOption(), + TextPosition: TextPosition.ToOption(), + MultiTextPosition: MultiTextPosition.ToOption(), + UseDefaults: UseDefaults.ToOption() + ); + + /// Creates a stacked bar chart from encoded values, with bars plotted horizontally. + /// Sets the bar lengths as an encoded typed array. + /// Sets the bar keys as an encoded typed array. + /// Sets where the bar base is drawn (in position axis units). + /// Sets the bar width (in position axis units) of all bars. + /// If set to false, ignore the global default settings set in Defaults + public static GenericChart StackedBar( + EncodedTypedArray valuesEncoded, + Optional KeysEncoded = default, + Optional Name = default, + Optional ShowLegend = default, + Optional Opacity = default, + Optional> MultiOpacity = default, + Optional Text = default, + Optional> MultiText = default, + Optional MarkerColor = default, + Optional MarkerColorScale = default, + Optional MarkerOutline = default, + Optional MarkerPatternShape = default, + Optional> MultiMarkerPatternShape = default, + Optional MarkerPattern = default, + Optional Marker = default, + Optional Base = default, + Optional Width = default, + Optional MultiWidthEncoded = default, + Optional TextPosition = default, + Optional> MultiTextPosition = default, + Optional UseDefaults = default + ) + where TextType : IConvertible + where BaseType : IConvertible + where WidthType : IConvertible + => + Plotly.NET.Chart2D_Bar.Chart.StackedBar( + valuesEncoded: valuesEncoded, + KeysEncoded: KeysEncoded.ToOption(), + Name: Name.ToOption(), + ShowLegend: ShowLegend.ToOption(), + Opacity: Opacity.ToOption(), + MultiOpacity: MultiOpacity.ToOption(), + Text: Text.ToOption(), + MultiText: MultiText.ToOption(), + MarkerColor: MarkerColor.ToOption(), + MarkerColorScale: MarkerColorScale.ToOption(), + MarkerOutline: MarkerOutline.ToOption(), + MarkerPatternShape: MarkerPatternShape.ToOption(), + MultiMarkerPatternShape: MultiMarkerPatternShape.ToOption(), + MarkerPattern: MarkerPattern.ToOption(), + Marker: Marker.ToOption(), + Base: Base.ToOption(), + Width: Width.ToOption(), + MultiWidthEncoded: MultiWidthEncoded.ToOption(), + TextPosition: TextPosition.ToOption(), + MultiTextPosition: MultiTextPosition.ToOption(), + UseDefaults: UseDefaults.ToOption() + ); + + /// Creates a column chart from encoded values, with bars plotted vertically. + /// Sets the bar lengths as an encoded typed array. + /// Sets the bar keys as an encoded typed array. + /// Sets where the bar base is drawn (in position axis units). + /// Sets the bar width (in position axis units) of all bars. + /// If set to false, ignore the global default settings set in Defaults + public static GenericChart Column( + EncodedTypedArray valuesEncoded, + Optional KeysEncoded = default, + Optional Name = default, + Optional ShowLegend = default, + Optional Opacity = default, + Optional> MultiOpacity = default, + Optional Text = default, + Optional> MultiText = default, + Optional MarkerColor = default, + Optional MarkerColorScale = default, + Optional MarkerOutline = default, + Optional MarkerPatternShape = default, + Optional> MultiMarkerPatternShape = default, + Optional MarkerPattern = default, + Optional Marker = default, + Optional Base = default, + Optional Width = default, + Optional MultiWidthEncoded = default, + Optional TextPosition = default, + Optional> MultiTextPosition = default, + Optional UseDefaults = default + ) + where TextType : IConvertible + where BaseType : IConvertible + where WidthType : IConvertible + => + Plotly.NET.Chart2D_Bar.Chart.Column( + valuesEncoded: valuesEncoded, + KeysEncoded: KeysEncoded.ToOption(), + Name: Name.ToOption(), + ShowLegend: ShowLegend.ToOption(), + Opacity: Opacity.ToOption(), + MultiOpacity: MultiOpacity.ToOption(), + Text: Text.ToOption(), + MultiText: MultiText.ToOption(), + MarkerColor: MarkerColor.ToOption(), + MarkerColorScale: MarkerColorScale.ToOption(), + MarkerOutline: MarkerOutline.ToOption(), + MarkerPatternShape: MarkerPatternShape.ToOption(), + MultiMarkerPatternShape: MultiMarkerPatternShape.ToOption(), + MarkerPattern: MarkerPattern.ToOption(), + Marker: Marker.ToOption(), + Base: Base.ToOption(), + Width: Width.ToOption(), + MultiWidthEncoded: MultiWidthEncoded.ToOption(), + TextPosition: TextPosition.ToOption(), + MultiTextPosition: MultiTextPosition.ToOption(), + UseDefaults: UseDefaults.ToOption() + ); + + /// Creates a stacked column chart from encoded values, with bars plotted vertically. + /// Sets the bar lengths as an encoded typed array. + /// Sets the bar keys as an encoded typed array. + /// Sets where the bar base is drawn (in position axis units). + /// Sets the bar width (in position axis units) of all bars. + /// If set to false, ignore the global default settings set in Defaults + public static GenericChart StackedColumn( + EncodedTypedArray valuesEncoded, + Optional KeysEncoded = default, + Optional Name = default, + Optional ShowLegend = default, + Optional Opacity = default, + Optional> MultiOpacity = default, + Optional Text = default, + Optional> MultiText = default, + Optional MarkerColor = default, + Optional MarkerColorScale = default, + Optional MarkerOutline = default, + Optional MarkerPatternShape = default, + Optional> MultiMarkerPatternShape = default, + Optional MarkerPattern = default, + Optional Marker = default, + Optional Base = default, + Optional Width = default, + Optional MultiWidthEncoded = default, + Optional TextPosition = default, + Optional> MultiTextPosition = default, + Optional UseDefaults = default + ) + where TextType : IConvertible + where BaseType : IConvertible + where WidthType : IConvertible + => + Plotly.NET.Chart2D_Bar.Chart.StackedColumn( + valuesEncoded: valuesEncoded, + KeysEncoded: KeysEncoded.ToOption(), + Name: Name.ToOption(), + ShowLegend: ShowLegend.ToOption(), + Opacity: Opacity.ToOption(), + MultiOpacity: MultiOpacity.ToOption(), + Text: Text.ToOption(), + MultiText: MultiText.ToOption(), + MarkerColor: MarkerColor.ToOption(), + MarkerColorScale: MarkerColorScale.ToOption(), + MarkerOutline: MarkerOutline.ToOption(), + MarkerPatternShape: MarkerPatternShape.ToOption(), + MultiMarkerPatternShape: MultiMarkerPatternShape.ToOption(), + MarkerPattern: MarkerPattern.ToOption(), + Marker: Marker.ToOption(), + Base: Base.ToOption(), + Width: Width.ToOption(), + MultiWidthEncoded: MultiWidthEncoded.ToOption(), + TextPosition: TextPosition.ToOption(), + MultiTextPosition: MultiTextPosition.ToOption(), + UseDefaults: UseDefaults.ToOption() + ); + + /// Creates a heatmap from encoded z data and optional encoded axes. + /// Sets the z matrix as an encoded typed array. + /// Sets the x coordinates as an encoded typed array. + /// Sets the y coordinates as an encoded typed array. + /// If set to false, ignore the global default settings set in Defaults + public static GenericChart Heatmap( + EncodedTypedArray zEncoded, + Optional xEncoded = default, + Optional yEncoded = default, + Optional Name = default, + Optional ShowLegend = default, + Optional Opacity = default, + Optional XGap = default, + Optional YGap = default, + Optional Text = default, + Optional> MultiText = default, + Optional ColorBar = default, + Optional ColorScale = default, + Optional ShowScale = default, + Optional ReverseScale = default, + Optional ZSmooth = default, + Optional Transpose = default, + Optional UseWebGL = default, + Optional ReverseYAxis = default, + Optional UseDefaults = default + ) + where TextType : IConvertible + => + Plotly.NET.Chart2D_Heatmap.Chart.Heatmap( + zEncoded: zEncoded, + xEncoded: xEncoded.ToOption(), + yEncoded: yEncoded.ToOption(), + Name: Name.ToOption(), + ShowLegend: ShowLegend.ToOption(), + Opacity: Opacity.ToOption(), + XGap: XGap.ToOption(), + YGap: YGap.ToOption(), + Text: Text.ToOption(), + MultiText: MultiText.ToOption(), + ColorBar: ColorBar.ToOption(), + ColorScale: ColorScale.ToOption(), + ShowScale: ShowScale.ToOption(), + ReverseScale: ReverseScale.ToOption(), + ZSmooth: ZSmooth.ToOption(), + Transpose: Transpose.ToOption(), + UseWebGL: UseWebGL.ToOption(), + ReverseYAxis: ReverseYAxis.ToOption(), + UseDefaults: UseDefaults.ToOption() + ); + + /// Creates a 2D histogram from encoded x and y data. + /// Sets the x sample data as an encoded typed array. + /// Sets the y sample data as an encoded typed array. + /// Sets the z aggregation data as an encoded typed array. + /// If set to false, ignore the global default settings set in Defaults + public static GenericChart Histogram2D( + EncodedTypedArray xEncoded, + EncodedTypedArray yEncoded, + Optional zEncoded = default, + Optional Name = default, + Optional ShowLegend = default, + Optional Opacity = default, + Optional XGap = default, + Optional YGap = default, + Optional HistFunc = default, + Optional HistNorm = default, + Optional NBinsX = default, + Optional NBinsY = default, + Optional XBins = default, + Optional YBins = default, + Optional ColorBar = default, + Optional ColorScale = default, + Optional ShowScale = default, + Optional ReverseScale = default, + Optional ZSmooth = default, + Optional UseDefaults = default + ) + => + Plotly.NET.Chart2D_Histogram.Chart.Histogram2D( + xEncoded: xEncoded, + yEncoded: yEncoded, + zEncoded: zEncoded.ToOption(), + Name: Name.ToOption(), + ShowLegend: ShowLegend.ToOption(), + Opacity: Opacity.ToOption(), + XGap: XGap.ToOption(), + YGap: YGap.ToOption(), + HistFunc: HistFunc.ToOption(), + HistNorm: HistNorm.ToOption(), + NBinsX: NBinsX.ToOption(), + NBinsY: NBinsY.ToOption(), + XBins: XBins.ToOption(), + YBins: YBins.ToOption(), + ColorBar: ColorBar.ToOption(), + ColorScale: ColorScale.ToOption(), + ShowScale: ShowScale.ToOption(), + ReverseScale: ReverseScale.ToOption(), + ZSmooth: ZSmooth.ToOption(), + UseDefaults: UseDefaults.ToOption() + ); + }; } diff --git a/src/Plotly.NET.CSharp/ChartAPI/Chart3D.cs b/src/Plotly.NET.CSharp/ChartAPI/Chart3D.cs index a5b78bd41..0a269c608 100644 --- a/src/Plotly.NET.CSharp/ChartAPI/Chart3D.cs +++ b/src/Plotly.NET.CSharp/ChartAPI/Chart3D.cs @@ -845,6 +845,74 @@ public static GenericChart IsoSurface( Camera: Camera.ToOption(), UseDefaults: UseDefaults.ToOption() ); + // ---- Encoded array overloads ---- + + /// Creates a Scatter3D plot from encoded x, y, and z typed arrays. + /// Sets the x coordinates as an encoded typed array. + /// Sets the y coordinates as an encoded typed array. + /// Sets the z coordinates as an encoded typed array. + /// Determines the drawing mode for this scatter trace. + /// If set to false, ignore the global default settings set in Defaults + public static GenericChart Scatter3D( + EncodedTypedArray xEncoded, + EncodedTypedArray yEncoded, + EncodedTypedArray zEncoded, + StyleParam.Mode mode, + Optional Name = default, + Optional ShowLegend = default, + Optional Opacity = default, + Optional> MultiOpacity = default, + Optional Text = default, + Optional> MultiText = default, + Optional TextPosition = default, + Optional> MultiTextPosition = default, + Optional MarkerColor = default, + Optional MarkerColorScale = default, + Optional MarkerOutline = default, + Optional MarkerSymbol = default, + Optional> MultiMarkerSymbol = default, + Optional Marker = default, + Optional LineColor = default, + Optional LineColorScale = default, + Optional LineWidth = default, + Optional LineDash = default, + Optional Line = default, + Optional CameraProjectionType = default, + Optional Camera = default, + Optional Projection = default, + Optional UseDefaults = default + ) + where TextType : IConvertible + => + Plotly.NET.Chart3D_Scatter.Chart.Scatter3D( + xEncoded: xEncoded, + yEncoded: yEncoded, + zEncoded: zEncoded, + mode: mode, + Name: Name.ToOption(), + ShowLegend: ShowLegend.ToOption(), + Opacity: Opacity.ToOption(), + MultiOpacity: MultiOpacity.ToOption(), + Text: Text.ToOption(), + MultiText: MultiText.ToOption(), + TextPosition: TextPosition.ToOption(), + MultiTextPosition: MultiTextPosition.ToOption(), + MarkerColor: MarkerColor.ToOption(), + MarkerColorScale: MarkerColorScale.ToOption(), + MarkerOutline: MarkerOutline.ToOption(), + MarkerSymbol: MarkerSymbol.ToOption(), + MultiMarkerSymbol: MultiMarkerSymbol.ToOption(), + Marker: Marker.ToOption(), + LineColor: LineColor.ToOption(), + LineColorScale: LineColorScale.ToOption(), + LineWidth: LineWidth.ToOption(), + LineDash: LineDash.ToOption(), + Line: Line.ToOption(), + CameraProjectionType: CameraProjectionType.ToOption(), + Camera: Camera.ToOption(), + Projection: Projection.ToOption(), + UseDefaults: UseDefaults.ToOption() + ); } } diff --git a/src/Plotly.NET.CSharp/ChartAPI/ChartDomain.cs b/src/Plotly.NET.CSharp/ChartAPI/ChartDomain.cs index d48058123..a3fe126e4 100644 --- a/src/Plotly.NET.CSharp/ChartAPI/ChartDomain.cs +++ b/src/Plotly.NET.CSharp/ChartAPI/ChartDomain.cs @@ -4,6 +4,7 @@ using Plotly.NET.TraceObjects; using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.InteropServices; @@ -569,6 +570,56 @@ public static GenericChart ParallelCoord( UseDefaults: UseDefaults.ToOption() ); + /// + /// Creates a parallel coordinates plot from encoded dimension values. + /// + /// Parallel coordinates are a common way of visualizing and analyzing high-dimensional datasets. + /// + /// Sets the values for each dimension as (dimensionKey, encodedDimensionValues) pairs. + /// Sets the trace name. The trace name appear as the legend item and on hover + /// Sets the color of the lines that are connecting the datums on the dimensions + /// Sets the colorscale of the lines that are connecting the datums on the dimensions + /// Whether or not to show the colorbar of the lines that are connecting the datums on the dimensions + /// Whether or not to reverse the colorscale of the lines that are connecting the datums on the dimensions + /// Sets the lines that are connecting the datums on the dimensions (use this for more finegrained control than the other line-associated arguments). + /// Sets the angle of the labels with respect to the horizontal. + /// Sets the label font of this trace. + /// Specifies the location of the `label`. + /// Sets the range font of this trace. + /// Sets the tick font of this trace. + /// If set to false, ignore the global default settings set in `Defaults` + public static GenericChart ParallelCoord( + IEnumerable<(string, EncodedTypedArray)> keyValuesEncoded, + Optional Name = default, + Optional LineColor = default, + Optional LineColorScale = default, + Optional ShowLineColorScale = default, + Optional ReverseLineColorScale = default, + Optional Line = default, + Optional LabelAngle = default, + Optional LabelFont = default, + Optional LabelSide = default, + Optional RangeFont = default, + Optional TickFont = default, + Optional UseDefaults = default + ) + => + Plotly.NET.ChartDomain_Relations.Chart.ParallelCoord( + keyValuesEncoded: keyValuesEncoded.Select(kv => kv.ToTuple()), + Name: Name.ToOption(), + LineColor: LineColor.ToOption(), + LineColorScale: LineColorScale.ToOption(), + ShowLineColorScale: ShowLineColorScale.ToOption(), + ReverseLineColorScale: ReverseLineColorScale.ToOption(), + Line: Line.ToOption(), + LabelAngle: LabelAngle.ToOption(), + LabelFont: LabelFont.ToOption(), + LabelSide: LabelSide.ToOption(), + RangeFont: RangeFont.ToOption(), + TickFont: TickFont.ToOption(), + UseDefaults: UseDefaults.ToOption() + ); + /// /// Creates a parallel categories plot. /// @@ -628,6 +679,63 @@ public static GenericChart ParallelCategories( UseDefaults: UseDefaults.ToOption() ); + /// + /// Creates a parallel categories plot from encoded dimension values. + /// + /// The parallel categories diagram (also known as parallel sets or alluvial diagram) is a visualization of + /// multi-dimensional categorical data sets. + /// + /// Sets the values for each dimension as (dimensionKey, encodedDimensionValues) pairs. + /// Sets the trace name. The trace name appear as the legend item and on hover + /// The number of observations represented by each state. Defaults to 1 so that each state represents one observation + /// Sets the color of the lines that are connecting the datums on the dimensions + /// Sets the shape of the lines that are connecting the datums on the dimensions + /// Sets the colorscale of the lines that are connecting the datums on the dimensions + /// Whether or not to show the colorbar of the lines that are connecting the datums on the dimensions + /// Whether or not to reverse the colorscale of the lines that are connecting the datums on the dimensions + /// Sets the lines that are connecting the datums on the dimensions (use this for more finegrained control than the other line-associated arguments). + /// Sets the drag interaction mode for categories and dimensions. If `perpendicular`, the categories can only move along a line perpendicular to the paths. If `freeform`, the categories can freely move on the plane. If `fixed`, the categories and dimensions are stationary. + /// Sort paths so that like colors are bundled together within each category. + /// Sets the path sorting algorithm. If `forward`, sort paths based on dimension categories from left to right. If `backward`, sort paths based on dimensions categories from right to left. + /// Sets the label font of this trace. + /// Sets the tick font of this trace. + /// If set to false, ignore the global default settings set in `Defaults` + public static GenericChart ParallelCategories( + IEnumerable<(string, EncodedTypedArray)> keyValuesEncoded, + Optional Name = default, + Optional Counts = default, + Optional LineColor = default, + Optional LineShape = default, + Optional LineColorScale = default, + Optional ShowLineColorScale = default, + Optional ReverseLineColorScale = default, + Optional Line = default, + Optional Arrangement = default, + Optional BundleColors = default, + Optional SortPaths = default, + Optional LabelFont = default, + Optional TickFont = default, + Optional UseDefaults = default + ) + => + Plotly.NET.ChartDomain_Relations.Chart.ParallelCategories( + keyValuesEncoded: keyValuesEncoded.Select(kv => kv.ToTuple()), + Name: Name.ToOption(), + Counts: Counts.ToOption(), + LineColor: LineColor.ToOption(), + LineShape: LineShape.ToOption(), + LineColorScale: LineColorScale.ToOption(), + ShowLineColorScale: ShowLineColorScale.ToOption(), + ReverseLineColorScale: ReverseLineColorScale.ToOption(), + Line: Line.ToOption(), + Arrangement: Arrangement.ToOption(), + BundleColors: BundleColors.ToOption(), + SortPaths: SortPaths.ToOption(), + LabelFont: LabelFont.ToOption(), + TickFont: TickFont.ToOption(), + UseDefaults: UseDefaults.ToOption() + ); + /// /// Creates a sankey diagram. /// @@ -672,6 +780,85 @@ public static GenericChart Sankey( UseDefaults: UseDefaults.ToOption() ); + /// + /// Creates a sankey diagram. + /// + /// A Sankey diagram is a flow diagram, in which the width of arrows is proportional to the flow quantity. + /// + /// Sets the labels of the nodes in the sankey diagram + /// (source, target) tuples which indicate connected nodes. These values map to the index in `nodeLabels` + /// The values for the links in the sankey diagram. + /// Sets the color of the nodes in the sankey diagram. + /// Sets the color of the node outlines in the sankey diagram. + /// Sets the outline width of the nodes in the sankey diagram. + /// Sets the thickness of the nodes in the sankey diagram. + /// Sets groups of nodes. Each group is defined by an array with the indices of the nodes it contains. Multiple groups can be specified. + /// Sets the color of the links in the sankey diagram. + /// Sets the colorscale of the links in the sankey diagram. + /// Sets the outline color of the links in the sankey diagram. + /// Sets the outline width of the links in the sankey diagram. + /// Sets the labels of the links in the sankey diagram. + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Assigns id labels to each datum. + /// Sets the orientation of the Sankey diagram. + /// Sets the text font of this trace. + /// If value is `snap` (the default), the node arrangement is assisted by automatic snapping of elements to preserve space between nodes specified via `nodepad`. If value is `perpendicular`, the nodes can only move along a line perpendicular to the flow. If value is `freeform`, the nodes can freely move on the plane. If value is `fixed`, the nodes are stationary. + /// Sets the horizontal alignment of the nodes in the Sankey diagram. If value is `justify` (the default), the nodes are spread to fill the width. If value is `left`, `right`, or `center`, the nodes are aligned accordingly. + /// Sets the value 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. + /// Adds a unit to follow the value in the hover tooltip. Add a space if a separation is necessary from the value. + /// If set to false, ignore the global default settings set in `Defaults` + public static GenericChart Sankey( + IEnumerable nodeLabels, + IEnumerable<(int, int)> linkedNodeIds, + IEnumerable linkValues, + Optional NodeColor = default, + Optional NodeOutlineColor = default, + Optional NodeOutlineWidth = default, + Optional NodeThickness = default, + Optional>> NodeGroups = default, + Optional LinkColor = default, + Optional> LinkColorScales = default, + Optional LinkOutlineColor = default, + Optional LinkOutlineWidth = default, + Optional> LinkLabels = default, + Optional Name = default, + Optional> Ids = default, + Optional Orientation = default, + Optional TextFont = default, + Optional Arrangement = default, + Optional NodeAlign = default, + Optional ValueFormat = default, + Optional ValueSuffix = default, + Optional UseDefaults = default + ) + where LinkValuesType : IConvertible + where IdsType : IConvertible + => + Plotly.NET.ChartDomain_Relations.Chart.Sankey, IdsType>( + nodeLabels, + linkedNodeIds.Select(link => link.ToTuple()), + linkValues, + NodeColor.ToOption(), + NodeOutlineColor.ToOption(), + NodeOutlineWidth.ToOption(), + NodeThickness.ToOption(), + NodeGroups.ToOption(), + LinkColor.ToOption(), + LinkColorScales.ToOption(), + LinkOutlineColor.ToOption(), + LinkOutlineWidth.ToOption(), + LinkLabels.ToOption(), + Name.ToOption(), + Ids.ToOption(), + Orientation.ToOption(), + TextFont.ToOption(), + Arrangement.ToOption(), + NodeAlign.ToOption(), + ValueFormat.ToOption(), + ValueSuffix.ToOption(), + UseDefaults.ToOption() + ); + /// /// Creates a table. /// @@ -886,4 +1073,3 @@ public static GenericChart Icicle + /// Creates a parallel coordinates plot from encoded dimension values. + /// + /// Parallel coordinates are a common way of visualizing and analyzing high-dimensional datasets. + /// + /// Sets the values for each dimension as (dimensionKey, encodedDimensionValues) pairs. + /// Sets the trace name. The trace name appear as the legend item and on hover + /// Sets the color of the lines that are connecting the datums on the dimensions + /// Sets the colorscale of the lines that are connecting the datums on the dimensions + /// Whether or not to show the colorbar of the lines that are connecting the datums on the dimensions + /// Whether or not to reverse the colorscale of the lines that are connecting the datums on the dimensions + /// Sets the lines that are connecting the datums on the dimensions (use this for more finegrained control than the other line-associated arguments). + /// Sets the angle of the labels with respect to the horizontal. + /// Sets the label font of this trace. + /// Specifies the location of the `label`. + /// Sets the range font of this trace. + /// Sets the tick font of this trace. + /// If set to false, ignore the global default settings set in `Defaults` + [] + static member ParallelCoord + ( + keyValuesEncoded: seq, + ?Name: string, + ?LineColor: Color, + ?LineColorScale: StyleParam.Colorscale, + ?ShowLineColorScale: bool, + ?ReverseLineColorScale: bool, + ?Line: Line, + ?LabelAngle: int, + ?LabelFont: Font, + ?LabelSide: StyleParam.Side, + ?RangeFont: Font, + ?TickFont: Font, + ?UseDefaults: bool + ) = + + let dims = + keyValuesEncoded |> Seq.map (fun (key, encodedVals) -> Dimension.initParallel (Label = key, ValuesEncoded = encodedVals)) + + Chart.ParallelCoord( + dimensions = dims, + ?Name = Name, + ?LineColor = LineColor, + ?LineColorScale = LineColorScale, + ?ShowLineColorScale = ShowLineColorScale, + ?ReverseLineColorScale = ReverseLineColorScale, + ?Line = Line, + ?LabelAngle = LabelAngle, + ?LabelFont = LabelFont, + ?LabelSide = LabelSide, + ?RangeFont = RangeFont, + ?TickFont = TickFont, + ?UseDefaults = UseDefaults + ) + /// /// Creates a parallel categories plot. /// @@ -289,6 +344,68 @@ module ChartDomain_Relations = ) |> GenericChart.ofTraceObject useDefaults + /// + /// Creates a parallel categories plot from encoded dimension values. + /// + /// The parallel categories diagram (also known as parallel sets or alluvial diagram) is a visualization of + /// multi-dimensional categorical data sets. + /// + /// Sets the values for each dimension as (dimensionKey, encodedDimensionValues) pairs. + /// Sets the trace name. The trace name appear as the legend item and on hover + /// The number of observations represented by each state. Defaults to 1 so that each state represents one observation + /// Sets the color of the lines that are connecting the datums on the dimensions + /// Sets the shape of the lines that are connecting the datums on the dimensions + /// Sets the colorscale of the lines that are connecting the datums on the dimensions + /// Whether or not to show the colorbar of the lines that are connecting the datums on the dimensions + /// Whether or not to reverse the colorscale of the lines that are connecting the datums on the dimensions + /// Sets the lines that are connecting the datums on the dimensions (use this for more finegrained control than the other line-associated arguments). + /// Sets the drag interaction mode for categories and dimensions. + /// Sort paths so that like colors are bundled together within each category. + /// Sets the path sorting algorithm. + /// Sets the label font of this trace. + /// Sets the tick font of this trace. + /// If set to false, ignore the global default settings set in `Defaults` + [] + static member ParallelCategories + ( + keyValuesEncoded: seq, + ?Name: string, + ?Counts: int, + ?LineColor: Color, + ?LineShape: StyleParam.Shape, + ?LineColorScale: StyleParam.Colorscale, + ?ShowLineColorScale: bool, + ?ReverseLineColorScale: bool, + ?Line: Line, + ?Arrangement: StyleParam.CategoryArrangement, + ?BundleColors: bool, + ?SortPaths: StyleParam.SortAlgorithm, + ?LabelFont: Font, + ?TickFont: Font, + ?UseDefaults: bool + ) = + + let dims = + keyValuesEncoded |> Seq.map (fun (key, encodedVals) -> Dimension.initParallel (Label = key, ValuesEncoded = encodedVals)) + + Chart.ParallelCategories( + dimensions = dims, + ?Name = Name, + ?Counts = Counts, + ?LineColor = LineColor, + ?LineShape = LineShape, + ?LineColorScale = LineColorScale, + ?ShowLineColorScale = ShowLineColorScale, + ?ReverseLineColorScale = ReverseLineColorScale, + ?Line = Line, + ?Arrangement = Arrangement, + ?BundleColors = BundleColors, + ?SortPaths = SortPaths, + ?LabelFont = LabelFont, + ?TickFont = TickFont, + ?UseDefaults = UseDefaults + ) + /// /// Creates a sankey diagram. /// @@ -364,6 +481,7 @@ module ChartDomain_Relations = /// Sets the orientation of the Sankey diagram. /// Sets the text font of this trace. /// If value is `snap` (the default), the node arrangement is assisted by automatic snapping of elements to preserve space between nodes specified via `nodepad`. If value is `perpendicular`, the nodes can only move along a line perpendicular to the flow. If value is `freeform`, the nodes can freely move on the plane. If value is `fixed`, the nodes are stationary. + /// Sets the horizontal alignment of the nodes in the Sankey diagram. If value is `justify` (the default), the nodes are spread to fill the width. If value is `left`, `right`, or `center`, the nodes are aligned accordingly. /// Sets the value 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. /// Adds a unit to follow the value in the hover tooltip. Add a space if a separation is necessary from the value. /// If set to false, ignore the global default settings set in `Defaults` @@ -388,6 +506,7 @@ module ChartDomain_Relations = ?Orientation: StyleParam.Orientation, ?TextFont: Font, ?Arrangement: StyleParam.CategoryArrangement, + ?NodeAlign: StyleParam.SankeyNodeAlign, ?ValueFormat: string, ?ValueSuffix: string, ?UseDefaults: bool @@ -400,6 +519,7 @@ module ChartDomain_Relations = SankeyNodes.init ( Label = nodeLabels, Line = nodeOutline, + ?Align = NodeAlign, ?Color = NodeColor, ?Thickness = NodeThickness, ?Groups = NodeGroups diff --git a/src/Plotly.NET/CommonAbstractions/StyleParams.fs b/src/Plotly.NET/CommonAbstractions/StyleParams.fs index 77438ba31..74c91ed89 100644 --- a/src/Plotly.NET/CommonAbstractions/StyleParams.fs +++ b/src/Plotly.NET/CommonAbstractions/StyleParams.fs @@ -2684,6 +2684,24 @@ module StyleParam = // #S# //-------------------------- + [] + type SankeyNodeAlign = + | Left + | Right + | Center + | Justify + + static member toString = + function + | Left -> "left" + | Right -> "right" + | Center -> "center" + | Justify -> "justify" + + static member convert = SankeyNodeAlign.toString >> box + override this.ToString() = this |> SankeyNodeAlign.toString + member this.Convert() = this |> SankeyNodeAlign.convert + [] type ScaleAnchor = | False diff --git a/src/Plotly.NET/Traces/ObjectAbstractions/Sankey.fs b/src/Plotly.NET/Traces/ObjectAbstractions/Sankey.fs index 9ae58ac34..4ee9d7ce8 100644 --- a/src/Plotly.NET/Traces/ObjectAbstractions/Sankey.fs +++ b/src/Plotly.NET/Traces/ObjectAbstractions/Sankey.fs @@ -11,8 +11,11 @@ type SankeyNodes() = static member init ( + ?Align: StyleParam.SankeyNodeAlign, ?Color: Color, + ?ColorEncoded: EncodedTypedArray, ?CustomData: seq<#IConvertible>, + ?CustomDataEncoded: EncodedTypedArray, ?Groups: seq<#seq>, ?HoverInfo: StyleParam.HoverInfo, ?HoverLabel: Hoverlabel, @@ -23,13 +26,18 @@ type SankeyNodes() = ?Pad: int, ?Thickness: int, ?X: seq<#IConvertible>, - ?Y: seq<#IConvertible> + ?XEncoded: EncodedTypedArray, + ?Y: seq<#IConvertible>, + ?YEncoded: EncodedTypedArray ) = SankeyNodes() |> SankeyNodes.style ( + ?Align = Align, ?Color = Color, + ?ColorEncoded = ColorEncoded, ?CustomData = CustomData, + ?CustomDataEncoded = CustomDataEncoded, ?Groups = Groups, ?HoverInfo = HoverInfo, ?HoverLabel = HoverLabel, @@ -40,14 +48,18 @@ type SankeyNodes() = ?Pad = Pad, ?Thickness = Thickness, ?X = X, - ?Y = Y - + ?XEncoded = XEncoded, + ?Y = Y, + ?YEncoded = YEncoded ) static member style ( + ?Align: StyleParam.SankeyNodeAlign, ?Color: Color, + ?ColorEncoded: EncodedTypedArray, ?CustomData: seq<#IConvertible>, + ?CustomDataEncoded: EncodedTypedArray, ?Groups: seq<#seq>, ?HoverInfo: StyleParam.HoverInfo, ?HoverLabel: Hoverlabel, @@ -58,12 +70,17 @@ type SankeyNodes() = ?Pad: int, ?Thickness: int, ?X: seq<#IConvertible>, - ?Y: seq<#IConvertible> + ?XEncoded: EncodedTypedArray, + ?Y: seq<#IConvertible>, + ?YEncoded: EncodedTypedArray ) = fun (sankeyNodes: SankeyNodes) -> sankeyNodes + |> DynObj.withOptionalPropertyBy "align" Align StyleParam.SankeyNodeAlign.convert |> DynObj.withOptionalProperty "color" Color + |> DynObj.withOptionalProperty "color" ColorEncoded |> DynObj.withOptionalProperty "customdata" CustomData + |> DynObj.withOptionalProperty "customdata" CustomDataEncoded |> DynObj.withOptionalProperty "groups" Groups |> DynObj.withOptionalPropertyBy "hoverinfo" HoverInfo StyleParam.HoverInfo.convert |> DynObj.withOptionalProperty "hoverlabel" HoverLabel @@ -73,7 +90,9 @@ type SankeyNodes() = |> DynObj.withOptionalProperty "pad" Pad |> DynObj.withOptionalProperty "thickness" Thickness |> DynObj.withOptionalProperty "x" X + |> DynObj.withOptionalProperty "x" XEncoded |> DynObj.withOptionalProperty "y" Y + |> DynObj.withOptionalProperty "y" YEncoded type SankeyLinkColorscale() = inherit DynamicObj() @@ -125,8 +144,10 @@ type SankeyLinks() = ( ?ArrowLen: int, ?Color: Color, + ?ColorEncoded: EncodedTypedArray, ?ColorScales: seq, ?CustomData: seq<#IConvertible>, + ?CustomDataEncoded: EncodedTypedArray, ?HoverInfo: StyleParam.HoverInfo, ?HoverLabel: Hoverlabel, ?HoverTemplate: string, @@ -134,16 +155,21 @@ type SankeyLinks() = ?Label: seq, ?Line: Line, ?Source: seq, + ?SourceEncoded: EncodedTypedArray, ?Target: seq, - ?Value: seq<#IConvertible> + ?TargetEncoded: EncodedTypedArray, + ?Value: seq<#IConvertible>, + ?ValueEncoded: EncodedTypedArray ) = SankeyLinks() |> SankeyLinks.style ( ?ArrowLen = ArrowLen, ?Color = Color, + ?ColorEncoded = ColorEncoded, ?ColorScales = ColorScales, ?CustomData = CustomData, + ?CustomDataEncoded = CustomDataEncoded, ?HoverInfo = HoverInfo, ?HoverLabel = HoverLabel, ?HoverTemplate = HoverTemplate, @@ -151,17 +177,21 @@ type SankeyLinks() = ?Label = Label, ?Line = Line, ?Source = Source, + ?SourceEncoded = SourceEncoded, ?Target = Target, - ?Value = Value - + ?TargetEncoded = TargetEncoded, + ?Value = Value, + ?ValueEncoded = ValueEncoded ) static member style ( ?ArrowLen: int, ?Color: Color, + ?ColorEncoded: EncodedTypedArray, ?ColorScales: seq, ?CustomData: seq<#IConvertible>, + ?CustomDataEncoded: EncodedTypedArray, ?HoverInfo: StyleParam.HoverInfo, ?HoverLabel: Hoverlabel, ?HoverTemplate: string, @@ -169,22 +199,30 @@ type SankeyLinks() = ?Label: seq, ?Line: Line, ?Source: seq, + ?SourceEncoded: EncodedTypedArray, ?Target: seq, - ?Value: seq<#IConvertible> + ?TargetEncoded: EncodedTypedArray, + ?Value: seq<#IConvertible>, + ?ValueEncoded: EncodedTypedArray ) = fun (sankeyLinks: SankeyLinks) -> sankeyLinks |> DynObj.withOptionalProperty "arrowlen" ArrowLen |> DynObj.withOptionalProperty "color" Color + |> DynObj.withOptionalProperty "color" ColorEncoded |> DynObj.withOptionalProperty "colorscales" ColorScales |> DynObj.withOptionalProperty "customdata" CustomData + |> DynObj.withOptionalProperty "customdata" CustomDataEncoded |> DynObj.withOptionalPropertyBy "hoverinfo" HoverInfo StyleParam.HoverInfo.convert |> DynObj.withOptionalProperty "hoverlabel" HoverLabel |> DynObj.withOptionalSingleOrMultiProperty "hovertemplate" (HoverTemplate, MultiHoverTemplate) |> DynObj.withOptionalProperty "label" Label |> DynObj.withOptionalProperty "line" Line |> DynObj.withOptionalProperty "source" Source + |> DynObj.withOptionalProperty "source" SourceEncoded |> DynObj.withOptionalProperty "target" Target + |> DynObj.withOptionalProperty "target" TargetEncoded |> DynObj.withOptionalProperty "value" Value + |> DynObj.withOptionalProperty "value" ValueEncoded diff --git a/tests/Common/FSharpTestBase/TestCharts/UpstreamFeatures/2.28.fs b/tests/Common/FSharpTestBase/TestCharts/UpstreamFeatures/2.28.fs index d3cc0e96d..c6f36718c 100644 --- a/tests/Common/FSharpTestBase/TestCharts/UpstreamFeatures/2.28.fs +++ b/tests/Common/FSharpTestBase/TestCharts/UpstreamFeatures/2.28.fs @@ -1043,3 +1043,82 @@ module ``Encoded typed arrays on carpet and domain traces`` = ) ) |> GenericChart.ofTraceObject true + +module ``Sankey node align`` = + + let ``Sankey with node align right`` = + let nodes = + SankeyNodes.init( + Label = ["A"; "B"; "C"], + Align = StyleParam.SankeyNodeAlign.Right + ) + let links = + SankeyLinks.init( + Source = [0; 1], + Target = [2; 2], + Value = [8; 4] + ) + Chart.Sankey(nodes, links, UseDefaults = false) + + let ``Sankey with node align via Chart overload`` = + Chart.Sankey( + nodeLabels = ["A"; "B"; "C"], + linkedNodeIds = [(0, 2); (1, 2)], + linkValues = [8; 4], + NodeAlign = StyleParam.SankeyNodeAlign.Left, + UseDefaults = false + ) + +module ``Sankey encoded node and link arrays`` = + + let ``Sankey with encoded node arrays`` = + let nodes = + SankeyNodes.init( + Label = ["A"; "B"; "C"], + ColorEncoded = EncodedTypedArray.ofFloat64Array [| 1.0; 2.0; 3.0 |], + CustomDataEncoded = EncodedTypedArray.ofFloat64Array [| 10.0; 20.0; 30.0 |], + XEncoded = EncodedTypedArray.ofFloat64Array [| 0.1; 0.5; 0.9 |], + YEncoded = EncodedTypedArray.ofFloat64Array [| 0.1; 0.5; 0.9 |] + ) + let links = + SankeyLinks.init( + Source = [0; 1], + Target = [2; 2], + Value = [8; 4] + ) + Chart.Sankey(nodes, links, UseDefaults = false) + + let ``Sankey with encoded link arrays`` = + let nodes = + SankeyNodes.init( + Label = ["A"; "B"; "C"] + ) + let links = + SankeyLinks.init( + SourceEncoded = EncodedTypedArray.ofInt32Array [| 0; 1 |], + TargetEncoded = EncodedTypedArray.ofInt32Array [| 2; 2 |], + ValueEncoded = EncodedTypedArray.ofFloat64Array [| 8.0; 4.0 |], + ColorEncoded = EncodedTypedArray.ofFloat64Array [| 1.0; 2.0 |], + CustomDataEncoded = EncodedTypedArray.ofFloat64Array [| 10.0; 20.0 |] + ) + Chart.Sankey(nodes, links, UseDefaults = false) + +module ``ParallelCoord and ParallelCategories encoded dimensions`` = + + let ``ParallelCoord with encoded dimensions`` = + Chart.ParallelCoord( + keyValuesEncoded = [ + "A", EncodedTypedArray.ofFloat64Array [| 1.0; 2.0; 3.0 |] + "B", EncodedTypedArray.ofFloat64Array [| 4.0; 5.0; 6.0 |] + ], + UseDefaults = false + ) + + let ``ParallelCategories with encoded dimensions`` = + Chart.ParallelCategories( + keyValuesEncoded = [ + "X", EncodedTypedArray.ofInt32Array [| 0; 1; 0 |] + "Y", EncodedTypedArray.ofInt32Array [| 1; 0; 1 |] + ], + UseDefaults = false + ) diff --git a/tests/ConsoleApps/FSharpConsole/Program.fs b/tests/ConsoleApps/FSharpConsole/Program.fs index 6ce7f451c..ce100c598 100644 --- a/tests/ConsoleApps/FSharpConsole/Program.fs +++ b/tests/ConsoleApps/FSharpConsole/Program.fs @@ -3,16 +3,10 @@ open Plotly.NET [] let main _ = - let chartPointDensityEncodedHelpers = - Chart.PointDensity( - xEncoded = EncodedTypedArray.ofFloat64Array [| 0.0; 1.0; 2.0; 3.0; 4.0 |], - yEncoded = EncodedTypedArray.ofFloat64Array [| 0.0; 1.0; 0.5; 2.0; 1.5 |], - ContoursColoring = StyleParam.ContourColoring.Fill, - Name = "encoded point density helper", - UseDefaults = true - ) - |> Chart.withTitle "PointDensity: encoded x/y at chart helper layer" - - chartPointDensityEncodedHelpers |> Chart.show + Chart.Heatmap( + zEncoded = EncodedTypedArray.ofFloat64Array([| 1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0; 8.0; 9.0 |], shape = [ 3; 3 ]), + Name = "encoded heatmap", + UseDefaults = false + )|> Chart.show 0 diff --git a/tests/CoreTests/CoreTests/UpstreamFeatures/2.28.fs b/tests/CoreTests/CoreTests/UpstreamFeatures/2.28.fs index 40a907ef2..7eac97bb8 100644 --- a/tests/CoreTests/CoreTests/UpstreamFeatures/2.28.fs +++ b/tests/CoreTests/CoreTests/UpstreamFeatures/2.28.fs @@ -905,3 +905,82 @@ module ``Encoded typed arrays on carpet and domain traces`` = ) ] ] + +module ``Sankey node align`` = + + [] + let ``Sankey node align tests`` = + testList "UpstreamFeatures.PlotlyJS_2_28" [ + testList "Sankey node align" [ + testCase "Sankey with node align right serializes align property on node object" (fun () -> + "\"node\":{\"align\":\"right\",\"label\":[\"A\",\"B\",\"C\"]}" + |> chartGeneratedContains ``Sankey node align``.``Sankey with node align right`` + ) + testCase "Sankey via Chart overload serializes align property on node object" (fun () -> + "\"node\":{\"align\":\"left\",\"label\":[\"A\",\"B\",\"C\"],\"line\":{}}" + |> chartGeneratedContains ``Sankey node align``.``Sankey with node align via Chart overload`` + ) + ] + ] + +module ``Sankey encoded node and link arrays`` = + + [] + let ``Sankey encoded node and link array tests`` = + testList "UpstreamFeatures.PlotlyJS_2_28" [ + testList "Sankey encoded node and link arrays" [ + testCase "Sankey node color is serialized as encoded object" (fun () -> + "\"color\":{\"bdata\":" + |> chartGeneratedContains ``Sankey encoded node and link arrays``.``Sankey with encoded node arrays`` + ) + testCase "Sankey node customdata is serialized as encoded object" (fun () -> + "\"customdata\":{\"bdata\":" + |> chartGeneratedContains ``Sankey encoded node and link arrays``.``Sankey with encoded node arrays`` + ) + testCase "Sankey node x is serialized as encoded object" (fun () -> + "\"x\":{\"bdata\":" + |> chartGeneratedContains ``Sankey encoded node and link arrays``.``Sankey with encoded node arrays`` + ) + testCase "Sankey node y is serialized as encoded object" (fun () -> + "\"y\":{\"bdata\":" + |> chartGeneratedContains ``Sankey encoded node and link arrays``.``Sankey with encoded node arrays`` + ) + testCase "Sankey link source is serialized as encoded object" (fun () -> + "\"source\":{\"bdata\":" + |> chartGeneratedContains ``Sankey encoded node and link arrays``.``Sankey with encoded link arrays`` + ) + testCase "Sankey link target is serialized as encoded object" (fun () -> + "\"target\":{\"bdata\":" + |> chartGeneratedContains ``Sankey encoded node and link arrays``.``Sankey with encoded link arrays`` + ) + testCase "Sankey link value is serialized as encoded object" (fun () -> + "\"value\":{\"bdata\":" + |> chartGeneratedContains ``Sankey encoded node and link arrays``.``Sankey with encoded link arrays`` + ) + testCase "Sankey link color is serialized as encoded object" (fun () -> + "\"color\":{\"bdata\":" + |> chartGeneratedContains ``Sankey encoded node and link arrays``.``Sankey with encoded link arrays`` + ) + testCase "Sankey link customdata is serialized as encoded object" (fun () -> + "\"customdata\":{\"bdata\":" + |> chartGeneratedContains ``Sankey encoded node and link arrays``.``Sankey with encoded link arrays`` + ) + ] + ] + +module ``ParallelCoord and ParallelCategories encoded dimensions`` = + + [] + let ``ParallelCoord and ParallelCategories encoded dimension tests`` = + testList "UpstreamFeatures.PlotlyJS_2_28" [ + testList "ParallelCoord and ParallelCategories encoded dimensions" [ + testCase "ParallelCoord dimension A values are serialized as encoded object" (fun () -> + "\"values\":{\"bdata\":" + |> chartGeneratedContains ``ParallelCoord and ParallelCategories encoded dimensions``.``ParallelCoord with encoded dimensions`` + ) + testCase "ParallelCategories dimension X values are serialized as encoded object" (fun () -> + "\"values\":{\"bdata\":" + |> chartGeneratedContains ``ParallelCoord and ParallelCategories encoded dimensions``.``ParallelCategories with encoded dimensions`` + ) + ] + ]