diff --git a/Plotly.NET.sln b/Plotly.NET.sln index 543255e56..04e086deb 100644 --- a/Plotly.NET.sln +++ b/Plotly.NET.sln @@ -5,6 +5,7 @@ VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{BF60BC93-E09B-4E5F-9D85-95A519479D54}" ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig .config\dotnet-tools.json = .config\dotnet-tools.json global.json = global.json LICENSE = LICENSE @@ -97,6 +98,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{7B09CC0A-F 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\09_4_treemap.fsx = docs\09_4_treemap.fsx + docs\09_5_sunburst.fsx = docs\09_5_sunburst.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 @@ -142,11 +145,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Plotly.NET.Tests.CSharp", " EndProject Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "Plotly.NET.ImageExport.Tests", "tests\Plotly.NET.ImageExport.Tests\Plotly.NET.ImageExport.Tests.fsproj", "{55A461C3-8018-4020-B16E-D6005BDFCAED}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8E913083-86D3-4C55-B260-2AC4AC21B2D9}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/docs/02_5_pie-doughnut-charts.fsx b/docs/02_5_pie-doughnut-charts.fsx index b166bf5cc..e7f29bc67 100644 --- a/docs/02_5_pie-doughnut-charts.fsx +++ b/docs/02_5_pie-doughnut-charts.fsx @@ -45,7 +45,7 @@ When creating pie charts, it is usually desirable to provide both labels and val *) let pie1 = - Chart.Pie(values,labels) + Chart.Pie(values,Labels = labels) (*** condition: ipynb ***) #if IPYNB @@ -59,9 +59,9 @@ pie1 |> GenericChart.toChartHTML let doughnut1 = Chart.Doughnut( values, - labels, + Labels = labels, Hole=0.3, - TextLabels=labels + MultiText = labels ) (*** condition: ipynb ***) @@ -73,19 +73,48 @@ doughnut1 doughnut1 |> GenericChart.toChartHTML (***include-it-raw***) -let sunburst1 = - Chart.Sunburst( - ["A";"B";"C";"D";"E"], - ["";"";"B";"B";""], - Values=[5.;0.;3.;2.;3.], - Text=["At";"Bt";"Ct";"Dt";"Et"] +(** +## More styled example + +This example shows the usage of some of the styling possibility using `Chart.Pie`. +For even more styling control, use the respective TraceStyle function `TraceDomainStyle.Pie` +*) + + +let pieStyled = + + let values = [19; 26; 55;] + let labels = ["Residential"; "Non-Residential"; "Utility"] + + Chart.Pie( + values, + Labels = labels, + SectionColors = [ + Color.fromKeyword Aqua + Color.fromKeyword Salmon + Color.fromKeyword Tan + ], + SectionOutlineColor = Color.fromKeyword Black, + SectionOutlineWidth = 2., + MultiText = [ + "Some" + "More" + "Stuff" + ], + MultiTextPosition = [ + StyleParam.TextPosition.Inside + StyleParam.TextPosition.Outside + StyleParam.TextPosition.Inside + ], + Rotation = 45., + MultiPull = [0.; 0.3; 0.] ) (*** condition: ipynb ***) #if IPYNB -sunburst1 +pieStyled #endif // IPYNB - + (***hide***) -sunburst1 |> GenericChart.toChartHTML +pieStyled |> GenericChart.toChartHTML (***include-it-raw***) diff --git a/docs/02_6_table.fsx b/docs/02_6_table.fsx index 59fc541a7..14ff95e79 100644 --- a/docs/02_6_table.fsx +++ b/docs/02_6_table.fsx @@ -36,15 +36,15 @@ let's first create some data for the purpose of creating example charts: open Plotly.NET open Plotly.NET.StyleParam -let header = ["RowIndex";"A";"simple";"table"] -let rows = - [ - ["0";"I" ;"am" ;"a"] - ["1";"little";"example";"!"] - ] - -let table1 = Chart.Table(header, rows) +let table1 = + let header = ["RowIndex";"A";"simple";"table"] + let rows = + [ + ["0";"I" ;"am" ;"a"] + ["1";"little";"example";"!"] + ] + Chart.Table(header, rows) (*** condition: ipynb ***) #if IPYNB @@ -60,39 +60,25 @@ A little bit of styling: *) let table2 = + let header = ["RowIndex";"A";"simple";"table"] + let rows = + [ + ["0";"I" ;"am" ;"a"] + ["1";"little";"example";"!"] + ] Chart.Table( header, rows, - //sets global header alignment - AlignHeader = [HorizontalAlign.Center], - //sets alignment for each column separately - //(The last alignment is applied to all potential following columns) - AlignCells = [HorizontalAlign.Left;HorizontalAlign.Center;HorizontalAlign.Right], - //sets global header color - ColorHeader = Color.fromString "#45546a", - //sets specific color to each header column - //ColorHeader=["#45546a";"#deebf7";"#45546a";"#deebf7"], - //sets global cell color - //ColorRows = "#deebf7", - //sets cell column colors - ColorCells = Color.fromColors [ - Color.fromString "#deebf7" - Color.fromString "lightgrey" - Color.fromString "#deebf7" - Color.fromString "lightgrey" - ], - //sets cell row colors - //ColorCells=[["#deebf7";"lightgrey"]], - //sets font of header - FontHeader = Font.init(FontFamily.Courier_New, Size=12., Color=Color.fromString "white"), - //sets the height of the header - HeightHeader= 30., - //sets lines of header - LineHeader = Line.init(2.,Color.fromString "black"), - ColumnWidth = [70;50;100;70], - //defines order of columns - ColumnOrder = [1;2;3;4] - ) + HeaderAlign = StyleParam.HorizontalAlign.Center, + CellsMultiAlign = [StyleParam.HorizontalAlign.Left; StyleParam.HorizontalAlign.Center; StyleParam.HorizontalAlign.Right], + HeaderFillColor = Color.fromString "#45546a", + CellsFillColor = Color.fromColors [Color.fromString "#deebf7"; Color.fromString "lightgrey"; Color.fromString "#deebf7"; Color.fromString "lightgrey"], + HeaderHeight = 30, + HeaderOutlineColor = Color.fromString "black", + HeaderOutlineWidth = 2., + MultiColumnWidth = [70.; 50.; 100.; 70.], + ColumnOrder = [1; 2; 3; 4] + ) (*** condition: ipynb ***) #if IPYNB @@ -107,41 +93,46 @@ table2 |> GenericChart.toChartHTML Value dependent cell coloring: *) -let header2 = ["Identifier";"T0";"T1";"T2";"T3"] -let rowvalues = - [ - [10001.;0.2;2.0;4.0;5.0] - [10002.;2.1;2.0;1.8;2.1] - [10003.;4.5;3.0;2.0;2.5] - [10004.;0.0;0.1;0.3;0.2] - [10005.;1.0;1.6;1.8;2.2] - [10006.;1.0;0.8;1.5;0.7] - [10007.;2.0;2.0;2.1;1.9] - ] - |> Seq.sortBy (fun x -> x.[1]) - -//map color from value to hex representation -let mapColor min max value = - let proportion = - (255. * (value - min) / (max - min)) - |> int - Color.fromRGB 255 (255 - proportion) proportion +let table3 = + let header2 = ["Identifier";"T0";"T1";"T2";"T3"] + let rowvalues = + [ + [10001.;0.2;2.0;4.0;5.0] + [10002.;2.1;2.0;1.8;2.1] + [10003.;4.5;3.0;2.0;2.5] + [10004.;0.0;0.1;0.3;0.2] + [10005.;1.0;1.6;1.8;2.2] + [10006.;1.0;0.8;1.5;0.7] + [10007.;2.0;2.0;2.1;1.9] + ] + |> Seq.sortBy (fun x -> x.[1]) -//Assign a color to every cell seperately. Matrix must be transposed for correct orientation. -let cellcolor = - rowvalues - |> Seq.map (fun row -> - row - |> Seq.mapi (fun index value -> - if index = 0 then Color.fromString "white" - else mapColor 0. 5. value + //map color from value to hex representation + let mapColor min max value = + let proportion = + (255. * (value - min) / (max - min)) + |> int + Color.fromRGB 255 (255 - proportion) proportion + + //Assign a color to every cell seperately. Matrix must be transposed for correct orientation. + let cellcolor = + rowvalues + |> Seq.map (fun row -> + row + |> Seq.mapi (fun index value -> + if index = 0 then Color.fromString "white" + else mapColor 0. 5. value + ) ) - ) - |> Seq.transpose - |> Seq.map Color.fromColors - |> Color.fromColors + |> Seq.transpose + |> Seq.map Color.fromColors + |> Color.fromColors -let table3 = Chart.Table(header2,rowvalues,ColorCells=cellcolor) + Chart.Table( + header2, + rowvalues, + CellsFillColor=cellcolor + ) (*** condition: ipynb ***) #if IPYNB @@ -158,7 +149,8 @@ Sequence representation: *) -let sequence = +let table4 = + let sequence = [ "ATGAGACGTCGAGACTGATAGACGTCGATAGACGTCGATAGACCG" "ATAGACTCGTGATAGACGTCGATAGACGTCGATAGAGTATAGACC" @@ -168,59 +160,56 @@ let sequence = ] |> String.concat "" -let elementsPerRow = 60 + let elementsPerRow = 60 -let headers = - [0..elementsPerRow] - |> Seq.map (fun x -> - if x%10=0 && x <> 0 then "|" - else "" - ) + let headers = + [0..elementsPerRow] + |> Seq.map (fun x -> + if x%10=0 && x <> 0 then "|" + else "" + ) -let cells = - sequence - |> Seq.chunkBySize elementsPerRow - |> Seq.mapi (fun i x -> Seq.append [string (i * elementsPerRow)] (Seq.map string x)) - -let cellcolors = - cells - |> Seq.map (fun row -> - row - |> Seq.map (fun element -> - match element with - //colors taken from DRuMS - //(http://biomodel.uah.es/en/model4/dna/atgc.htm) - | "A" -> Color.fromHex "#5050FF" - | "T" -> Color.fromHex "#E6E600" - | "G" -> Color.fromHex "#00C000" - | "C" -> Color.fromHex "#E00000" - | "U" -> Color.fromHex "#B48100" - | _ -> Color.fromString "white" + let cells = + sequence + |> Seq.chunkBySize elementsPerRow + |> Seq.mapi (fun i x -> Seq.append [string (i * elementsPerRow)] (Seq.map string x)) + + let cellcolors = + cells + |> Seq.map (fun row -> + row + |> Seq.map (fun element -> + match element with + //colors taken from DRuMS + //(http://biomodel.uah.es/en/model4/dna/atgc.htm) + | "A" -> Color.fromString "#5050FF" + | "T" -> Color.fromString "#E6E600" + | "G" -> Color.fromString "#00C000" + | "C" -> Color.fromString "#E00000" + | "U" -> Color.fromString "#B48100" + | _ -> Color.fromString "white" + ) ) - ) - |> Seq.transpose - |> Seq.map (fun x -> Seq.append x (seq [Color.fromString "white"])) - |> Seq.map Color.fromColors - |> Color.fromColors + |> Seq.transpose + |> Seq.map (fun x -> Seq.append x (seq [Color.fromString "white"])) + |> Seq.map Color.fromColors + |> Color.fromColors -let font = Font.init(FontFamily.Consolas,Size=14.) -let line = Line.init(0.,Color.fromString "white") -let chartwidth = 50. + 10. * float elementsPerRow + let line = Line.init(Width = 0., Color = Color.fromString "white") + let chartwidth = 50 + 10 * elementsPerRow -let table4 = Chart.Table( headers, cells, - LineCells = line, - LineHeader = line, - HeightCells = 20., - FontHeader = font, - FontCells = font, - ColumnWidth = [50;10], - AlignCells = [HorizontalAlign.Right;HorizontalAlign.Center], - ColorCells = cellcolors + CellsOutline = line, + HeaderOutline = line, + CellsHeight = 20, + MultiColumnWidth = [50.;10.], + CellsMultiAlign = [StyleParam.HorizontalAlign.Right;StyleParam.HorizontalAlign.Center], + CellsFillColor = cellcolors, + UseDefaults = false ) - |> Chart.withSize(chartwidth,nan) + |> Chart.withSize(Width=chartwidth) |> Chart.withTitle "Sequence A" (*** condition: ipynb ***) diff --git a/docs/07_3_funnel_area.fsx b/docs/07_3_funnel_area.fsx index 7736d0c61..105aef81b 100644 --- a/docs/07_3_funnel_area.fsx +++ b/docs/07_3_funnel_area.fsx @@ -47,7 +47,7 @@ open Plotly.NET let line = Line.init (Color=Color.fromString "purple", Width=3.) let funnelArea = - Chart.FunnelArea(Values=values, Text=text, Line=line) + Chart.FunnelArea(values, MultiText=text, SectionOutline=line) (*** condition: ipynb ***) #if IPYNB @@ -58,3 +58,38 @@ funnelArea funnelArea |> GenericChart.toChartHTML (***include-it-raw***) + +(** +## More styled example + +This example shows the usage of some of the styling possibility using `Chart.FunnelArea`. +For even more styling control, use the respective TraceStyle function `TraceDomainStyle.FunnelArea` +*) + +let funnelAreaStyled = + let values = [|5; 4; 3|] + let labels = [|"The 1st"; "The 2nd"; "The 3rd"|] + + Chart.FunnelArea( + values, + Labels = labels, + MultiText = labels, + SectionColors = [ + Color.fromKeyword Aqua + Color.fromKeyword Salmon + Color.fromKeyword Tan + ], + SectionOutlineColor = Color.fromKeyword Black, + SectionOutlineWidth = 2., + AspectRatio = 0.75, + BaseRatio = 0.1 + ) + +(*** condition: ipynb ***) +#if IPYNB +funnelAreaStyled +#endif // IPYNB + +(***hide***) +funnelAreaStyled |> GenericChart.toChartHTML +(***include-it-raw***) \ No newline at end of file diff --git a/docs/09_0_parallel-categories.fsx b/docs/09_0_parallel-categories.fsx index a3b328900..ac7c704e2 100644 --- a/docs/09_0_parallel-categories.fsx +++ b/docs/09_0_parallel-categories.fsx @@ -45,8 +45,8 @@ let dims = let parcats = Chart.ParallelCategories( dims, - Color = Color.fromColorScaleValues [0.;1.;0.;1.;0.;0.;0.], - Colorscale = StyleParam.Colorscale.Blackbody + LineColor = Color.fromColorScaleValues [0.;1.;0.;1.;0.;0.;0.], + LineColorScale = StyleParam.Colorscale.Blackbody ) (*** condition: ipynb ***) @@ -56,4 +56,35 @@ parcats (***hide***) parcats |> GenericChart.toChartHTML -(***include-it-raw***) \ No newline at end of file +(***include-it-raw***) + +(** +## More styled example + +This example shows the usage of some of the styling possibility using `Chart.ParallelCategories`. +For even more styling control, use the respective TraceStyle function `TraceDomainStyle.ParallelCategories` +*) + +let parcatsStyled = + let dims = + [ + Dimension.initParallel(Values = ["A";"A";"A";"B";"B";"B";"C";"D"],Label="Lvl1") + Dimension.initParallel(Values = ["AA";"AA";"AB";"AB";"AB";"AB";"AB";"AB"],Label="Lvl2") + Dimension.initParallel(Values = ["AAA";"AAB";"AAC";"AAC";"AAB";"AAB";"AAA";"AAA"],Label="Lvl3") + ] + + Chart.ParallelCategories( + dims, + LineColor = Color.fromColorScaleValues [0; 1; 2; 2; 1; 1; 0; 0], // These values map to the last category axis, meaning [AAA => 0; AAB = 1; AAC => 2] + LineColorScale = StyleParam.Colorscale.Viridis, + BundleColors = false + ) + +(*** condition: ipynb ***) +#if IPYNB +parcatsStyled +#endif // IPYNB + +(***hide***) +parcatsStyled |> GenericChart.toChartHTML +(***include-it-raw***) diff --git a/docs/09_1_parallel-coords.fsx b/docs/09_1_parallel-coords.fsx index cc9f5ba0a..daae58e71 100644 --- a/docs/09_1_parallel-coords.fsx +++ b/docs/09_1_parallel-coords.fsx @@ -53,7 +53,7 @@ the position of the vertex on the i-th axis corresponds to the i-th coordinate o *) let parcoords1 = - Chart.ParallelCoord(data,Color=Color.fromString "blue", UseDefaults = false) + Chart.ParallelCoord(data,LineColor=Color.fromString "blue", UseDefaults = false) (*** condition: ipynb ***) #if IPYNB @@ -64,48 +64,54 @@ parcoords1 parcoords1 |> GenericChart.toChartHTML (***include-it-raw***) +(** +## More styled example + +This example shows the usage of some of the styling possibility using `Chart.ParallelCoord`. +For even more styling control, use the respective TraceStyle function `TraceDomainStyle.ParallelCoord` +*) + open Plotly.NET.TraceObjects -// Dynamic object version - -let parcoords = - let v = [| - Dimension.initParallel( - Values = [|1.;4.;|], - Range = StyleParam.Range.MinMax (1.,5.), - ConstraintRange = StyleParam.Range.MinMax (1.,2.), - Label="A"); - Dimension.initParallel( - Values = [|3.;1.5;|], - Range = StyleParam.Range.MinMax (1.,5.), - Label="B", - Tickvals=[|1.5;3.;4.;5.;|]); - Dimension.initParallel( - Values = [|2.;4.;|], - Range = StyleParam.Range.MinMax (1.,5.), - Label= "C", - Tickvals=[|1.;2.;4.;5.;|], - TickText=[|"txt 1";"txt 2";"txt 4";"txt 5";|]); - Dimension.initParallel( - Values = [|4.;2.;|], - Range = StyleParam.Range.MinMax (1.,5.), - Label="D"); - |] - - let dyn = Trace("parcoords") - - dyn?dimensions <- v - dyn?line <- Line.init(Color =Color.fromString "blue") - - dyn - |> GenericChart.ofTraceObject false +#r "nuget: FSharp.Data" +#r "nuget: Deedle" + +open FSharp.Data +open Deedle + +let parcoordsStyled = + + let data = + "https://raw.githubusercontent.com/bcdunbar/datasets/master/iris.csv" + |> Http.RequestString + |> Frame.ReadCsvString + + let dims = + [ + Dimension.initParallel(Label = "sepal_length", Values = (data |> Frame.getCol "sepal_length" |> Series.values), Range = StyleParam.Range.MinMax(0., 8.)) + Dimension.initParallel(Label = "sepal_width" , Values = (data |> Frame.getCol "sepal_width" |> Series.values), Range = StyleParam.Range.MinMax(0., 8.)) + Dimension.initParallel(Label = "petal_length", Values = (data |> Frame.getCol "petal_length" |> Series.values), Range = StyleParam.Range.MinMax(0., 8.)) + Dimension.initParallel(Label = "petal_width" , Values = (data |> Frame.getCol "petal_width" |> Series.values), Range = StyleParam.Range.MinMax(0., 8.)) + ] + + let colors = + data + |> Frame.getCol "species_id" + |> Series.values + |> Color.fromColorScaleValues + + Chart.ParallelCoord( + dims, + LineColorScale = StyleParam.Colorscale.Viridis, + LineColor = colors + ) + (*** condition: ipynb ***) #if IPYNB -parcoords +parcoordsStyled #endif // IPYNB - + (***hide***) -parcoords |> GenericChart.toChartHTML +parcoordsStyled |> GenericChart.toChartHTML (***include-it-raw***) - diff --git a/docs/09_2_sankey.fsx b/docs/09_2_sankey.fsx index 745020821..2ac15f30a 100644 --- a/docs/09_2_sankey.fsx +++ b/docs/09_2_sankey.fsx @@ -35,29 +35,38 @@ These are usually used to depict flow between nodes or stations. To create Sankey, a set of nodes and links between them are required. These are created using the provided Node and Link structures. *) - -open Plotly.NET - -// create nodes -let n1 = Node.Create("a",color="Black") -let n2 = Node.Create("b",color="Red") -let n3 = Node.Create("c",color="Purple") -let n4 = Node.Create("d",color="Green") -let n5 = Node.Create("e",color="Orange") - -// create links between nodes -let link1 = Link.Create(n1,n2,value=1.0) -let link2 = Link.Create(n2,n3,value=2.0) -let link3 = Link.Create(n1,n5,value=1.3) -let link4 = Link.Create(n4,n5,value=1.5) -let link5 = Link.Create(n3,n5,value=0.5) +open Plotly.NET let sankey1 = Chart.Sankey( - [n1;n2;n3;n4;n5], - [link1;link2;link3;link4;link5] + nodeLabels = ["A1"; "A2"; "B1"; "B2"; "C1"; "C2"; "D1"], + linkedNodeIds = [ // Edgelist, toupling sourceIndex => targetIndex of the link + 0,2 + 0,3 + 1,3 + 2,4 + 3,4 + 3,5 + 4,6 + 5,6 + ], + NodeOutlineColor = Color.fromKeyword Black, + NodeOutlineWidth = 1., + linkValues = [8; 4; 2; 7; 3; 2; 5; 2], + LinkColor = Color.fromColors [ + Color.fromHex "#828BFB" + Color.fromHex "#828BFB" + Color.fromHex "#F27762" + Color.fromHex "#33D6AB" + Color.fromHex "#BC82FB" + Color.fromHex "#BC82FB" + Color.fromHex "#FFB47B" + Color.fromHex "#47DCF5" + ], + LinkOutlineColor = Color.fromKeyword Black, + LinkOutlineWidth = 1., + UseDefaults = false ) - |> Chart.withTitle "Sankey Sample" (*** condition: ipynb ***) #if IPYNB diff --git a/docs/09_3_icicle.fsx b/docs/09_3_icicle.fsx index 288f9e615..04348f111 100644 --- a/docs/09_3_icicle.fsx +++ b/docs/09_3_icicle.fsx @@ -42,14 +42,14 @@ 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 = +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) + ShowSectionColorScale = true, + SectionColorScale = StyleParam.Colorscale.Viridis, + TilingOrientation = StyleParam.Orientation.Vertical, + TilingFlip = StyleParam.TilingFlip.Y, PathBarEdgeShape = StyleParam.PathbarEdgeShape.BackSlash ) @@ -62,3 +62,46 @@ icicle icicle |> GenericChart.toChartHTML (***include-it-raw***) +(** +## More styled example + +This example shows the usage of some of the styling possibility using `Chart.Icicle`. +For even more styling control, use the respective TraceStyle function `TraceDomainStyle.Icicle` +*) + +let icicleStyled = + let labelsParents = [ + ("A",""), 20 + ("B",""), 1 + ("C",""), 2 + ("D",""), 3 + ("E",""), 4 + + ("AA","A"), 15 + ("AB","A"), 5 + + ("BA","B"), 1 + + ("AAA", "AA"), 10 + ("AAB", "AA"), 5 + ] + + Chart.Icicle( + labelsParents |> Seq.map fst, + Values = (labelsParents |> Seq.map snd), + BranchValues = StyleParam.BranchValues.Total, // branch values are the total of their childrens values + SectionColorScale = StyleParam.Colorscale.Viridis, + ShowSectionColorScale = true, + SectionOutlineColor = Color.fromKeyword Black, + Tiling = IcicleTiling.init(Flip = StyleParam.TilingFlip.XY), + UseDefaults = false + ) + +(*** condition: ipynb ***) +#if IPYNB +icicleStyled +#endif // IPYNB + +(***hide***) +icicleStyled |> GenericChart.toChartHTML +(***include-it-raw***) diff --git a/docs/09_4_treemap.fsx b/docs/09_4_treemap.fsx new file mode 100644 index 000000000..24bb778db --- /dev/null +++ b/docs/09_4_treemap.fsx @@ -0,0 +1,81 @@ +(** +--- +title: Treemap Charts +category: Categorical Charts +categoryindex: 10 +index: 5 +--- +*) + + +(*** hide ***) + +(*** condition: prepare ***) +#r "nuget: Newtonsoft.JSON, 12.0.3" +#r "nuget: DynamicObj" +#r "../bin/Plotly.NET/netstandard2.0/Plotly.NET.dll" + +(*** condition: ipynb ***) +#if IPYNB +#r "nuget: Plotly.NET, {{fsdocs-package-version}}" +#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}" +#endif // IPYNB + +(** +# Treemap 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 treemap charts in F#. + +Treemap Chart is intended for the visualization of hierarchical data in the form of nested rectangles. +Each level of such a tree structure is depicted as a colored rectangle, often called a branch, which contains other rectangles (leaves). +The space inside each of the rectangles that compose a Treemap is highlighted based on the quantitative value in the corresponding data point. + +## Treemap example + +This example shows the usage of some of the styling possibility using `Chart.Treemap`. +For even more styling control, use the respective TraceStyle function `TraceDomainStyle.Treemap` +*) + +open Plotly.NET +open Plotly.NET.TraceObjects + +let treemapStyled = + let labelsParents = [ + ("A",""), 20 + ("B",""), 1 + ("C",""), 2 + ("D",""), 3 + ("E",""), 4 + + ("AA","A"), 15 + ("AB","A"), 5 + + ("BA","B"), 1 + + ("AAA", "AA"), 10 + ("AAB", "AA"), 5 + ] + + Chart.Treemap( + labelsParents |> Seq.map fst, + Values = (labelsParents |> Seq.map snd), + BranchValues = StyleParam.BranchValues.Total, // branch values are the total of their childrens values + SectionColorScale = StyleParam.Colorscale.Viridis, + ShowSectionColorScale = true, + SectionOutlineColor = Color.fromKeyword Black, + Tiling = TreemapTiling.init(Packing = StyleParam.TreemapTilingPacking.SliceDice) + ) + +(*** condition: ipynb ***) +#if IPYNB +treemapStyled +#endif // IPYNB + +(***hide***) +treemapStyled |> GenericChart.toChartHTML +(***include-it-raw***) + diff --git a/docs/09_5_sunburst.fsx b/docs/09_5_sunburst.fsx new file mode 100644 index 000000000..649304092 --- /dev/null +++ b/docs/09_5_sunburst.fsx @@ -0,0 +1,94 @@ +(** +--- +title: Sunburst Charts +category: Categorical Charts +categoryindex: 10 +index: 6 +--- +*) + + +(*** hide ***) + +(*** condition: prepare ***) +#r "nuget: Newtonsoft.JSON, 12.0.3" +#r "nuget: DynamicObj" +#r "../bin/Plotly.NET/netstandard2.0/Plotly.NET.dll" + +(*** condition: ipynb ***) +#if IPYNB +#r "nuget: Plotly.NET, {{fsdocs-package-version}}" +#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}" +#endif // IPYNB + +(** +# Sunburst 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 sunburst charts in F#. + +Sunburst Chart � also known as Ring Chart, Multi-level Pie Chart, and Radial Treemap � is typically used to visualize hierarchical data structures. +A Sunburst Chart consists of an inner circle surrounded by rings of deeper hierarchy levels. +The angle of each segment is either proportional to a value or divided equally under its parent node. + +## Simple sunburst plot +*) +open Plotly.NET + +let values = [19; 26; 55;] +let labels = ["Residential"; "Non-Residential"; "Utility"] + +let sunburstChart = + Chart.Sunburst( + ["A";"B";"C";"D";"E"], + ["";"";"B";"B";""], + Values=[5.;0.;3.;2.;3.], + MultiText=["At";"Bt";"Ct";"Dt";"Et"] + ) + +(** +## More styled example + +This example shows the usage of some of the styling possibility using `Chart.Sunburst`. +For even more styling control, use the respective TraceStyle function `TraceDomainStyle.Sunburst` +*) + +let sunburstStyled = + let labelsParents = [ + ("A",""), 20 + ("B",""), 1 + ("C",""), 2 + ("D",""), 3 + ("E",""), 4 + + ("AA","A"), 15 + ("AB","A"), 5 + + ("BA","B"), 1 + + ("AAA", "AA"), 10 + ("AAB", "AA"), 5 + ] + + Chart.Sunburst( + labelsParents |> Seq.map fst, + Values = (labelsParents |> Seq.map snd), + BranchValues = StyleParam.BranchValues.Total, // branch values are the total of their childrens values + SectionColorScale = StyleParam.Colorscale.Viridis, + ShowSectionColorScale = true, + SectionOutlineColor = Color.fromKeyword Black, + Rotation = 45, + UseDefaults = false + ) + +(*** condition: ipynb ***) +#if IPYNB +sunburstStyled +#endif // IPYNB + +(***hide***) +sunburstStyled |> GenericChart.toChartHTML +(***include-it-raw***) diff --git a/src/Plotly.NET/ChartAPI/Chart2D.fs b/src/Plotly.NET/ChartAPI/Chart2D.fs index 724757491..e54744b19 100644 --- a/src/Plotly.NET/ChartAPI/Chart2D.fs +++ b/src/Plotly.NET/ChartAPI/Chart2D.fs @@ -30,6 +30,7 @@ module Chart2D = Trace2D.initHeatmap style |> GenericChart.ofTraceObject useDefaults + /// /// Creates a Scatter chart. Scatter charts are the basis of Point, Line, and Bubble Charts in Plotly, and can be customized as such. We also provide abstractions for those: Chart.Line, Chart.Point, Chart.Bubble /// diff --git a/src/Plotly.NET/ChartAPI/ChartDomain.fs b/src/Plotly.NET/ChartAPI/ChartDomain.fs index fa3e862f6..77fcbe4f6 100644 --- a/src/Plotly.NET/ChartAPI/ChartDomain.fs +++ b/src/Plotly.NET/ChartAPI/ChartDomain.fs @@ -23,44 +23,70 @@ module ChartDomain = static member Pie ( values: seq<#IConvertible>, - [] ?Labels: seq<#IConvertible>, [] ?Name: string, - [] ?TextLabels: seq<#IConvertible>, - [] ?TextPosition: StyleParam.TextPosition, - [] ?Direction: StyleParam.Direction, - [] ?Pull: float, [] ?ShowLegend: bool, - [] ?SectionColors: seq, [] ?Opacity: float, + [] ?MultiOpacity: seq, + [] ?Labels: seq<#IConvertible>, + [] ?Pull: float, + [] ?MultiPull: seq, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, + [] ?TextPosition: StyleParam.TextPosition, + [] ?MultiTextPosition: seq, + [] ?SectionColors: seq, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, + [] ?TextInfo: StyleParam.TextInfo, + [] ?Direction: StyleParam.Direction, + [] ?Hole: float, + [] ?Rotation: float, [] ?Sort: bool, - [] ?UseDefaults: bool + [] ?UseDefaults: bool ) = let useDefaults = defaultArg UseDefaults true + let outline = + SectionOutline + |> Option.defaultValue (Line.init ()) + |> Line.style ( + ?Color = SectionOutlineColor, + ?Width = SectionOutlineWidth, + ?MultiWidth = SectionOutlineMultiWidth + ) + + let marker = + Marker + |> Option.defaultValue (TraceObjects.Marker.init ()) + |> TraceObjects.Marker.style (?Colors = SectionColors, ?MultiOpacity = MultiOpacity, Outline = outline) + + TraceDomain.initPie ( TraceDomainStyle.Pie( Values = values, - ?Labels = Labels, ?Name = Name, - ?Text = TextLabels, - ?TextPosition = TextPosition, - ?Direction = Direction, - ?Pull = Pull, ?ShowLegend = ShowLegend, ?Opacity = Opacity, + ?Labels = Labels, + ?Pull = Pull, + ?MultiPull = MultiPull, + ?Text = Text, + ?MultiText = MultiText, + ?TextPosition = TextPosition, + ?MultiTextPosition = MultiTextPosition, + Marker = marker, + ?TextInfo = TextInfo, + ?Direction = Direction, + ?Hole = Hole, + ?Rotation = Rotation, ?Sort = Sort + ) ) - |> TraceStyle.Marker(?Colors = SectionColors) - |> TraceStyle.TextLabel( - ?Text = - (if TextLabels.IsSome then - TextLabels - else - Labels), - ?Textposition = TextPosition - ) |> GenericChart.ofTraceObject useDefaults /// Shows how proportions of data, shown as pie-shaped pieces, contribute to the data. @@ -69,15 +95,27 @@ module ChartDomain = ( valuesLabels: seq<#IConvertible * #IConvertible>, [] ?Name: string, - [] ?TextLabels: seq<#IConvertible>, - [] ?TextPosition: StyleParam.TextPosition, - [] ?Direction: StyleParam.Direction, - [] ?Pull: float, [] ?ShowLegend: bool, - [] ?SectionColors: seq, [] ?Opacity: float, + [] ?MultiOpacity: seq, + [] ?Pull: float, + [] ?MultiPull: seq, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, + [] ?TextPosition: StyleParam.TextPosition, + [] ?MultiTextPosition: seq, + [] ?SectionColors: seq, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, + [] ?TextInfo: StyleParam.TextInfo, + [] ?Direction: StyleParam.Direction, + [] ?Hole: float, + [] ?Rotation: float, [] ?Sort: bool, - [] ?UseDefaults: bool + [] ?UseDefaults: bool ) = let values, labels = Seq.unzip valuesLabels @@ -86,13 +124,25 @@ module ChartDomain = values, Labels = labels, ?Name = Name, - ?TextLabels = TextLabels, - ?TextPosition = TextPosition, - ?Direction = Direction, - ?Pull = Pull, ?ShowLegend = ShowLegend, - ?SectionColors = SectionColors, ?Opacity = Opacity, + ?MultiOpacity = MultiOpacity, + ?Pull = Pull, + ?MultiPull = MultiPull, + ?Text = Text, + ?MultiText = MultiText, + ?TextPosition = TextPosition, + ?MultiTextPosition = MultiTextPosition, + ?SectionColors = SectionColors, + ?SectionOutlineColor = SectionOutlineColor, + ?SectionOutlineWidth = SectionOutlineWidth, + ?SectionOutlineMultiWidth = SectionOutlineMultiWidth, + ?SectionOutline = SectionOutline, + ?Marker = Marker, + ?TextInfo = TextInfo, + ?Direction = Direction, + ?Hole = Hole, + ?Rotation = Rotation, ?Sort = Sort, ?UseDefaults = UseDefaults ) @@ -103,48 +153,60 @@ module ChartDomain = static member Doughnut ( values: seq<#IConvertible>, - [] ?Labels: seq<#IConvertible>, - [] ?Hole: float, [] ?Name: string, - [] ?TextLabels: seq<#IConvertible>, - [] ?TextPosition: StyleParam.TextPosition, - [] ?Direction: StyleParam.Direction, - [] ?Pull: float, + [] ?Hole: float, [] ?ShowLegend: bool, - [] ?SectionColors: seq, [] ?Opacity: float, + [] ?MultiOpacity: seq, + [] ?Labels: seq<#IConvertible>, + [] ?Pull: float, + [] ?MultiPull: seq, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, + [] ?TextPosition: StyleParam.TextPosition, + [] ?MultiTextPosition: seq, + [] ?SectionColors: seq, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, + [] ?TextInfo: StyleParam.TextInfo, + [] ?Direction: StyleParam.Direction, + [] ?Rotation: float, [] ?Sort: bool, - [] ?UseDefaults: bool + [] ?UseDefaults: bool ) = let useDefaults = defaultArg UseDefaults true - let hole' = Option.defaultValue 0.4 Hole + let hole = Option.defaultValue 0.4 Hole - TraceDomain.initPie ( - TraceDomainStyle.Pie( - Values = values, - ?Labels = Labels, - ?Name = Name, - ?Text = TextLabels, - ?TextPosition = TextPosition, - ?Direction = Direction, - ?Pull = Pull, - ?ShowLegend = ShowLegend, - ?Opacity = Opacity, - Hole = hole', - ?Sort = Sort - ) - ) - |> TraceStyle.Marker(?Colors = SectionColors) - |> TraceStyle.TextLabel( - ?Text = - (if TextLabels.IsSome then - TextLabels - else - Labels), - ?Textposition = TextPosition + Chart.Pie( + values, + Hole = hole, + ?Labels = Labels, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Opacity = Opacity, + ?MultiOpacity = MultiOpacity, + ?MultiPull = MultiPull, + ?Pull = Pull, + ?Text = Text, + ?MultiText = MultiText, + ?TextPosition = TextPosition, + ?MultiTextPosition = MultiTextPosition, + ?SectionColors = SectionColors, + ?SectionOutlineColor = SectionOutlineColor, + ?SectionOutlineWidth = SectionOutlineWidth, + ?SectionOutlineMultiWidth = SectionOutlineMultiWidth, + ?SectionOutline = SectionOutline, + ?Marker = Marker, + ?TextInfo = TextInfo, + ?Direction = Direction, + ?Rotation = Rotation, + ?Sort = Sort, + ?UseDefaults = UseDefaults ) - |> GenericChart.ofTraceObject useDefaults /// Shows how proportions of data, shown as pie-shaped pieces, contribute to the data as a whole. @@ -154,30 +216,52 @@ module ChartDomain = valuesLabels: seq<#IConvertible * #IConvertible>, [] ?Hole: float, [] ?Name: string, - [] ?TextLabels: seq<#IConvertible>, - [] ?TextPosition: StyleParam.TextPosition, - [] ?Direction: StyleParam.Direction, - [] ?Pull: float, [] ?ShowLegend: bool, - [] ?SectionColors: seq, [] ?Opacity: float, + [] ?MultiOpacity: seq, + [] ?Pull: float, + [] ?MultiPull: seq, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, + [] ?TextPosition: StyleParam.TextPosition, + [] ?MultiTextPosition: seq, + [] ?SectionColors: seq, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, + [] ?TextInfo: StyleParam.TextInfo, + [] ?Direction: StyleParam.Direction, + [] ?Rotation: float, [] ?Sort: bool, - [] ?UseDefaults: bool + [] ?UseDefaults: bool ) = let values, labels = Seq.unzip valuesLabels Chart.Doughnut( values, Labels = labels, + ?Hole = Hole, ?Name = Name, - ?TextLabels = TextLabels, - ?TextPosition = TextPosition, - ?Direction = Direction, - ?Pull = Pull, ?ShowLegend = ShowLegend, - ?SectionColors = SectionColors, ?Opacity = Opacity, - ?Hole = Hole, + ?MultiOpacity = MultiOpacity, + ?Pull = Pull, + ?MultiPull = MultiPull, + ?Text = Text, + ?MultiText = MultiText, + ?TextPosition = TextPosition, + ?MultiTextPosition = MultiTextPosition, + ?SectionColors = SectionColors, + ?SectionOutlineColor = SectionOutlineColor, + ?SectionOutlineWidth = SectionOutlineWidth, + ?SectionOutlineMultiWidth = SectionOutlineMultiWidth, + ?SectionOutline = SectionOutline, + ?Marker = Marker, + ?TextInfo = TextInfo, + ?Direction = Direction, + ?Rotation = Rotation, ?Sort = Sort, ?UseDefaults = UseDefaults ) @@ -185,422 +269,857 @@ module ChartDomain = /// Creates a FunnelArea chart. - /// FunnelArea charts visualize stages in a process using area-encoded trapezoids. This trace can be used to show data in a part-to-whole representation similar to a "pie" trace, wherein each item appears in a single stage. See also the "funnel" trace type for a different approach to visualizing funnel data. - /// - /// Parameters: - /// - /// Values : Sets the values of the sectors. If omitted, we count occurrences of each label. - /// - /// Labels : Sets the sector labels. If `labels` entries are duplicated, we sum associated `values` or simply count occurrences if `values` is not provided. For other array attributes (including color) we use the first non-empty entry among all occurrences of the label. - /// - /// dLabel : Sets the label step. See `label0` for more info. - /// - /// Label0 : Alternate to `labels`. Builds a numeric set of labels. Use with `dlabel` where `label0` is the starting label and `dlabel` the step. - /// - /// Name : Sets the trace name. The trace name appear as the legend item and on hover. - /// - /// ShowLegend : Determines whether or not an item corresponding to this trace is shown in the legend. - /// - /// Opacity : Sets the opacity of the trace. - /// - /// Color : Sets Marker Color - /// - /// Line : Line type - /// - /// Text : Sets text elements associated with each sector. If trace `textinfo` contains a "text" flag, these elements will be seen on the chart. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. - /// - /// TextPosition : Specifies the location of the `textinfo`. - /// - /// X : Sets the horizontal domain of this funnelarea trace (in plot fraction). - /// - /// Y : Sets the vertical domain of this funnelarea trace (in plot fraction). - /// - /// Row : If there is a layout grid, use the domain for this row in the grid for this funnelarea trace . - /// - /// Column : If there is a layout grid, use the domain for this column in the grid for this funnelarea trace . - /// - /// Aspectratio : Sets the ratio between height and width - /// - /// Baseratio : Sets the ratio between bottom length and maximum top length. - /// - /// Insidetextfont: Sets the font used for `textinfo` lying inside the sector. - /// - /// Scalegroup : If there are multiple funnelareas that should be sized according to their totals, link them by providing a non-empty group id here shared by every trace in the same group. [] static member FunnelArea ( - [] ?Values, - [] ?Labels, - [] ?dLabel, - [] ?Label0, - [] ?Name, - [] ?ShowLegend, - [] ?Opacity, - [] ?Color, - [] ?Line, - [] ?Text, - [] ?TextPosition, - [] ?X, - [] ?Y, - [] ?Row, - [] ?Column, - [] ?Aspectratio, - [] ?Baseratio, - [] ?Insidetextfont, - [] ?Scalegroup, - [] ?UseDefaults: bool + values: seq<#IConvertible>, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?Opacity: float, + [] ?MultiOpacity: seq, + [] ?Labels: seq<#IConvertible>, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, + [] ?TextPosition: StyleParam.TextPosition, + [] ?MultiTextPosition: seq, + [] ?SectionColors: seq, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, + [] ?TextInfo: StyleParam.TextInfo, + [] ?AspectRatio: float, + [] ?BaseRatio: float, + [] ?UseDefaults: bool ) = + let useDefaults = defaultArg UseDefaults true + let outline = + SectionOutline + |> Option.defaultValue (Line.init ()) + |> Line.style ( + ?Color = SectionOutlineColor, + ?Width = SectionOutlineWidth, + ?MultiWidth = SectionOutlineMultiWidth + ) + + let marker = + Marker + |> Option.defaultValue (TraceObjects.Marker.init ()) + |> TraceObjects.Marker.style (?Colors = SectionColors, ?MultiOpacity = MultiOpacity, Outline = outline) + + TraceDomain.initFunnelArea ( TraceDomainStyle.FunnelArea( - ?Values = Values, + Values = values, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Opacity = Opacity, ?Labels = Labels, - ?dLabel = dLabel, - ?Label0 = Label0, - ?Aspectratio = Aspectratio, - ?Baseratio = Baseratio, - ?Insidetextfont = Insidetextfont, - ?Scalegroup = Scalegroup + ?Text = Text, + ?MultiText = MultiText, + ?TextPosition = TextPosition, + ?MultiTextPosition = MultiTextPosition, + Marker = marker, + ?TextInfo = TextInfo, + ?AspectRatio = AspectRatio, + ?BaseRatio = BaseRatio ) ) - |> TraceStyle.TraceInfo(?Name = Name, ?ShowLegend = ShowLegend, ?Opacity = Opacity) - |> TraceStyle.Marker(?Color = Color, ?Outline = Line) - |> TraceStyle.Domain(?X = X, ?Y = Y, ?Row = Row, ?Column = Column) - |> TraceStyle.TextLabel(?Text = Text, ?Textposition = TextPosition) |> GenericChart.ofTraceObject useDefaults + /// Creates a FunnelArea chart. + [] + static member FunnelArea + ( + valuesLabels: seq<#IConvertible * #IConvertible>, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?Opacity: float, + [] ?MultiOpacity: seq, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, + [] ?TextPosition: StyleParam.TextPosition, + [] ?MultiTextPosition: seq, + [] ?SectionColors: seq, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, + [] ?TextInfo: StyleParam.TextInfo, + [] ?AspectRatio: float, + [] ?BaseRatio: float, + [] ?UseDefaults: bool + ) = + let values, labels = Seq.unzip valuesLabels + + Chart.FunnelArea( + values, + Labels = labels, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Opacity = Opacity, + ?MultiOpacity = MultiOpacity, + ?Text = Text, + ?MultiText = MultiText, + ?TextPosition = TextPosition, + ?MultiTextPosition = MultiTextPosition, + ?SectionColors = SectionColors, + ?SectionOutlineColor = SectionOutlineColor, + ?SectionOutlineWidth = SectionOutlineWidth, + ?SectionOutlineMultiWidth = SectionOutlineMultiWidth, + ?SectionOutline = SectionOutline, + ?Marker = Marker, + ?TextInfo = TextInfo, + ?AspectRatio = AspectRatio, + ?BaseRatio = BaseRatio, + ?UseDefaults = UseDefaults + ) + /// Creates a sunburst chart. Visualize hierarchical data spanning outward radially from root to leaves. - /// Applies the styles of sundburst plot to TraceObjects - /// - /// Parameters: - /// - /// labels: Sets the labels of each of the sectors. - /// - /// parents: Sets the parent sectors for each of the sectors. Empty string items '' are understood to reference the root node in the hierarchy. If `ids` is filled, `parents` items are understood to be "ids" themselves. When `ids` is not set, plotly attempts to find matching items in `labels`, but beware they must be unique. - /// - /// Ids: Assigns id labels to each datum. These ids for object constancy of data points during animation. - /// - /// Values: Sets the values associated with each of the sectors. Use with `branchvalues` to determine how the values are summed. - /// - /// Text: Sets text elements associated with each sector. If trace `textinfo` contains a "text" flag, these elements will be seen on the chart. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. - /// - /// Branchvalues: Determines how the items in `values` are summed. When set to "total", items in `values` are taken to be value of all its descendants. When set to "remainder", items in `values` corresponding to the root and the branches sectors are taken to be the extra part not part of the sum of the values at their leaves. - /// - /// Level: Sets the level from which this trace hierarchy is rendered. Set `level` to `''` to start from the root node in the hierarchy. Must be an "id" if `ids` is filled in, otherwise plotly attempts to find a matching item in `labels`. - /// - /// Maxdepth: Sets the number of rendered sectors from any given `level`. Set `maxdepth` to "-1" to render all the levels in the hierarchy. - /// - /// ColorBar: Sets the ColorBar for the chart - /// - ///Colors: Sets the color of each sector of this trace. If not specified, the default trace color set is used to pick the sector colors. [] static member Sunburst ( - labels, - parents, - [] ?Ids, - [] ?Values, - [] ?Text, - [] ?Branchvalues, - [] ?Level, - [] ?Maxdepth, - [] ?Color, - [] ?ColorBar: ColorBar, - [] ?UseDefaults: bool + labels: seq<#IConvertible>, + parents: seq<#IConvertible>, + [] ?Values: seq<#IConvertible>, + [] ?Ids: seq<#IConvertible>, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?Opacity: float, + [] ?MultiOpacity: seq, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, + [] ?SectionColors: seq, + [] ?SectionColorScale: StyleParam.Colorscale, + [] ?ShowSectionColorScale: bool, + [] ?ReverseSectionColorScale: bool, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, + [] ?TextInfo: StyleParam.TextInfo, + [] ?BranchValues: StyleParam.BranchValues, + [] ?Count: string, + [] ?Root: SunburstRoot, + [] ?Leaf: SunburstLeaf, + [] ?Level: string, + [] ?MaxDepth: int, + [] ?Rotation: int, + [] ?Sort: bool, + [] ?UseDefaults: bool ) = let useDefaults = defaultArg UseDefaults true + let outline = + SectionOutline + |> Option.defaultValue (Line.init ()) + |> Line.style ( + ?Color = SectionOutlineColor, + ?Width = SectionOutlineWidth, + ?MultiWidth = SectionOutlineMultiWidth + ) + + let marker = + Marker + |> Option.defaultValue (TraceObjects.Marker.init ()) + |> TraceObjects.Marker.style ( + ?MultiOpacity = MultiOpacity, + ?Colors = SectionColors, + ?Colorscale = SectionColorScale, + ?ShowScale = ShowSectionColorScale, + ?ReverseScale = ReverseSectionColorScale, + Outline = outline + ) + TraceDomain.initSunburst ( TraceDomainStyle.Sunburst( - labels = labels, - parents = parents, - ?Ids = Ids, + Labels = labels, + Parents = parents, + Marker = marker, ?Values = Values, + ?Ids = Ids, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Opacity = Opacity, ?Text = Text, - ?Branchvalues = Branchvalues, + ?MultiText = MultiText, + ?TextInfo = TextInfo, + ?Rotation = Rotation, + ?Sort = Sort, + ?BranchValues = BranchValues, + ?Count = Count, + ?Root = Root, + ?Leaf = Leaf, ?Level = Level, - ?Maxdepth = Maxdepth + ?MaxDepth = MaxDepth + ) ) - |> TraceStyle.Marker(?Color = Color, ?ColorBar = ColorBar) |> GenericChart.ofTraceObject useDefaults - /// Creates a treemap chart. Treemap charts visualize hierarchical data using nested rectangles. Same as Sunburst the hierarchy is defined by labels and parents attributes. Click on one sector to zoom in/out, which also displays a pathbar in the upper-left corner of your treemap. To zoom out you can use the path bar as well. - /// - /// Parameters: - /// - /// labels: Sets the labels of each of the sectors. - /// - /// parents: Sets the parent sectors for each of the sectors. Empty string items '' are understood to reference the root node in the hierarchy. If `ids` is filled, `parents` items are understood to be "ids" themselves. When `ids` is not set, plotly attempts to find matching items in `labels`, but beware they must be unique. - /// - /// Ids: Assigns id labels to each datum. These ids for object constancy of data points during animation. - /// - /// Values: Sets the values associated with each of the sectors. Use with `branchvalues` to determine how the values are summed. - /// - /// Text: Sets text elements associated with each sector. If trace `textinfo` contains a "text" flag, these elements will be seen on the chart. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. - /// - /// Branchvalues: Determines how the items in `values` are summed. When set to "total", items in `values` are taken to be value of all its descendants. When set to "remainder", items in `values` corresponding to the root and the branches sectors are taken to be the extra part not part of the sum of the values at their leaves. - /// - /// Level: Sets the level from which this trace hierarchy is rendered. Set `level` to `''` to start from the root node in the hierarchy. Must be an "id" if `ids` is filled in, otherwise plotly attempts to find a matching item in `labels`. - /// - /// Maxdepth: Sets the number of rendered sectors from any given `level`. Set `maxdepth` to "-1" to render all the levels in the hierarchy. - /// - /// ColorBar: Sets the ColorBar for the chart - /// - ///Colors: Sets the color of each sector of this trace. If not specified, the default trace color set is used to pick the sector colors. + /// Creates a sunburst chart. Visualize hierarchical data spanning outward radially from root to leaves. [] - static member Treemap + static member Sunburst ( + labelsparents: seq<#IConvertible * #IConvertible>, + [] ?Values: seq<#IConvertible>, + [] ?Ids: seq<#IConvertible>, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?Opacity: float, + [] ?MultiOpacity: seq, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, + [] ?SectionColors: seq, + [] ?SectionColorScale: StyleParam.Colorscale, + [] ?ShowSectionColorScale: bool, + [] ?ReverseSectionColorScale: bool, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, + [] ?TextInfo: StyleParam.TextInfo, + [] ?BranchValues: StyleParam.BranchValues, + [] ?Count: string, + [] ?Root: SunburstRoot, + [] ?Leaf: SunburstLeaf, + [] ?Level: string, + [] ?MaxDepth: int, + [] ?Rotation: int, + [] ?Sort: bool, + [] ?UseDefaults: bool + ) = + + let labels, parents = Seq.unzip labelsparents + + Chart.Sunburst( labels, parents, - [] ?Ids, - [] ?Values, - [] ?Text, - [] ?Branchvalues, - [] ?Tiling, - [] ?PathBar, - [] ?Level, - [] ?Maxdepth, - [] ?Color, - [] ?ColorBar: ColorBar, - [] ?UseDefaults: bool + ?Values = Values, + ?Ids = Ids, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Opacity = Opacity, + ?MultiOpacity = MultiOpacity, + ?Text = Text, + ?MultiText = MultiText, + ?SectionColors = SectionColors, + ?SectionColorScale = SectionColorScale, + ?ShowSectionColorScale = ShowSectionColorScale, + ?ReverseSectionColorScale = ReverseSectionColorScale, + ?SectionOutlineColor = SectionOutlineColor, + ?SectionOutlineWidth = SectionOutlineWidth, + ?SectionOutlineMultiWidth = SectionOutlineMultiWidth, + ?SectionOutline = SectionOutline, + ?Marker = Marker, + ?TextInfo = TextInfo, + ?BranchValues = BranchValues, + ?Count = Count, + ?Root = Root, + ?Leaf = Leaf, + ?Level = Level, + ?MaxDepth = MaxDepth, + ?Rotation = Rotation, + ?Sort = Sort, + ?UseDefaults = UseDefaults + ) + + + /// Creates a treemap chart. Treemap charts visualize hierarchical data using nested rectangles. Same as Sunburst the hierarchy is defined by labels and parents attributes. Click on one sector to zoom in/out, which also displays a pathbar in the upper-left corner of your treemap. To zoom out you can use the path bar as well. + [] + static member Treemap + ( + labels: seq<#IConvertible>, + parents: seq<#IConvertible>, + [] ?Values: seq<#IConvertible>, + [] ?Ids: seq<#IConvertible>, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?Opacity: float, + [] ?MultiOpacity: seq, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, + [] ?TextPosition: StyleParam.TextPosition, + [] ?MultiTextPosition: seq, + [] ?SectionColors: seq, + [] ?SectionColorScale: StyleParam.Colorscale, + [] ?ShowSectionColorScale: bool, + [] ?ReverseSectionColorScale: bool, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, + [] ?TextInfo: StyleParam.TextInfo, + [] ?BranchValues: StyleParam.BranchValues, + [] ?Count: string, + [] ?Tiling: TreemapTiling, + [] ?PathBar: Pathbar, + [] ?Root: TreemapRoot, + [] ?Level: string, + [] ?MaxDepth: int, + [] ?UseDefaults: bool ) = let useDefaults = defaultArg UseDefaults true + let outline = + SectionOutline + |> Option.defaultValue (Line.init ()) + |> Line.style ( + ?Color = SectionOutlineColor, + ?Width = SectionOutlineWidth, + ?MultiWidth = SectionOutlineMultiWidth + ) + + let marker = + Marker + |> Option.defaultValue (TraceObjects.Marker.init ()) + |> TraceObjects.Marker.style ( + ?MultiOpacity = MultiOpacity, + ?Colors = SectionColors, + ?Colorscale = SectionColorScale, + ?ShowScale = ShowSectionColorScale, + ?ReverseScale = ReverseSectionColorScale, + Outline = outline + ) + TraceDomain.initTreemap ( TraceDomainStyle.Treemap( - labels = labels, - parents = parents, - ?Ids = Ids, + Labels = labels, + Parents = parents, + Marker = marker, ?Values = Values, + ?Ids = Ids, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Opacity = Opacity, ?Text = Text, - ?Branchvalues = Branchvalues, + ?MultiText = MultiText, + ?TextPosition = TextPosition, + ?MultiTextPosition = MultiTextPosition, + ?TextInfo = TextInfo, + ?BranchValues = BranchValues, + ?Count = Count, ?Tiling = Tiling, ?PathBar = PathBar, + ?Root = Root, ?Level = Level, - ?Maxdepth = Maxdepth + ?MaxDepth = MaxDepth ) ) - |> TraceStyle.Marker(?Color = Color, ?ColorBar = ColorBar) |> GenericChart.ofTraceObject useDefaults + /// Creates a treemap chart. Treemap charts visualize hierarchical data using nested rectangles. Same as Sunburst the hierarchy is defined by labels and parents attributes. Click on one sector to zoom in/out, which also displays a pathbar in the upper-left corner of your treemap. To zoom out you can use the path bar as well. + [] + static member Treemap + ( + labelsparents: seq<#IConvertible * #IConvertible>, + [] ?Values: seq<#IConvertible>, + [] ?Ids: seq<#IConvertible>, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?Opacity: float, + [] ?MultiOpacity: seq, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, + [] ?TextPosition: StyleParam.TextPosition, + [] ?MultiTextPosition: seq, + [] ?SectionColors: seq, + [] ?SectionColorScale: StyleParam.Colorscale, + [] ?ShowSectionColorScale: bool, + [] ?ReverseSectionColorScale: bool, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, + [] ?TextInfo: StyleParam.TextInfo, + [] ?BranchValues: StyleParam.BranchValues, + [] ?Count: string, + [] ?Tiling: TreemapTiling, + [] ?PathBar: Pathbar, + [] ?Root: TreemapRoot, + [] ?Level: string, + [] ?MaxDepth: int, + [] ?UseDefaults: bool + ) = + + let labels, parents = Seq.unzip labelsparents + + Chart.Treemap( + labels, + parents, + ?Values = Values, + ?Ids = Ids, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Opacity = Opacity, + ?MultiOpacity = MultiOpacity, + ?Text = Text, + ?MultiText = MultiText, + ?TextPosition = TextPosition, + ?MultiTextPosition = MultiTextPosition, + ?SectionColors = SectionColors, + ?SectionColorScale = SectionColorScale, + ?ShowSectionColorScale = ShowSectionColorScale, + ?ReverseSectionColorScale = ReverseSectionColorScale, + ?SectionOutlineColor = SectionOutlineColor, + ?SectionOutlineWidth = SectionOutlineWidth, + ?SectionOutlineMultiWidth = SectionOutlineMultiWidth, + ?SectionOutline = SectionOutline, + ?Marker = Marker, + ?TextInfo = TextInfo, + ?BranchValues = BranchValues, + ?Count = Count, + ?Tiling = Tiling, + ?PathBar = PathBar, + ?Root = Root, + ?Level = Level, + ?MaxDepth = MaxDepth, + ?UseDefaults = UseDefaults + ) + /// Computes the parallel coordinates plot [] static member ParallelCoord ( - dims: seq<'key * #seq<'values>>, - [] ?Range, - [] ?Constraintrange, - [] ?Color, - [] ?Colorscale, - [] ?Width, - [] ?Dash, - [] ?Domain, - [] ?Labelfont, - [] ?Tickfont, - [] ?Rangefont, - [] ?UseDefaults: bool + dimensions: seq, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?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 useDefaults = defaultArg UseDefaults true - let dims' = - dims - |> Seq.map - (fun (k, vals) -> - Dimension.initParallel ( - Values = vals, - ?Range = Range, - ?ConstraintRange = Constraintrange, - Label = k - )) + let line = + Line + |> Option.defaultValue (Plotly.NET.Line.init ()) + |> Plotly.NET.Line.style ( + ?Color = LineColor, + ?Colorscale = LineColorScale, + ?ShowScale = ShowLineColorScale, + ?ReverseScale = ReverseLineColorScale + ) TraceDomain.initParallelCoord ( TraceDomainStyle.ParallelCoord( - Dimensions = dims', - ?Domain = Domain, - ?Labelfont = Labelfont, - ?Tickfont = Tickfont, - ?Rangefont = Rangefont + Dimensions = dimensions, + Line = line, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?LabelAngle = LabelAngle, + ?LabelFont = LabelFont, + ?LabelSide = LabelSide, + ?RangeFont = RangeFont, + ?TickFont = TickFont ) ) - |> TraceStyle.Line(?Width = Width, ?Color = Color, ?Dash = Dash, ?Colorscale = Colorscale) |> GenericChart.ofTraceObject useDefaults - /// Computes the parallel coordinates plot [] static member ParallelCoord ( - dims: seq, - [] ?Color, - [] ?Colorscale, - [] ?Width, - [] ?Dash, - [] ?Domain, - [] ?Labelfont, - [] ?Tickfont, - [] ?Rangefont, - [] ?UseDefaults: bool + keyValues: seq>, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?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 useDefaults = defaultArg UseDefaults true + let dims = + keyValues |> Seq.map (fun (key, vals) -> Dimension.initParallel (Label = key, Values = vals)) - TraceDomain.initParallelCoord ( - TraceDomainStyle.ParallelCoord( - Dimensions = dims, - ?Domain = Domain, - ?Labelfont = Labelfont, - ?Tickfont = Tickfont, - ?Rangefont = Rangefont - ) + Chart.ParallelCoord( + dimensions = dims, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?LineColor = LineColor, + ?LineColorScale = LineColorScale, + ?ShowLineColorScale = ShowLineColorScale, + ?ReverseLineColorScale = ReverseLineColorScale, + ?Line = Line, + ?LabelAngle = LabelAngle, + ?LabelFont = LabelFont, + ?LabelSide = LabelSide, + ?RangeFont = RangeFont, + ?TickFont = TickFont, + ?UseDefaults = UseDefaults ) - |> TraceStyle.Line(?Width = Width, ?Color = Color, ?Dash = Dash, ?Colorscale = Colorscale) - |> GenericChart.ofTraceObject useDefaults - ///Parallel categories diagram for multidimensional categorical data. + /// Computes the parallel categories plot [] static member ParallelCategories ( - dims: seq<'key * #seq<'values>>, - [] ?Range, - [] ?Constraintrange, - [] ?Color, - [] ?Colorscale, - [] ?Width, - [] ?Dash, - [] ?Domain, - [] ?Labelfont, - [] ?Tickfont, - [] ?Rangefont, - [] ?UseDefaults: bool + dimensions: seq, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?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 useDefaults = defaultArg UseDefaults true - let dims' = - dims - |> Seq.map - (fun (k, vals) -> - Dimension.initParallel ( - Values = vals, - ?Range = Range, - ?ConstraintRange = Constraintrange, - Label = k - )) + let line = + Line + |> Option.defaultValue (Plotly.NET.Line.init ()) + |> Plotly.NET.Line.style ( + ?Color = LineColor, + ?Shape = LineShape, + ?Colorscale = LineColorScale, + ?ShowScale = ShowLineColorScale, + ?ReverseScale = ReverseLineColorScale + ) TraceDomain.initParallelCategories ( TraceDomainStyle.ParallelCategories( - Dimensions = dims', - ?Domain = Domain, - ?Labelfont = Labelfont, - ?Tickfont = Tickfont, - ?Rangefont = Rangefont + Dimensions = dimensions, + Line = line, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Counts = Counts, + ?Arrangement = Arrangement, + ?BundleColors = BundleColors, + ?SortPaths = SortPaths, + ?LabelFont = LabelFont, + ?TickFont = TickFont ) ) - |> TraceStyle.Line(?Width = Width, ?Color = Color, ?Dash = Dash, ?Colorscale = Colorscale) + |> GenericChart.ofTraceObject useDefaults - /// + /// Computes the parallel categories plot [] static member ParallelCategories ( - dims: seq, - [] ?Color, - [] ?Colorscale, - [] ?Width, - [] ?Dash, - [] ?Domain, - [] ?Labelfont, - [] ?Tickfont, - [] ?Rangefont, - [] ?UseDefaults: bool + keyValues: seq>, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?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 useDefaults = defaultArg UseDefaults true + let dims = + keyValues |> Seq.map (fun (key, vals) -> Dimension.initParallel (Label = key, Values = vals)) + + let line = + Line + |> Option.defaultValue (Plotly.NET.Line.init ()) + |> Plotly.NET.Line.style ( + ?Color = LineColor, + ?Shape = LineShape, + ?Colorscale = LineColorScale, + ?ShowScale = ShowLineColorScale, + ?ReverseScale = ReverseLineColorScale + ) + TraceDomain.initParallelCategories ( TraceDomainStyle.ParallelCategories( Dimensions = dims, - ?Domain = Domain, - ?Color = Color, - ?Labelfont = Labelfont, - ?Tickfont = Tickfont, - ?Rangefont = Rangefont + Line = line, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Counts = Counts, + ?Arrangement = Arrangement, + ?BundleColors = BundleColors, + ?SortPaths = SortPaths, + ?LabelFont = LabelFont, + ?TickFont = TickFont ) ) - |> TraceStyle.Line(?Width = Width, ?Dash = Dash, ?Colorscale = Colorscale) |> GenericChart.ofTraceObject useDefaults + /// Computes the sankey plot + [] + static member Sankey + ( + nodes: SankeyNodes, + links: SankeyLinks, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?Ids: seq<#IConvertible>, + [] ?Orientation: StyleParam.Orientation, + [] ?TextFont: Font, + [] ?Arrangement: StyleParam.CategoryArrangement, + [] ?ValueFormat: string, + [] ?ValueSuffix: string, + [] ?UseDefaults: bool + ) = - /// creates table out of header sequence and row sequences + let useDefaults = defaultArg UseDefaults true + + TraceDomain.initSankey ( + TraceDomainStyle.Sankey( + Node = nodes, + Link = links, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Ids = Ids, + ?Orientation = Orientation, + ?TextFont = TextFont, + ?Arrangement = Arrangement, + ?ValueFormat = ValueFormat, + ?ValueSuffix = ValueSuffix + + ) + ) + |> GenericChart.ofTraceObject useDefaults + + [] + static member Sankey + ( + nodeLabels: seq, + linkedNodeIds: seq, + linkValues: seq<#IConvertible>, + [] ?NodeColor: Color, + [] ?NodeOutlineColor: Color, + [] ?NodeOutlineWidth: float, + [] ?NodeThickness: int, + [] ?NodeGroups: seq<#seq>, + [] ?LinkColor: Color, + [] ?LinkColorScales: seq, + [] ?LinkOutlineColor: Color, + [] ?LinkOutlineWidth: float, + [] ?LinkLabels: seq, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?Ids: seq<#IConvertible>, + [] ?Orientation: StyleParam.Orientation, + [] ?TextFont: Font, + [] ?Arrangement: StyleParam.CategoryArrangement, + [] ?ValueFormat: string, + [] ?ValueSuffix: string, + [] ?UseDefaults: bool + ) = + + let nodeOutline = + Line.init (?Color = NodeOutlineColor, ?Width = NodeOutlineWidth) + + let nodes = + SankeyNodes.init ( + Label = nodeLabels, + Line = nodeOutline, + ?Color = NodeColor, + ?Thickness = NodeThickness, + ?Groups = NodeGroups + ) + + let linklOutline = + Line.init (?Color = LinkOutlineColor, ?Width = LinkOutlineWidth) + + let sources, targets = Seq.unzip linkedNodeIds + + let colorScales = + LinkColorScales + |> Option.map (fun c -> c |> Seq.map (fun cs -> SankeyLinkColorscale.init (ColorScale = cs))) + + let links = + SankeyLinks.init ( + Source = sources, + Target = targets, + Line = linklOutline, + Value = linkValues, + ?ColorScales = colorScales, + ?Color = LinkColor, + ?Label = LinkLabels + ) + + Chart.Sankey( + nodes, + links, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?Ids = Ids, + ?Orientation = Orientation, + ?TextFont = TextFont, + ?Arrangement = Arrangement, + ?ValueFormat = ValueFormat, + ?ValueSuffix = ValueSuffix, + ?UseDefaults = UseDefaults + ) + + /// creates table chart [] static member Table ( - headerValues, - cellValues, - [] ?AlignHeader, - [] ?AlignCells, - [] ?ColumnWidth, - [] ?ColumnOrder, - [] ?ColorHeader, - [] ?ColorCells, - [] ?FontHeader, - [] ?FontCells, - [] ?HeightHeader, - [] ?HeightCells, - [] ?LineHeader, - [] ?LineCells, + header: TableHeader, + cells: TableCells, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?ColumnOrder: seq, + [] ?ColumnWidth: float, + [] ?MultiColumnWidth: seq, [] ?UseDefaults: bool ) = let useDefaults = defaultArg UseDefaults true TraceDomain.initTable ( - - let CellFilling = - match ColorCells with - | Some color -> Some(CellColor.init (?Color = ColorCells)) - | Option.None -> Option.None - - let HeaderFilling = - match ColorHeader with - | Some color -> Some(CellColor.init (?Color = ColorHeader)) - | Option.None -> Option.None - TraceDomainStyle.Table( - header = - TableHeader.init ( - headerValues |> Seq.map seq, - ?Align = AlignHeader, - ?Fill = HeaderFilling, - ?Font = FontHeader, - ?Height = HeightHeader, - ?Line = LineHeader - ), - cells = - TableCells.init ( - cellValues |> Seq.transpose, - ?Align = AlignCells, - ?Fill = CellFilling, - ?Font = FontCells, - ?Height = HeightCells, - ?Line = LineCells - ), + Header = header, + Cells = cells, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?ColumnOrder = ColumnOrder, ?ColumnWidth = ColumnWidth, - ?ColumnOrder = ColumnOrder + ?MultiColumnWidth = MultiColumnWidth + ) ) |> GenericChart.ofTraceObject useDefaults + + /// creates table chart + [] + static member Table + ( + headerValues: seq<#seq<#IConvertible>>, + cellsValues: seq<#seq<#IConvertible>>, + [] ?TransposeCells: bool, + [] ?HeaderAlign: StyleParam.HorizontalAlign, + [] ?HeaderMultiAlign: seq, + [] ?HeaderFillColor: Color, + [] ?HeaderHeight: int, + [] ?HeaderOutlineColor: Color, + [] ?HeaderOutlineWidth: float, + [] ?HeaderOutlineMultiWidth: seq, + [] ?HeaderOutline: Line, + [] ?CellsAlign: StyleParam.HorizontalAlign, + [] ?CellsMultiAlign: seq, + [] ?CellsFillColor: Color, + [] ?CellsHeight: int, + [] ?CellsOutlineColor: Color, + [] ?CellsOutlineWidth: float, + [] ?CellsOutlineMultiWidth: seq, + [] ?CellsOutline: Line, + [] ?Name: string, + [] ?ShowLegend: bool, + [] ?ColumnOrder: seq, + [] ?ColumnWidth: float, + [] ?MultiColumnWidth: seq, + [] ?UseDefaults: bool + ) = + + let useDefaults = defaultArg UseDefaults true + + let transpose = defaultArg TransposeCells true + + let cellsValues = + if transpose then + cellsValues |> Seq.map Seq.cast |> Seq.transpose + else + cellsValues |> Seq.map Seq.cast + + let headerFill = + TableFill.init (?Color = HeaderFillColor) + + let headerOutline = + HeaderOutline + |> Option.defaultValue (Plotly.NET.Line.init ()) + |> Plotly.NET.Line.style ( + ?Color = HeaderOutlineColor, + ?Width = HeaderOutlineWidth, + ?MultiWidth = HeaderOutlineMultiWidth + ) + + let header = + TableHeader.init ( + Values = headerValues, + Fill = headerFill, + Line = headerOutline, + ?Align = HeaderAlign, + ?MultiAlign = HeaderMultiAlign, + ?Height = HeaderHeight + ) + + let cellsFill = TableFill.init (?Color = CellsFillColor) + + let cellsOutline = + CellsOutline + |> Option.defaultValue (Plotly.NET.Line.init ()) + |> Plotly.NET.Line.style ( + ?Color = CellsOutlineColor, + ?Width = CellsOutlineWidth, + ?MultiWidth = CellsOutlineMultiWidth + ) + + let cells = + TableCells.init ( + Values = cellsValues, + Fill = cellsFill, + Line = cellsOutline, + ?Align = CellsAlign, + ?MultiAlign = CellsMultiAlign, + ?Height = CellsHeight + ) + + Chart.Table( + header, + cells, + ?Name = Name, + ?ShowLegend = ShowLegend, + ?ColumnOrder = ColumnOrder, + ?ColumnWidth = ColumnWidth, + ?MultiColumnWidth = MultiColumnWidth, + ?UseDefaults = UseDefaults + + ) + /// creates table out of header sequence and row sequences [] static member Indicator @@ -662,20 +1181,25 @@ module ChartDomain = ( labels: seq<#IConvertible>, parents: seq<#IConvertible>, + [] ?Values: seq<#IConvertible>, + [] ?Ids: 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, + [] ?SectionColors: seq, + [] ?SectionColorScale: StyleParam.Colorscale, + [] ?ShowSectionColorScale: bool, + [] ?ReverseSectionColorScale: bool, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, [] ?BranchValues: StyleParam.BranchValues, [] ?Count: StyleParam.IcicleCount, [] ?TilingOrientation: StyleParam.Orientation, @@ -683,11 +1207,36 @@ module ChartDomain = [] ?Tiling: IcicleTiling, [] ?PathBarEdgeShape: StyleParam.PathbarEdgeShape, [] ?PathBar: Pathbar, - [] ?UseDefaults: bool + [] ?TextInfo: StyleParam.TextInfo, + [] ?Root: IcicleRoot, + [] ?Level: string, + [] ?MaxDepth: int, + [] ?UseDefaults: bool ) = let useDefaults = defaultArg UseDefaults true + let outline = + SectionOutline + |> Option.defaultValue (Line.init ()) + |> Line.style ( + ?Color = SectionOutlineColor, + ?Width = SectionOutlineWidth, + ?MultiWidth = SectionOutlineMultiWidth + ) + + let marker = + Marker + |> Option.defaultValue (TraceObjects.Marker.init ()) + |> TraceObjects.Marker.style ( + ?MultiOpacity = MultiOpacity, + ?Colors = SectionColors, + ?Colorscale = SectionColorScale, + ?ShowScale = ShowSectionColorScale, + ?ReverseScale = ReverseSectionColorScale, + Outline = outline + ) + let tiling = Tiling |> Option.defaultValue (IcicleTiling.init ()) @@ -698,51 +1247,55 @@ module ChartDomain = TraceDomain.initIcicle ( TraceDomainStyle.Icicle( + Labels = labels, + Parents = parents, + Marker = marker, + PathBar = pathbar, + Tiling = tiling, + ?Values = Values, + ?Ids = Ids, ?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 + ?TextInfo = TextInfo, + ?Root = Root, + ?Level = Level, + ?MaxDepth = MaxDepth ) ) |> GenericChart.ofTraceObject useDefaults + /// creates table out of header sequence and row sequences [] static member Icicle ( - labelsParents: seq<#IConvertible * #IConvertible>, + labelsparents: seq<#IConvertible * #IConvertible>, + [] ?Values: seq<#IConvertible>, + [] ?Ids: 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, + [] ?SectionColors: seq, + [] ?SectionColorScale: StyleParam.Colorscale, + [] ?ShowSectionColorScale: bool, + [] ?ReverseSectionColorScale: bool, + [] ?SectionOutlineColor: Color, + [] ?SectionOutlineWidth: float, + [] ?SectionOutlineMultiWidth: seq, + [] ?SectionOutline: Line, + [] ?Marker: Marker, [] ?BranchValues: StyleParam.BranchValues, [] ?Count: StyleParam.IcicleCount, [] ?TilingOrientation: StyleParam.Orientation, @@ -750,28 +1303,37 @@ module ChartDomain = [] ?Tiling: IcicleTiling, [] ?PathBarEdgeShape: StyleParam.PathbarEdgeShape, [] ?PathBar: Pathbar, - [] ?UseDefaults: bool + [] ?TextInfo: StyleParam.TextInfo, + [] ?Root: IcicleRoot, + [] ?Level: string, + [] ?MaxDepth: int, + [] ?UseDefaults: bool ) = - let labels, parents = Seq.unzip labelsParents + let labels, parents = Seq.unzip labelsparents Chart.Icicle( labels, parents, + ?Values = Values, + ?Ids = Ids, ?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, + ?SectionColors = SectionColors, + ?SectionColorScale = SectionColorScale, + ?ShowSectionColorScale = ShowSectionColorScale, + ?ReverseSectionColorScale = ReverseSectionColorScale, + ?SectionOutlineColor = SectionOutlineColor, + ?SectionOutlineWidth = SectionOutlineWidth, + ?SectionOutlineMultiWidth = SectionOutlineMultiWidth, + ?SectionOutline = SectionOutline, + ?Marker = Marker, ?BranchValues = BranchValues, ?Count = Count, ?TilingOrientation = TilingOrientation, @@ -779,5 +1341,10 @@ module ChartDomain = ?Tiling = Tiling, ?PathBarEdgeShape = PathBarEdgeShape, ?PathBar = PathBar, + ?TextInfo = TextInfo, + ?Root = Root, + ?Level = Level, + ?MaxDepth = MaxDepth, ?UseDefaults = UseDefaults + ) diff --git a/src/Plotly.NET/CommonAbstractions/Line.fs b/src/Plotly.NET/CommonAbstractions/Line.fs index 793f9c834..879ecf294 100644 --- a/src/Plotly.NET/CommonAbstractions/Line.fs +++ b/src/Plotly.NET/CommonAbstractions/Line.fs @@ -11,27 +11,46 @@ type Line() = /// Initialized Line object static member init ( - [] ?Width, - [] ?Color, - [] ?Shape, - [] ?Dash, - [] ?Smoothing, - [] ?Colorscale, - [] ?OutlierColor, - [] ?OutlierWidth, - [] ?ColorBar + [] ?Color: Color, + [] ?Width: float, + [] ?MultiWidth: seq, + [] ?Shape: StyleParam.Shape, + [] ?Dash: StyleParam.DrawingStyle, + [] ?Smoothing: float, + [] ?OutlierColor: Color, + [] ?OutlierWidth: float, + [] ?AutoColorScale: bool, + [] ?CAuto: bool, + [] ?CMax: float, + [] ?CMid: float, + [] ?CMin: float, + [] ?ColorAxis: StyleParam.SubPlotId, + [] ?Colorscale: StyleParam.Colorscale, + [] ?ReverseScale: bool, + [] ?ShowScale: bool, + [] ?ColorBar: #DynamicObj ) = Line() |> Line.style ( ?Color = Color, ?Width = Width, + ?MultiWidth = MultiWidth, ?Shape = Shape, - ?Smoothing = Smoothing, ?Dash = Dash, - ?Colorscale = Colorscale, + ?Smoothing = Smoothing, ?OutlierColor = OutlierColor, ?OutlierWidth = OutlierWidth, + ?AutoColorScale = AutoColorScale, + ?CAuto = CAuto, + ?CMax = CMax, + ?CMid = CMid, + ?CMin = CMin, + ?ColorAxis = ColorAxis, + ?Colorscale = Colorscale, + ?ReverseScale = ReverseScale, + ?ShowScale = ShowScale, ?ColorBar = ColorBar + ) @@ -40,7 +59,7 @@ type Line() = ( [] ?Color: Color, [] ?Width: float, - [] ?MultiWidths: seq, + [] ?MultiWidth: seq, [] ?Shape: StyleParam.Shape, [] ?Dash: StyleParam.DrawingStyle, [] ?Smoothing: float, @@ -54,11 +73,12 @@ type Line() = [] ?ColorAxis: StyleParam.SubPlotId, [] ?Colorscale: StyleParam.Colorscale, [] ?ReverseScale: bool, + [] ?ShowScale: bool, [] ?ColorBar: #DynamicObj ) = (fun (line: Line) -> Color |> DynObj.setValueOpt line "color" - (Width, MultiWidths) |> DynObj.setSingleOrMultiOpt line "width" + (Width, MultiWidth) |> DynObj.setSingleOrMultiOpt line "width" Shape |> DynObj.setValueOptBy line "shape" StyleParam.Shape.convert Smoothing |> DynObj.setValueOpt line "smoothing" Dash |> DynObj.setValueOptBy line "dash" StyleParam.DrawingStyle.convert @@ -73,6 +93,7 @@ type Line() = ColorAxis |> DynObj.setValueOptBy line "coloraxis" StyleParam.SubPlotId.convert Colorscale |> DynObj.setValueOptBy line "colorscale" StyleParam.Colorscale.convert ReverseScale |> DynObj.setValueOpt line "reversescale" + ShowScale |> DynObj.setValueOpt line "showscale" ColorBar |> DynObj.setValueOpt line "colorbar" // out -> diff --git a/src/Plotly.NET/CommonAbstractions/StyleParams.fs b/src/Plotly.NET/CommonAbstractions/StyleParams.fs index 34dffa15b..3659d4122 100644 --- a/src/Plotly.NET/CommonAbstractions/StyleParams.fs +++ b/src/Plotly.NET/CommonAbstractions/StyleParams.fs @@ -398,6 +398,23 @@ module StyleParam = // #C# //-------------------------- + [] + type CategoryArrangement = + | Perpendicular + | FreeForm + | Fixed + | Snap + + static member toString = + function + | Perpendicular -> "perpendicular" + | FreeForm -> "freeform" + | Fixed -> "fixed" + | Snap -> "snap" + + static member convert = CategoryArrangement.toString >> box + override this.ToString() = this |> CategoryArrangement.toString + member this.Convert() = this |> CategoryArrangement.convert [] type ConstraintOperation = @@ -2271,6 +2288,20 @@ module StyleParam = // #S# //-------------------------- + [] + type SortAlgorithm = + | Forward + | Backward + + static member toString = + function + | Forward -> "forward" + | Backward -> "backward" + + static member convert = SortAlgorithm.toString >> box + override this.ToString() = this |> SortAlgorithm.toString + member this.Convert() = this |> SortAlgorithm.convert + [] type SpanMode = | Soft diff --git a/src/Plotly.NET/Extensions/SankeyExtension.fs b/src/Plotly.NET/Extensions/SankeyExtension.fs deleted file mode 100644 index 906f6dfec..000000000 --- a/src/Plotly.NET/Extensions/SankeyExtension.fs +++ /dev/null @@ -1,300 +0,0 @@ -namespace Plotly.NET - -open DynamicObj -open System.Runtime.InteropServices - -type Node = - { - Label: string - Groups: string [] option - XRank: int option - YRank: int option - Color: obj option - LineColor: obj option - LineWidth: float option - } - static member Create(label, ?groups, ?xRank, ?yRank, ?color, ?lineColor, ?lineWidth) = - { - Label = label - Groups = groups - XRank = xRank - YRank = yRank - Color = color - LineColor = lineColor - LineWidth = lineWidth - } - -type Link = - { - Source: Node - Target: Node - Value: float option - Label: string option - Color: obj option - LineColor: obj option - LineWidth: float option - } - static member Create(src, tgt, ?value, ?label, ?color, ?lineColor, ?lineWidth) = - { - Source = src - Target = tgt - Value = value - Label = label - Color = color - LineColor = lineColor - LineWidth = lineWidth - } - -[] -module SankeyExtension = - - type TraceDomainStyle with - [] - static member Sankey - ( - nodes: Node seq, - links: Link seq, - ?nodePadding: float, - ?nodeThickness: float, - ?nodeColor: obj, - ?nodeLineColor: obj, - ?nodeLineWidth: float, - ?linkColor: obj, - ?linkLineColor: obj, - ?linkLineWidth: float - ) = - (fun (trace: ('T :> Trace)) -> - let nonUniqueLabels = - nodes |> Seq.countBy (fun x -> x.Label) |> Seq.filter (fun (_, c) -> c > 1) - - if nonUniqueLabels |> Seq.length > 0 then - failwithf "duplicated label names %A" (nonUniqueLabels |> Seq.map fst) - - let lblMap = - nodes |> Seq.mapi (fun i x -> x.Label, i) |> Map.ofSeq // give each node an index - - let link = - let linkClrs = - links - |> Seq.map (fun x -> x.Color) - |> Seq.map - (function - | Some x -> x - | None -> linkColor |> Option.defaultValue null) - |> fun xs -> - if xs |> Seq.exists (fun x -> x <> null) then - xs |> Seq.toArray |> Some - else - None - - let linkLineClrs = - links - |> Seq.map (fun x -> x.LineColor) - |> Seq.map - (function - | Some x -> x - | None -> linkLineColor |> Option.defaultValue null) - |> fun xs -> - if xs |> Seq.exists (fun x -> x <> null) then - xs |> Seq.toArray |> Some - else - None - - let linkLineWidths = - links - |> Seq.map (fun x -> x.LineWidth) - |> Seq.map - (function - | Some x -> x - | None -> linkLineWidth |> Option.defaultValue 0.5) - |> fun xs -> - if xs |> Seq.exists (fun x -> x <> 0.5) then - xs |> Seq.toArray |> Some - else - None - - let values = - links - |> Seq.map (fun x -> x.Value) - |> fun xs -> - if xs |> Seq.exists Option.isSome then - xs - |> Seq.map - (function - | Some x -> box x - | None -> null) - |> Seq.toArray - |> Some - else - None - - let line = - match (linkLineClrs, linkLineWidths) with - | None, None -> None - | cs, ws -> - let ln = new DynamicObj() - DynObj.setValueOpt ln "color" cs - DynObj.setValueOpt ln "width" ws - Some ln - - let l = new DynamicObj() - DynObj.setValue l "source" (links |> Seq.map (fun x -> lblMap.[x.Source.Label])) - DynObj.setValue l "target" (links |> Seq.map (fun x -> lblMap.[x.Target.Label])) - DynObj.setValueOpt l "color" linkClrs - DynObj.setValueOpt l "value" values - DynObj.setValueOpt l "line" line - - l - - let node = - let groups = - nodes - |> Seq.collect - (fun x -> x.Groups |> Option.defaultValue [||] |> Array.map (fun g -> g, lblMap.[x.Label])) - |> Seq.groupBy fst - |> Seq.map (fun (g, gs) -> gs |> Seq.map snd) - |> fun xs -> - if Seq.isEmpty xs then - None - else - Some(xs |> Seq.map Seq.toArray |> Seq.toArray) - - let xRanks = - nodes - |> Seq.map (fun x -> x.XRank |> Option.map box |> Option.defaultValue null) - |> fun xs -> - if xs |> Seq.exists (fun x -> x <> null) then - xs |> Seq.toArray |> Some - else - None - - let yRanks = - nodes - |> Seq.map (fun x -> x.YRank |> Option.map box |> Option.defaultValue null) - |> fun xs -> - if xs |> Seq.exists (fun x -> x <> null) then - xs |> Seq.toArray |> Some - else - None - - let nodeClrs = - nodes - |> Seq.map (fun x -> x.Color) - |> Seq.map - (function - | Some x -> x - | None -> nodeColor |> Option.defaultValue null) - |> fun xs -> - if xs |> Seq.exists (fun x -> x <> null) then - xs |> Seq.toArray |> Some - else - None - - let nodeLineClrs = - nodes - |> Seq.map (fun x -> x.LineColor) - |> Seq.map - (function - | Some x -> x - | None -> nodeLineColor |> Option.defaultValue null) - |> fun xs -> - if xs |> Seq.exists (fun x -> x <> null) then - xs |> Seq.toArray |> Some - else - None - - let nodeLineWidths = - nodes - |> Seq.map (fun x -> x.LineWidth) - |> Seq.map - (function - | Some x -> x - | None -> nodeLineWidth |> Option.defaultValue 0.5) - |> fun xs -> - if xs |> Seq.exists (fun x -> x <> 0.5) then - xs |> Seq.toArray |> Some - else - None - - let line = - match (nodeLineClrs, nodeLineWidths) with - | None, None -> None - | cs, ws -> - let ln = new DynamicObj() - DynObj.setValueOpt ln "color" cs - DynObj.setValueOpt ln "width" ws - Some ln - - let n = new DynamicObj() - DynObj.setValue n "label" (nodes |> Seq.map (fun x -> x.Label)) - DynObj.setValueOpt n "groups" groups - DynObj.setValueOpt n "pad" nodePadding - DynObj.setValueOpt n "thickness" nodeThickness - DynObj.setValueOpt n "x" xRanks - DynObj.setValueOpt n "y" yRanks - DynObj.setValueOpt n "color" nodeClrs - DynObj.setValueOpt n "line" line - n - - DynObj.setValue trace "node" node - DynObj.setValue trace "link" link - - trace) - - type Chart with - [] - static member Sankey - ( - nodes: Node seq, - links: Link seq, - [] ?nodePadding: float, - [] ?nodeThickness: float, - [] ?nodeColor: obj, - [] ?nodeLineColor: obj, - [] ?nodeLineWidth: float, - [] ?linkColor: obj, - [] ?linkLineColor: obj, - [] ?linkLineWidth: float, - [] ?UseDefaults: bool - ) = - - let useDefaults = defaultArg UseDefaults true - - TraceDomain.initSankey ( - TraceDomainStyle.Sankey( - nodes, - links, - ?nodePadding = nodePadding, - ?nodeThickness = nodeThickness, - ?nodeColor = nodeColor, - ?nodeLineColor = nodeLineColor, - ?nodeLineWidth = nodeLineWidth, - ?linkColor = linkColor, - ?linkLineColor = linkLineColor, - ?linkLineWidth = linkLineWidth - ) - ) - |> GenericChart.ofTraceObject useDefaults - - -(* - #load "SetEnv.fsx" - open Plotly.NET - open PlotlyExts - let testSankey() = - let n1 = Node.Create("a",color="Black") - let n2 = Node.Create("b",color="Red") - let n3 = Node.Create("c",color="Purple") - let n4 = Node.Create("d",color="Green") - let n5 = Node.Create("e",color="Orange") - let link1 = Link.Create(n1,n2,value=1.0) - let link2 = Link.Create(n2,n3,value=2.0) - let link3 = Link.Create(n1,n5,value=1.3) - let link4 = Link.Create(n4,n5,value=1.5) - let link5 = Link.Create(n3,n5,value=0.5) - Chart.Sankey([n1;n2;n3;n4;n5],[link1;link2;link3;link4;link5]) - |> Chart.withTitle "Sankey Sample" - |> Chart.Show - - testSankey() - *) diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index f2ab7ee1b..0abef9f91 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -88,7 +88,8 @@ #load "Selection.fs" #load "StockData.fs" #load "Pathbar.fs" -#load "TreemapTiling.fs" +#load "Treemap.fs" +#load "Sunburst.fs" #load "Contours.fs" #load "Dimensions.fs" #load "WaterfallConnector.fs" @@ -103,6 +104,7 @@ #load "Icicle.fs" #load "FinanceMarker.fs" #load "SplomDiagonal.fs" +#load "Sankey.fs" #I "Traces" @@ -151,10 +153,6 @@ #load "GenericChartExtensions.fs" -#I "Extensions" - -#load "SankeyExtension.fs" - open DynamicObj open Plotly.NET @@ -183,151 +181,3 @@ open Plotly.NET open FSharp.Data open Deedle -//---------------------- Generate linearly spaced vector ---------------------- -let linspace (min,max,n) = - if n <= 2 then failwithf "n needs to be larger then 2" - let bw = float (max - min) / (float n - 1.) - Array.init n (fun i -> min + (bw * float i)) - //[|min ..bw ..max|] - -//---------------------- Create example data ---------------------- -let size = 100 -let x = linspace(-2. * Math.PI, 2. * Math.PI, size) -let y = linspace(-2. * Math.PI, 2. * Math.PI, size) - -let f x y = - (5. * x / (x**2. + y**2. + 1.) ) - -let z = - Array.init size (fun i -> - Array.init size (fun j -> - f x.[j] y.[i] - ) - ) - -let rnd = System.Random() -let a = Array.init 50 (fun _ -> rnd.NextDouble()) -let b = Array.init 50 (fun _ -> rnd.NextDouble()) -let c = Array.init 50 (fun _ -> rnd.NextDouble()) - -open Plotly.NET.TraceObjects - -[ - Chart.Line3D( - [1,2,3; 4,5,6], - UseDefaults = false - ) - - - Chart.Line3D( - [1,2,3; 4,5,6], - UseDefaults = false - ) - -] -|> Chart.Grid(2,1) -|> Chart.withScene( - Scene.init( - Camera = Camera.init( - Projection = StyleParam.CameraProjection.Perspective - ) - ), StyleParam.SubPlotId.Scene 1 -) -|> Chart.withScene( - Scene.init( - Camera = Camera.init( - Projection = StyleParam.CameraProjection.Orthographic - ) - ), StyleParam.SubPlotId.Scene 2 -) -|> Chart.withSize (1000,1000) -|> Chart.show - -Chart.Bubble3D( - [for i in 0..10 do yield (i,i,i)], - [0 .. 10 .. 100], - MarkerColor = Color.fromColorScaleValues [0..10], - MarkerSymbol = StyleParam.MarkerSymbol3D.Diamond -) - -|> Chart.show - - -let data = - Http.RequestString @"https://raw.githubusercontent.com/plotly/datasets/master/iris-data.csv" - |> fun csv -> Frame.ReadCsvString(csv,true,separators=",") - -let sepalLengthData = data.["sepal length"] |> Series.values -let sepalWidthData = data.["sepal width"] |> Series.values -let petalLengthData = data.["petal length"] |> Series.values -let petalWidthData = data.["petal width"] |> Series.values - - -let colors = - data - |> Frame.getCol "class" - |> Series.values - |> Seq.cast - |> Seq.map (fun x -> - match x with - | "Iris-setosa" -> 0. - | "Iris-versicolor" -> 0.5 - | _ -> 1 - ) - |> Color.fromColorScaleValues - -Chart.Splom( - [ - "sepal length" , sepalLengthData - "sepal width" , sepalWidthData - "petal length" , petalLengthData - "petal width" , petalWidthData - ], - MarkerColor = colors -) -|> Chart.withLayout( - Layout.init( - HoverMode = StyleParam.HoverMode.Closest, - DragMode = StyleParam.DragMode.Select - ) -) -|> Chart.withSize (1000,1000) -|> Chart.show - - -Chart.Splom( - [ - "sepal length" , sepalLengthData - "sepal width" , sepalWidthData - "petal length" , petalLengthData - "petal width" , petalWidthData - ], - MarkerColor = colors, - ShowDiagonal = false -) -|> Chart.withLayout( - Layout.init( - HoverMode = StyleParam.HoverMode.Closest, - DragMode = StyleParam.DragMode.Select - ) -) -|> Chart.withSize (1000,1000) -|> Chart.show - -Chart.Splom( - [ - "sepal length" , sepalLengthData - "sepal width" , sepalWidthData - "petal length" , petalLengthData - "petal width" , petalWidthData - ], - MarkerColor = colors, - ShowLowerHalf = false -) -|> Chart.withLayout( - Layout.init( - HoverMode = StyleParam.HoverMode.Closest, - DragMode = StyleParam.DragMode.Select - ) -) -|> Chart.withSize (1000,1000) -|> Chart.show \ No newline at end of file diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index 2f8254695..1062a8a98 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -93,7 +93,8 @@ - + + @@ -108,6 +109,7 @@ + @@ -118,6 +120,7 @@ + @@ -137,7 +140,6 @@ - diff --git a/src/Plotly.NET/Templates/ChartTemplates.fs b/src/Plotly.NET/Templates/ChartTemplates.fs index dcbc4604f..46d0dcda3 100644 --- a/src/Plotly.NET/Templates/ChartTemplates.fs +++ b/src/Plotly.NET/Templates/ChartTemplates.fs @@ -646,6 +646,21 @@ module ChartTemplates = 1.0, "#f0f921" ] ) ) + + TraceDomain.initTable ( + TraceDomainStyle.Table( + Cells = + TableCells.init ( + Fill = TableFill.init (Color = Color.fromHex "#EBF0F8"), + Line = Line.init (Color = Color.fromKeyword White) + ), + Header = + TableCells.init ( + Fill = TableFill.init (Color = Color.fromHex "#C8D4E3"), + Line = Line.init (Color = Color.fromKeyword White) + ) + ) + ) ] Template.init (layoutTempplate, traceTemplates) |> Template.withColorWay ColorWays.plotly diff --git a/src/Plotly.NET/Traces/ObjectAbstractions/Sankey.fs b/src/Plotly.NET/Traces/ObjectAbstractions/Sankey.fs new file mode 100644 index 000000000..25aaf417d --- /dev/null +++ b/src/Plotly.NET/Traces/ObjectAbstractions/Sankey.fs @@ -0,0 +1,192 @@ +namespace Plotly.NET.TraceObjects + +open Plotly.NET +open Plotly.NET.LayoutObjects +open DynamicObj +open System +open System.Runtime.InteropServices + +type SankeyNodes() = + inherit DynamicObj() + + static member init + ( + [] ?Color: Color, + [] ?CustomData: seq<#IConvertible>, + [] ?Groups: seq<#seq>, + [] ?HoverInfo: StyleParam.HoverInfo, + [] ?HoverLabel: Hoverlabel, + [] ?HoverTemplate: string, + [] ?MultiHoverTemplate: seq, + [] ?Label: seq, + [] ?Line: Line, + [] ?Pad: int, + [] ?Thickness: int, + [] ?X: seq<#IConvertible>, + [] ?Y: seq<#IConvertible> + ) = + + SankeyNodes() + |> SankeyNodes.style ( + ?Color = Color, + ?CustomData = CustomData, + ?Groups = Groups, + ?HoverInfo = HoverInfo, + ?HoverLabel = HoverLabel, + ?HoverTemplate = HoverTemplate, + ?MultiHoverTemplate = MultiHoverTemplate, + ?Label = Label, + ?Line = Line, + ?Pad = Pad, + ?Thickness = Thickness, + ?X = X, + ?Y = Y + + ) + + static member style + ( + [] ?Color: Color, + [] ?CustomData: seq<#IConvertible>, + [] ?Groups: seq<#seq>, + [] ?HoverInfo: StyleParam.HoverInfo, + [] ?HoverLabel: Hoverlabel, + [] ?HoverTemplate: string, + [] ?MultiHoverTemplate: seq, + [] ?Label: seq, + [] ?Line: Line, + [] ?Pad: int, + [] ?Thickness: int, + [] ?X: seq<#IConvertible>, + [] ?Y: seq<#IConvertible> + ) = + (fun (sankeyNodes: SankeyNodes) -> + + Color |> DynObj.setValueOpt sankeyNodes "color" + CustomData |> DynObj.setValueOpt sankeyNodes "customdata" + Groups |> DynObj.setValueOpt sankeyNodes "hoverinfo" + HoverInfo |> DynObj.setValueOptBy sankeyNodes "color" StyleParam.HoverInfo.convert + HoverLabel |> DynObj.setValueOpt sankeyNodes "hoverlabel" + (HoverTemplate, MultiHoverTemplate) |> DynObj.setSingleOrMultiOpt sankeyNodes "hovertemplate" + Label |> DynObj.setValueOpt sankeyNodes "label" + Line |> DynObj.setValueOpt sankeyNodes "line" + Pad |> DynObj.setValueOpt sankeyNodes "pad" + Thickness |> DynObj.setValueOpt sankeyNodes "thickness" + X |> DynObj.setValueOpt sankeyNodes "x" + Y |> DynObj.setValueOpt sankeyNodes "y" + + sankeyNodes) + +type SankeyLinkColorscale() = + inherit DynamicObj() + + static member init + ( + [] ?CMax: float, + [] ?CMin: float, + [] ?ColorScale: StyleParam.Colorscale, + [] ?Label: string, + [] ?Name: string, + [] ?TemplateItemName: string + ) = + + SankeyLinkColorscale() + |> SankeyLinkColorscale.style ( + ?CMax = CMax, + ?CMin = CMin, + ?ColorScale = ColorScale, + ?Label = Label, + ?Name = Name, + ?TemplateItemName = TemplateItemName + + ) + + static member style + ( + [] ?CMax: float, + [] ?CMin: float, + [] ?ColorScale: StyleParam.Colorscale, + [] ?Label: string, + [] ?Name: string, + [] ?TemplateItemName: string + ) = + (fun (sankeyLinkColorscale: SankeyLinkColorscale) -> + + CMax |> DynObj.setValueOpt sankeyLinkColorscale "cmax" + CMin |> DynObj.setValueOpt sankeyLinkColorscale "cmin" + ColorScale |> DynObj.setValueOptBy sankeyLinkColorscale "colorscale" StyleParam.Colorscale.convert + Label |> DynObj.setValueOpt sankeyLinkColorscale "label" + Name |> DynObj.setValueOpt sankeyLinkColorscale "name" + TemplateItemName |> DynObj.setValueOpt sankeyLinkColorscale "templateitemname" + + + sankeyLinkColorscale) + +type SankeyLinks() = + inherit DynamicObj() + + static member init + ( + [] ?Color: Color, + [] ?ColorScales: seq, + [] ?CustomData: seq<#IConvertible>, + [] ?HoverInfo: StyleParam.HoverInfo, + [] ?HoverLabel: Hoverlabel, + [] ?HoverTemplate: string, + [] ?MultiHoverTemplate: seq, + [] ?Label: seq, + [] ?Line: Line, + [] ?Source: seq, + [] ?Target: seq, + [] ?Value: seq<#IConvertible> + ) = + + SankeyLinks() + |> SankeyLinks.style ( + ?Color = Color, + ?ColorScales = ColorScales, + ?CustomData = CustomData, + ?HoverInfo = HoverInfo, + ?HoverLabel = HoverLabel, + ?HoverTemplate = HoverTemplate, + ?MultiHoverTemplate = MultiHoverTemplate, + ?Label = Label, + ?Line = Line, + ?Source = Source, + ?Target = Target, + ?Value = Value + + ) + + static member style + ( + [] ?Color: Color, + [] ?ColorScales: seq, + [] ?CustomData: seq<#IConvertible>, + [] ?HoverInfo: StyleParam.HoverInfo, + [] ?HoverLabel: Hoverlabel, + [] ?HoverTemplate: string, + [] ?MultiHoverTemplate: seq, + [] ?Label: seq, + [] ?Line: Line, + [] ?Source: seq, + [] ?Target: seq, + [] ?Value: seq<#IConvertible> + ) = + (fun (sankeyLinks: SankeyLinks) -> + + Color |> DynObj.setValueOpt sankeyLinks "color" + ColorScales |> DynObj.setValueOpt sankeyLinks "colorscales" + CustomData |> DynObj.setValueOpt sankeyLinks "customdata" + HoverInfo |> DynObj.setValueOptBy sankeyLinks "hoverinfo" StyleParam.HoverInfo.convert + HoverLabel |> DynObj.setValueOpt sankeyLinks "hoverlabel" + HoverTemplate |> DynObj.setValueOpt sankeyLinks "hovertemplate" + MultiHoverTemplate |> DynObj.setValueOpt sankeyLinks "multihovertemplate" + Label |> DynObj.setValueOpt sankeyLinks "label" + Line |> DynObj.setValueOpt sankeyLinks "line" + Source |> DynObj.setValueOpt sankeyLinks "source" + Target |> DynObj.setValueOpt sankeyLinks "target" + Value |> DynObj.setValueOpt sankeyLinks "value" + + + sankeyLinks) diff --git a/src/Plotly.NET/Traces/ObjectAbstractions/Sunburst.fs b/src/Plotly.NET/Traces/ObjectAbstractions/Sunburst.fs new file mode 100644 index 000000000..bac124273 --- /dev/null +++ b/src/Plotly.NET/Traces/ObjectAbstractions/Sunburst.fs @@ -0,0 +1,36 @@ +namespace Plotly.NET.TraceObjects + +open Plotly.NET +open Plotly.NET.LayoutObjects +open DynamicObj +open System +open System.Runtime.InteropServices + + +type SunburstRoot() = + inherit DynamicObj() + + static member init([] ?Color: Color) = + + SunburstRoot() |> SunburstRoot.style (?Color = Color) + + static member style([] ?Color: Color) = + (fun (root: SunburstRoot) -> + + Color |> DynObj.setValueOpt root "color" + + root) + +type SunburstLeaf() = + inherit DynamicObj() + + static member init([] ?Opacity: float) = + + SunburstLeaf() |> SunburstLeaf.style (?Opacity = Opacity) + + static member style([] ?Opacity: float) = + (fun (leaf: SunburstLeaf) -> + + Opacity |> DynObj.setValueOpt leaf "opacity" + + leaf) diff --git a/src/Plotly.NET/Traces/ObjectAbstractions/Table.fs b/src/Plotly.NET/Traces/ObjectAbstractions/Table.fs index b61660900..0fbcf1aae 100644 --- a/src/Plotly.NET/Traces/ObjectAbstractions/Table.fs +++ b/src/Plotly.NET/Traces/ObjectAbstractions/Table.fs @@ -7,64 +7,17 @@ open System open System.Runtime.InteropServices /// CellColor type inherits from dynamic object -type CellColor() = +type TableFill() = inherit DynamicObj() - /// Initialized Line object static member init([] ?Color: Color) = - CellColor() |> CellColor.style (?Color = Color) - // Applies the styles to CellColor() - static member style([] ?Color: Color) = - (fun (cell: CellColor) -> - Color |> DynObj.setValueOpt cell "color" - // out -> - cell) - - -/// Header type inherits from dynamic object -type TableHeader() = - inherit DynamicObj() - - /// Initialized Header object - static member init - ( - values: seq<#seq<#IConvertible>>, - [] ?Align: seq, - [] ?Height: float, - [] ?Fill: CellColor, - [] ?Font: Font, - [] ?Line: Line - ) = - TableHeader() - |> TableHeader.style ( - values = values, - ?Align = Align, - ?Height = Height, - ?Fill = Fill, - ?Font = Font, - ?Line = Line - - ) + TableFill() |> TableFill.style (?Color = Color) - /// Applies the styles to TableHeader() - static member style - ( - values: seq<#seq<#IConvertible>>, - [] ?Align: seq, - [] ?Height: float, - [] ?Fill: CellColor, - [] ?Font: Font, - [] ?Line: Line - ) = - (fun (header: TableHeader) -> + static member style([] ?Color: Color) = + (fun (fill: TableFill) -> + Color |> DynObj.setValueOpt fill "color" + fill) - values |> DynObj.setValue header "values" - Align |> DynObj.setValueOptBy header "align" (Seq.map StyleParam.HorizontalAlign.convert) - Height |> DynObj.setValueOpt header "height" - Fill |> DynObj.setValueOpt header "fill" - Line |> DynObj.setValueOpt header "line" - Font |> DynObj.setValueOpt header "font" - header) /// Cells type inherits from dynamic object type TableCells() = @@ -73,40 +26,64 @@ type TableCells() = /// Initialized Cells object static member init ( - values: seq<#seq<#IConvertible>>, - ?Align: seq, - ?Height: float, - ?Fill: CellColor, + ?Align: StyleParam.HorizontalAlign, + ?MultiAlign: seq, + ?Fill: TableFill, ?Font: Font, - ?Line: Line + ?Format: seq, + ?Height: int, + ?Line: Line, + ?Prefix: string, + ?MultiPrefix: seq, + ?Suffix: string, + ?MultiSuffix: seq, + ?Values: seq<#seq<#IConvertible>> ) = TableCells() |> TableCells.style ( - values = values, ?Align = Align, - ?Height = Height, + ?MultiAlign = MultiAlign, ?Fill = Fill, ?Font = Font, - ?Line = Line - + ?Format = Format, + ?Height = Height, + ?Line = Line, + ?Prefix = Prefix, + ?MultiPrefix = MultiPrefix, + ?Suffix = Suffix, + ?MultiSuffix = MultiSuffix, + ?Values = Values ) //Applies the styles to TableCells() static member style ( - values: seq<#seq<#IConvertible>>, - ?Align: seq, - ?Height: float, - ?Fill: CellColor, - ?Font: Font, - ?Line: Line + [] ?Align: StyleParam.HorizontalAlign, + [] ?MultiAlign: seq, + [] ?Fill: TableFill, + [] ?Font: Font, + [] ?Format: seq, + [] ?Height: int, + [] ?Line: Line, + [] ?Prefix: string, + [] ?MultiPrefix: seq, + [] ?Suffix: string, + [] ?MultiSuffix: seq, + [] ?Values: seq<#seq<#IConvertible>> ) = (fun (cells: TableCells) -> - values |> DynObj.setValue cells "values" - Align |> DynObj.setValueOptBy cells "align" (Seq.map StyleParam.HorizontalAlign.convert) - Height |> DynObj.setValueOpt cells "height" + (Align, MultiAlign) |> DynObj.setSingleOrMultiOptBy cells "align" StyleParam.HorizontalAlign.convert Fill |> DynObj.setValueOpt cells "fill" - Line |> DynObj.setValueOpt cells "line" Font |> DynObj.setValueOpt cells "font" + Format |> DynObj.setValueOpt cells "format" + Height |> DynObj.setValueOpt cells "height" + Line |> DynObj.setValueOpt cells "line" + (Prefix, MultiPrefix) |> DynObj.setSingleOrMultiOpt cells "prefix" + (Suffix, MultiSuffix) |> DynObj.setSingleOrMultiOpt cells "suffix" + Values |> DynObj.setValueOpt cells "values" + + cells) + +type TableHeader = TableCells diff --git a/src/Plotly.NET/Traces/ObjectAbstractions/Treemap.fs b/src/Plotly.NET/Traces/ObjectAbstractions/Treemap.fs new file mode 100644 index 000000000..d9de061bb --- /dev/null +++ b/src/Plotly.NET/Traces/ObjectAbstractions/Treemap.fs @@ -0,0 +1,66 @@ +namespace Plotly.NET.TraceObjects + +open Plotly.NET +open Plotly.NET.LayoutObjects +open DynamicObj +open System +open System.Runtime.InteropServices + + +type TreemapRoot() = + inherit DynamicObj() + + static member init([] ?Color: Color) = + + TreemapRoot() |> TreemapRoot.style (?Color = Color) + + static member style([] ?Color: Color) = + (fun (root: TreemapRoot) -> + + Color |> DynObj.setValueOpt root "color" + + root) + +type TreemapLeaf() = + inherit DynamicObj() + + static member init([] ?Opacity: float) = + + TreemapLeaf() |> TreemapLeaf.style (?Opacity = Opacity) + + static member style([] ?Opacity: float) = + (fun (leaf: TreemapLeaf) -> + + Opacity |> DynObj.setValueOpt leaf "opacity" + + leaf) + + +type TreemapTiling() = + inherit DynamicObj() + + static member init + ( + [] ?Packing: StyleParam.TreemapTilingPacking, + [] ?SquarifyRatio: float, + [] ?Flip: StyleParam.TilingFlip, + [] ?Pad: float + ) = + + TreemapTiling() + |> TreemapTiling.style (?Packing = Packing, ?SquarifyRatio = SquarifyRatio, ?Flip = Flip, ?Pad = Pad) + + static member style + ( + [] ?Packing: StyleParam.TreemapTilingPacking, + [] ?SquarifyRatio: float, + [] ?Flip: StyleParam.TilingFlip, + [] ?Pad: float + ) = + (fun (tiling: TreemapTiling) -> + Packing |> DynObj.setValueOptBy tiling "packing" StyleParam.TreemapTilingPacking.convert + SquarifyRatio |> DynObj.setValueOpt tiling "squarifyRatio" + Flip |> DynObj.setValueOptBy tiling "flip" StyleParam.TilingFlip.convert + Pad |> DynObj.setValueOpt tiling "pad" + + tiling) diff --git a/src/Plotly.NET/Traces/ObjectAbstractions/TreemapTiling.fs b/src/Plotly.NET/Traces/ObjectAbstractions/TreemapTiling.fs deleted file mode 100644 index af7408118..000000000 --- a/src/Plotly.NET/Traces/ObjectAbstractions/TreemapTiling.fs +++ /dev/null @@ -1,58 +0,0 @@ -namespace Plotly.NET.TraceObjects - -open Plotly.NET -open Plotly.NET.LayoutObjects -open DynamicObj -open System -open System.Runtime.InteropServices - -type TreemapTiling() = - inherit DynamicObj() - - ///Initializes tiling object (used in Chart.Treemap) - /// - ///Parameters: - /// - ///Packing : Determines d3 treemap solver. For more info please refer to https://github.com/d3/d3-hierarchy#treemap-tiling - /// - ///SquarifyRatio: When using "squarify" `packing` algorithm, according to https://github.com/d3/d3-hierarchy/blob/master/README.md#squarify_ratio this option specifies the desired aspect ratio of the generated rectangles. The ratio must be specified as a number greater than or equal to one. Note that the orientation of the generated rectangles (tall or wide) is not implied by the ratio; for example, a ratio of two will attempt to produce a mixture of rectangles whose width:height ratio is either 2:1 or 1:2. When using "squarify", unlike d3 which uses the Golden Ratio i.e. 1.618034, Plotly applies 1 to increase squares in treemap layouts. - /// - ///Flip : Determines if the positions obtained from solver are flipped on each axis. - /// - ///Pad : Sets the inner padding (in px). - static member init - ( - [] ?Packing: StyleParam.TreemapTilingPacking, - [] ?SquarifyRatio: float, - [] ?Flip: StyleParam.TilingFlip, - [] ?Pad: float - ) = - - TreemapTiling() - |> TreemapTiling.style (?Packing = Packing, ?SquarifyRatio = SquarifyRatio, ?Flip = Flip, ?Pad = Pad) - - ///Applies the given styles to the given tiling object - /// - ///Parameters: - /// - ///Packing : Determines d3 treemap solver. For more info please refer to https://github.com/d3/d3-hierarchy#treemap-tiling - /// - ///SquarifyRatio: When using "squarify" `packing` algorithm, according to https://github.com/d3/d3-hierarchy/blob/master/README.md#squarify_ratio this option specifies the desired aspect ratio of the generated rectangles. The ratio must be specified as a number greater than or equal to one. Note that the orientation of the generated rectangles (tall or wide) is not implied by the ratio; for example, a ratio of two will attempt to produce a mixture of rectangles whose width:height ratio is either 2:1 or 1:2. When using "squarify", unlike d3 which uses the Golden Ratio i.e. 1.618034, Plotly applies 1 to increase squares in treemap layouts. - /// - ///Flip : Determines if the positions obtained from solver are flipped on each axis. - /// - ///Pad : Sets the inner padding (in px). - static member style - ( - [] ?Packing: StyleParam.TreemapTilingPacking, - [] ?SquarifyRatio: float, - [] ?Flip: StyleParam.TilingFlip, - [] ?Pad: float - ) = - (fun (tiling: TreemapTiling) -> - Packing |> DynObj.setValueOptBy tiling "packing" StyleParam.TreemapTilingPacking.convert - SquarifyRatio |> DynObj.setValueOpt tiling "squarifyRatio" - 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 4dea9f2a6..5d11c3c09 100644 --- a/src/Plotly.NET/Traces/TraceDomain.fs +++ b/src/Plotly.NET/Traces/TraceDomain.fs @@ -65,12 +65,18 @@ type TraceDomainStyle() = [] ?DLabel: #IConvertible, [] ?Label0: #IConvertible, [] ?Pull: float, - [] ?Text: seq<#IConvertible>, + [] ?MultiPull: seq, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, [] ?TextPosition: StyleParam.TextPosition, - [] ?TextTemplate: seq<#IConvertible>, - [] ?HoverText: seq<#IConvertible>, - [] ?HoverInfo: string, - [] ?HoverTemplate: seq<#IConvertible>, + [] ?MultiTextPosition: seq, + [] ?TextTemplate: string, + [] ?MultiTextTemplate: seq, + [] ?HoverText: string, + [] ?MultiHoverText: seq, + [] ?HoverInfo: StyleParam.HoverInfo, + [] ?HoverTemplate: string, + [] ?MultiHoverTemplate: seq, [] ?Meta: seq<#IConvertible>, [] ?CustomData: seq<#IConvertible>, [] ?Domain: Domain, @@ -89,228 +95,477 @@ type TraceDomainStyle() = [] ?Sort: bool, [] ?UIRevision: string ) = - (fun (pie: ('T :> Trace)) -> - - Name |> DynObj.setValueOpt pie "name" - Title |> DynObj.setValueOpt pie "title" - Visible |> DynObj.setValueOptBy pie "visible" StyleParam.Visible.convert - ShowLegend |> DynObj.setValueOpt pie "showlegend" - LegendGroup |> DynObj.setValueOpt pie "legendgroup" - LegendGroupTitle |> DynObj.setValueOpt pie "legendgrouptitle" - Opacity |> DynObj.setValueOpt pie "opacity" - Ids |> DynObj.setValueOpt pie "ids" - Values |> DynObj.setValueOpt pie "values" - Labels |> DynObj.setValueOpt pie "labels" - DLabel |> DynObj.setValueOpt pie "dlabel" - Label0 |> DynObj.setValueOpt pie "label0" - Pull |> DynObj.setValueOpt pie "pull" - Text |> DynObj.setValueOpt pie "text" - TextPosition |> DynObj.setValueOptBy pie "textposition" StyleParam.TextPosition.convert - TextTemplate |> DynObj.setValueOpt pie "texttemplate" - HoverText |> DynObj.setValueOpt pie "hovertext" - HoverInfo |> DynObj.setValueOpt pie "hoverinfo" - HoverTemplate |> DynObj.setValueOpt pie "hovertemplate" - Meta |> DynObj.setValueOpt pie "meta" - CustomData |> DynObj.setValueOpt pie "customdata" - Domain |> DynObj.setValueOpt pie "domain" - AutoMargin |> DynObj.setValueOpt pie "automargin" - Marker |> DynObj.setValueOpt pie "marker" - TextFont |> DynObj.setValueOpt pie "textfont" - TextInfo |> DynObj.setValueOptBy pie "textinfo" StyleParam.TextInfo.convert - Direction |> DynObj.setValueOptBy pie "direction" StyleParam.Direction.convert - Hole |> DynObj.setValueOpt pie "hole" - HoverLabel |> DynObj.setValueOpt pie "hoverlabel" - InsideTextFont |> DynObj.setValueOpt pie "insidetextfont" + (fun (trace: ('T :> Trace)) -> - InsideTextOrientation - |> DynObj.setValueOptBy pie "insidetextorientation" StyleParam.InsideTextOrientation.convert + Name |> DynObj.setValueOpt trace "name" + Title |> DynObj.setValueOpt trace "title" + Visible |> DynObj.setValueOptBy trace "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt trace "showlegend" + LegendGroup |> DynObj.setValueOpt trace "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt trace "legendgrouptitle" + Opacity |> DynObj.setValueOpt trace "opacity" + Ids |> DynObj.setValueOpt trace "ids" + Values |> DynObj.setValueOpt trace "values" + Labels |> DynObj.setValueOpt trace "labels" + DLabel |> DynObj.setValueOpt trace "dlabel" + Label0 |> DynObj.setValueOpt trace "label0" + (Pull, MultiPull) |> DynObj.setSingleOrMultiOpt trace "pull" + (Text, MultiText) |> DynObj.setSingleOrMultiOpt trace "text" + + (TextPosition, MultiTextPosition) + |> DynObj.setSingleOrMultiOptBy trace "textposition" StyleParam.TextPosition.convert - OutsideTextFont |> DynObj.setValueOpt pie "outsidetextfont" - Rotation |> DynObj.setValueOpt pie "rotation" - ScaleGroup |> DynObj.setValueOpt pie "scalegroup" - Sort |> DynObj.setValueOpt pie "sort" - UIRevision |> DynObj.setValueOpt pie "uirevision" + (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" + AutoMargin |> DynObj.setValueOpt trace "automargin" + Marker |> DynObj.setValueOpt trace "marker" + TextFont |> DynObj.setValueOpt trace "textfont" + TextInfo |> DynObj.setValueOptBy trace "textinfo" StyleParam.TextInfo.convert + Direction |> DynObj.setValueOptBy trace "direction" StyleParam.Direction.convert + Hole |> DynObj.setValueOpt trace "hole" + HoverLabel |> DynObj.setValueOpt trace "hoverlabel" + InsideTextFont |> DynObj.setValueOpt trace "insidetextfont" - pie) + InsideTextOrientation + |> DynObj.setValueOptBy trace "insidetextorientation" StyleParam.InsideTextOrientation.convert + OutsideTextFont |> DynObj.setValueOpt trace "outsidetextfont" + Rotation |> DynObj.setValueOpt trace "rotation" + ScaleGroup |> DynObj.setValueOpt trace "scalegroup" + Sort |> DynObj.setValueOpt trace "sort" + UIRevision |> DynObj.setValueOpt trace "uirevision" + trace) + + /// Applies the styles of funnelarea plot to TraceObjects static member FunnelArea ( + [] ?Name: string, + [] ?Title: Title, + [] ?Visible: StyleParam.Visible, + [] ?ShowLegend: bool, + [] ?LegendGroup: string, + [] ?LegendGroupTitle: Title, + [] ?Opacity: float, + [] ?Ids: seq<#IConvertible>, [] ?Values: seq<#IConvertible>, [] ?Labels: seq<#IConvertible>, - [] ?dLabel: float, - [] ?Label0: float, - [] ?Aspectratio: float, - [] ?Baseratio: float, - [] ?Insidetextfont: Font, - [] ?Scalegroup: string + [] ?DLabel: #IConvertible, + [] ?Label0: #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: seq<#IConvertible>, + [] ?CustomData: seq<#IConvertible>, + [] ?Domain: Domain, + [] ?Marker: Marker, + [] ?TextFont: Font, + [] ?TextInfo: StyleParam.TextInfo, + [] ?AspectRatio: float, + [] ?BaseRatio: float, + [] ?HoverLabel: Hoverlabel, + [] ?InsideTextFont: Font, + [] ?ScaleGroup: string, + [] ?UIRevision: string ) = (fun (trace: ('T :> Trace)) -> + Name |> DynObj.setValueOpt trace "name" + Title |> DynObj.setValueOpt trace "title" + Visible |> DynObj.setValueOptBy trace "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt trace "showlegend" + LegendGroup |> DynObj.setValueOpt trace "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt trace "legendgrouptitle" + Opacity |> DynObj.setValueOpt trace "opacity" + Ids |> DynObj.setValueOpt trace "ids" Values |> DynObj.setValueOpt trace "values" Labels |> DynObj.setValueOpt trace "labels" - dLabel |> DynObj.setValueOpt trace "dlabel" + DLabel |> DynObj.setValueOpt trace "dlabel" Label0 |> DynObj.setValueOpt trace "label0" - Aspectratio |> DynObj.setValueOpt trace "aspectratio" - Baseratio |> DynObj.setValueOpt trace "baseratio" - Insidetextfont |> DynObj.setValueOpt trace "insidetextfont" - Scalegroup |> DynObj.setValueOpt trace "scalegroup" + (Text, MultiText) |> DynObj.setSingleOrMultiOpt trace "text" - trace + (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 + AspectRatio |> DynObj.setValueOpt trace "aspectratio" + BaseRatio |> DynObj.setValueOpt trace "baseratio" + HoverLabel |> DynObj.setValueOpt trace "hoverlabel" + InsideTextFont |> DynObj.setValueOpt trace "insidetextfont" + ScaleGroup |> DynObj.setValueOpt trace "scalegroup" + UIRevision |> DynObj.setValueOpt trace "uirevision" + + trace) - ) - - /// Applies the styles of sundburst plot to TraceObjects - /// - /// Parameters: - /// - /// labels: Sets the labels of each of the sectors. - /// - /// parents: Sets the parent sectors for each of the sectors. Empty string items '' are understood to reference the root node in the hierarchy. If `ids` is filled, `parents` items are understood to be "ids" themselves. When `ids` is not set, plotly attempts to find matching items in `labels`, but beware they must be unique. - /// - /// Ids: Assigns id labels to each datum. These ids for object constancy of data points during animation. - /// - /// Values: Sets the values associated with each of the sectors. Use with `branchvalues` to determine how the values are summed. - /// - /// Text: Sets text elements associated with each sector. If trace `textinfo` contains a "text" flag, these elements will be seen on the chart. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. - /// - /// Branchvalues: Determines how the items in `values` are summed. When set to "total", items in `values` are taken to be value of all its descendants. When set to "remainder", items in `values` corresponding to the root and the branches sectors are taken to be the extra part not part of the sum of the values at their leaves. - /// - /// Level: Sets the level from which this trace hierarchy is rendered. Set `level` to `''` to start from the root node in the hierarchy. Must be an "id" if `ids` is filled in, otherwise plotly attempts to find a matching item in `labels`. - /// - /// Maxdepth: Sets the number of rendered sectors from any given `level`. Set `maxdepth` to "-1" to render all the levels in the hierarchy. + /// Applies the styles of sunburst plot to TraceObjects static member Sunburst ( - labels: seq<#IConvertible>, - parents: seq<#IConvertible>, - [] ?Ids: seq, - [] ?Values: seq, - [] ?Text: seq, - [] ?Branchvalues: StyleParam.BranchValues, - [] ?Level, - [] ?Maxdepth: int + [] ?Name: string, + [] ?Title: Title, + [] ?Visible: StyleParam.Visible, + [] ?ShowLegend: bool, + [] ?LegendGroup: string, + [] ?LegendGroupTitle: Title, + [] ?Opacity: float, + [] ?Ids: seq<#IConvertible>, + [] ?Parents: seq<#IConvertible>, + [] ?Values: seq<#IConvertible>, + [] ?Labels: seq<#IConvertible>, + [] ?Text: #IConvertible, + [] ?MultiText: seq<#IConvertible>, + [] ?TextTemplate: string, + [] ?MultiTextTemplate: seq, + [] ?HoverText: string, + [] ?MultiHoverText: seq, + [] ?HoverInfo: StyleParam.HoverInfo, + [] ?HoverTemplate: string, + [] ?MultiHoverTemplate: seq, + [] ?Meta: seq<#IConvertible>, + [] ?CustomData: seq<#IConvertible>, + [] ?Domain: Domain, + [] ?Marker: Marker, + [] ?TextFont: Font, + [] ?TextInfo: StyleParam.TextInfo, + [] ?BranchValues: StyleParam.BranchValues, + [] ?Count: string, + [] ?HoverLabel: Hoverlabel, + [] ?InsideTextFont: Font, + [] ?InsideTextOrientation: StyleParam.InsideTextOrientation, + [] ?OutsideTextFont: Font, + [] ?Root: SunburstRoot, + [] ?Leaf: SunburstLeaf, + [] ?Level: string, + [] ?MaxDepth: int, + [] ?Rotation: int, + [] ?Sort: bool, + [] ?UIRevision: string ) = (fun (trace: ('T :> Trace)) -> - labels |> DynObj.setValue trace "labels" - parents |> DynObj.setValue trace "parents" + + Name |> DynObj.setValueOpt trace "name" + Title |> DynObj.setValueOpt trace "title" + Visible |> DynObj.setValueOptBy trace "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt trace "showlegend" + 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" - Text |> DynObj.setValueOpt trace "text" - Branchvalues |> DynObj.setValueOptBy trace "branchvalues" StyleParam.BranchValues.convert + Labels |> DynObj.setValueOpt trace "labels" + (Text, MultiText) |> DynObj.setSingleOrMultiOpt trace "text" + (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.setValueOpt trace "count" + HoverLabel |> DynObj.setValueOpt trace "hoverlabel" + InsideTextFont |> DynObj.setValueOpt trace "insidetextfont" + + InsideTextOrientation + |> DynObj.setValueOptBy trace "insidetextorientation" StyleParam.InsideTextOrientation.convert + + 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" + MaxDepth |> DynObj.setValueOpt trace "maxdepth" + Rotation |> DynObj.setValueOpt trace "rotation" + Sort |> DynObj.setValueOpt trace "sort" + UIRevision |> DynObj.setValueOpt trace "uirevision" + trace) /// Applies the styles of treemap plot to TraceObjects - /// - /// Parameters: - /// - /// labels : Sets the labels of each of the sectors. - /// - /// parents : Sets the parent sectors for each of the sectors. Empty string items '' are understood to reference the root node in the hierarchy. If `ids` is filled, `parents` items are understood to be "ids" themselves. When `ids` is not set, plotly attempts to find matching items in `labels`, but beware they must be unique. - /// - /// Ids : Assigns id labels to each datum. These ids for object constancy of data points during animation. - /// - /// Values : Sets the values associated with each of the sectors. Use with `branchvalues` to determine how the values are summed. - /// - /// Text : Sets text elements associated with each sector. If trace `textinfo` contains a "text" flag, these elements will be seen on the chart. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. - /// - /// Branchvalues: Determines how the items in `values` are summed. When set to "total", items in `values` are taken to be value of all its descendants. When set to "remainder", items in `values` corresponding to the root and the branches sectors are taken to be the extra part not part of the sum of the values at their leaves. - /// - /// Tiling : Sets Tiling algorithm options - /// - /// PathBar : Sets the Pathbar used to navigate zooming - /// - /// Level : Sets the level from which this trace hierarchy is rendered. Set `level` to `''` to start from the root node in the hierarchy. Must be an "id" if `ids` is filled in, otherwise plotly attempts to find a matching item in `labels`. - /// - /// Maxdepth : Sets the number of rendered sectors from any given `level`. Set `maxdepth` to "-1" to render all the levels in the hierarchy. static member Treemap ( - labels: seq<#IConvertible>, - parents: seq<#IConvertible>, - [] ?Ids: seq, - [] ?Values: seq, - [] ?Text: seq, - [] ?Branchvalues: StyleParam.BranchValues, + [] ?Name: string, + [] ?Title: Title, + [] ?Visible: StyleParam.Visible, + [] ?ShowLegend: bool, + [] ?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: seq<#IConvertible>, + [] ?CustomData: seq<#IConvertible>, + [] ?Domain: Domain, + [] ?Marker: Marker, + [] ?TextFont: Font, + [] ?TextInfo: StyleParam.TextInfo, + [] ?BranchValues: StyleParam.BranchValues, + [] ?Count: string, [] ?Tiling: TreemapTiling, [] ?PathBar: Pathbar, - [] ?Level, - [] ?Maxdepth: int + [] ?HoverLabel: Hoverlabel, + [] ?InsideTextFont: Font, + [] ?OutsideTextFont: Font, + [] ?Root: TreemapRoot, + [] ?Level: string, + [] ?MaxDepth: int, + [] ?UIRevision: string ) = (fun (trace: ('T :> Trace)) -> - labels |> DynObj.setValue trace "labels" - parents |> DynObj.setValue trace "parents" + + Name |> DynObj.setValueOpt trace "name" + Title |> DynObj.setValueOpt trace "title" + Visible |> DynObj.setValueOptBy trace "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt trace "showlegend" + 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" - Text |> DynObj.setValueOpt trace "text" - Branchvalues |> DynObj.setValueOptBy trace "branchvalues" StyleParam.BranchValues.convert + 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.setValueOpt trace "count" 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" Level |> DynObj.setValueOpt trace "level" - Maxdepth |> DynObj.setValueOpt trace "maxdepth" - trace) - + MaxDepth |> DynObj.setValueOpt trace "maxdepth" + UIRevision |> DynObj.setValueOpt trace "uirevision" + trace) // Applies the styles of parallel coordinates plot to TraceObjects static member ParallelCoord ( + [] ?Name: string, + [] ?Visible: StyleParam.Visible, + [] ?ShowLegend: bool, + [] ?LegendGroup: string, + [] ?LegendGroupTitle: Title, + [] ?Ids: seq<#IConvertible>, [] ?Dimensions: seq, - [] ?Line, - [] ?Domain, - [] ?Labelfont, - [] ?Tickfont: Font, - [] ?Rangefont: Font + [] ?Meta: seq<#IConvertible>, + [] ?CustomData: seq<#IConvertible>, + [] ?Domain: Domain, + [] ?Line: Line, + [] ?LabelAngle: int, + [] ?LabelFont: Font, + [] ?LabelSide: StyleParam.Side, + [] ?RangeFont: Font, + [] ?TickFont: Font, + [] ?UIRevision: string ) = - (fun (parcoords: ('T :> Trace)) -> + (fun (trace: ('T :> Trace)) -> - Dimensions |> DynObj.setValueOpt parcoords "dimensions" - Line |> DynObj.setValueOpt parcoords "line" - Domain |> DynObj.setValueOpt parcoords "domain" - Labelfont |> DynObj.setValueOpt parcoords "labelfont" - Tickfont |> DynObj.setValueOpt parcoords "tickfont" - Rangefont |> DynObj.setValueOpt parcoords "rangefont" + Name |> DynObj.setValueOpt trace "name" + Visible |> DynObj.setValueOptBy trace "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt trace "showlegend" + LegendGroup |> DynObj.setValueOpt trace "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt trace "legendgrouptitle" + Ids |> DynObj.setValueOpt trace "ids" + Dimensions |> DynObj.setValueOpt trace "dimensions" + Meta |> DynObj.setValueOpt trace "meta" + CustomData |> DynObj.setValueOpt trace "customdata" + Domain |> DynObj.setValueOpt trace "domain" + Line |> DynObj.setValueOpt trace "line" + LabelAngle |> DynObj.setValueOpt trace "labelangle" + LabelFont |> DynObj.setValueOpt trace "labelfont" + LabelSide |> DynObj.setValueOpt trace "labelside" + RangeFont |> DynObj.setValueOpt trace "rangefont" + TickFont |> DynObj.setValueOpt trace "tickfont " + UIRevision |> DynObj.setValueOpt trace "uirevision" - // out -> - parcoords) + trace) static member ParallelCategories ( + [] ?Name: string, + [] ?Visible: StyleParam.Visible, + [] ?ShowLegend: bool, + [] ?LegendGroup: string, + [] ?LegendGroupTitle: Title, + [] ?Counts: int, [] ?Dimensions: seq, - [] ?Line, - [] ?Domain, - [] ?Color: Color, - [] ?Labelfont, - [] ?Tickfont: Font, - [] ?Rangefont: Font + [] ?HoverInfo: StyleParam.HoverInfo, + [] ?HoverTemplate: string, + [] ?MultiHoverTemplate: seq, + [] ?Meta: seq<#IConvertible>, + [] ?Domain: Domain, + [] ?Line: Line, + [] ?Arrangement: StyleParam.CategoryArrangement, + [] ?BundleColors: bool, + [] ?SortPaths: StyleParam.SortAlgorithm, + [] ?Hoveron: StyleParam.HoverOn, + [] ?LabelFont: Font, + [] ?TickFont: Font, + [] ?UIRevision: string + ) = + (fun (trace: ('T :> Trace)) -> + + Name |> DynObj.setValueOpt trace "name" + Visible |> DynObj.setValueOptBy trace "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt trace "showlegend" + LegendGroup |> DynObj.setValueOpt trace "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt trace "legendgrouptitle" + Counts |> DynObj.setValueOpt trace "counts" + Dimensions |> DynObj.setValueOpt trace "dimensions" + HoverInfo |> DynObj.setValueOptBy trace "hoverinfo" StyleParam.HoverInfo.convert + (HoverTemplate, MultiHoverTemplate) |> DynObj.setSingleOrMultiOpt trace "hovertemplate" + Meta |> DynObj.setValueOpt trace "meta" + Domain |> DynObj.setValueOpt trace "domain" + Line |> DynObj.setValueOpt trace "line" + Arrangement |> DynObj.setValueOptBy trace "arrangement" StyleParam.CategoryArrangement.convert + BundleColors |> DynObj.setValueOpt trace "bundlecolors" + SortPaths |> DynObj.setValueOptBy trace "sortpaths" StyleParam.SortAlgorithm.convert + Hoveron |> DynObj.setValueOptBy trace "hoveron" StyleParam.HoverOn.convert + LabelFont |> DynObj.setValueOpt trace "labelfont" + TickFont |> DynObj.setValueOpt trace "tickfont " + UIRevision |> DynObj.setValueOpt trace "uirevision" + + trace) + + static member Sankey + ( + [] ?Name: string, + [] ?Visible: StyleParam.Visible, + [] ?ShowLegend: bool, + [] ?LegendGroup: string, + [] ?LegendGroupTitle: Title, + [] ?Ids: seq<#IConvertible>, + [] ?HoverInfo: StyleParam.HoverInfo, + [] ?Meta: seq<#IConvertible>, + [] ?CustomData: seq<#IConvertible>, + [] ?Domain: Domain, + [] ?Orientation: StyleParam.Orientation, + [] ?Node: SankeyNodes, + [] ?Link: SankeyLinks, + [] ?TextFont: Font, + [] ?SelectedPoints: seq<#IConvertible>, + [] ?Arrangement: StyleParam.CategoryArrangement, + [] ?HoverLabel: Hoverlabel, + [] ?ValueFormat: string, + [] ?ValueSuffix: string, + [] ?UIRevision: string ) = - (fun (parcats: ('T :> Trace)) -> + (fun (trace: ('T :> Trace)) -> - Dimensions |> DynObj.setValueOpt parcats "dimensions" - Line |> DynObj.setValueOpt parcats "line" - Domain |> DynObj.setValueOpt parcats "domain" - Color |> DynObj.setValueOpt parcats "color" - Labelfont |> DynObj.setValueOpt parcats "labelfont" - Tickfont |> DynObj.setValueOpt parcats "tickfont" - Rangefont |> DynObj.setValueOpt parcats "rangefont" + Name |> DynObj.setValueOpt trace "name" + Visible |> DynObj.setValueOptBy trace "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt trace "showlegend" + LegendGroup |> DynObj.setValueOpt trace "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt trace "legendgrouptitle" + Ids |> DynObj.setValueOpt trace "ids" + HoverInfo |> DynObj.setValueOptBy trace "hoverinfo" StyleParam.HoverInfo.convert + Meta |> DynObj.setValueOpt trace "meta" + CustomData |> DynObj.setValueOpt trace "customdata" + Domain |> DynObj.setValueOpt trace "domain" + Orientation |> DynObj.setValueOptBy trace "orientation" StyleParam.Orientation.convert + Node |> DynObj.setValueOpt trace "node" + Link |> DynObj.setValueOpt trace "link" + TextFont |> DynObj.setValueOpt trace "textfont" + SelectedPoints |> DynObj.setValueOpt trace "selectedpoints" + Arrangement |> DynObj.setValueOptBy trace "arrangement" StyleParam.CategoryArrangement.convert + HoverLabel |> DynObj.setValueOpt trace "hoverlabel" + ValueFormat |> DynObj.setValueOpt trace "valueformat" + ValueSuffix |> DynObj.setValueOpt trace "valuesuffix" + UIRevision |> DynObj.setValueOpt trace "uirevision" - // out -> - parcats) + trace) // Applies the styles of table plot to TraceObjects static member Table ( - header: TableHeader, - cells: TableCells, - [] ?ColumnWidth: seq, - [] ?ColumnOrder: seq + [] ?Name: string, + [] ?Visible: StyleParam.Visible, + [] ?ShowLegend: bool, + [] ?LegendGroup: string, + [] ?LegendGroupTitle: Title, + [] ?Ids: seq<#IConvertible>, + [] ?ColumnOrder: seq, + [] ?ColumnWidth: float, + [] ?MultiColumnWidth: seq, + [] ?Meta: seq<#IConvertible>, + [] ?CustomData: seq<#IConvertible>, + [] ?Domain: Domain, + [] ?Cells: TableCells, + [] ?Header: TableHeader, + [] ?HoverLabel: Hoverlabel, + [] ?UIRevision: string ) = (fun (trace: ('T :> Trace)) -> - header |> DynObj.setValue trace "header" - cells |> DynObj.setValue trace "cells" - ColumnWidth |> DynObj.setValueOpt trace "columnwidth" + + Name |> DynObj.setValueOpt trace "name" + Visible |> DynObj.setValueOptBy trace "visible" StyleParam.Visible.convert + ShowLegend |> DynObj.setValueOpt trace "showlegend" + LegendGroup |> DynObj.setValueOpt trace "legendgroup" + LegendGroupTitle |> DynObj.setValueOpt trace "legendgrouptitle" + Ids |> DynObj.setValueOpt trace "ids" ColumnOrder |> DynObj.setValueOpt trace "columnorder" - // out -> + (ColumnWidth, MultiColumnWidth) |> DynObj.setSingleOrMultiOpt trace "columnwidth" + Meta |> DynObj.setValueOpt trace "meta" + CustomData |> DynObj.setValueOpt trace "customdata" + Domain |> DynObj.setValueOpt trace "domain" + Cells |> DynObj.setValueOpt trace "cells" + Header |> DynObj.setValueOpt trace "header" + HoverLabel |> DynObj.setValueOpt trace "hoverlabel" + UIRevision |> DynObj.setValueOpt trace "uirevision" + trace) static member Indicator diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/CategoricalCharts.fs b/tests/Plotly.NET.Tests/HtmlCodegen/CategoricalCharts.fs index ae40fc6c8..4bee4086e 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/CategoricalCharts.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/CategoricalCharts.fs @@ -9,7 +9,7 @@ open System open TestUtils.HtmlCodegen -let parallelCategoriesChart = +let parcats = let dims = [ Dimension.initParallel(Values = ["Cat1";"Cat1";"Cat1";"Cat1";"Cat2";"Cat2";"Cat3"],Label="A") @@ -18,8 +18,25 @@ let parallelCategoriesChart = Chart.ParallelCategories( dims, - Color=Color.fromColorScaleValues [0.;1.;0.;1.;0.;0.;0.], - Colorscale = StyleParam.Colorscale.Blackbody, + LineColor=Color.fromColorScaleValues [0.;1.;0.;1.;0.;0.;0.], + LineColorScale = StyleParam.Colorscale.Blackbody, + UseDefaults = false + ) + + +let parcatsStyled = + let dims = + [ + Dimension.initParallel(Values = ["A";"A";"A";"B";"B";"B";"C";"D"],Label="Lvl1") + Dimension.initParallel(Values = ["AA";"AA";"AB";"AB";"AB";"AB";"AB";"AB"],Label="Lvl2") + Dimension.initParallel(Values = ["AAA";"AAB";"AAC";"AAC";"AAB";"AAB";"AAA";"AAA"],Label="Lvl3") + ] + + Chart.ParallelCategories( + dims, + LineColor = Color.fromColorScaleValues [0; 1; 2; 2; 1; 1; 0; 0], // These values map to the last category axis, meaning [AAA => 0; AAB = 1; AAC => 2] + LineColorScale = StyleParam.Colorscale.Viridis, + BundleColors = false, UseDefaults = false ) @@ -27,16 +44,23 @@ let parallelCategoriesChart = let ``Parallel categories charts`` = testList "CategoricalCharts.Parallel categories charts" [ testCase "Parallel categories data" ( fun () -> - """var data = [{"type":"parcats","dimensions":[{"label":"A","values":["Cat1","Cat1","Cat1","Cat1","Cat2","Cat2","Cat3"],"axis":{}},{"label":"B","values":[0,1,0,1,0,0,0],"ticktext":["YES","NO"],"axis":{}}],"color":[0.0,1.0,0.0,1.0,0.0,0.0,0.0],"line":{"colorscale":"Blackbody"}}];""" - |> chartGeneratedContains parallelCategoriesChart + """var data = [{"type":"parcats","dimensions":[{"label":"A","values":["Cat1","Cat1","Cat1","Cat1","Cat2","Cat2","Cat3"],"axis":{}},{"label":"B","values":[0,1,0,1,0,0,0],"ticktext":["YES","NO"],"axis":{}}],"line":{"color":[0.0,1.0,0.0,1.0,0.0,0.0,0.0],"colorscale":"Blackbody"}}];""" + |> chartGeneratedContains parcats ); testCase "Parallel categories layout" ( fun () -> - emptyLayout parallelCategoriesChart + emptyLayout parcats + ); + testCase "Parallel categories styled data" ( fun () -> + """var data = [{"type":"parcats","dimensions":[{"label":"Lvl1","values":["A","A","A","B","B","B","C","D"],"axis":{}},{"label":"Lvl2","values":["AA","AA","AB","AB","AB","AB","AB","AB"],"axis":{}},{"label":"Lvl3","values":["AAA","AAB","AAC","AAC","AAB","AAB","AAA","AAA"],"axis":{}}],"line":{"color":[0,1,2,2,1,1,0,0],"colorscale":"Viridis"},"bundlecolors":false}];""" + |> chartGeneratedContains parcatsStyled + ); + testCase "Parallel categories styled layout" ( fun () -> + emptyLayout parcatsStyled ); ] -let parcoords1Chart = +let parcoords = let data = [ "A",[1.;4.;3.4;0.7;] @@ -44,91 +68,91 @@ let parcoords1Chart = "C",[2.;4.;3.1;5.] "D",[4.;2.;2.;4.;] ] - Chart.ParallelCoord(data,Color=Color.fromString "blue", UseDefaults = false) - -let parcoordsChart = - let v = [| - Dimension.initParallel( - Values = [|1.;4.;|], - Range = StyleParam.Range.MinMax (1.,5.), - ConstraintRange = StyleParam.Range.MinMax (1.,2.), - Label="A"); - Dimension.initParallel( - Values = [|3.;1.5;|], - Range = StyleParam.Range.MinMax (1.,5.), - Label="B", - Tickvals=[|1.5;3.;4.;5.;|]); - Dimension.initParallel( - Values = [|2.;4.;|], - Range = StyleParam.Range.MinMax (1.,5.), - Label= "C", - Tickvals=[|1.;2.;4.;5.;|], - TickText=[|"txt 1";"txt 2";"txt 4";"txt 5";|]); - Dimension.initParallel( - Values = [|4.;2.;|], - Range = StyleParam.Range.MinMax (1.,5.), - Label="D"); - |] - - let dyn = Trace("parcoords") - - dyn?dimensions <- v - dyn?line <- Line.init(Color =Color.fromString "blue") - - dyn - |> GenericChart.ofTraceObject false + Chart.ParallelCoord(data,LineColor=Color.fromString "blue", UseDefaults = false) + +let parcoordsStyled = + + let dims = + [ + Dimension.initParallel(Label = "1", Values = ([1;2;3;4] ), Range = StyleParam.Range.MinMax(0., 8.)) + Dimension.initParallel(Label = "2", Values = ([1;2;3;4] |> List.rev ), Range = StyleParam.Range.MinMax(0., 8.)) + Dimension.initParallel(Label = "3", Values = ([1;2;3;4] ), Range = StyleParam.Range.MinMax(0., 8.)) + Dimension.initParallel(Label = "4", Values = ([1;2;3;4] |> List.rev ), Range = StyleParam.Range.MinMax(0., 8.)) + ] + + let colors = + [1;2;3;4] + |> Color.fromColorScaleValues + + Chart.ParallelCoord( + dims, + LineColorScale = StyleParam.Colorscale.Viridis, + LineColor = colors, + UseDefaults = false + ) [] let ``Parallel coordinates charts`` = testList "CategoricalCharts.Parallel coordinates charts" [ - testCase "Parallel coordinates 1 data" ( fun () -> + testCase "Parallel coordinates data" ( fun () -> """var data = [{"type":"parcoords","dimensions":[{"label":"A","values":[1.0,4.0,3.4,0.7],"axis":{}},{"label":"B","values":[3.0,1.5,1.7,2.3],"axis":{}},{"label":"C","values":[2.0,4.0,3.1,5.0],"axis":{}},{"label":"D","values":[4.0,2.0,2.0,4.0],"axis":{}}],"line":{"color":"blue"}}];""" - |> chartGeneratedContains parcoords1Chart + |> chartGeneratedContains parcoords ); - testCase "Parallel coordinates 1 layout" ( fun () -> - emptyLayout parcoords1Chart + testCase "Parallel coordinates layout" ( fun () -> + emptyLayout parcoords ); - testCase "Parallel coordinates data" ( fun () -> - """var data = [{"type":"parcoords","dimensions":[{"label":"A","values":[1.0,4.0],"constraintrange":[1.0,2.0],"range":[1.0,5.0],"axis":{}},{"label":"B","values":[3.0,1.5],"range":[1.0,5.0],"tickvals":[1.5,3.0,4.0,5.0],"axis":{}},{"label":"C","values":[2.0,4.0],"range":[1.0,5.0],"ticktext":["txt 1","txt 2","txt 4","txt 5"],"tickvals":[1.0,2.0,4.0,5.0],"axis":{}},{"label":"D","values":[4.0,2.0],"range":[1.0,5.0],"axis":{}}],"line":{"color":"blue"}}];""" - |> chartGeneratedContains parcoordsChart + testCase "Parallel coordinates styled data" ( fun () -> + """var data = [{"type":"parcoords","dimensions":[{"label":"1","values":[1,2,3,4],"range":[0.0,8.0],"axis":{}},{"label":"2","values":[4,3,2,1],"range":[0.0,8.0],"axis":{}},{"label":"3","values":[1,2,3,4],"range":[0.0,8.0],"axis":{}},{"label":"4","values":[4,3,2,1],"range":[0.0,8.0],"axis":{}}],"line":{"color":[1,2,3,4],"colorscale":"Viridis"}}];""" + |> chartGeneratedContains parcoordsStyled ); - testCase "Parallel coordinates layout" ( fun () -> - emptyLayout parcoordsChart + testCase "Parallel coordinates styled layout" ( fun () -> + emptyLayout parcoordsStyled ); ] -let sankey1 = - // create nodes - let n1 = Node.Create("a",color=Color.fromString "Black") - let n2 = Node.Create("b",color=Color.fromString "Red") - let n3 = Node.Create("c",color=Color.fromString "Purple") - let n4 = Node.Create("d",color=Color.fromString "Green") - let n5 = Node.Create("e",color=Color.fromString "Orange") - - // create links between nodes - let link1 = Link.Create(n1,n2,value=1.0) - let link2 = Link.Create(n2,n3,value=2.0) - let link3 = Link.Create(n1,n5,value=1.3) - let link4 = Link.Create(n4,n5,value=1.5) - let link5 = Link.Create(n3,n5,value=0.5) + +let styledSankey = Chart.Sankey( - [n1;n2;n3;n4;n5], - [link1;link2;link3;link4;link5], + nodeLabels = ["A1"; "A2"; "B1"; "B2"; "C1"; "C2"; "D1"], + linkedNodeIds = [ + 0,2 + 0,3 + 1,3 + 2,4 + 3,4 + 3,5 + 4,6 + 5,6 + ], + NodeOutlineColor = Color.fromKeyword Black, + NodeOutlineWidth = 1., + linkValues = [8; 4; 2; 7; 3; 2; 5; 2], + LinkColor = Color.fromColors [ + Color.fromHex "#828BFB" + Color.fromHex "#828BFB" + Color.fromHex "#F27762" + Color.fromHex "#33D6AB" + Color.fromHex "#BC82FB" + Color.fromHex "#BC82FB" + Color.fromHex "#FFB47B" + Color.fromHex "#47DCF5" + ], + LinkOutlineColor = Color.fromKeyword Black, + LinkOutlineWidth = 1., UseDefaults = false ) - |> Chart.withTitle "Sankey Sample" + [] let ``Sankey charts`` = testList "CategoricalCharts.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 + """var data = [{"type":"sankey","node":{"label":["A1","A2","B1","B2","C1","C2","D1"],"line":{"color":"rgba(0, 0, 0, 1.0)","width":1.0}},"link":{"color":["rgba(130, 139, 251, 1.0)","rgba(130, 139, 251, 1.0)","rgba(242, 119, 98, 1.0)","rgba(51, 214, 171, 1.0)","rgba(188, 130, 251, 1.0)","rgba(188, 130, 251, 1.0)","rgba(255, 180, 123, 1.0)","rgba(71, 220, 245, 1.0)"],"line":{"color":"rgba(0, 0, 0, 1.0)","width":1.0},"source":[0,0,1,2,3,3,4,5],"target":[2,3,3,4,4,5,6,6],"value":[8,4,2,7,3,2,5,2]}}];""" + |> chartGeneratedContains styledSankey ) testCase "Sankey layout" ( fun () -> - "var layout = {\"title\":{\"text\":\"Sankey Sample\"}};" - |> chartGeneratedContains sankey1 + emptyLayout styledSankey ) ] @@ -139,22 +163,157 @@ let icicleChart = Chart.Icicle( character, parent, - ShowScale = true, - ColorScale = StyleParam.Colorscale.Viridis, + ShowSectionColorScale = true, + SectionColorScale = StyleParam.Colorscale.Viridis, TilingOrientation = StyleParam.Orientation.Vertical, TilingFlip = StyleParam.TilingFlip.Y, PathBarEdgeShape = StyleParam.PathbarEdgeShape.BackSlash, UseDefaults = false ) +let icicleStyled = + let labelsParents = [ + ("A",""), 20 + ("B",""), 1 + ("C",""), 2 + ("D",""), 3 + ("E",""), 4 + + ("AA","A"), 15 + ("AB","A"), 5 + + ("BA","B"), 1 + + ("AAA", "AA"), 10 + ("AAB", "AA"), 5 + ] + + Chart.Icicle( + labelsParents |> Seq.map fst, + Values = (labelsParents |> Seq.map snd), + BranchValues = StyleParam.BranchValues.Total, // branch values are the total of their childrens values + SectionColorScale = StyleParam.Colorscale.Viridis, + ShowSectionColorScale = true, + SectionOutlineColor = Color.fromKeyword Black, + Tiling = IcicleTiling.init(Flip = StyleParam.TilingFlip.XY), + UseDefaults = false + ) + [] 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}}];""" + """var data = [{"type":"icicle","parents":["","Eve","Eve","Seth","Seth","Eve","Eve","Awan","Eve"],"labels":["Eve","Cain","Seth","Enos","Noam","Abel","Awan","Enoch","Azura"],"marker":{"colorscale":"Viridis","line":{},"showscale":true},"tiling":{"flip":"y","orientation":"v"},"pathbar":{"edgeshape":"\\"}}];""" |> chartGeneratedContains icicleChart ) testCase "Icicle layout" ( fun () -> emptyLayout icicleChart + ) + testCase "Icicle styled data" ( fun () -> + """var data = [{"type":"icicle","parents":["","","","","","A","A","B","AA","AA"],"values":[20,1,2,3,4,15,5,1,10,5],"labels":["A","B","C","D","E","AA","AB","BA","AAA","AAB"],"marker":{"colorscale":"Viridis","line":{"color":"rgba(0, 0, 0, 1.0)"},"showscale":true},"branchvalues":"total","tiling":{"flip":"x+y"},"pathbar":{}}];""" + |> chartGeneratedContains icicleStyled + ) + testCase "Icicle styled layout" ( fun () -> + emptyLayout icicleStyled ) + ] + + +let sunburstChart = + let values = [19; 26; 55;] + let labels = ["Residential"; "Non-Residential"; "Utility"] + Chart.Sunburst( + ["A";"B";"C";"D";"E"], + ["";"";"B";"B";""], + Values=[5.;0.;3.;2.;3.], + MultiText=["At";"Bt";"Ct";"Dt";"Et"], + UseDefaults = false + ) + +let sunburstStyled = + let labelsParents = [ + ("A",""), 20 + ("B",""), 1 + ("C",""), 2 + ("D",""), 3 + ("E",""), 4 + + ("AA","A"), 15 + ("AB","A"), 5 + + ("BA","B"), 1 + + ("AAA", "AA"), 10 + ("AAB", "AA"), 5 + ] + + Chart.Sunburst( + labelsParents |> Seq.map fst, + Values = (labelsParents |> Seq.map snd), + BranchValues = StyleParam.BranchValues.Total, // branch values are the total of their childrens values + SectionColorScale = StyleParam.Colorscale.Viridis, + ShowSectionColorScale = true, + SectionOutlineColor = Color.fromKeyword Black, + Rotation = 45, + UseDefaults = false + ) + +[] +let ``Sunburst charts`` = + testList "CategoricalCharts.Sunburst charts" [ + testCase "Sunburst data" ( fun () -> + """var data = [{"type":"sunburst","parents":["","","B","B",""],"values":[5.0,0.0,3.0,2.0,3.0],"labels":["A","B","C","D","E"],"text":["At","Bt","Ct","Dt","Et"],"marker":{"line":{}}}];""" + |> chartGeneratedContains sunburstChart + ); + testCase "Sunburst layout" ( fun () -> + emptyLayout sunburstChart + ); + testCase "Sunburst styled data" ( fun () -> + """var data = [{"type":"sunburst","parents":["","","","","","A","A","B","AA","AA"],"values":[20,1,2,3,4,15,5,1,10,5],"labels":["A","B","C","D","E","AA","AB","BA","AAA","AAB"],"marker":{"colorscale":"Viridis","line":{"color":"rgba(0, 0, 0, 1.0)"},"showscale":true},"branchvalues":"total","rotation":45}];""" + |> chartGeneratedContains sunburstStyled + ); + testCase "Sunburst styled layout" ( fun () -> + emptyLayout sunburstStyled + ); + ] + + +let treemapStyled = + let labelsParents = [ + ("A",""), 20 + ("B",""), 1 + ("C",""), 2 + ("D",""), 3 + ("E",""), 4 + + ("AA","A"), 15 + ("AB","A"), 5 + + ("BA","B"), 1 + + ("AAA", "AA"), 10 + ("AAB", "AA"), 5 + ] + + Chart.Treemap( + labelsParents |> Seq.map fst, + Values = (labelsParents |> Seq.map snd), + BranchValues = StyleParam.BranchValues.Total, // branch values are the total of their childrens values + SectionColorScale = StyleParam.Colorscale.Viridis, + ShowSectionColorScale = true, + SectionOutlineColor = Color.fromKeyword Black, + Tiling = TreemapTiling.init(Packing = StyleParam.TreemapTilingPacking.SliceDice), + UseDefaults = false + ) + +[] +let ``Treemap charts`` = + testList "CategoricalCharts.Treemap charts" [ + testCase "Treemap styled data" ( fun () -> + """var data = [{"type":"treemap","parents":["","","","","","A","A","B","AA","AA"],"values":[20,1,2,3,4,15,5,1,10,5],"labels":["A","B","C","D","E","AA","AB","BA","AAA","AAB"],"marker":{"colorscale":"Viridis","line":{"color":"rgba(0, 0, 0, 1.0)"},"showscale":true},"branchvalues":"total","tiling":{"packing":"slice-dice"}}];""" + |> chartGeneratedContains treemapStyled + ); + testCase "Treemap styled layout" ( fun () -> + emptyLayout treemapStyled + ); ] \ No newline at end of file diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/FinanceCharts.fs b/tests/Plotly.NET.Tests/HtmlCodegen/FinanceCharts.fs index 663ec3e7f..e58de225a 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/FinanceCharts.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/FinanceCharts.fs @@ -86,22 +86,49 @@ let funnelArea = let values = [|5; 4; 3; 2; 1|] let text = [|"The 1st"; "The 2nd"; "The 3rd"; "The 4th"; "The 5th"|] let line = Line.init (Color=Color.fromString "purple", Width=3.) - Chart.FunnelArea(Values=values, Text=text, Line=line, UseDefaults = false) + Chart.FunnelArea(values, MultiText=text, SectionOutline=line, UseDefaults = false) + + +let funnelAreaStyled = + let values = [|5; 4; 3|] + let labels = [|"The 1st"; "The 2nd"; "The 3rd"|] + + Chart.FunnelArea( + values, + Labels = labels, + MultiText = labels, + SectionColors = [ + Color.fromKeyword Aqua + Color.fromKeyword Salmon + Color.fromKeyword Tan + ], + SectionOutlineColor = Color.fromKeyword Black, + SectionOutlineWidth = 2., + AspectRatio = 0.75, + BaseRatio = 0.1, + UseDefaults = false + ) + [] let ``Funnel area charts`` = testList "FinanceCharts.Funnel area charts" [ testCase "Funnel area data" ( fun () -> - "var data = [{\"type\":\"funnelarea\",\"values\":[5,4,3,2,1],\"marker\":{\"line\":{\"color\":\"purple\",\"width\":3.0}},\"domain\":{},\"text\":[\"The 1st\",\"The 2nd\",\"The 3rd\",\"The 4th\",\"The 5th\"]}];" + """var data = [{"type":"funnelarea","values":[5,4,3,2,1],"text":["The 1st","The 2nd","The 3rd","The 4th","The 5th"],"marker":{"line":{"color":"purple","width":3.0}}}];""" |> chartGeneratedContains funnelArea ); testCase "Funnel area layout" ( fun () -> emptyLayout funnelArea + ); + testCase "Funnel area styled data" ( fun () -> + """var data = [{"type":"funnelarea","values":[5,4,3],"labels":["The 1st","The 2nd","The 3rd"],"text":["The 1st","The 2nd","The 3rd"],"marker":{"colors":["rgba(0, 255, 255, 1.0)","rgba(250, 128, 114, 1.0)","rgba(210, 180, 140, 1.0)"],"line":{"color":"rgba(0, 0, 0, 1.0)","width":2.0}},"aspectratio":0.75,"baseratio":0.1}];""" + |> chartGeneratedContains funnelAreaStyled + ); + testCase "Funnel area styled layout" ( fun () -> + emptyLayout funnelAreaStyled ); ] - - let indicators = [ ChartDomain.Chart.Indicator( diff --git a/tests/Plotly.NET.Tests/HtmlCodegen/SimpleCharts.fs b/tests/Plotly.NET.Tests/HtmlCodegen/SimpleCharts.fs index b02ee7aca..7eae5314c 100644 --- a/tests/Plotly.NET.Tests/HtmlCodegen/SimpleCharts.fs +++ b/tests/Plotly.NET.Tests/HtmlCodegen/SimpleCharts.fs @@ -234,27 +234,46 @@ let ``Bubble charts`` = let pieChart = let values = [19; 26; 55;] let labels = ["Residential"; "Non-Residential"; "Utility"] - Chart.Pie(values, labels, UseDefaults = false) + Chart.Pie(values, Labels = labels, UseDefaults = false) + +let pieStyled = -let doughnutChart = let values = [19; 26; 55;] let labels = ["Residential"; "Non-Residential"; "Utility"] - Chart.Doughnut( + + Chart.Pie( values, - labels, - Hole=0.3, - TextLabels=labels, + Labels = labels, + SectionColors = [ + Color.fromKeyword Aqua + Color.fromKeyword Salmon + Color.fromKeyword Tan + ], + SectionOutlineColor = Color.fromKeyword Black, + SectionOutlineWidth = 2., + MultiText = [ + "Some" + "More" + "Stuff" + ], + MultiTextPosition = [ + StyleParam.TextPosition.Inside + StyleParam.TextPosition.Outside + StyleParam.TextPosition.Inside + ], + Rotation = 45., + MultiPull = [0.; 0.3; 0.], UseDefaults = false ) -let sunburstChart = +let doughnutChart = let values = [19; 26; 55;] let labels = ["Residential"; "Non-Residential"; "Utility"] - Chart.Sunburst( - ["A";"B";"C";"D";"E"], - ["";"";"B";"B";""], - Values=[5.;0.;3.;2.;3.], - Text=["At";"Bt";"Ct";"Dt";"Et"], + Chart.Doughnut( + values, + Labels = labels, + Hole=0.3, + MultiText=labels, UseDefaults = false ) @@ -262,26 +281,26 @@ let sunburstChart = let ``Pie and doughnut Charts`` = testList "SimpleCharts.Pie and doughnut Charts" [ testCase "Pie data" ( fun () -> - "var data = [{\"type\":\"pie\",\"values\":[19,26,55],\"labels\":[\"Residential\",\"Non-Residential\",\"Utility\"],\"marker\":{},\"text\":[\"Residential\",\"Non-Residential\",\"Utility\"]}];" - |> chartGeneratedContains pieChart + """var data = [{"type":"pie","values":[19,26,55],"labels":["Residential","Non-Residential","Utility"],"marker":{"line":{}}}];""" + |> chartGeneratedContains pieChart ); testCase "Pie layout" ( fun () -> emptyLayout pieChart + ); + testCase "Pie styled data" ( fun () -> + """var data = [{"type":"pie","values":[19,26,55],"labels":["Residential","Non-Residential","Utility"],"pull":[0.0,0.3,0.0],"text":["Some","More","Stuff"],"textposition":["inside","outside","inside"],"marker":{"colors":["rgba(0, 255, 255, 1.0)","rgba(250, 128, 114, 1.0)","rgba(210, 180, 140, 1.0)"],"line":{"color":"rgba(0, 0, 0, 1.0)","width":2.0}},"rotation":45.0}];""" + |> chartGeneratedContains pieStyled + ); + testCase "Pie styled layout" ( fun () -> + emptyLayout pieStyled ); testCase "Doughnut data" ( fun () -> - """var data = [{"type":"pie","values":[19,26,55],"labels":["Residential","Non-Residential","Utility"],"text":["Residential","Non-Residential","Utility"],"hole":0.3,"marker":{}}];""" + """var data = [{"type":"pie","values":[19,26,55],"labels":["Residential","Non-Residential","Utility"],"text":["Residential","Non-Residential","Utility"],"marker":{"line":{}},"hole":0.3}];""" |> chartGeneratedContains doughnutChart ); testCase "Doughnut layout" ( fun () -> emptyLayout doughnutChart ); - testCase "Sunburst data" ( fun () -> - "var data = [{\"type\":\"sunburst\",\"labels\":[\"A\",\"B\",\"C\",\"D\",\"E\"],\"parents\":[\"\",\"\",\"B\",\"B\",\"\"],\"values\":[5.0,0.0,3.0,2.0,3.0],\"text\":[\"At\",\"Bt\",\"Ct\",\"Dt\",\"Et\"],\"marker\":{}}];" - |> chartGeneratedContains sunburstChart - ); - testCase "Sunburst layout" ( fun () -> - emptyLayout sunburstChart - ); ] @@ -304,15 +323,15 @@ let tableStyledChart = Chart.Table( header, rows, - AlignHeader = [HorizontalAlign.Center], - AlignCells = [HorizontalAlign.Left; HorizontalAlign.Center; HorizontalAlign.Right], - ColorHeader = Color.fromString "#45546a", - ColorCells = Color.fromColors [Color.fromString "#deebf7"; Color.fromString "lightgrey"; Color.fromString "#deebf7"; Color.fromString "lightgrey"], - FontHeader = Font.init(FontFamily.Courier_New, Size=12., Color=Color.fromString "white"), - HeightHeader= 30., - LineHeader = Line.init(2.,Color.fromString "black"), - ColumnWidth = [70; 50; 100; 70], - ColumnOrder = [1; 2; 3; 4], + HeaderAlign = HorizontalAlign.Center, + CellsMultiAlign = [HorizontalAlign.Left; HorizontalAlign.Center; HorizontalAlign.Right], + HeaderFillColor = Color.fromString "#45546a", + CellsFillColor = Color.fromColors [Color.fromString "#deebf7"; Color.fromString "lightgrey"; Color.fromString "#deebf7"; Color.fromString "lightgrey"], + HeaderHeight = 30, + HeaderOutlineColor = Color.fromString "black", + HeaderOutlineWidth = 2., + MultiColumnWidth = [70.; 50.; 100.; 70.], + ColumnOrder = [1; 2; 3; 4], UseDefaults = false ) @@ -351,7 +370,12 @@ let tableColorDependentChart = |> Seq.map Color.fromColors |> Color.fromColors - Chart.Table(header2,rowvalues,ColorCells=cellcolor, UseDefaults = false) + Chart.Table( + header2, + rowvalues, + CellsFillColor=cellcolor, + UseDefaults = false + ) let sequencePresentationTableChart = let sequence = @@ -399,21 +423,18 @@ let sequencePresentationTableChart = |> Seq.map Color.fromColors |> Color.fromColors - let font = Font.init(FontFamily.Consolas,Size=14.) - let line = Line.init(0., Color.fromString "white") + let line = Line.init(Width = 0., Color = Color.fromString "white") let chartwidth = 50 + 10 * elementsPerRow Chart.Table( headers, cells, - LineCells = line, - LineHeader = line, - HeightCells = 20., - FontHeader = font, - FontCells = font, - ColumnWidth = [50;10], - AlignCells = [HorizontalAlign.Right;HorizontalAlign.Center], - ColorCells = cellcolors, + CellsOutline = line, + HeaderOutline = line, + CellsHeight = 20, + MultiColumnWidth = [50.;10.], + CellsMultiAlign = [HorizontalAlign.Right;HorizontalAlign.Center], + CellsFillColor = cellcolors, UseDefaults = false ) |> Chart.withSize(Width=chartwidth) @@ -424,28 +445,28 @@ let sequencePresentationTableChart = let ``Table charts`` = testList "SimpleCharts.Table charts" [ testCase "First table data" ( fun () -> - "var data = [{\"type\":\"table\",\"header\":{\"values\":[\"RowIndex\",\"A\",\"simple\",\"table\"]},\"cells\":{\"values\":[[\"0\",\"1\"],[\"I\",\"little\"],[\"am\",\"example\"],[\"a\",\"!\"]]}}];" + """var data = [{"type":"table","cells":{"fill":{},"line":{},"values":[["0","1"],["I","little"],["am","example"],["a","!"]]},"header":{"fill":{},"line":{},"values":["RowIndex","A","simple","table"]}}];""" |> chartGeneratedContains table1Chart ); testCase "First table layout" ( fun () -> emptyLayout table1Chart ); testCase "Styled table data" ( fun () -> - "var data = [{\"type\":\"table\",\"header\":{\"values\":[\"RowIndex\",\"A\",\"simple\",\"table\"],\"align\":[\"center\"],\"height\":30.0,\"fill\":{\"color\":\"#45546a\"},\"line\":{\"color\":\"black\",\"width\":2.0},\"font\":{\"family\":\"Courier New\",\"size\":12.0,\"color\":\"white\"}},\"cells\":{\"values\":[[\"0\",\"1\"],[\"I\",\"little\"],[\"am\",\"example\"],[\"a\",\"!\"]],\"align\":[\"left\",\"center\",\"right\"],\"fill\":{\"color\":[\"#deebf7\",\"lightgrey\",\"#deebf7\",\"lightgrey\"]}},\"columnwidth\":[70,50,100,70],\"columnorder\":[1,2,3,4]}];" + """var data = [{"type":"table","columnorder":[1,2,3,4],"columnwidth":[70.0,50.0,100.0,70.0],"cells":{"align":["left","center","right"],"fill":{"color":["#deebf7","lightgrey","#deebf7","lightgrey"]},"line":{},"values":[["0","1"],["I","little"],["am","example"],["a","!"]]},"header":{"align":"center","fill":{"color":"#45546a"},"height":30,"line":{"color":"black","width":2.0},"values":["RowIndex","A","simple","table"]}}];""" |> chartGeneratedContains tableStyledChart ); testCase "Styled table layout" ( fun () -> emptyLayout tableStyledChart ); testCase "Color dependent chart data" ( fun () -> - """var data = [{"type":"table","header":{"values":["Identifier","T0","T1","T2","T3"]},"cells":{"values":[[10004.0,10001.0,10005.0,10006.0,10007.0,10002.0,10003.0],[0.0,0.2,1.0,1.0,2.0,2.1,4.5],[0.1,2.0,1.6,0.8,2.0,2.0,3.0],[0.3,4.0,1.8,1.5,2.1,1.8,2.0],[0.2,5.0,2.2,0.7,1.9,2.1,2.5]],"fill":{"color":[["white","white","white","white","white","white","white"],["rgba(255, 255, 0, 1.0)","rgba(255, 245, 10, 1.0)","rgba(255, 204, 51, 1.0)","rgba(255, 204, 51, 1.0)","rgba(255, 153, 102, 1.0)","rgba(255, 148, 107, 1.0)","rgba(255, 26, 229, 1.0)"],["rgba(255, 250, 5, 1.0)","rgba(255, 153, 102, 1.0)","rgba(255, 174, 81, 1.0)","rgba(255, 215, 40, 1.0)","rgba(255, 153, 102, 1.0)","rgba(255, 153, 102, 1.0)","rgba(255, 102, 153, 1.0)"],["rgba(255, 240, 15, 1.0)","rgba(255, 51, 204, 1.0)","rgba(255, 164, 91, 1.0)","rgba(255, 179, 76, 1.0)","rgba(255, 148, 107, 1.0)","rgba(255, 164, 91, 1.0)","rgba(255, 153, 102, 1.0)"],["rgba(255, 245, 10, 1.0)","rgba(255, 0, 255, 1.0)","rgba(255, 143, 112, 1.0)","rgba(255, 220, 35, 1.0)","rgba(255, 159, 96, 1.0)","rgba(255, 148, 107, 1.0)","rgba(255, 128, 127, 1.0)"]]}}}];""" + """var data = [{"type":"table","cells":{"fill":{"color":[["white","white","white","white","white","white","white"],["rgba(255, 255, 0, 1.0)","rgba(255, 245, 10, 1.0)","rgba(255, 204, 51, 1.0)","rgba(255, 204, 51, 1.0)","rgba(255, 153, 102, 1.0)","rgba(255, 148, 107, 1.0)","rgba(255, 26, 229, 1.0)"],["rgba(255, 250, 5, 1.0)","rgba(255, 153, 102, 1.0)","rgba(255, 174, 81, 1.0)","rgba(255, 215, 40, 1.0)","rgba(255, 153, 102, 1.0)","rgba(255, 153, 102, 1.0)","rgba(255, 102, 153, 1.0)"],["rgba(255, 240, 15, 1.0)","rgba(255, 51, 204, 1.0)","rgba(255, 164, 91, 1.0)","rgba(255, 179, 76, 1.0)","rgba(255, 148, 107, 1.0)","rgba(255, 164, 91, 1.0)","rgba(255, 153, 102, 1.0)"],["rgba(255, 245, 10, 1.0)","rgba(255, 0, 255, 1.0)","rgba(255, 143, 112, 1.0)","rgba(255, 220, 35, 1.0)","rgba(255, 159, 96, 1.0)","rgba(255, 148, 107, 1.0)","rgba(255, 128, 127, 1.0)"]]},"line":{},"values":[[10004.0,10001.0,10005.0,10006.0,10007.0,10002.0,10003.0],[0.0,0.2,1.0,1.0,2.0,2.1,4.5],[0.1,2.0,1.6,0.8,2.0,2.0,3.0],[0.3,4.0,1.8,1.5,2.1,1.8,2.0],[0.2,5.0,2.2,0.7,1.9,2.1,2.5]]},"header":{"fill":{},"line":{},"values":["Identifier","T0","T1","T2","T3"]}}];""" |> chartGeneratedContains tableColorDependentChart ); testCase "Color dependent chart layout" ( fun () -> emptyLayout tableColorDependentChart ); testCase "Sequence presentation table data" ( fun () -> - "var data = [{\"type\":\"table\",\"header\":{\"values\":[\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"|\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"|\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"|\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"|\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"|\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"|\"],\"line\":{\"color\":\"white\",\"width\":0.0},\"font\":{\"family\":\"Consolas\",\"size\":14.0}},\"cells\":{\"values\":[[\"0\",\"60\",\"120\",\"180\"],[\"A\",\"A\",\"G\",\"A\"],[\"T\",\"C\",\"T\",\"C\"],[\"G\",\"G\",\"C\",\"G\"],[\"A\",\"T\",\"G\",\"T\"],[\"G\",\"C\",\"A\",\"C\"],[\"A\",\"G\",\"T\",\"G\"],[\"C\",\"A\",\"A\",\"A\"],[\"G\",\"T\",\"G\",\"T\"],[\"T\",\"A\",\"A\",\"A\"],[\"C\",\"G\",\"C\",\"G\"],[\"G\",\"A\",\"G\",\"A\"],[\"A\",\"C\",\"T\",\"C\"],[\"G\",\"G\",\"C\",\"C\"],[\"A\",\"T\",\"G\",\"G\"],[\"C\",\"C\",\"A\",\"T\"],[\"T\",\"G\",\"T\",\"A\"],[\"G\",\"A\",\"A\",\"G\"],[\"A\",\"T\",\"G\",\"A\"],[\"T\",\"A\",\"A\",\"C\"],[\"A\",\"G\",\"G\",\"G\"],[\"G\",\"A\",\"A\",\"T\"],[\"A\",\"G\",\"T\",\"C\"],[\"C\",\"T\",\"A\",\"G\"],[\"G\",\"A\",\"G\",\"A\"],[\"T\",\"T\",\"A\",\"T\"],[\"C\",\"A\",\"C\",\"A\"],[\"G\",\"G\",\"G\",\"G\"],[\"A\",\"A\",\"T\",\"A\"],[\"T\",\"C\",\"C\",\"C\"],[\"A\",\"C\",\"G\",\"G\"],[\"G\",\"G\",\"A\",\"T\"],[\"A\",\"T\",\"T\",\"C\"],[\"C\",\"G\",\"A\",\"G\"],[\"G\",\"A\",\"G\",\"A\"],[\"T\",\"T\",\"A\",\"T\"],[\"C\",\"A\",\"C\",\"A\"],[\"G\",\"G\",\"C\",\"G\"],[\"A\",\"A\",\"G\",\"A\"],[\"T\",\"C\",\"T\",\"C\"],[\"A\",\"G\",\"A\",\"C\"],[\"G\",\"T\",\"T\",\"G\"],[\"A\",\"C\",\"A\",\"T\"],[\"C\",\"G\",\"G\"],[\"C\",\"A\",\"A\"],[\"G\",\"G\",\"A\"],[\"A\",\"A\",\"G\"],[\"T\",\"A\",\"A\"],[\"A\",\"G\",\"C\"],[\"G\",\"A\",\"G\"],[\"A\",\"C\",\"T\"],[\"C\",\"G\",\"C\"],[\"T\",\"T\",\"G\"],[\"C\",\"C\",\"A\"],[\"G\",\"G\",\"T\"],[\"T\",\"A\",\"A\"],[\"G\",\"T\",\"G\"],[\"A\",\"A\",\"A\"],[\"T\",\"G\",\"T\"],[\"A\",\"A\",\"A\"],[\"G\",\"C\",\"G\"]],\"align\":[\"right\",\"center\"],\"height\":20.0,\"fill\":{\"color\":[[\"white\",\"white\",\"white\",\"white\",\"white\"],[\"#5050FF\",\"#5050FF\",\"#00C000\",\"#5050FF\",\"white\"],[\"#E6E600\",\"#E00000\",\"#E6E600\",\"#E00000\",\"white\"],[\"#00C000\",\"#00C000\",\"#E00000\",\"#00C000\",\"white\"],[\"#5050FF\",\"#E6E600\",\"#00C000\",\"#E6E600\",\"white\"],[\"#00C000\",\"#E00000\",\"#5050FF\",\"#E00000\",\"white\"],[\"#5050FF\",\"#00C000\",\"#E6E600\",\"#00C000\",\"white\"],[\"#E00000\",\"#5050FF\",\"#5050FF\",\"#5050FF\",\"white\"],[\"#00C000\",\"#E6E600\",\"#00C000\",\"#E6E600\",\"white\"],[\"#E6E600\",\"#5050FF\",\"#5050FF\",\"#5050FF\",\"white\"],[\"#E00000\",\"#00C000\",\"#E00000\",\"#00C000\",\"white\"],[\"#00C000\",\"#5050FF\",\"#00C000\",\"#5050FF\",\"white\"],[\"#5050FF\",\"#E00000\",\"#E6E600\",\"#E00000\",\"white\"],[\"#00C000\",\"#00C000\",\"#E00000\",\"#E00000\",\"white\"],[\"#5050FF\",\"#E6E600\",\"#00C000\",\"#00C000\",\"white\"],[\"#E00000\",\"#E00000\",\"#5050FF\",\"#E6E600\",\"white\"],[\"#E6E600\",\"#00C000\",\"#E6E600\",\"#5050FF\",\"white\"],[\"#00C000\",\"#5050FF\",\"#5050FF\",\"#00C000\",\"white\"],[\"#5050FF\",\"#E6E600\",\"#00C000\",\"#5050FF\",\"white\"],[\"#E6E600\",\"#5050FF\",\"#5050FF\",\"#E00000\",\"white\"],[\"#5050FF\",\"#00C000\",\"#00C000\",\"#00C000\",\"white\"],[\"#00C000\",\"#5050FF\",\"#5050FF\",\"#E6E600\",\"white\"],[\"#5050FF\",\"#00C000\",\"#E6E600\",\"#E00000\",\"white\"],[\"#E00000\",\"#E6E600\",\"#5050FF\",\"#00C000\",\"white\"],[\"#00C000\",\"#5050FF\",\"#00C000\",\"#5050FF\",\"white\"],[\"#E6E600\",\"#E6E600\",\"#5050FF\",\"#E6E600\",\"white\"],[\"#E00000\",\"#5050FF\",\"#E00000\",\"#5050FF\",\"white\"],[\"#00C000\",\"#00C000\",\"#00C000\",\"#00C000\",\"white\"],[\"#5050FF\",\"#5050FF\",\"#E6E600\",\"#5050FF\",\"white\"],[\"#E6E600\",\"#E00000\",\"#E00000\",\"#E00000\",\"white\"],[\"#5050FF\",\"#E00000\",\"#00C000\",\"#00C000\",\"white\"],[\"#00C000\",\"#00C000\",\"#5050FF\",\"#E6E600\",\"white\"],[\"#5050FF\",\"#E6E600\",\"#E6E600\",\"#E00000\",\"white\"],[\"#E00000\",\"#00C000\",\"#5050FF\",\"#00C000\",\"white\"],[\"#00C000\",\"#5050FF\",\"#00C000\",\"#5050FF\",\"white\"],[\"#E6E600\",\"#E6E600\",\"#5050FF\",\"#E6E600\",\"white\"],[\"#E00000\",\"#5050FF\",\"#E00000\",\"#5050FF\",\"white\"],[\"#00C000\",\"#00C000\",\"#E00000\",\"#00C000\",\"white\"],[\"#5050FF\",\"#5050FF\",\"#00C000\",\"#5050FF\",\"white\"],[\"#E6E600\",\"#E00000\",\"#E6E600\",\"#E00000\",\"white\"],[\"#5050FF\",\"#00C000\",\"#5050FF\",\"#E00000\",\"white\"],[\"#00C000\",\"#E6E600\",\"#E6E600\",\"#00C000\",\"white\"],[\"#5050FF\",\"#E00000\",\"#5050FF\",\"#E6E600\",\"white\"],[\"#E00000\",\"#00C000\",\"#00C000\",\"white\"],[\"#E00000\",\"#5050FF\",\"#5050FF\",\"white\"],[\"#00C000\",\"#00C000\",\"#5050FF\",\"white\"],[\"#5050FF\",\"#5050FF\",\"#00C000\",\"white\"],[\"#E6E600\",\"#5050FF\",\"#5050FF\",\"white\"],[\"#5050FF\",\"#00C000\",\"#E00000\",\"white\"],[\"#00C000\",\"#5050FF\",\"#00C000\",\"white\"],[\"#5050FF\",\"#E00000\",\"#E6E600\",\"white\"],[\"#E00000\",\"#00C000\",\"#E00000\",\"white\"],[\"#E6E600\",\"#E6E600\",\"#00C000\",\"white\"],[\"#E00000\",\"#E00000\",\"#5050FF\",\"white\"],[\"#00C000\",\"#00C000\",\"#E6E600\",\"white\"],[\"#E6E600\",\"#5050FF\",\"#5050FF\",\"white\"],[\"#00C000\",\"#E6E600\",\"#00C000\",\"white\"],[\"#5050FF\",\"#5050FF\",\"#5050FF\",\"white\"],[\"#E6E600\",\"#00C000\",\"#E6E600\",\"white\"],[\"#5050FF\",\"#5050FF\",\"#5050FF\",\"white\"],[\"#00C000\",\"#E00000\",\"#00C000\",\"white\"]]},\"line\":{\"color\":\"white\",\"width\":0.0},\"font\":{\"family\":\"Consolas\",\"size\":14.0}},\"columnwidth\":[50,10]}];" + """var data = [{"type":"table","columnwidth":[50.0,10.0],"cells":{"align":["right","center"],"fill":{"color":[["white","white","white","white","white"],["#5050FF","#5050FF","#00C000","#5050FF","white"],["#E6E600","#E00000","#E6E600","#E00000","white"],["#00C000","#00C000","#E00000","#00C000","white"],["#5050FF","#E6E600","#00C000","#E6E600","white"],["#00C000","#E00000","#5050FF","#E00000","white"],["#5050FF","#00C000","#E6E600","#00C000","white"],["#E00000","#5050FF","#5050FF","#5050FF","white"],["#00C000","#E6E600","#00C000","#E6E600","white"],["#E6E600","#5050FF","#5050FF","#5050FF","white"],["#E00000","#00C000","#E00000","#00C000","white"],["#00C000","#5050FF","#00C000","#5050FF","white"],["#5050FF","#E00000","#E6E600","#E00000","white"],["#00C000","#00C000","#E00000","#E00000","white"],["#5050FF","#E6E600","#00C000","#00C000","white"],["#E00000","#E00000","#5050FF","#E6E600","white"],["#E6E600","#00C000","#E6E600","#5050FF","white"],["#00C000","#5050FF","#5050FF","#00C000","white"],["#5050FF","#E6E600","#00C000","#5050FF","white"],["#E6E600","#5050FF","#5050FF","#E00000","white"],["#5050FF","#00C000","#00C000","#00C000","white"],["#00C000","#5050FF","#5050FF","#E6E600","white"],["#5050FF","#00C000","#E6E600","#E00000","white"],["#E00000","#E6E600","#5050FF","#00C000","white"],["#00C000","#5050FF","#00C000","#5050FF","white"],["#E6E600","#E6E600","#5050FF","#E6E600","white"],["#E00000","#5050FF","#E00000","#5050FF","white"],["#00C000","#00C000","#00C000","#00C000","white"],["#5050FF","#5050FF","#E6E600","#5050FF","white"],["#E6E600","#E00000","#E00000","#E00000","white"],["#5050FF","#E00000","#00C000","#00C000","white"],["#00C000","#00C000","#5050FF","#E6E600","white"],["#5050FF","#E6E600","#E6E600","#E00000","white"],["#E00000","#00C000","#5050FF","#00C000","white"],["#00C000","#5050FF","#00C000","#5050FF","white"],["#E6E600","#E6E600","#5050FF","#E6E600","white"],["#E00000","#5050FF","#E00000","#5050FF","white"],["#00C000","#00C000","#E00000","#00C000","white"],["#5050FF","#5050FF","#00C000","#5050FF","white"],["#E6E600","#E00000","#E6E600","#E00000","white"],["#5050FF","#00C000","#5050FF","#E00000","white"],["#00C000","#E6E600","#E6E600","#00C000","white"],["#5050FF","#E00000","#5050FF","#E6E600","white"],["#E00000","#00C000","#00C000","white"],["#E00000","#5050FF","#5050FF","white"],["#00C000","#00C000","#5050FF","white"],["#5050FF","#5050FF","#00C000","white"],["#E6E600","#5050FF","#5050FF","white"],["#5050FF","#00C000","#E00000","white"],["#00C000","#5050FF","#00C000","white"],["#5050FF","#E00000","#E6E600","white"],["#E00000","#00C000","#E00000","white"],["#E6E600","#E6E600","#00C000","white"],["#E00000","#E00000","#5050FF","white"],["#00C000","#00C000","#E6E600","white"],["#E6E600","#5050FF","#5050FF","white"],["#00C000","#E6E600","#00C000","white"],["#5050FF","#5050FF","#5050FF","white"],["#E6E600","#00C000","#E6E600","white"],["#5050FF","#5050FF","#5050FF","white"],["#00C000","#E00000","#00C000","white"]]},"height":20,"line":{"color":"white","width":0.0},"values":[["0","60","120","180"],["A","A","G","A"],["T","C","T","C"],["G","G","C","G"],["A","T","G","T"],["G","C","A","C"],["A","G","T","G"],["C","A","A","A"],["G","T","G","T"],["T","A","A","A"],["C","G","C","G"],["G","A","G","A"],["A","C","T","C"],["G","G","C","C"],["A","T","G","G"],["C","C","A","T"],["T","G","T","A"],["G","A","A","G"],["A","T","G","A"],["T","A","A","C"],["A","G","G","G"],["G","A","A","T"],["A","G","T","C"],["C","T","A","G"],["G","A","G","A"],["T","T","A","T"],["C","A","C","A"],["G","G","G","G"],["A","A","T","A"],["T","C","C","C"],["A","C","G","G"],["G","G","A","T"],["A","T","T","C"],["C","G","A","G"],["G","A","G","A"],["T","T","A","T"],["C","A","C","A"],["G","G","C","G"],["A","A","G","A"],["T","C","T","C"],["A","G","A","C"],["G","T","T","G"],["A","C","A","T"],["C","G","G"],["C","A","A"],["G","G","A"],["A","A","G"],["T","A","A"],["A","G","C"],["G","A","G"],["A","C","T"],["C","G","C"],["T","T","G"],["C","C","A"],["G","G","T"],["T","A","A"],["G","T","G"],["A","A","A"],["T","G","T"],["A","A","A"],["G","C","G"]]},"header":{"fill":{},"line":{"color":"white","width":0.0},"values":["","","","","","","","","","","|","","","","","","","","","","|","","","","","","","","","","|","","","","","","","","","","|","","","","","","","","","","|","","","","","","","","","","|"]}}];""" |> chartGeneratedContains sequencePresentationTableChart ); testCase "Sequence presentation table layout" ( fun () ->