Skip to content

Commit

Permalink
Report with multiple charts.
Browse files Browse the repository at this point in the history
  • Loading branch information
cinar committed Dec 10, 2023
1 parent da4e9e0 commit 64bcbfb
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 24 deletions.
26 changes: 18 additions & 8 deletions helper/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ The information provided on this project is strictly for informational purposes
- [type Number](<#Number>)
- [type Report](<#Report>)
- [func NewReport\(title string, date \<\-chan time.Time\) \*Report](<#NewReport>)
- [func \(r \*Report\) AddColumn\(column ReportColumn\)](<#Report.AddColumn>)
- [func \(r \*Report\) AddChart\(\) int](<#Report.AddChart>)
- [func \(r \*Report\) AddColumn\(column ReportColumn, charts ...int\)](<#Report.AddColumn>)
- [func \(r \*Report\) WriteToFile\(fileName string\) error](<#Report.WriteToFile>)
- [func \(r \*Report\) WriteToWriter\(writer io.Writer\) error](<#Report.WriteToWriter>)
- [type ReportColumn](<#ReportColumn>)
Expand Down Expand Up @@ -852,7 +853,7 @@ type Number interface {
```

<a name="Report"></a>
## type [Report](<https://github.com/cinar/indicator/blob/v2/helper/report.go#L52-L54>)
## type [Report](<https://github.com/cinar/indicator/blob/v2/helper/report.go#L53-L55>)

Report generates an HTML file containing an interactive chart that visually represents the provided data and annotations.

Expand All @@ -865,25 +866,34 @@ type Report struct {
```

<a name="NewReport"></a>
### func [NewReport](<https://github.com/cinar/indicator/blob/v2/helper/report.go#L59>)
### func [NewReport](<https://github.com/cinar/indicator/blob/v2/helper/report.go#L60>)

```go
func NewReport(title string, date <-chan time.Time) *Report
```

NewReport takes a channel of time as the time axis and returns a new instance of the Report struct. This instance can later be used to add data and annotations and subsequently generate a report.

<a name="Report.AddChart"></a>
### func \(\*Report\) [AddChart](<https://github.com/cinar/indicator/blob/v2/helper/report.go#L76>)

```go
func (r *Report) AddChart() int
```

AddChart adds a new chart to the report and returns its unique identifier. This identifier can be used later to refer to the chart and add columns to it.

<a name="Report.AddColumn"></a>
### func \(\*Report\) [AddColumn](<https://github.com/cinar/indicator/blob/v2/helper/report.go#L70>)
### func \(\*Report\) [AddColumn](<https://github.com/cinar/indicator/blob/v2/helper/report.go#L83>)

```go
func (r *Report) AddColumn(column ReportColumn)
func (r *Report) AddColumn(column ReportColumn, charts ...int)
```

AddColumn adds a new data column to the report.
AddColumn adds a new data column to the specified charts. If no chart is specified, it will be added to the main chart.

<a name="Report.WriteToFile"></a>
### func \(\*Report\) [WriteToFile](<https://github.com/cinar/indicator/blob/v2/helper/report.go#L89>)
### func \(\*Report\) [WriteToFile](<https://github.com/cinar/indicator/blob/v2/helper/report.go#L111>)

```go
func (r *Report) WriteToFile(fileName string) error
Expand All @@ -892,7 +902,7 @@ func (r *Report) WriteToFile(fileName string) error
WriteToFile writes the generated report content to a file with the specified name. This allows users to conveniently save the report for later viewing or analysis.

<a name="Report.WriteToWriter"></a>
### func \(\*Report\) [WriteToWriter](<https://github.com/cinar/indicator/blob/v2/helper/report.go#L77>)
### func \(\*Report\) [WriteToWriter](<https://github.com/cinar/indicator/blob/v2/helper/report.go#L99>)

```go
func (r *Report) WriteToWriter(writer io.Writer) error
Expand Down
26 changes: 24 additions & 2 deletions helper/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type reportModel struct {
Title string
Date <-chan time.Time
Columns []ReportColumn
Views [][]int
}

// Report generates an HTML file containing an interactive chart that
Expand All @@ -62,13 +63,34 @@ func NewReport(title string, date <-chan time.Time) *Report {
Title: title,
Date: date,
Columns: []ReportColumn{},
Views: [][]int{
{},
},
},
}
}

// AddColumn adds a new data column to the report.
func (r *Report) AddColumn(column ReportColumn) {
// AddChart adds a new chart to the report and returns its unique
// identifier. This identifier can be used later to refer to the
// chart and add columns to it.
func (r *Report) AddChart() int {
r.model.Views = append(r.model.Views, []int{})
return len(r.model.Views) - 1
}

// AddColumn adds a new data column to the specified charts. If no
// chart is specified, it will be added to the main chart.
func (r *Report) AddColumn(column ReportColumn, charts ...int) {
r.model.Columns = append(r.model.Columns, column)
columnID := len(r.model.Columns)

if len(charts) == 0 {
charts = append(charts, 0)
}

for _, chartID := range charts {
r.model.Views[chartID] = append(r.model.Views[chartID], columnID)
}
}

// WriteToWriter writes the report content to the provided io.Writer.
Expand Down
37 changes: 29 additions & 8 deletions helper/report.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
</h1>

<div id="dashboard">
<div id="chart"></div>
{{ range $i, $view := .Views }}
<div id="chart{{ $i }}"></div>
{{ if eq $i 0 }}
<div id="controls"></div>
{{ end }}
{{ end }}
</div>
</div>
</section>
Expand All @@ -36,18 +40,28 @@
function drawDashboard() {
var dashboard = new google.visualization.Dashboard(document.getElementById("dashboard"));

var chart = new google.visualization.ChartWrapper({
{{ range $i, $view := .Views }}
var chart{{ $i }} = new google.visualization.ChartWrapper({
"chartType": "LineChart",
"containerId": "chart",
"containerId": "chart{{ $i }}",
"options": {
"title": "{{ .Title }}",
"curveType": "function",
"legend": {
"position": "right",
},
"height": 400,
"height":
{{ if eq $i 0 }}400{{ else }}200{{ end }},
},
"view": {
"columns": [
0,
{{ range $view }}
{{ . }},
{{ end }}
]
},
});
{{ end }}

var rangeFilter = new google.visualization.ControlWrapper({
"controlType": "ChartRangeFilter",
Expand All @@ -58,22 +72,25 @@
"chartOptions": {
"height": 50,
},
"chartView": {
"columns": [0, 1],
}
},
},
});

// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn("date", "Date");
{{ range.Columns }}
{{ range .Columns }}
data.addColumn({
"type": "{{ .Type }}",
"label": "{{ .Name }}",
"role": "{{ .Role }}",
});
{{ end }}

{{ range.Date }}
{{ range .Date }}
data.addRow([
new Date({{ .Format "2006, 1, 2" }}),
{{ range $.Columns }}
Expand All @@ -82,7 +99,11 @@
]);
{{ end }}

dashboard.bind(rangeFilter, chart);
dashboard.bind(rangeFilter, [
{{ range $i, $id := .Views }}
chart{{ $i }},
{{ end }}
]);
dashboard.draw(data);
}
</script>
Expand Down
6 changes: 4 additions & 2 deletions helper/report_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ func TestReportWriteToFile(t *testing.T) {
annotations := helper.Map(inputs[4], func(row *Row) string { return row.Annotation })

report := helper.NewReport("Test Report", dates)
report.AddChart()

report.AddColumn(helper.NewNumericReportColumn("High", highs))
report.AddColumn(helper.NewNumericReportColumn("Low", lows))
report.AddColumn(helper.NewNumericReportColumn("Close", closes))
report.AddColumn(helper.NewAnnotationReportColumn(annotations))
report.AddColumn(helper.NewNumericReportColumn("Close", closes), 0, 1)
report.AddColumn(helper.NewAnnotationReportColumn(annotations), 0, 1)

fileName := "report.html"
defer os.Remove(fileName)
Expand Down
11 changes: 7 additions & 4 deletions strategy/apo_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,19 @@ func (a *ApoStrategy[T]) Compute(c <-chan T) <-chan Action {
// Report takes input channels containing dates and values, computes the recommended actions
// based on the data, and generates a report annotated with those actions.
func (a *ApoStrategy[T]) Report(dates <-chan time.Time, c <-chan T) *helper.Report {
cs := helper.Duplicate(c, 2)
cs := helper.Duplicate(c, 3)

dates = helper.Skip(dates, a.Apo.SlowPeriod-1)
cs[0] = helper.Skip(cs[0], a.Apo.SlowPeriod-1)

annotations := ActionsToAnnotations(a.Compute(cs[1]))
apo := a.Apo.Compute(cs[1])
annotations := ActionsToAnnotations(a.Compute(cs[2]))

report := helper.NewReport("APO Strategy", dates)
report.AddChart()

report.AddColumn(helper.NewNumericReportColumn("Close", cs[0]))
report.AddColumn(helper.NewAnnotationReportColumn(annotations))
report.AddColumn(helper.NewNumericReportColumn("APO", apo), 1)
report.AddColumn(helper.NewAnnotationReportColumn(annotations), 0, 1)

return report
}

0 comments on commit 64bcbfb

Please sign in to comment.