@isoftdata/utility-dashboard-backend 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +164 -133
  2. package/index.js +39 -20
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,133 +1,164 @@
1
- # utility-dashboard-backend
2
- A backend utility for formatting and loading dashboard chart and report data to be usable by the [frontend dashboard component](https://github.com/ISoft-Data-Systems/ractive-component-web-dashboard).
3
-
4
- ## Prerequisites
5
-
6
- * A MySQL database schema as outlined in [schema.md](schema.md)
7
- * A backend that can fetches rows from the chart, report, and report chart tables from the database with their primary keys. Any json columns should be parsed as objects.
8
- * A connection or pool of connections from the `mysql` NPM module for running the charts' queries
9
- * The [dashboard Ractive component](https://github.com/ISoft-Data-Systems/ractive-component-web-dashboard) on the client
10
-
11
- ## API
12
-
13
- ### formatReportMetadata
14
-
15
- This function returns data in the format expected for the `loadReportMetadata` function on the dashboard client component.
16
-
17
- #### Function signature:
18
-
19
- ```js
20
- async formatReportMetadata(mysqlConnection, { report, chartsInReport })
21
- ```
22
-
23
- #### Example Usage (From Pro Web `server/chart-loader.js`):
24
-
25
- ```js
26
- async function loadReportMetadata({ dashboardReportId, chartId }) {
27
- const report = await db.dashboardReport.loadById({ dashboardReportId }) // gets a report by its id
28
- const chartsInReport = await db.dashboardChart.loadByReport({ dashboardReportId, chartId }) // gets all charts for a specified report, or if `chartId` is specified, only gets that chart for that report.
29
- return await formatReportMetadata(db.pool, { report, chartsInReport })
30
- }
31
- ```
32
-
33
- #### mysqlConnection
34
- A connection or pool of connections from the `mysql` npm module.
35
-
36
- #### report
37
-
38
- A report `object`, a single row from the `dashboard_report`/`wa_dashboard_report` table/view. The `parameters` Array from the `json` column should also be parsed from JSON and appended to this object.
39
-
40
- Example:
41
-
42
- ```js
43
- {
44
- dashboardReportId: 1,
45
- reportName: 'report_overview',
46
- reportTitle: 'Overview',
47
- shareType: 'everyone',
48
- shareId: null,
49
- ownerId: null,
50
- parameters: [ // parameters deconstructed from `json` column after parsing
51
- {
52
- name: 'date_range',
53
- type: 'dateRange',
54
- title: 'Date Range',
55
- default: 'This Year'
56
- }
57
- ]
58
- }
59
- ```
60
-
61
- #### chartsInReport
62
-
63
- An `Array` of chart `object`s, one for each chart in the report, multiple rows from the `dashboard_chart`/`wa_dashboard_chart` table/view joined with `dashboard_report_chart`/`wa_dashboard_report_chart` to get the chart's rank.
64
-
65
- Example:
66
-
67
- ```js
68
- [
69
- {
70
- chartId: 10,
71
- name: 'line_sales_over_time_and_previous_period',
72
- title: 'Sales over Time',
73
- supertype: 'google',
74
- formatting: { Sales: [Object] },
75
- multiSeries: {
76
- value: 'Sales',
77
- series: 'Period',
78
- tooltip: 'Tooltip',
79
- groupXAxisBy: 'Date'
80
- },
81
- chartWrapper: { options: [Object], chartType: 'LineChart' },
82
- rank: 1
83
- },
84
- {
85
- chartId: 16,
86
- name: 'map_sales_by_lat_long',
87
- title: 'Sales Map',
88
- supertype: 'google',
89
- formatting: { Sales: [Object] },
90
- chartWrapper: { options: [Object], chartType: 'GeoChart' },
91
- rank: 2
92
- }
93
- ]
94
- ```
95
-
96
- ### formatChartDataForReport
97
-
98
- This function returns data in the format expected for the `loadChartDataForReport` function on the dashboard client component, including applying any report-specific chart options overrides and running the chart's query.
99
-
100
- #### Function signature
101
-
102
- ```js
103
- async formatChartDataForReport(mysqlConnection, { reportParameters, chart, reportChart, parameterSelectionList })
104
- ```
105
-
106
- #### Example usage: (from Pro Web `server/chart-loader.js`)
107
-
108
- ```js
109
- async function loadChartDataForReport ({ dashboardReportId, chartId, parameterSelectionList }) {
110
- const report = await db.dashboardReport.loadById({ dashboardReportId }) // get the report object
111
- const chart = await db.dashboardChart.loadById({ chartId }) // get the chart object
112
- const reportChart = await db.dashboardReportChart.loadByReportAndChartId({ chartId, dashboardReportId }) // get the report chart for the rank/overrides
113
- try {
114
- const chartData = await formatChartDataForReport(db.pool, { reportParameters: report.parameters, chart, reportChart, parameterSelectionList })
115
- return chartData
116
- } catch (err) {
117
- console.error(err)
118
- return { isErrored: true }
119
- }
120
- }
121
- ```
122
-
123
- #### mysqlConnection
124
- A connection or pool of connections from the `mysql` npm module.
125
-
126
- #### reportParameters
127
- The `parameters` array from a report object.
128
-
129
- #### chartId
130
- The id of a chart row in `wa_dashboard_chart`.
131
-
132
- #### parameterSelectionList
133
- The array of selected parameters sent from the client dashboard.
1
+ # utility-dashboard-backend
2
+ A backend utility for formatting and loading dashboard chart and report data to be usable by the [frontend dashboard component](https://github.com/ISoft-Data-Systems/ractive-component-web-dashboard).
3
+
4
+ ## Prerequisites
5
+
6
+ * A MySQL database schema as outlined in [schema.md](schema.md)
7
+ * A backend that can fetches rows from the chart, report, and report chart tables from the database with their primary keys. Any json columns should be parsed as objects.
8
+ * A connection or pool of connections from the `mysql` NPM module for running the charts' queries
9
+ * The [dashboard Ractive component](https://github.com/ISoft-Data-Systems/ractive-component-web-dashboard) on the client
10
+
11
+ ## API
12
+
13
+ ### formatReportMetadata
14
+
15
+ This function returns data in the format expected for the `loadReportMetadata` function on the dashboard client component.
16
+
17
+ #### Function signature:
18
+
19
+ ```js
20
+ async formatReportMetadata(mysqlConnection, { report, chartsInReport })
21
+ ```
22
+
23
+ #### Example Usage (From Pro Web `server/chart-loader.js`):
24
+
25
+ ```js
26
+ async function loadReportMetadata({ dashboardReportId, chartId }) {
27
+ const report = await db.dashboardReport.loadById({ dashboardReportId }) // gets a report by its id
28
+ const chartsInReport = await db.dashboardChart.loadByReport({ dashboardReportId, chartId }) // gets all charts for a specified report, or if `chartId` is specified, only gets that chart for that report.
29
+ return await formatReportMetadata(db.pool, { report, chartsInReport })
30
+ }
31
+ ```
32
+
33
+ #### mysqlConnection
34
+ A connection or pool of connections from the `mysql` npm module.
35
+
36
+ #### report
37
+
38
+ A report `object`, a single row from the `dashboard_report`/`wa_dashboard_report` table/view. The `parameters` Array from the `json` column should also be parsed from JSON and appended to this object.
39
+
40
+ Example:
41
+
42
+ ```js
43
+ {
44
+ dashboardReportId: 1,
45
+ reportName: 'report_overview',
46
+ reportTitle: 'Overview',
47
+ shareType: 'everyone',
48
+ shareId: null,
49
+ ownerId: null,
50
+ parameters: [ // parameters deconstructed from `json` column after parsing
51
+ {
52
+ name: 'date_range',
53
+ type: 'dateRange',
54
+ title: 'Date Range',
55
+ default: 'This Year'
56
+ }
57
+ ]
58
+ }
59
+ ```
60
+
61
+ #### chartsInReport
62
+
63
+ An `Array` of chart `object`s, one for each chart in the report, multiple rows from the `dashboard_chart`/`wa_dashboard_chart` table/view joined with `dashboard_report_chart`/`wa_dashboard_report_chart` to get the chart's rank.
64
+
65
+ Example:
66
+
67
+ ```js
68
+ [
69
+ {
70
+ chartId: 10,
71
+ name: 'line_sales_over_time_and_previous_period',
72
+ title: 'Sales over Time',
73
+ supertype: 'google',
74
+ formatting: { Sales: [Object] },
75
+ multiSeries: {
76
+ value: 'Sales',
77
+ series: 'Period',
78
+ tooltip: 'Tooltip',
79
+ groupXAxisBy: 'Date'
80
+ },
81
+ chartWrapper: { options: [Object], chartType: 'LineChart' },
82
+ rank: 1
83
+ },
84
+ {
85
+ chartId: 16,
86
+ name: 'map_sales_by_lat_long',
87
+ title: 'Sales Map',
88
+ supertype: 'google',
89
+ formatting: { Sales: [Object] },
90
+ chartWrapper: { options: [Object], chartType: 'GeoChart' },
91
+ rank: 2
92
+ }
93
+ ]
94
+ ```
95
+
96
+ ### formatChartDataForReport
97
+
98
+ This function returns data in the format expected for the `loadChartDataForReport` function on the dashboard client component, including applying any report-specific chart options overrides and running the chart's query.
99
+
100
+ #### Function signature
101
+
102
+ ```js
103
+ async formatChartDataForReport(mysqlConnection, { reportParameters, chart, reportChart, parameterSelectionList })
104
+ ```
105
+
106
+ #### Example usage: (from Pro Web `server/chart-loader.js`)
107
+
108
+ ```js
109
+ async function loadChartDataForReport ({ dashboardReportId, chartId, parameterSelectionList }) {
110
+ const report = await db.dashboardReport.loadById({ dashboardReportId }) // get the report object
111
+ const chart = await db.dashboardChart.loadById({ chartId }) // get the chart object
112
+ const reportChart = await db.dashboardReportChart.loadByReportAndChartId({ chartId, dashboardReportId }) // get the report chart for the rank/overrides
113
+ try {
114
+ const chartData = await formatChartDataForReport(db.pool, { reportParameters: report.parameters, chart, reportChart, parameterSelectionList })
115
+ return chartData
116
+ } catch (err) {
117
+ console.error(err)
118
+ return { isErrored: true }
119
+ }
120
+ }
121
+ ```
122
+
123
+ #### mysqlConnection
124
+ A connection or pool of connections from the `mysql` npm module.
125
+
126
+ #### reportParameters
127
+ The `parameters` array from a report object.
128
+
129
+ #### chartId
130
+ The id of a chart row in `wa_dashboard_chart`.
131
+
132
+ #### parameterSelectionList
133
+ The array of selected parameters sent from the client dashboard.
134
+
135
+ ### loadOutputParameterValues
136
+
137
+ This function outputs the report's parameter values in the format expected by the dashboard client and backend. When sending to the client, including `forClient: true` will not include the properties only needed by the backend.
138
+
139
+ ### Function signature
140
+
141
+ ```js
142
+ async function loadOutputParameterValues(mysqlConnection, { definitionList, selectionList = [], forClient = false })
143
+ ```
144
+
145
+ #### Example Usage
146
+
147
+ #### mysqlConnection
148
+ A connection or pool of connections from the `mysql` npm module.
149
+
150
+ #### definitionList
151
+
152
+ The `parameters` property from the `json` column of a row in the `dashboard_report` table.
153
+
154
+ #### selectionList
155
+
156
+ An array of objects representing the selected parameters sent from the client. Only needed when loading the chart data, not when loading the report "metadata". Each parameter object should match the format specified in [schema.md](schema.md).
157
+
158
+ #### forClient
159
+
160
+ If this value is truthy, parameters' `queryValues` properties will be excluded, as the client does not need them.
161
+
162
+ ### Returns
163
+
164
+ An array of objects matching the format outlined in [schema.md](schema.md)
package/index.js CHANGED
@@ -32,33 +32,15 @@ const handleChartTypeSpecificQuirks = (chartType, resultSet) => {
32
32
  }
33
33
 
34
34
  const loadChartData = async(mysqlConnection, { name, query: queryObject, formatting, chartWrapper, multiSeries, parameters, table, ...theRest }) => { // needs database connection
35
- let { results: queryResultSet, fields } = (queryObject && queryObject.sql) ? await queryWithFields(mysqlConnection, queryObject) : { fields: [], results: [] }
36
- let data = handleChartTypeSpecificQuirks(chartWrapper.chartType, queryResultSet)
37
-
38
- if (multiSeries) {
39
- ({ data, formatting, fields } = getMultiSeriesData({
40
- data,
41
- seriesOptions: multiSeries,
42
- formatting,
43
- fields,
44
- }))
45
- }
35
+ const dataTable = await loadDataTable(mysqlConnection, { query: queryObject, multiSeries, formatting, chartType: chartWrapper.chartType })
46
36
 
47
37
  const proccessedFormatting = handleFormattingTemplates(formatting)
48
38
 
49
- let dataTable = getDataTableFormat(data, fields, multiSeries) //per the Google Charts docs, the DataTable object literal format is the most performant, so we'll turn it into that format before returning
50
-
51
- // Stacked area charts will have holes / jagged lines if there are nulls in the middle of a column
52
- // Presumably we'll also want to be able to have non-cumulative area charts at some point
53
- if (chartWrapper.chartType == 'AreaChart') {
54
- dataTable = makeDataCumulative(dataTable)
55
- }
56
-
57
39
  if (chartWrapper.chartType === 'Table') {
58
40
  return {
59
41
  ...theRest,
60
42
  chartWrapper,
61
- table: { ...table, ...getRactiveTableDataFormat(data, fields, formatting) },
43
+ table: { ...table, ...dataTable },
62
44
  formatting: proccessedFormatting,
63
45
  }
64
46
  }
@@ -71,6 +53,38 @@ const loadChartData = async(mysqlConnection, { name, query: queryObject, formatt
71
53
  formatting: proccessedFormatting,
72
54
  }
73
55
  }
56
+ /*
57
+ * Returns only the data needed to render out the chart. If chartType is 'Table', it will return it in the format consumed by the ractive table component.
58
+ * Otherwise, it will return data in the google chart Datatable object literal format.
59
+ * multiSeries, formatting properties should be deconstructed from the chart object, chartType should be deconstructed from the chart's chartWrapper property
60
+ */
61
+ const loadDataTable = async(mysqlConnection, { query: queryObject, multiSeries, formatting, chartType }) => {
62
+ let { results: queryResultSet, fields } = (queryObject && queryObject.sql) ? await queryWithFields(mysqlConnection, queryObject) : { fields: [], results: [] }
63
+ let data = handleChartTypeSpecificQuirks(chartType, queryResultSet)
64
+
65
+ if (chartType === 'Table') {
66
+ return getRactiveTableDataFormat(data, fields, formatting)
67
+ }
68
+
69
+ if (multiSeries) {
70
+ ({ data, formatting, fields } = getMultiSeriesData({
71
+ data,
72
+ seriesOptions: multiSeries,
73
+ formatting,
74
+ fields,
75
+ }))
76
+ }
77
+
78
+ let dataTable = getDataTableFormat(data, fields, multiSeries) //per the Google Charts docs, the DataTable object literal format is the most performant, so we'll turn it into that format before returning
79
+
80
+ // Stacked area charts will have holes / jagged lines if there are nulls in the middle of a column
81
+ // Presumably we'll also want to be able to have non-cumulative area charts at some point
82
+ if (chartType === 'AreaChart') {
83
+ dataTable = makeDataCumulative(dataTable)
84
+ }
85
+
86
+ return dataTable
87
+ }
74
88
 
75
89
  const loadOptionList = async(mysqlConnection, optionListQuery, optionList = []) => {
76
90
  return [
@@ -173,6 +187,10 @@ module.exports = {
173
187
  formatChartDataForReport: async(mysqlConnection, { reportParameters, chart, reportChart, parameterSelectionList }) => {
174
188
  try {
175
189
  const parameterValues = await loadOutputParameterValues(mysqlConnection, { definitionList: reportParameters, selectionList: parameterSelectionList })
190
+ if (reportChart?.jsonOverride?.chartWrapper?.dataTable) {
191
+ const { dataTable, ...chartWrapper } = reportChart.jsonOverride.chartWrapper
192
+ reportChart.jsonOverride.chartWrapper = chartWrapper
193
+ }
176
194
  return await loadChartData(mysqlConnection, {
177
195
  ...chart,
178
196
  reportChartId: reportChart.reportChartId,
@@ -185,4 +203,5 @@ module.exports = {
185
203
  }
186
204
  },
187
205
  loadOutputParameterValues,
206
+ loadDataTable,
188
207
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isoftdata/utility-dashboard-backend",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "A utility for formatting chart and report data to be usable by the frontend dashboard component.",
5
5
  "main": "index.js",
6
6
  "scripts": {