Skip to content

Commit 0ae6fec

Browse files
authored
Merge pull request #111 from WhiteBlackGoose/quack-12
2 parents 384ec4b + e11bdb5 commit 0ae6fec

File tree

5 files changed

+278
-151
lines changed

5 files changed

+278
-151
lines changed

src/Plotly.NET/Playground.fsx

Lines changed: 0 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -802,154 +802,3 @@ let values,labels =
802802
|> Seq.unzip
803803

804804
let cols =[|"black";"blue"|]
805-
806-
let pointMapboxChart =
807-
let cityNames = [
808-
"Montreal"; "Toronto"; "Vancouver"; "Calgary"; "Edmonton";
809-
"Ottawa"; "Halifax"; "Victoria"; "Winnepeg"; "Regina"
810-
]
811-
812-
let lon = [
813-
-73.57; -79.24; -123.06; -114.1; -113.28;
814-
-75.43; -63.57; -123.21; -97.13; -104.6
815-
]
816-
let lat = [
817-
45.5; 43.4; 49.13; 51.1; 53.34; 45.24;
818-
44.64; 48.25; 49.89; 50.45
819-
]
820-
Chart.PointMapbox(
821-
lon,lat,
822-
Labels = cityNames,
823-
TextPosition = StyleParam.TextPosition.TopCenter
824-
)
825-
|> Chart.withMapbox(
826-
Mapbox.init(
827-
Style=StyleParam.MapboxStyle.OpenStreetMap,
828-
Center=(-104.6,50.45)
829-
)
830-
)
831-
832-
833-
open Deedle
834-
open FSharp.Data
835-
open System.IO
836-
open System.Text
837-
838-
839-
let flightsChart =
840-
let data =
841-
"start_lat,start_lon,end_lat,end_lon,airline,airport1,airport2,cnt
842-
32.89595056,-97.0372,35.04022222,-106.6091944,AA,DFW,ABQ,444
843-
41.979595,-87.90446417,30.19453278,-97.66987194,AA,ORD,AUS,166
844-
32.89595056,-97.0372,41.93887417,-72.68322833,AA,DFW,BDL,162
845-
18.43941667,-66.00183333,41.93887417,-72.68322833,AA,SJU,BDL,56
846-
32.89595056,-97.0372,33.56294306,-86.75354972,AA,DFW,BHM,168
847-
25.79325,-80.29055556,36.12447667,-86.67818222,AA,MIA,BNA,56
848-
32.89595056,-97.0372,42.3643475,-71.00517917,AA,DFW,BOS,422
849-
25.79325,-80.29055556,42.3643475,-71.00517917,AA,MIA,BOS,392"
850-
|> fun csv -> Frame.ReadCsvString(csv,true,separators=",")
851-
852-
let opacityVals : float [] = data.["cnt"] |> Series.values |> fun s -> s |> Seq.map (fun v -> v/(Seq.max s)) |> Array.ofSeq
853-
let startCoords = Series.zipInner data.["start_lon"] data.["start_lat"]
854-
let endCoords = Series.zipInner data.["end_lon"] data.["end_lat"]
855-
let coords = Series.zipInner startCoords endCoords |> Series.values
856-
857-
coords
858-
|> Seq.mapi (fun i (startCoords,endCoords) ->
859-
Chart.LineMapbox(
860-
[startCoords; endCoords],
861-
Opacity = opacityVals.[i],
862-
Color = "red"
863-
)
864-
)
865-
|> Chart.Combine
866-
|> Chart.withLegend(false)
867-
|> Chart.withMapbox(
868-
Mapbox.init(
869-
Style=StyleParam.MapboxStyle.OpenStreetMap,
870-
Center=(-97.0372,32.8959)
871-
)
872-
)
873-
|> Chart.withMarginSize(0,0,50,0)
874-
|> Chart.withTitle "Feb. 2011 American Airline flights"
875-
876-
877-
let dataDensityMapbox =
878-
"Date,Latitude,Longitude,Magnitude
879-
01/02/1965,19.246,145.616,6.0
880-
01/04/1965,1.8630000000000002,127.352,5.8
881-
01/05/1965,-20.579,-173.972,6.2
882-
01/08/1965,-59.076,-23.557,5.8
883-
01/09/1965,11.937999999999999,126.427,5.8
884-
01/10/1965,-13.405,166.62900000000002,6.7
885-
01/12/1965,27.357,87.867,5.9
886-
01/15/1965,-13.309000000000001,166.21200000000002,6.0
887-
01/16/1965,-56.452,-27.043000000000003,6.0
888-
01/17/1965,-24.563000000000002,178.487,5.8
889-
01/17/1965,-6.807,108.988,5.9
890-
01/24/1965,-2.608,125.95200000000001,8.2
891-
01/29/1965,54.636,161.703,5.5
892-
02/01/1965,-18.697,-177.864,5.6
893-
02/02/1965,37.523,73.251,6.0
894-
02/04/1965,-51.84,139.741,6.1
895-
02/04/1965,51.251000000000005,178.715,8.7
896-
02/04/1965,51.638999999999996,175.055,6.0
897-
02/04/1965,52.528,172.007,5.7
898-
02/04/1965,51.626000000000005,175.74599999999998,5.8
899-
02/04/1965,51.037,177.84799999999998,5.9
900-
02/04/1965,51.73,173.975,5.9
901-
02/04/1965,51.775,173.058,5.7
902-
02/04/1965,52.611000000000004,172.588,5.7
903-
02/04/1965,51.831,174.368,5.7
904-
02/04/1965,51.948,173.96900000000002,5.6
905-
02/04/1965,51.443000000000005,179.605,7.3
906-
02/04/1965,52.773,171.97400000000002,6.5
907-
02/04/1965,51.772,174.696,5.6
908-
02/04/1965,52.975,171.09099999999998,6.4
909-
02/04/1965,52.99,170.87400000000002,5.8
910-
02/04/1965,51.536,175.045,5.8
911-
02/04/1965,13.245,-44.922,5.8
912-
02/04/1965,51.812,174.206,5.7
913-
02/05/1965,51.762,174.84099999999998,5.7
914-
02/05/1965,52.438,174.321,6.3
915-
02/05/1965,51.946000000000005,173.84,5.7
916-
02/05/1965,51.738,174.56599999999997,6.0
917-
02/05/1965,51.486999999999995,176.558,5.6
918-
02/06/1965,53.008,-162.00799999999998,6.4
919-
02/06/1965,52.184,175.505,6.2
920-
02/06/1965,52.076,172.918,5.6
921-
02/06/1965,51.744,175.213,5.7
922-
02/06/1965,52.056999999999995,174.11599999999999,5.7
923-
02/06/1965,53.191,-161.859,6.3
924-
02/06/1965,51.446999999999996,176.46900000000002,5.8
925-
02/07/1965,51.258,173.393,5.7
926-
02/07/1965,52.031000000000006,175.41099999999997,5.7
927-
02/07/1965,51.294,179.092,5.8
928-
02/08/1965,55.223,165.426,5.9
929-
02/09/1965,-18.718,169.386,5.6
930-
02/09/1965,52.815,171.90400000000002,6.0
931-
02/12/1965,52.188,172.752,5.8
932-
02/15/1965,51.00899999999999,179.325,5.8
933-
02/15/1965,3.0260000000000002,125.95100000000001,5.9
934-
02/16/1965,38.908,142.095,5.7
935-
02/17/1965,51.693999999999996,176.446,5.7
936-
02/17/1965,21.526999999999997,143.08100000000002,5.6
937-
02/18/1965,25.011,94.186,5.6"
938-
|> fun d -> Frame.ReadCsvString(d,true,separators=",")
939-
940-
let lon = dataDensityMapbox.["Longitude"] |> Series.values
941-
let lat= dataDensityMapbox.["Latitude"] |> Series.values
942-
let magnitudes = dataDensityMapbox.["Magnitude"] |> Series.values
943-
Chart.DensityMapbox(
944-
lon,
945-
lat,
946-
Z = magnitudes,
947-
Radius=8.,
948-
Colorscale=StyleParam.Colorscale.Viridis
949-
)
950-
|> Chart.withMapbox(
951-
Mapbox.init(
952-
Style = StyleParam.MapboxStyle.StamenTerrain,
953-
Center = (60.,30.)
954-
)
955-
) |> Chart.Show
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
module Tests.CategoricalCharts
2+
3+
open Expecto
4+
open Plotly.NET
5+
open TestUtils
6+
open Plotly.NET.GenericChart
7+
open System
8+
9+
let parallelCategoriesChart =
10+
let dims =
11+
[
12+
Dimensions.init(["Cat1";"Cat1";"Cat1";"Cat1";"Cat2";"Cat2";"Cat3"],Label="A")
13+
Dimensions.init([0;1;0;1;0;0;0],Label="B",TickText=["YES";"NO"])
14+
]
15+
16+
Chart.ParallelCategories(
17+
dims,
18+
Color=[0.;1.;0.;1.;0.;0.;0.],
19+
Colorscale = StyleParam.Colorscale.Blackbody
20+
)
21+
22+
[<Tests>]
23+
let ``Parallel categories charts`` =
24+
testList "CategoricalCharts.Parallel categories charts" [
25+
testCase "Parallel categories data" ( fun () ->
26+
"var data = [{\"type\":\"parcats\",\"dimensions\":[{\"values\":[\"Cat1\",\"Cat1\",\"Cat1\",\"Cat1\",\"Cat2\",\"Cat2\",\"Cat3\"],\"label\":\"A\"},{\"values\":[0,1,0,1,0,0,0],\"label\":\"B\",\"ticktext\":[\"YES\",\"NO\"]}],\"color\":[0.0,1.0,0.0,1.0,0.0,0.0,0.0],\"line\":{\"colorscale\":\"Blackbody\"}}];"
27+
|> chartGeneratedContains parallelCategoriesChart
28+
);
29+
testCase "Parallel categories layout" ( fun () ->
30+
emptyLayout parallelCategoriesChart
31+
);
32+
]
33+
34+
35+
let parcoords1Chart =
36+
let data =
37+
[
38+
"A",[1.;4.;3.4;0.7;]
39+
"B",[3.;1.5;1.7;2.3;]
40+
"C",[2.;4.;3.1;5.]
41+
"D",[4.;2.;2.;4.;]
42+
]
43+
Chart.ParallelCoord(data,Color="blue")
44+
45+
let parcoordsChart =
46+
let v = [|
47+
Dimensions.init([|1.;4.;|],
48+
StyleParam.Range.MinMax (1.,5.),StyleParam.Range.MinMax (1.,2.),Label="A");
49+
Dimensions.init([|3.;1.5;|],
50+
StyleParam.Range.MinMax (1.,5.),Label="B",Tickvals=[|1.5;3.;4.;5.;|]);
51+
Dimensions.init([|2.;4.;|],
52+
StyleParam.Range.MinMax (1.,5.),Label="C",Tickvals=[|1.;2.;4.;5.;|],
53+
TickText=[|"txt 1";"txt 2";"txt 4";"txt 5";|]);
54+
Dimensions.init([|4.;2.;|],
55+
StyleParam.Range.MinMax (1.,5.),Label="D");
56+
|]
57+
58+
let dyn = Trace("parcoords")
59+
60+
dyn?dimensions <- v
61+
dyn?line <- Line.init(Color = "blue")
62+
63+
dyn
64+
|> GenericChart.ofTraceObject
65+
66+
[<Tests>]
67+
let ``Parallel coordinates charts`` =
68+
testList "CategoricalCharts.Parallel coordinates charts" [
69+
testCase "Parallel coordinates 1 data" ( fun () ->
70+
"var data = [{\"type\":\"parcoords\",\"dimensions\":[{\"values\":[1.0,4.0,3.4,0.7],\"label\":\"A\"},{\"values\":[3.0,1.5,1.7,2.3],\"label\":\"B\"},{\"values\":[2.0,4.0,3.1,5.0],\"label\":\"C\"},{\"values\":[4.0,2.0,2.0,4.0],\"label\":\"D\"}],\"line\":{\"color\":\"blue\"}}];"
71+
|> chartGeneratedContains parcoords1Chart
72+
);
73+
testCase "Parallel coordinates 1 layout" ( fun () ->
74+
emptyLayout parcoords1Chart
75+
);
76+
testCase "Parallel coordinates data" ( fun () ->
77+
"var data = [{\"type\":\"parcoords\",\"dimensions\":[{\"values\":[1.0,4.0],\"range\":[1.0,5.0],\"constraintrange\":[1.0,2.0],\"label\":\"A\"},{\"values\":[3.0,1.5],\"range\":[1.0,5.0],\"label\":\"B\",\"tickvals\":[1.5,3.0,4.0,5.0]},{\"values\":[2.0,4.0],\"range\":[1.0,5.0],\"label\":\"C\",\"tickvals\":[1.0,2.0,4.0,5.0],\"ticktext\":[\"txt 1\",\"txt 2\",\"txt 4\",\"txt 5\"]},{\"values\":[4.0,2.0],\"range\":[1.0,5.0],\"label\":\"D\"}],\"line\":{\"color\":\"blue\"}}];"
78+
|> chartGeneratedContains parcoordsChart
79+
);
80+
testCase "Parallel coordinates layout" ( fun () ->
81+
emptyLayout parcoordsChart
82+
);
83+
]
84+
85+
86+
let sankey1 =
87+
// create nodes
88+
let n1 = Node.Create("a",color="Black")
89+
let n2 = Node.Create("b",color="Red")
90+
let n3 = Node.Create("c",color="Purple")
91+
let n4 = Node.Create("d",color="Green")
92+
let n5 = Node.Create("e",color="Orange")
93+
94+
// create links between nodes
95+
let link1 = Link.Create(n1,n2,value=1.0)
96+
let link2 = Link.Create(n2,n3,value=2.0)
97+
let link3 = Link.Create(n1,n5,value=1.3)
98+
let link4 = Link.Create(n4,n5,value=1.5)
99+
let link5 = Link.Create(n3,n5,value=0.5)
100+
Chart.Sankey(
101+
[n1;n2;n3;n4;n5],
102+
[link1;link2;link3;link4;link5]
103+
)
104+
|> Chart.withTitle "Sankey Sample"
105+
106+
[<Tests>]
107+
let ``Sankey charts`` =
108+
testList "CategoricalCharts.Sankey charts" [
109+
testCase "Sankey data" ( fun () ->
110+
"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]}}];"
111+
|> chartGeneratedContains sankey1
112+
);
113+
testCase "Sankey layout" ( fun () ->
114+
"var layout = {\"title\":\"Sankey Sample\"};"
115+
|> chartGeneratedContains sankey1
116+
);
117+
]
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
module Tests.FinanceCharts
2+
3+
open Expecto
4+
open Plotly.NET
5+
open TestUtils
6+
open Plotly.NET.GenericChart
7+
open System
8+
9+
let candles =
10+
[|("2020-01-17T13:40:00", 0.68888, 0.68888, 0.68879, 0.6888);
11+
("2020-01-17T13:41:00", 0.68883, 0.68884, 0.68875, 0.68877);
12+
("2020-01-17T13:42:00", 0.68878, 0.68889, 0.68878, 0.68886);
13+
("2020-01-17T13:43:00", 0.68886, 0.68886, 0.68876, 0.68879);
14+
("2020-01-17T13:44:00", 0.68879, 0.68879, 0.68873, 0.68874);
15+
("2020-01-17T13:45:00", 0.68875, 0.68877, 0.68867, 0.68868);
16+
("2020-01-17T13:46:00", 0.68869, 0.68887, 0.68869, 0.68883);
17+
("2020-01-17T13:47:00", 0.68883, 0.68899, 0.68883, 0.68899);
18+
("2020-01-17T13:48:00", 0.68898, 0.689, 0.68885, 0.68889);
19+
("2020-01-17T13:49:00", 0.68889, 0.68893, 0.68881, 0.68893);
20+
("2020-01-17T13:50:00", 0.68891, 0.68896, 0.68886, 0.68891);
21+
|]
22+
|> Array.map (fun (d,o,h,l,c)->System.DateTime.Parse d, StockData.Create(o,h,l,c))
23+
24+
let candles1Chart = Chart.Candlestick candles
25+
26+
27+
let candles2Chart =
28+
let rangeslider = RangeSlider.init(Visible=false)
29+
Chart.Candlestick candles
30+
|> Chart.withX_AxisRangeSlider rangeslider
31+
32+
[<Tests>]
33+
let ``Candlestick charts`` =
34+
testList "FinanceCharts.Candlestick charts" [
35+
testCase "Finance 1 data" ( fun () ->
36+
"var data = [{\"type\":\"candlestick\",\"open\":[0.68888,0.68883,0.68878,0.68886,0.68879,0.68875,0.68869,0.68883,0.68898,0.68889,0.68891],\"high\":[0.68888,0.68884,0.68889,0.68886,0.68879,0.68877,0.68887,0.68899,0.689,0.68893,0.68896],\"low\":[0.68879,0.68875,0.68878,0.68876,0.68873,0.68867,0.68869,0.68883,0.68885,0.68881,0.68886],\"close\":[0.6888,0.68877,0.68886,0.68879,0.68874,0.68868,0.68883,0.68899,0.68889,0.68893,0.68891],\"x\":[\"2020-01-17T13:40:00\",\"2020-01-17T13:41:00\",\"2020-01-17T13:42:00\",\"2020-01-17T13:43:00\",\"2020-01-17T13:44:00\",\"2020-01-17T13:45:00\",\"2020-01-17T13:46:00\",\"2020-01-17T13:47:00\",\"2020-01-17T13:48:00\",\"2020-01-17T13:49:00\",\"2020-01-17T13:50:00\"],\"xaxis\":\"x\",\"yaxis\":\"y\"}];"
37+
|> chartGeneratedContains candles1Chart
38+
);
39+
testCase "Finance 1 layout" ( fun () ->
40+
emptyLayout candles1Chart
41+
);
42+
testCase "Finance 2 data" ( fun () ->
43+
"var data = [{\"type\":\"candlestick\",\"open\":[0.68888,0.68883,0.68878,0.68886,0.68879,0.68875,0.68869,0.68883,0.68898,0.68889,0.68891],\"high\":[0.68888,0.68884,0.68889,0.68886,0.68879,0.68877,0.68887,0.68899,0.689,0.68893,0.68896],\"low\":[0.68879,0.68875,0.68878,0.68876,0.68873,0.68867,0.68869,0.68883,0.68885,0.68881,0.68886],\"close\":[0.6888,0.68877,0.68886,0.68879,0.68874,0.68868,0.68883,0.68899,0.68889,0.68893,0.68891],\"x\":[\"2020-01-17T13:40:00\",\"2020-01-17T13:41:00\",\"2020-01-17T13:42:00\",\"2020-01-17T13:43:00\",\"2020-01-17T13:44:00\",\"2020-01-17T13:45:00\",\"2020-01-17T13:46:00\",\"2020-01-17T13:47:00\",\"2020-01-17T13:48:00\",\"2020-01-17T13:49:00\",\"2020-01-17T13:50:00\"],\"xaxis\":\"x\",\"yaxis\":\"y\"}];"
44+
|> chartGeneratedContains candles2Chart
45+
);
46+
testCase "Finance 2 layout" ( fun () ->
47+
"var layout = {\"xaxis\":{\"rangeslider\":{\"visible\":false,\"yaxis\":{}}}};"
48+
|> chartGeneratedContains candles2Chart
49+
);
50+
]
51+
52+
53+
let funnelChart =
54+
let y = [|"Sales person A"; "Sales person B"; "Sales person C"; "Sales person D"; "Sales person E"|]
55+
let x = [|1200.; 909.4; 600.6; 300.; 80.|]
56+
57+
// Customize the connector lines used to connect the funnel bars
58+
let connectorLine = Line.init (Color="royalblue", Dash=StyleParam.DrawingStyle.Dot, Width=3.)
59+
let connector = FunnelConnector.init(Line=connectorLine)
60+
61+
// Customize the outline of the funnel bars
62+
let line = Line.init(Width=2.,Color="3E4E88")
63+
64+
Chart.Funnel (x,y,Color="59D4E8", Line=line, Connector=connector)
65+
|> Chart.withMarginSize(Left=100)
66+
67+
[<Tests>]
68+
let ``Funnel charts`` =
69+
testList "FinanceCharts.Funnel charts" [
70+
testCase "Funnel data" ( fun () ->
71+
"var data = [{\"type\":\"funnel\",\"x\":[1200.0,909.4,600.6,300.0,80.0],\"y\":[\"Sales person A\",\"Sales person B\",\"Sales person C\",\"Sales person D\",\"Sales person E\"],\"connector\":{\"line\":{\"color\":\"royalblue\",\"width\":3.0,\"dash\":\"dot\"}},\"marker\":{\"color\":\"59D4E8\",\"line\":{\"color\":\"3E4E88\",\"width\":2.0}}}];"
72+
|> chartGeneratedContains funnelChart
73+
);
74+
testCase "Funnel layout" ( fun () ->
75+
"var layout = {\"margin\":{\"l\":100}};"
76+
|> chartGeneratedContains funnelChart
77+
);
78+
]
79+
80+
81+
82+
let funnelArea =
83+
let values = [|5; 4; 3; 2; 1|]
84+
let text = [|"The 1st"; "The 2nd"; "The 3rd"; "The 4th"; "The 5th"|]
85+
let line = Line.init (Color="purple", Width=3.)
86+
Chart.FunnelArea(Values=values, Text=text, Line=line)
87+
88+
[<Tests>]
89+
let ``Funnel area charts`` =
90+
testList "FinanceCharts.Funnel area charts" [
91+
testCase "Funnel area data" ( fun () ->
92+
"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\"]}];"
93+
|> chartGeneratedContains funnelArea
94+
);
95+
testCase "Funnel area layout" ( fun () ->
96+
emptyLayout funnelArea
97+
);
98+
]

0 commit comments

Comments
 (0)