Skip to content

Commit ef4f0fd

Browse files
committed
GenericChart
1 parent 15bcdfe commit ef4f0fd

File tree

4 files changed

+171
-33
lines changed

4 files changed

+171
-33
lines changed

src/FSharp.Plotly/ChartExtensions.fs

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,72 @@
11
namespace FSharp.Plotly
22

3+
open System
4+
open System.IO
5+
open StyleGramar
6+
open ChartArea
7+
open GenericChart
8+
9+
/// Extensions methods for Charts supporting the fluent pipeline style 'Chart.WithXYZ(...)'.
310
[<AutoOpen>]
411
module ChartExtensions =
5-
6-
7-
open System
8-
open System.IO
9-
10-
open StyleGramar
11-
open ChartArea
12-
13-
open GenericChart
14-
15-
16-
12+
13+
/// Provides a set of static methods for creating charts.
1714
type Chart with
1815

19-
static member withMarker(marker:Marker) =
20-
(fun (ch:GenericChart) ->
21-
ch
22-
|> GenericChart.mapTrace (fun gc ->
23-
gc.set_marker marker
24-
gc)
16+
// ####################### Apply to trace
17+
18+
/// Set the name related properties of a trace
19+
static member withTraceName(?Name,?Showlegend,?Legendgroup,?Visible) =
20+
(fun (ch:GenericChart) ->
21+
ch |> mapiTrace (fun i trace ->
22+
let naming i name = name |> Option.map (fun v -> if i = 0 then v else sprintf "%s_%i" v i)
23+
trace |> Helpers.ApplyTraceStyles(trace.``type``,?name=(naming i Name),?showlegend=Showlegend,?legendgroup=Legendgroup,?visible=Visible))
24+
)
25+
26+
/// Set the name related properties of a trace
27+
// TODO
28+
static member withTraceInfo(?textinfo,?textinfoposition,?hoverinfo) =
29+
(fun (ch:GenericChart) ->
30+
ch |> mapiTrace (fun i trace ->
31+
trace) // |> Helpers.ApplyTraceStyles())
32+
)
33+
34+
/// Apply styling to the Marker(s) of the chart as Object.
35+
static member withMarkerOption(marker:Marker) =
36+
(fun (ch:GenericChart) ->
37+
ch |> mapTrace (fun gc ->
38+
gc.set_marker marker
39+
gc)
2540
)
2641

42+
/// Apply styling to the Marker(s) of the chart.
2743
static member withMarkerStyle(?Size,?Color,?Symbol,?Opacity) =
2844
let marker =
2945
Marker()
3046
|> Helpers.ApplyMarkerStyles(?size=Size,?color=Color,?symbol=Symbol,?opacity=Opacity)
3147

32-
Chart.withMarker(marker)
48+
Chart.withMarkerOption(marker)
3349

34-
35-
static member withLine(line:Line) =
36-
(fun (ch:GenericChart) ->
37-
ch
38-
|> GenericChart.mapTrace (fun gc ->
39-
gc.set_line line
40-
gc)
50+
/// Apply styling to the Line(s) of the chart as Object.
51+
static member withLineOption(line:Line) =
52+
(fun (ch:GenericChart) ->
53+
ch |> mapTrace (fun gc ->
54+
gc.set_line line
55+
gc)
4156
)
4257

58+
/// Apply styling to the Line(s) of the chart.
4359
static member withLineStyle(?Width,?Color,?Shape,?Dash,?Smoothing,?ColorScale) =
4460
let line =
4561
Line()
4662
|> Helpers.ApplyLineStyles(?width=Width,?color=Color,?shape=Shape,?dash=Dash,?smoothing=Smoothing,?colorScale=ColorScale)
4763

48-
Chart.withLine(line)
64+
Chart.withLineOption(line)
65+
66+
4967

68+
// ####################### Apply to layout
69+
5070

5171
static member withX_AxisStyle(title) =
5272
(fun (ch:GenericChart) ->
@@ -71,8 +91,6 @@ module ChartExtensions =
7191
GenericChart.setLayout layout ch)
7292

7393

74-
// -------------
75-
// with Layout
7694
static member withLayout(layout:Layout) =
7795
(fun (ch:GenericChart) ->
7896
GenericChart.setLayout layout ch)
@@ -107,6 +125,10 @@ module ChartExtensions =
107125
static member withError(layout:Layout) =
108126
(fun (ch:GenericChart) ->
109127
GenericChart.setLayout layout ch)
128+
129+
130+
131+
// #######################
110132

111133
static member Show (ch:GenericChart) =
112134
let guid = Guid.NewGuid().ToString()

src/FSharp.Plotly/ChartHelpers.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ open ChartArea
1010
open GenericChart
1111

1212

13-
13+
// internal
1414
type private Helpers() =
1515

1616
// Applies the styles to GenericTrace()
@@ -482,6 +482,7 @@ type private Helpers() =
482482
static member ApplyBinsStyles
483483
(?startBins:float,?endBins:float,?size
484484
) =
485+
485486
(fun (bins:('T :> Bins)) ->
486487
startBins |> Option.iter bins.set_start
487488
endBins |> Option.iter bins.set_end

src/FSharp.Plotly/GenericChart.fs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
open System
44
open Newtonsoft.Json
55

6-
6+
/// HTML template for Plotly.js
77
module HTML =
88

99
let doc =
@@ -28,6 +28,8 @@ module HTML =
2828
Plotly.newPlot('[ID]', data, layout);
2929
</script>"""
3030

31+
32+
/// Module
3133
module GenericChart =
3234

3335
type GenericChart =
@@ -97,12 +99,26 @@ module GenericChart =
9799

98100

99101

100-
102+
/// Creates a new GenericChart whose traces are the results of applying the given function to each of the trace of the GenericChart.
101103
let mapTrace f gChart =
102104
match gChart with
103105
| Chart (trace,layout) -> Chart (f trace,layout)
104106
| MultiChart (traces,layout) -> MultiChart (traces |> Seq.map f,layout)
105107

108+
/// Creates a new GenericChart whose traces are the results of applying the given function to each of the trace of the GenericChart.
109+
/// The integer index passed to the function indicates the index (from 0) of element being transformed.
110+
let mapiTrace f gChart =
111+
match gChart with
112+
| Chart (trace,layout) -> Chart (f 0 trace,layout)
113+
| MultiChart (traces,layout) -> MultiChart (traces |> Seq.mapi f,layout)
114+
115+
/// Returns the number of traces within the GenericChart
116+
let countTrace gChart =
117+
match gChart with
118+
| Chart (_) -> 1
119+
| MultiChart (traces,_) -> traces |> Seq.length
120+
121+
106122
let setLayout layout gChart =
107123
match gChart with
108124
| Chart (trace,_) -> Chart (trace,Some layout)

src/FSharp.Plotly/Script.fsx

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,16 @@ Chart.BoxPlot(["bin1";"bin2";"bin1";"bin2";"bin1";"bin2";"bin1";"bin1";"bin2";"b
5252
Chart.BoxPlot(x=yValues,Jitter=0.3,Boxpoints= StyleOption.Boxpoints.Outliers)
5353
|> Chart.Show
5454

55+
56+
open Newtonsoft.Json
57+
5558
Chart.BoxPlot(y=yValues,Jitter=0.3,Boxpoints=StyleOption.Boxpoints.Suspectedoutliers)
56-
|> Chart.Show
59+
60+
Chart.Line(xValues,yValues',Name="line")
61+
|> Chart.withMarker(StyleGramar.Marker())
62+
|> GenericChart.getTraces
63+
|> JsonConvert.SerializeObject
64+
//|> Chart.Show
5765

5866

5967

@@ -133,3 +141,94 @@ Chart.BoxPlot(y=c,Jitter=0.3,Boxpoints= StyleOption.Boxpoints.Outliers);
133141
|> Chart.Combine
134142
|> Chart.Show
135143

144+
145+
146+
147+
148+
let buildApply (applyStyle:'a -> 'a) =
149+
let instance =
150+
System.Activator.CreateInstance<'a>()
151+
applyStyle instance
152+
153+
154+
let optBuildApply (applyStyle:'a -> 'a) (item:'a option) =
155+
match item with
156+
| Some item' -> applyStyle item'
157+
| None -> buildApply applyStyle
158+
159+
160+
161+
162+
163+
164+
open System.Reflection
165+
166+
let tryGetPropertyName (expr : Microsoft.FSharp.Quotations.Expr) =
167+
match expr with
168+
| Microsoft.FSharp.Quotations.Patterns.PropertyGet (_,pInfo,_) -> Some pInfo.Name
169+
| _ -> None
170+
171+
let trySetPropertyValue (o:obj) (propName:string) (value:obj) =
172+
let property = o.GetType().GetProperty(propName)
173+
try
174+
//property.SetValue(o, System.Convert.ChangeType(value, property.PropertyType), null)
175+
property.SetValue(o, value, null)
176+
Some o
177+
with
178+
| :? System.ArgumentException -> None
179+
180+
181+
let tryGetPropertyValue (o:obj) (propName:string) =
182+
try
183+
Some (o.GetType().GetProperty(propName).GetValue(o, null))
184+
with
185+
| :? System.Reflection.TargetInvocationException -> None
186+
187+
let tryGetPropertyValueAs<'a> (o:obj) (propName:string) =
188+
try
189+
let v = (o.GetType().GetProperty(propName).GetValue(o, null))
190+
Some (v :?> 'a)
191+
with
192+
| :? System.Reflection.TargetInvocationException -> None
193+
194+
195+
let updatePropertyValue (o:obj) (expr : Microsoft.FSharp.Quotations.Expr) (f: 'a option -> 'a) =
196+
let propName = tryGetPropertyName expr
197+
let v = f (tryGetPropertyValueAs<'a> o propName.Value)
198+
trySetPropertyValue o propName.Value v |> ignore
199+
o
200+
201+
202+
let t = Trace()
203+
204+
205+
type H =
206+
static member applyMarkerStyle(?Size,?SizeMin) =
207+
(fun (m:StyleGramar.Marker) ->
208+
Size |> Option.iter m.set_size
209+
SizeMin |> Option.iter m.set_sizemin
210+
m
211+
)
212+
213+
214+
let markerOptionBuild = optBuildApply (H.applyMarkerStyle(Size=10))
215+
216+
217+
218+
updatePropertyValue t <@ t.marker @> markerOptionBuild
219+
220+
221+
t.marker
222+
223+
let m = StyleGramar.Marker(size=1)
224+
225+
trySetPropertyValue m "size" 2
226+
227+
m.sizemin
228+
229+
tryGetPropertyValue m "cmax"
230+
231+
232+
233+
tryGetPropertyValue m (tryGetPropertyName <@ m.size @>) .Value
234+

0 commit comments

Comments
 (0)