diff --git a/Plotly.NET.sln b/Plotly.NET.sln index 9052fc405..91b2bb5b7 100644 --- a/Plotly.NET.sln +++ b/Plotly.NET.sln @@ -89,6 +89,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{7B09CC0A-F docs\09_0_parallel-categories.fsx = docs\09_0_parallel-categories.fsx docs\09_1_parallel-coords.fsx = docs\09_1_parallel-coords.fsx docs\09_2_sankey.fsx = docs\09_2_sankey.fsx + docs\09_3_icicle.fsx = docs\09_3_icicle.fsx docs\10_0_ternary_line_scatter_plots.fsx = docs\10_0_ternary_line_scatter_plots.fsx docs\10_1_styling_ternary_layouts.fsx = docs\10_1_styling_ternary_layouts.fsx docs\11_1_carpet_line_scatter_plots.fsx = docs\11_1_carpet_line_scatter_plots.fsx diff --git a/docs/09_3_icicle.fsx b/docs/09_3_icicle.fsx new file mode 100644 index 000000000..288f9e615 --- /dev/null +++ b/docs/09_3_icicle.fsx @@ -0,0 +1,64 @@ +(** +--- +title: Icicle Charts +category: Categorical Charts +categoryindex: 10 +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 + +(** +# Icicle 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 icicle charts in F#. + +Icicle charts visualize hierarchical data using rectangular sectors that cascade from root to leaves in one of four directions: up, down, left, or right. +Similar to Sunburst charts and Treemaps charts, the hierarchy is defined by labels and parents attributes. +Click on one sector to zoom in/out, which also displays a pathbar on the top of your icicle. +To zoom out, you can click the parent sector or click the pathbar as well. +*) + +open Plotly.NET +open Plotly.NET.TraceObjects + +let character = ["Eve"; "Cain"; "Seth"; "Enos"; "Noam"; "Abel"; "Awan"; "Enoch"; "Azura"] +let parent = [""; "Eve"; "Eve"; "Seth"; "Seth"; "Eve"; "Eve"; "Awan"; "Eve" ] + +let icicle = + Chart.Icicle( + character, + parent, + ShowScale = true, + ColorScale = StyleParam.Colorscale.Viridis, + TilingOrientation = StyleParam.Orientation.Vertical, // wether the icicles will grow in the vertical (up/down) or horizontal (left/right) direction + TilingFlip = StyleParam.TilingFlip.Y, // flip in the Y direction (grow up instead of down) + PathBarEdgeShape = StyleParam.PathbarEdgeShape.BackSlash + ) + +(*** condition: ipynb ***) +#if IPYNB +icicle +#endif // IPYNB + +(***hide***) +icicle |> GenericChart.toChartHTML +(***include-it-raw***) + diff --git a/src/Plotly.NET/ChartAPI/ChartDomain.fs b/src/Plotly.NET/ChartAPI/ChartDomain.fs index bea924810..7c11e2a96 100644 --- a/src/Plotly.NET/ChartAPI/ChartDomain.fs +++ b/src/Plotly.NET/ChartAPI/ChartDomain.fs @@ -559,4 +559,126 @@ module ChartDomain = Gauge = gauge ) ) - |> GenericChart.ofTraceObject \ No newline at end of file + |> GenericChart.ofTraceObject + + /// creates table out of header sequence and row sequences + [] + static member Icicle + ( + labels : seq<#IConvertible>, + parents : seq<#IConvertible>, + [] ?Name : string, + [] ?ShowLegend : bool, + [] ?Values : seq<#IConvertible>, + [] ?Opacity : float, + [] ?MultiOpacity : seq, + [] ?Color : Color, + [] ?ColorScale : StyleParam.Colorscale, + [] ?ShowScale : bool, + [] ?Marker : Marker, + [] ?Text : #IConvertible, + [] ?MultiText : seq<#IConvertible>, + [] ?TextPosition : StyleParam.TextPosition, + [] ?MultiTextPosition : seq, + [] ?Domain : Domain, + [] ?BranchValues : StyleParam.BranchValues, + [] ?Count : StyleParam.IcicleCount, + [] ?TilingOrientation : StyleParam.Orientation, + [] ?TilingFlip : StyleParam.TilingFlip, + [] ?Tiling : IcicleTiling, + [] ?PathBarEdgeShape : StyleParam.PathbarEdgeShape, + [] ?PathBar : Pathbar + ) = + + let tiling = + Tiling + |> Option.defaultValue(IcicleTiling.init()) + |> IcicleTiling.style(?Orientation = TilingOrientation, ?Flip = TilingFlip) + + let pathbar = + PathBar + |> Option.defaultValue(Pathbar.init()) + |> Pathbar.style(?EdgeShape = PathBarEdgeShape) + + TraceDomain.initIcicle( + TraceDomainStyle.Icicle( + ?Name = Name , + ?ShowLegend = ShowLegend , + ?Opacity = Opacity , + Parents = parents , + ?Values = Values , + Labels = labels , + ?Text = Text , + ?MultiText = MultiText , + ?TextPosition = TextPosition , + ?MultiTextPosition = MultiTextPosition , + ?Domain = Domain , + ?Marker = Marker , + ?BranchValues = BranchValues , + ?Count = Count , + Tiling = tiling , + PathBar = pathbar + ) + >> TraceStyle.Marker ( + ?Color = Color, + ?MultiOpacity = MultiOpacity, + ?Colorscale = ColorScale, + ?ShowScale = ShowScale + ) + ) + |> GenericChart.ofTraceObject + + /// creates table out of header sequence and row sequences + [] + static member Icicle + ( + labelsParents: seq<#IConvertible * #IConvertible>, + [] ?Name : string, + [] ?ShowLegend : bool, + [] ?Values : seq<#IConvertible>, + [] ?Opacity : float, + [] ?MultiOpacity : seq, + [] ?Color : Color, + [] ?ColorScale : StyleParam.Colorscale, + [] ?ShowScale : bool, + [] ?Marker : Marker, + [] ?Text : #IConvertible, + [] ?MultiText : seq<#IConvertible>, + [] ?TextPosition : StyleParam.TextPosition, + [] ?MultiTextPosition : seq, + [] ?Domain : Domain, + [] ?BranchValues : StyleParam.BranchValues, + [] ?Count : StyleParam.IcicleCount, + [] ?TilingOrientation : StyleParam.Orientation, + [] ?TilingFlip : StyleParam.TilingFlip, + [] ?Tiling : IcicleTiling, + [] ?PathBarEdgeShape : StyleParam.PathbarEdgeShape, + [] ?PathBar : Pathbar + ) = + + let labels, parents = Seq.unzip labelsParents + + Chart.Icicle( + labels, parents, + ?Name = Name , + ?ShowLegend = ShowLegend , + ?Values = Values , + ?Opacity = Opacity , + ?MultiOpacity = MultiOpacity , + ?Color = Color , + ?ColorScale = ColorScale , + ?ShowScale = ShowScale , + ?Marker = Marker , + ?Text = Text , + ?MultiText = MultiText , + ?TextPosition = TextPosition , + ?MultiTextPosition = MultiTextPosition , + ?Domain = Domain , + ?BranchValues = BranchValues , + ?Count = Count , + ?TilingOrientation = TilingOrientation , + ?TilingFlip = TilingFlip , + ?Tiling = Tiling , + ?PathBarEdgeShape = PathBarEdgeShape , + ?PathBar = PathBar + ) \ No newline at end of file diff --git a/src/Plotly.NET/CommonAbstractions/StyleParams.fs b/src/Plotly.NET/CommonAbstractions/StyleParams.fs index 931d51e9e..c216e0a67 100644 --- a/src/Plotly.NET/CommonAbstractions/StyleParams.fs +++ b/src/Plotly.NET/CommonAbstractions/StyleParams.fs @@ -1113,6 +1113,19 @@ module StyleParam = //-------------------------- // #I# //-------------------------- + + [] + type IcicleCount = + | Branches | Leaves | BranchesLeaves + static member toString = function + | Branches -> "branches" + | Leaves -> "leaves" + | BranchesLeaves-> "branches+leaves" + + static member convert = IcicleCount.toString >> box + override this.ToString() = this |> IcicleCount.toString + member this.Convert() = this |> IcicleCount.convert + [] type IndicatorMode = @@ -1144,7 +1157,6 @@ module StyleParam = static member convert = IndicatorAlignment.toString >> box override this.ToString() = this |> IndicatorAlignment.toString member this.Convert() = this |> IndicatorAlignment.convert - [] type IndicatorGaugeShape = | Angular | Bullet @@ -2216,7 +2228,22 @@ module StyleParam = //-------------------------- // #T# //-------------------------- - + + [] + type TilingFlip = + | X + | Y + | XY + + static member toString = function + | X -> "x" + | Y -> "y" + | XY-> "x+y" + + static member convert = TilingFlip.toString >> box + override this.ToString() = this |> TilingFlip.toString + member this.Convert() = this |> TilingFlip.convert + [] type TransitionEasing = | Linear @@ -2404,7 +2431,7 @@ module StyleParam = member this.Convert() = this |> UnitMode.convert [] - type TreemapEdgeShape = + type PathbarEdgeShape = | ArrowRight | ArrowLeft | Straight | Slash | BackSlash static member toString = function @@ -2414,9 +2441,9 @@ module StyleParam = | Slash -> "/" | BackSlash -> """\""" - static member convert = TreemapEdgeShape.toString >> box - override this.ToString() = this |> TreemapEdgeShape.toString - member this.Convert() = this |> TreemapEdgeShape.convert + static member convert = PathbarEdgeShape.toString >> box + override this.ToString() = this |> PathbarEdgeShape.toString + member this.Convert() = this |> PathbarEdgeShape.convert [] type TreemapTilingPacking = diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index 80c96406d..f9ad1e05f 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -93,6 +93,7 @@ #load "Error.fs" #load "Table.fs" #load "Indicator.fs" +#load "Icicle.fs" #I "Traces" @@ -160,6 +161,20 @@ open FSharpAux open System open System.IO +let character = ["Eve"; "Cain"; "Seth"; "Enos"; "Noam"; "Abel"; "Awan"; "Enoch"; "Azura"] +let parent = [""; "Eve"; "Eve"; "Seth"; "Seth"; "Eve"; "Eve"; "Awan"; "Eve" ] + +Chart.Icicle( + character, + parent, + ShowScale = true, + ColorScale = StyleParam.Colorscale.Viridis, + TilingOrientation = StyleParam.Orientation.Vertical, + TilingFlip = StyleParam.TilingFlip.Y, + PathBarEdgeShape = StyleParam.PathbarEdgeShape.BackSlash +) +|> Chart.show + [ Chart.Indicator( 120., StyleParam.IndicatorMode.NumberDeltaGauge, diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index 98adb202c..4a0121606 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -101,6 +101,7 @@ + diff --git a/src/Plotly.NET/Traces/ObjectAbstractions/Icicle.fs b/src/Plotly.NET/Traces/ObjectAbstractions/Icicle.fs new file mode 100644 index 000000000..bda88b739 --- /dev/null +++ b/src/Plotly.NET/Traces/ObjectAbstractions/Icicle.fs @@ -0,0 +1,88 @@ +namespace Plotly.NET.TraceObjects + +open Plotly.NET +open Plotly.NET.LayoutObjects +open DynamicObj +open System +open System.Runtime.InteropServices + +type IcicleRoot () = + inherit DynamicObj () + + static member init + ( + [] ?Color : Color + ) = + IcicleRoot () + |> IcicleRoot.style + ( + ?Color = Color + ) + + static member style + ( + [] ?Color : Color + ) = + (fun (icicleRoot: IcicleRoot) -> + + Color |> DynObj.setValueOpt icicleRoot "color" + + icicleRoot + ) + +type IcicleLeaf () = + inherit DynamicObj () + + static member init + ( + [] ?Opacity : float + ) = + IcicleLeaf () + |> IcicleLeaf.style + ( + ?Opacity = Opacity + ) + + static member style + ( + [] ?Opacity : float + ) = + (fun (icicleLeaf: IcicleLeaf) -> + + Opacity |> DynObj.setValueOpt icicleLeaf "opacity" + + icicleLeaf + ) + +type IcicleTiling () = + inherit DynamicObj () + + static member init + ( + [] ?Flip : StyleParam.TilingFlip, + [] ?Orientation : StyleParam.Orientation, + [] ?Pad : int + ) = + IcicleTiling () + |> IcicleTiling.style + ( + ?Flip = Flip , + ?Orientation = Orientation, + ?Pad = Pad + ) + + static member style + ( + [] ?Flip : StyleParam.TilingFlip, + [] ?Orientation : StyleParam.Orientation, + [] ?Pad : int + ) = + (fun (icicleTiling: IcicleTiling) -> + + Flip |> DynObj.setValueOptBy icicleTiling "flip" StyleParam.TilingFlip.convert + Orientation |> DynObj.setValueOptBy icicleTiling "orientation" StyleParam.Orientation.convert + Pad |> DynObj.setValueOpt icicleTiling "pad" + + icicleTiling + ) + diff --git a/src/Plotly.NET/Traces/ObjectAbstractions/Pathbar.fs b/src/Plotly.NET/Traces/ObjectAbstractions/Pathbar.fs index 3c8a4382f..a3f86144a 100644 --- a/src/Plotly.NET/Traces/ObjectAbstractions/Pathbar.fs +++ b/src/Plotly.NET/Traces/ObjectAbstractions/Pathbar.fs @@ -26,7 +26,7 @@ type Pathbar () = ( [] ?Visible :bool, [] ?Side :StyleParam.Side, - [] ?EdgeShape :StyleParam.TreemapEdgeShape, + [] ?EdgeShape :StyleParam.PathbarEdgeShape, [] ?Thickness :float, [] ?Textfont :Font ) = @@ -58,14 +58,14 @@ type Pathbar () = ( [] ?Visible :bool, [] ?Side :StyleParam.Side, - [] ?EdgeShape :StyleParam.TreemapEdgeShape, + [] ?EdgeShape :StyleParam.PathbarEdgeShape, [] ?Thickness :float, [] ?Textfont :Font ) = (fun (pathbar:Pathbar) -> Visible |> DynObj.setValueOpt pathbar "visible" Side |> DynObj.setValueOptBy pathbar "side" StyleParam.Side.convert - EdgeShape |> DynObj.setValueOptBy pathbar "edgeshape" StyleParam.TreemapEdgeShape.convert + EdgeShape |> DynObj.setValueOptBy pathbar "edgeshape" StyleParam.PathbarEdgeShape.convert Thickness |> DynObj.setValueOpt pathbar "thickness" Textfont |> DynObj.setValueOpt pathbar "textfont " diff --git a/src/Plotly.NET/Traces/ObjectAbstractions/TreemapTiling.fs b/src/Plotly.NET/Traces/ObjectAbstractions/TreemapTiling.fs index 6960f7492..99dee9703 100644 --- a/src/Plotly.NET/Traces/ObjectAbstractions/TreemapTiling.fs +++ b/src/Plotly.NET/Traces/ObjectAbstractions/TreemapTiling.fs @@ -24,7 +24,7 @@ type TreemapTiling () = ( [] ?Packing : StyleParam.TreemapTilingPacking, [] ?SquarifyRatio : float, - [] ?Flip : string, + [] ?Flip : StyleParam.TilingFlip, [] ?Pad : float ) = @@ -52,14 +52,14 @@ type TreemapTiling () = ( [] ?Packing : StyleParam.TreemapTilingPacking, [] ?SquarifyRatio : float, - [] ?Flip : string, + [] ?Flip : StyleParam.TilingFlip, [] ?Pad : float ) = (fun (tiling:TreemapTiling) -> Packing |> DynObj.setValueOptBy tiling "packing" StyleParam.TreemapTilingPacking.convert SquarifyRatio |> DynObj.setValueOpt tiling "squarifyRatio" - Flip |> DynObj.setValueOpt tiling "flip" + Flip |> DynObj.setValueOptBy tiling "flip" StyleParam.TilingFlip.convert Pad |> DynObj.setValueOpt tiling "pad" tiling diff --git a/src/Plotly.NET/Traces/TraceDomain.fs b/src/Plotly.NET/Traces/TraceDomain.fs index 7641f0c5f..916ec4a2c 100644 --- a/src/Plotly.NET/Traces/TraceDomain.fs +++ b/src/Plotly.NET/Traces/TraceDomain.fs @@ -46,6 +46,10 @@ type TraceDomain(traceTypeName) = static member initIndicator (applyStyle: TraceDomain -> TraceDomain) = TraceDomain("indicator") |> applyStyle + ///initializes a trace of type "icicle" applying the given trace styling function + static member initIcicle (applyStyle: TraceDomain -> TraceDomain) = + TraceDomain("icicle") |> applyStyle + type TraceDomainStyle() = static member SetDomain @@ -369,3 +373,90 @@ type TraceDomainStyle() = UIRevision |> DynObj.setValueOpt trace "uirevision" trace + + static member Icicle + ( + [] ?Name : string, + [] ?Title : string, + [] ?Visible : StyleParam.Visible, + [] ?ShowLegend : bool, + [] ?LegendRank : int, + [] ?LegendGroup : string, + [] ?LegendGroupTitle : Title, + [] ?Opacity : float, + [] ?Ids : seq<#IConvertible>, + [] ?Parents : seq<#IConvertible>, + [] ?Values : seq<#IConvertible>, + [] ?Labels : seq<#IConvertible>, + [] ?Text : #IConvertible, + [] ?MultiText : seq<#IConvertible>, + [] ?TextPosition : StyleParam.TextPosition, + [] ?MultiTextPosition : seq, + [] ?TextTemplate : string, + [] ?MultiTextTemplate : seq, + [] ?HoverText : string, + [] ?MultiHoverText : seq, + [] ?HoverInfo : StyleParam.HoverInfo, + [] ?HoverTemplate : string, + [] ?MultiHoverTemplate: seq, + [] ?Meta : string, + [] ?CustomData : seq<#IConvertible>, + [] ?Domain : Domain, + [] ?Marker : Marker, + [] ?TextFont : Font, + [] ?TextInfo : StyleParam.TextInfo, + [] ?BranchValues : StyleParam.BranchValues, + [] ?Count : StyleParam.IcicleCount, + [] ?Tiling : IcicleTiling, + [] ?PathBar : Pathbar, + [] ?HoverLabel : Hoverlabel, + [] ?InsideTextFont : Font, + [] ?OutsideTextFont : Font, + [] ?Root : IcicleRoot, + [] ?Leaf : IcicleLeaf, + [] ?Level : string, + [] ?MaxDepth : int, + [] ?Sort : bool, + [] ?UIRevision : string + ) = + fun (trace: #Trace) -> + + Name |> DynObj.setValueOpt trace "name" + Title |> DynObj.setValueOpt trace "title" + Visible |> DynObj.setValueOptBy trace "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt trace "showlegend" + LegendRank |> DynObj.setValueOpt trace "legendrank" + LegendGroup |> DynObj.setValueOpt trace "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt trace "legendgrouptitle" + Opacity |> DynObj.setValueOpt trace "opacity" + Ids |> DynObj.setValueOpt trace "ids" + Parents |> DynObj.setValueOpt trace "parents" + Values |> DynObj.setValueOpt trace "values" + Labels |> DynObj.setValueOpt trace "labels" + (Text, MultiText) |> DynObj.setSingleOrMultiOpt trace "text" + (TextPosition, MultiTextPosition) |> DynObj.setSingleOrMultiOptBy trace "textposition" StyleParam.TextPosition.convert + (TextTemplate, MultiTextTemplate) |> DynObj.setSingleOrMultiOpt trace "texttemplate" + (HoverText, MultiHoverText) |> DynObj.setSingleOrMultiOpt trace "hovertext" + HoverInfo |> DynObj.setValueOptBy trace "hoverinfo" StyleParam.HoverInfo.convert + (HoverTemplate, MultiHoverTemplate) |> DynObj.setSingleOrMultiOpt trace "hovertemplate" + Meta |> DynObj.setValueOpt trace "meta" + CustomData |> DynObj.setValueOpt trace "customdata" + Domain |> DynObj.setValueOpt trace "domain" + Marker |> DynObj.setValueOpt trace "marker" + TextFont |> DynObj.setValueOpt trace "textfont" + TextInfo |> DynObj.setValueOptBy trace "textinfo" StyleParam.TextInfo.convert + BranchValues |> DynObj.setValueOptBy trace "branchvalues" StyleParam.BranchValues.convert + Count |> DynObj.setValueOptBy trace "count" StyleParam.IcicleCount.convert + Tiling |> DynObj.setValueOpt trace "tiling" + PathBar |> DynObj.setValueOpt trace "pathbar" + HoverLabel |> DynObj.setValueOpt trace "hoverlabel" + InsideTextFont |> DynObj.setValueOpt trace "insidetextfont" + OutsideTextFont |> DynObj.setValueOpt trace "outsidetextfont" + Root |> DynObj.setValueOpt trace "root" + Leaf |> DynObj.setValueOpt trace "leaf" + Level |> DynObj.setValueOpt trace "level" + MaxDepth |> DynObj.setValueOpt trace "maxdepth" + Sort |> DynObj.setValueOpt trace "sort" + UIRevision |> DynObj.setValueOpt trace "uirevision" + + trace diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/CategoricalCharts.fs b/tests/Plotly.NET.Tests/HtmlCodegen/CategoricalCharts.fs index 4a9bf9acd..c6c95cd13 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/CategoricalCharts.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/CategoricalCharts.fs @@ -112,9 +112,35 @@ let ``Sankey charts`` = testCase "Sankey data" ( fun () -> "var data = [{\"type\":\"sankey\",\"node\":{\"label\":[\"a\",\"b\",\"c\",\"d\",\"e\"],\"color\":[\"Black\",\"Red\",\"Purple\",\"Green\",\"Orange\"]},\"link\":{\"source\":[0,1,0,3,2],\"target\":[1,2,4,4,4],\"value\":[1.0,2.0,1.3,1.5,0.5]}}];" |> chartGeneratedContains sankey1 - ); + ) testCase "Sankey layout" ( fun () -> "var layout = {\"title\":{\"text\":\"Sankey Sample\"}};" |> chartGeneratedContains sankey1 - ); + ) + ] + +let character = ["Eve"; "Cain"; "Seth"; "Enos"; "Noam"; "Abel"; "Awan"; "Enoch"; "Azura"] +let parent = [""; "Eve"; "Eve"; "Seth"; "Seth"; "Eve"; "Eve"; "Awan"; "Eve" ] + +let icicleChart = + Chart.Icicle( + character, + parent, + ShowScale = true, + ColorScale = StyleParam.Colorscale.Viridis, + TilingOrientation = StyleParam.Orientation.Vertical, + TilingFlip = StyleParam.TilingFlip.Y, + PathBarEdgeShape = StyleParam.PathbarEdgeShape.BackSlash + ) + +[] +let ``Icicle charts`` = + testList "CategoricalCharts.Icicle charts" [ + testCase "Icicle data" ( fun () -> + """var data = [{"type":"icicle","parents":["","Eve","Eve","Seth","Seth","Eve","Eve","Awan","Eve"],"labels":["Eve","Cain","Seth","Enos","Noam","Abel","Awan","Enoch","Azura"],"tiling":{"flip":"y","orientation":"v"},"pathbar":{"edgeshape":"\\"},"marker":{"colorscale":"Viridis","showscale":true}}];""" + |> chartGeneratedContains icicleChart + ) + testCase "Icicle layout" ( fun () -> + emptyLayout icicleChart + ) ] \ No newline at end of file