Skip to content

Add Chart.Indicator and related Trace/Layout objects #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Plotly.NET.sln
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{7B09CC0A-F
docs\07_0_candlestick.fsx = docs\07_0_candlestick.fsx
docs\07_1_funnel.fsx = docs\07_1_funnel.fsx
docs\07_2_funnel_area.fsx = docs\07_2_funnel_area.fsx
docs\07_3_indicator.fsx = docs\07_3_indicator.fsx
docs\08_0_polar_line-scatter-plots.fsx = docs\08_0_polar_line-scatter-plots.fsx
docs\08_1_polar_bar_charts.fsx = docs\08_1_polar_bar_charts.fsx
docs\08_2_styling_polar_layouts.fsx = docs\08_2_styling_polar_layouts.fsx
Expand Down
88 changes: 88 additions & 0 deletions docs/07_3_indicator.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
(**
---
title: Indicator Charts
category: Finance Charts
categoryindex: 7
index: 4
---
*)

(*** hide ***)

(*** condition: prepare ***)
#r "nuget: Newtonsoft.JSON, 13.0.1"
#r "nuget: DynamicObj"
#r "../bin/Plotly.NET/net5.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

(**
# Indicator 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 indicator charts in F#.

Indicator Charts visualize the evolution of a value compared to a reference value, optionally inside a range.

There are different types of indicator charts, depending on the `IndicatorMode` used in chart generation:

- `Delta`/`Number` (and combinations) simply shows if the value is increasing or decreasing compared to the reference
- Any combination of the above with `Gauge` adds a customizable gauge that indicates where the value lies inside a given range.
*)

open Plotly.NET
open Plotly.NET.TraceObjects
open Plotly.NET.LayoutObjects

let allIndicatorTypes =
[
Chart.Indicator(
120., StyleParam.IndicatorMode.NumberDeltaGauge,
Title = "Bullet gauge",
DeltaReference = 90.,
Range = StyleParam.Range.MinMax(-200., 200.),
GaugeShape = StyleParam.IndicatorGaugeShape.Bullet,
ShowGaugeAxis = false,
Domain = Domain.init(Row = 0, Column = 0)
)
Chart.Indicator(
200., StyleParam.IndicatorMode.NumberDeltaGauge,
Title = "Angular gauge",
Delta = IndicatorDelta.init(Reference=160),
Range = StyleParam.Range.MinMax(0., 250.),
Domain = Domain.init(Row = 0, Column = 1)
)
Chart.Indicator(
300., StyleParam.IndicatorMode.NumberDelta,
Title = "number and delta",
DeltaReference = 90.,
Domain = Domain.init(Row = 1, Column = 0)
)
Chart.Indicator(
40., StyleParam.IndicatorMode.Delta,
Title = "delta",
DeltaReference = 90.,
Domain = Domain.init(Row = 1, Column = 1)
)
]
|> Chart.combine
|> Chart.withLayoutGridStyle(Rows = 2, Columns = 2)
|> Chart.withMarginSize(Left = 200)


(*** condition: ipynb ***)
#if IPYNB
allIndicatorTypes
#endif // IPYNB

(***hide***)
allIndicatorTypes |> GenericChart.toChartHTML
(***include-it-raw***)

51 changes: 51 additions & 0 deletions src/Plotly.NET/ChartAPI/ChartDomain.fs
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,54 @@ module ChartDomain =
)
)
|> GenericChart.ofTraceObject

/// creates table out of header sequence and row sequences
[<Extension>]
static member Indicator
(
value : IConvertible,
mode : StyleParam.IndicatorMode,
[<Optional;DefaultParameterValue(null)>] ?Range : StyleParam.Range,
[<Optional;DefaultParameterValue(null)>] ?Name : string,
[<Optional;DefaultParameterValue(null)>] ?Title : string,
[<Optional;DefaultParameterValue(null)>] ?ShowLegend : bool,
[<Optional;DefaultParameterValue(null)>] ?Domain : Domain,
[<Optional;DefaultParameterValue(null)>] ?Align : StyleParam.IndicatorAlignment,
[<Optional;DefaultParameterValue(null)>] ?DeltaReference : #IConvertible,
[<Optional;DefaultParameterValue(null)>] ?Delta : IndicatorDelta,
[<Optional;DefaultParameterValue(null)>] ?Number : IndicatorNumber,
[<Optional;DefaultParameterValue(null)>] ?GaugeShape : StyleParam.IndicatorGaugeShape,
[<Optional;DefaultParameterValue(null)>] ?Gauge : IndicatorGauge,
[<Optional;DefaultParameterValue(null)>] ?ShowGaugeAxis : bool,
[<Optional;DefaultParameterValue(null)>] ?GaugeAxis : LinearAxis
) =
let axis =
GaugeAxis
|> Option.defaultValue(LinearAxis.init())
|> LinearAxis.style(?Range=Range, ?Visible=ShowGaugeAxis)

let gauge =
Gauge
|> Option.defaultValue(IndicatorGauge.init())
|> IndicatorGauge.style(Axis=axis, ?Shape=GaugeShape)

let delta =
Delta
|> Option.defaultValue(IndicatorDelta.init())
|> IndicatorDelta.style(?Reference = DeltaReference)

TraceDomain.initIndicator(
TraceDomainStyle.Indicator(
?Name = Name ,
?Title = Title ,
?ShowLegend = ShowLegend,
Mode = mode ,
Value = value ,
?Domain = Domain ,
?Align = Align ,
Delta = delta ,
?Number = Number ,
Gauge = gauge
)
)
|> GenericChart.ofTraceObject
55 changes: 55 additions & 0 deletions src/Plotly.NET/CommonAbstractions/StyleParams.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,61 @@ module StyleParam =
// #I#
//--------------------------

[<RequireQualifiedAccess>]
type IndicatorMode =
| Number | Delta | Gauge
| NumberDelta | NumberGauge
| DeltaGauge
| NumberDeltaGauge
static member toString = function
| Number -> "number"
| Delta -> "delta"
| Gauge -> "gauge"
| NumberDelta -> "number+delta"
| NumberGauge -> "number+gauge"
| DeltaGauge -> "delta+gauge"
| NumberDeltaGauge -> "number+delta+gauge"

static member convert = IndicatorMode.toString >> box
override this.ToString() = this |> IndicatorMode.toString
member this.Convert() = this |> IndicatorMode.convert

[<RequireQualifiedAccess>]
type IndicatorAlignment =
| Left | Center | Right
static member toString = function
| Left -> "left"
| Center-> "center"
| Right -> "right"

static member convert = IndicatorAlignment.toString >> box
override this.ToString() = this |> IndicatorAlignment.toString
member this.Convert() = this |> IndicatorAlignment.convert

[<RequireQualifiedAccess>]
type IndicatorGaugeShape =
| Angular | Bullet
static member toString = function
| Angular -> "angular"
| Bullet -> "bullet"

static member convert = IndicatorGaugeShape.toString >> box
override this.ToString() = this |> IndicatorGaugeShape.toString
member this.Convert() = this |> IndicatorGaugeShape.convert

[<RequireQualifiedAccess>]
type IndicatorDeltaPosition =
| Top | Bottom | Left | Right
static member toString = function
| Top -> "top"
| Bottom -> "bottom"
| Left -> "left"
| Right -> "right"

static member convert = IndicatorDeltaPosition.toString >> box
override this.ToString() = this |> IndicatorDeltaPosition.toString
member this.Convert() = this |> IndicatorDeltaPosition.convert

[<RequireQualifiedAccess>]
type InsideTextAnchor =
| End | Middle | Start
Expand Down
Loading