@hisptz/dhis2-analytics 1.0.0

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 (105) hide show
  1. package/README.md +45 -0
  2. package/d2.config.js +8 -0
  3. package/package.json +55 -0
  4. package/src/components/ChartAnalytics/ChartAnalytics.stories.tsx +250 -0
  5. package/src/components/ChartAnalytics/ChartAnalytics.test.tsx +51 -0
  6. package/src/components/ChartAnalytics/components/DownloadMenu/components/Menu.tsx +48 -0
  7. package/src/components/ChartAnalytics/components/DownloadMenu/constants/menu.ts +38 -0
  8. package/src/components/ChartAnalytics/components/DownloadMenu/index.tsx +67 -0
  9. package/src/components/ChartAnalytics/components/DownloadMenu/interfaces/menu.ts +1 -0
  10. package/src/components/ChartAnalytics/data/column-data.json +210 -0
  11. package/src/components/ChartAnalytics/data/complex-multi-series-data.json +124 -0
  12. package/src/components/ChartAnalytics/data/multi-series-data.json +536 -0
  13. package/src/components/ChartAnalytics/data/pie-data.json +115 -0
  14. package/src/components/ChartAnalytics/data/stacked-chart-data.json +415 -0
  15. package/src/components/ChartAnalytics/hooks/useChart.ts +35 -0
  16. package/src/components/ChartAnalytics/index.tsx +23 -0
  17. package/src/components/ChartAnalytics/models/column.ts +50 -0
  18. package/src/components/ChartAnalytics/models/index.ts +78 -0
  19. package/src/components/ChartAnalytics/models/line.ts +31 -0
  20. package/src/components/ChartAnalytics/models/multi-series.ts +115 -0
  21. package/src/components/ChartAnalytics/models/pie.ts +54 -0
  22. package/src/components/ChartAnalytics/services/export.ts +38 -0
  23. package/src/components/ChartAnalytics/styles/custom-highchart.css +48 -0
  24. package/src/components/ChartAnalytics/types/props.tsx +48 -0
  25. package/src/components/ChartAnalytics/utils/chart.ts +123 -0
  26. package/src/components/CircularProgressDashboard/CircularProgressIndicator.stories.tsx +41 -0
  27. package/src/components/CircularProgressDashboard/CircularProgressIndicator.test.tsx +9 -0
  28. package/src/components/CircularProgressDashboard/index.tsx +35 -0
  29. package/src/components/CircularProgressDashboard/types/props.tsx +17 -0
  30. package/src/components/Map/Map.stories.tsx +339 -0
  31. package/src/components/Map/components/EarthEngineLayerConfiguration/EarthEngineLayerConfigModal.stories.tsx +28 -0
  32. package/src/components/Map/components/EarthEngineLayerConfiguration/EarthEngineLayerConfiguration.stories.tsx +34 -0
  33. package/src/components/Map/components/EarthEngineLayerConfiguration/index.tsx +412 -0
  34. package/src/components/Map/components/MapArea/index.tsx +83 -0
  35. package/src/components/Map/components/MapArea/interfaces/index.ts +39 -0
  36. package/src/components/Map/components/MapControls/components/CustomControl/index.tsx +24 -0
  37. package/src/components/Map/components/MapControls/components/DownloadControl/index.tsx +10 -0
  38. package/src/components/Map/components/MapControls/components/FullscreenControl/index.tsx +7 -0
  39. package/src/components/Map/components/MapControls/index.tsx +24 -0
  40. package/src/components/Map/components/MapLayer/components/BoundaryLayer/hooks/useBoundaryData.ts +7 -0
  41. package/src/components/Map/components/MapLayer/components/BoundaryLayer/index.tsx +55 -0
  42. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/components/EarthEngineLegend.tsx +76 -0
  43. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/constants/index.ts +430 -0
  44. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/hooks/index.ts +34 -0
  45. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/index.tsx +185 -0
  46. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/interfaces/index.ts +56 -0
  47. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/services/api.js +34233 -0
  48. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/services/engine.ts +423 -0
  49. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/utils/index.ts +105 -0
  50. package/src/components/Map/components/MapLayer/components/LegendArea/LegendArea.module.css +12 -0
  51. package/src/components/Map/components/MapLayer/components/LegendArea/components/LegendCardHeader/index.tsx +17 -0
  52. package/src/components/Map/components/MapLayer/components/LegendArea/index.tsx +168 -0
  53. package/src/components/Map/components/MapLayer/components/PointLayer/components/PointLegend/index.tsx +44 -0
  54. package/src/components/Map/components/MapLayer/components/PointLayer/hooks/index.ts +8 -0
  55. package/src/components/Map/components/MapLayer/components/PointLayer/index.tsx +36 -0
  56. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/components/BubbleLegend/components/Bubble.tsx +48 -0
  57. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/components/BubbleLegend/components/Bubbles.tsx +150 -0
  58. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/components/BubbleLegend/index.tsx +39 -0
  59. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/index.tsx +57 -0
  60. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Choropleth/components/ChoroplethLegend.tsx +43 -0
  61. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Choropleth/index.tsx +38 -0
  62. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/CustomTooltip/index.tsx +26 -0
  63. package/src/components/Map/components/MapLayer/components/ThematicLayer/hooks/config.ts +10 -0
  64. package/src/components/Map/components/MapLayer/components/ThematicLayer/index.tsx +46 -0
  65. package/src/components/Map/components/MapLayer/components/ThematicLayer/styles/legends.css +62 -0
  66. package/src/components/Map/components/MapLayer/index.tsx +32 -0
  67. package/src/components/Map/components/MapLayer/interfaces/index.ts +139 -0
  68. package/src/components/Map/components/MapProvider/components/MapLayerProvider/hooks/index.tsx +359 -0
  69. package/src/components/Map/components/MapProvider/components/MapLayerProvider/index.tsx +105 -0
  70. package/src/components/Map/components/MapProvider/hooks/index.ts +14 -0
  71. package/src/components/Map/components/MapProvider/index.tsx +93 -0
  72. package/src/components/Map/components/MapUpdater/index.tsx +8 -0
  73. package/src/components/Map/components/ThematicLayerConfiguration/ThematicLayerConfigModal.stories.tsx +28 -0
  74. package/src/components/Map/components/ThematicLayerConfiguration/ThematicLayerConfiguration.stories.tsx +34 -0
  75. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/components/ColorScale/index.tsx +24 -0
  76. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/constants/colors.ts +433 -0
  77. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/index.tsx +50 -0
  78. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/styles/ColorScale.module.css +15 -0
  79. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/styles/ColorScaleSelect.module.css +12 -0
  80. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/utils/colors.ts +91 -0
  81. package/src/components/Map/components/ThematicLayerConfiguration/components/CustomLegend/index.tsx +45 -0
  82. package/src/components/Map/components/ThematicLayerConfiguration/components/IndicatorSelectorModal/index.tsx +47 -0
  83. package/src/components/Map/components/ThematicLayerConfiguration/components/LegendSetSelector/index.tsx +57 -0
  84. package/src/components/Map/components/ThematicLayerConfiguration/index.tsx +248 -0
  85. package/src/components/Map/constants/colors.ts +433 -0
  86. package/src/components/Map/constants/legendSet.ts +19 -0
  87. package/src/components/Map/hooks/map.ts +47 -0
  88. package/src/components/Map/index.tsx +65 -0
  89. package/src/components/Map/interfaces/index.ts +57 -0
  90. package/src/components/Map/state/index.tsx +31 -0
  91. package/src/components/Map/utils/colors.ts +95 -0
  92. package/src/components/Map/utils/helpers.ts +15 -0
  93. package/src/components/Map/utils/map.ts +150 -0
  94. package/src/components/SingleValueContainer/SingleValueContainer.stories.tsx +146 -0
  95. package/src/components/SingleValueContainer/SingleValueContainer.test.tsx +24 -0
  96. package/src/components/SingleValueContainer/components/SingleValueItem/SingleValueItem.tsx +46 -0
  97. package/src/components/SingleValueContainer/components/SingleValueItem/SingleValuePercentage.tsx +12 -0
  98. package/src/components/SingleValueContainer/index.tsx +30 -0
  99. package/src/components/SingleValueContainer/styles/SingleValueContainer.module.css +39 -0
  100. package/src/components/SingleValueContainer/types/props.tsx +16 -0
  101. package/src/data/map.json +5984 -0
  102. package/src/dataProviders/map.tsx +24 -0
  103. package/src/index.test.ts +7 -0
  104. package/src/index.ts +4 -0
  105. package/tsconfig.json +45 -0
@@ -0,0 +1,415 @@
1
+ {
2
+ "headers": [
3
+ {
4
+ "name": "ou",
5
+ "column": "Organisation unit",
6
+ "valueType": "TEXT",
7
+ "type": "java.lang.String",
8
+ "hidden": false,
9
+ "meta": true
10
+ },
11
+ {
12
+ "name": "pe",
13
+ "column": "Period",
14
+ "valueType": "TEXT",
15
+ "type": "java.lang.String",
16
+ "hidden": false,
17
+ "meta": true
18
+ },
19
+ {
20
+ "name": "value",
21
+ "column": "Value",
22
+ "valueType": "NUMBER",
23
+ "type": "java.lang.Double",
24
+ "hidden": false,
25
+ "meta": false
26
+ }
27
+ ],
28
+ "metaData": {
29
+ "items": {
30
+ "202107": {
31
+ "name": "July 2021"
32
+ },
33
+ "202108": {
34
+ "name": "August 2021"
35
+ },
36
+ "202109": {
37
+ "name": "September 2021"
38
+ },
39
+ "202110": {
40
+ "name": "October 2021"
41
+ },
42
+ "202111": {
43
+ "name": "November 2021"
44
+ },
45
+ "202112": {
46
+ "name": "December 2021"
47
+ },
48
+ "202201": {
49
+ "name": "January 2022"
50
+ },
51
+ "202202": {
52
+ "name": "February 2022"
53
+ },
54
+ "202203": {
55
+ "name": "March 2022"
56
+ },
57
+ "202204": {
58
+ "name": "April 2022"
59
+ },
60
+ "202205": {
61
+ "name": "May 2022"
62
+ },
63
+ "202206": {
64
+ "name": "June 2022"
65
+ },
66
+ "jUb8gELQApl": {
67
+ "name": "Kailahun"
68
+ },
69
+ "PMa2VCrupOd": {
70
+ "name": "Kambia"
71
+ },
72
+ "ou": {
73
+ "name": "Organisation unit"
74
+ },
75
+ "O6uvpzGd5pu": {
76
+ "name": "Bo"
77
+ },
78
+ "eTDtyyaSA7f": {
79
+ "name": "FIC <1y"
80
+ },
81
+ "fdc6uOvgoji": {
82
+ "name": "Bombali"
83
+ },
84
+ "LAST_12_MONTHS": {
85
+ "name": "Last 12 months"
86
+ },
87
+ "dx": {
88
+ "name": "Data"
89
+ },
90
+ "pe": {
91
+ "name": "Period"
92
+ },
93
+ "lc3eMKXaEfw": {
94
+ "name": "Bonthe"
95
+ }
96
+ },
97
+ "dimensions": {
98
+ "dx": [
99
+ "eTDtyyaSA7f"
100
+ ],
101
+ "pe": [
102
+ "202107",
103
+ "202108",
104
+ "202109",
105
+ "202110",
106
+ "202111",
107
+ "202112",
108
+ "202201",
109
+ "202202",
110
+ "202203",
111
+ "202204",
112
+ "202205",
113
+ "202206"
114
+ ],
115
+ "ou": [
116
+ "jUb8gELQApl",
117
+ "PMa2VCrupOd",
118
+ "O6uvpzGd5pu",
119
+ "lc3eMKXaEfw",
120
+ "fdc6uOvgoji"
121
+ ],
122
+ "co": []
123
+ }
124
+ },
125
+ "rows": [
126
+ [
127
+ "jUb8gELQApl",
128
+ "202107",
129
+ "66.0"
130
+ ],
131
+ [
132
+ "jUb8gELQApl",
133
+ "202108",
134
+ "80.6"
135
+ ],
136
+ [
137
+ "jUb8gELQApl",
138
+ "202109",
139
+ "83.2"
140
+ ],
141
+ [
142
+ "jUb8gELQApl",
143
+ "202110",
144
+ "60.1"
145
+ ],
146
+ [
147
+ "jUb8gELQApl",
148
+ "202111",
149
+ "78.8"
150
+ ],
151
+ [
152
+ "jUb8gELQApl",
153
+ "202112",
154
+ "52.2"
155
+ ],
156
+ [
157
+ "jUb8gELQApl",
158
+ "202201",
159
+ "72.7"
160
+ ],
161
+ [
162
+ "jUb8gELQApl",
163
+ "202202",
164
+ "85.8"
165
+ ],
166
+ [
167
+ "jUb8gELQApl",
168
+ "202203",
169
+ "78.7"
170
+ ],
171
+ [
172
+ "jUb8gELQApl",
173
+ "202204",
174
+ "82.9"
175
+ ],
176
+ [
177
+ "jUb8gELQApl",
178
+ "202205",
179
+ "82.2"
180
+ ],
181
+ [
182
+ "jUb8gELQApl",
183
+ "202206",
184
+ "78.5"
185
+ ],
186
+ [
187
+ "PMa2VCrupOd",
188
+ "202107",
189
+ "57.5"
190
+ ],
191
+ [
192
+ "PMa2VCrupOd",
193
+ "202108",
194
+ "59.2"
195
+ ],
196
+ [
197
+ "PMa2VCrupOd",
198
+ "202109",
199
+ "73.4"
200
+ ],
201
+ [
202
+ "PMa2VCrupOd",
203
+ "202110",
204
+ "63.9"
205
+ ],
206
+ [
207
+ "PMa2VCrupOd",
208
+ "202111",
209
+ "72.2"
210
+ ],
211
+ [
212
+ "PMa2VCrupOd",
213
+ "202112",
214
+ "51.5"
215
+ ],
216
+ [
217
+ "PMa2VCrupOd",
218
+ "202201",
219
+ "59.7"
220
+ ],
221
+ [
222
+ "PMa2VCrupOd",
223
+ "202202",
224
+ "69.6"
225
+ ],
226
+ [
227
+ "PMa2VCrupOd",
228
+ "202203",
229
+ "59.0"
230
+ ],
231
+ [
232
+ "PMa2VCrupOd",
233
+ "202204",
234
+ "63.0"
235
+ ],
236
+ [
237
+ "PMa2VCrupOd",
238
+ "202205",
239
+ "53.5"
240
+ ],
241
+ [
242
+ "PMa2VCrupOd",
243
+ "202206",
244
+ "64.6"
245
+ ],
246
+ [
247
+ "O6uvpzGd5pu",
248
+ "202107",
249
+ "70.7"
250
+ ],
251
+ [
252
+ "O6uvpzGd5pu",
253
+ "202108",
254
+ "105.6"
255
+ ],
256
+ [
257
+ "O6uvpzGd5pu",
258
+ "202109",
259
+ "81.0"
260
+ ],
261
+ [
262
+ "O6uvpzGd5pu",
263
+ "202110",
264
+ "104.7"
265
+ ],
266
+ [
267
+ "O6uvpzGd5pu",
268
+ "202111",
269
+ "117.0"
270
+ ],
271
+ [
272
+ "O6uvpzGd5pu",
273
+ "202112",
274
+ "59.9"
275
+ ],
276
+ [
277
+ "O6uvpzGd5pu",
278
+ "202201",
279
+ "58.6"
280
+ ],
281
+ [
282
+ "O6uvpzGd5pu",
283
+ "202202",
284
+ "72.0"
285
+ ],
286
+ [
287
+ "O6uvpzGd5pu",
288
+ "202203",
289
+ "66.5"
290
+ ],
291
+ [
292
+ "O6uvpzGd5pu",
293
+ "202204",
294
+ "71.2"
295
+ ],
296
+ [
297
+ "O6uvpzGd5pu",
298
+ "202205",
299
+ "77.9"
300
+ ],
301
+ [
302
+ "O6uvpzGd5pu",
303
+ "202206",
304
+ "74.3"
305
+ ],
306
+ [
307
+ "lc3eMKXaEfw",
308
+ "202107",
309
+ "88.2"
310
+ ],
311
+ [
312
+ "lc3eMKXaEfw",
313
+ "202108",
314
+ "98.1"
315
+ ],
316
+ [
317
+ "lc3eMKXaEfw",
318
+ "202109",
319
+ "112.7"
320
+ ],
321
+ [
322
+ "lc3eMKXaEfw",
323
+ "202111",
324
+ "96.2"
325
+ ],
326
+ [
327
+ "lc3eMKXaEfw",
328
+ "202201",
329
+ "58.5"
330
+ ],
331
+ [
332
+ "lc3eMKXaEfw",
333
+ "202202",
334
+ "71.5"
335
+ ],
336
+ [
337
+ "lc3eMKXaEfw",
338
+ "202203",
339
+ "65.8"
340
+ ],
341
+ [
342
+ "lc3eMKXaEfw",
343
+ "202204",
344
+ "71.5"
345
+ ],
346
+ [
347
+ "lc3eMKXaEfw",
348
+ "202205",
349
+ "70.8"
350
+ ],
351
+ [
352
+ "lc3eMKXaEfw",
353
+ "202206",
354
+ "72.6"
355
+ ],
356
+ [
357
+ "fdc6uOvgoji",
358
+ "202107",
359
+ "75.7"
360
+ ],
361
+ [
362
+ "fdc6uOvgoji",
363
+ "202108",
364
+ "76.6"
365
+ ],
366
+ [
367
+ "fdc6uOvgoji",
368
+ "202109",
369
+ "83.2"
370
+ ],
371
+ [
372
+ "fdc6uOvgoji",
373
+ "202110",
374
+ "69.8"
375
+ ],
376
+ [
377
+ "fdc6uOvgoji",
378
+ "202112",
379
+ "119.6"
380
+ ],
381
+ [
382
+ "fdc6uOvgoji",
383
+ "202201",
384
+ "75.4"
385
+ ],
386
+ [
387
+ "fdc6uOvgoji",
388
+ "202202",
389
+ "80.3"
390
+ ],
391
+ [
392
+ "fdc6uOvgoji",
393
+ "202203",
394
+ "71.7"
395
+ ],
396
+ [
397
+ "fdc6uOvgoji",
398
+ "202204",
399
+ "77.9"
400
+ ],
401
+ [
402
+ "fdc6uOvgoji",
403
+ "202205",
404
+ "76.5"
405
+ ],
406
+ [
407
+ "fdc6uOvgoji",
408
+ "202206",
409
+ "76.1"
410
+ ]
411
+ ],
412
+ "height": 57,
413
+ "width": 3,
414
+ "headerWidth": 3
415
+ }
@@ -0,0 +1,35 @@
1
+ import type {Analytics} from "@hisptz/dhis2-utils";
2
+ import HighCharts from "highcharts";
3
+ import {useCallback, useEffect, useState} from "react";
4
+ import {DHIS2Chart} from "../models";
5
+ import {ChartConfig, ChartType} from "../types/props";
6
+ import {getChartInstance, updateLayout} from "../utils/chart";
7
+
8
+ export function useChart({ id, analytics, config }: { id: string; analytics: Analytics; config: ChartConfig }): {
9
+ chart?: HighCharts.Options;
10
+ changeChartType: (type: ChartType) => void;
11
+ } {
12
+ const [chart, setChart] = useState<HighCharts.Options | undefined>(getChartInstance(id, analytics, config).getOptions());
13
+
14
+ const changeChartType = useCallback(
15
+ (type: ChartType) => {
16
+ const updatedLayout = updateLayout(config, { type });
17
+ const updatedConfig = { ...config, layout: updatedLayout, type };
18
+ const chartInstance: DHIS2Chart = getChartInstance(id, analytics, updatedConfig);
19
+ setChart(chartInstance.getOptions());
20
+ },
21
+ [config, id, analytics]
22
+ );
23
+
24
+ useEffect(() => {
25
+ if (analytics && config) {
26
+ const chartInstance: DHIS2Chart = getChartInstance(id, analytics, config);
27
+ setChart(chartInstance.getOptions());
28
+ }
29
+ }, [analytics, config, id]);
30
+
31
+ return {
32
+ chart,
33
+ changeChartType,
34
+ };
35
+ }
@@ -0,0 +1,23 @@
1
+ import {uid} from "@hisptz/dhis2-utils";
2
+ import HighCharts from "highcharts";
3
+ import HighchartsReact from "highcharts-react-official";
4
+ import React, {forwardRef, useRef} from "react";
5
+ import ChartDownloadMenu from "./components/DownloadMenu";
6
+ import {useChart} from "./hooks/useChart";
7
+ import {ChartAnalyticsProps} from "./types/props";
8
+ import "./styles/custom-highchart.css";
9
+
10
+ export * from "./services/export";
11
+ export { ChartDownloadMenu };
12
+
13
+ function ChartAnalytics({ analytics, config, containerProps }: ChartAnalyticsProps, ref: React.ForwardedRef<HighchartsReact.RefObject>) {
14
+ const id = useRef(`${uid()}-chart-item`);
15
+ const { chart } = useChart({ id: id.current, analytics, config });
16
+
17
+ if (!chart) {
18
+ return null;
19
+ }
20
+ return <HighchartsReact immutable ref={ref} containerProps={{ id: id.current, ...(containerProps ?? {}) }} highcharts={HighCharts} options={{ ...chart }} />;
21
+ }
22
+
23
+ export default forwardRef(ChartAnalytics);
@@ -0,0 +1,50 @@
1
+ import {PlotOptions, SeriesOptionsType, XAxisOptions} from "highcharts";
2
+ import {getAllCategories, getPointSeries} from "../utils/chart";
3
+ import {DHIS2Chart} from "./index";
4
+
5
+ export class DHIS2ColumnChart extends DHIS2Chart {
6
+ getCategories(): any[] | undefined {
7
+ return undefined;
8
+ }
9
+
10
+ getHighchartsType(): string {
11
+ return "column";
12
+ }
13
+
14
+ getPlotOptions(): PlotOptions {
15
+ return {
16
+ column: {
17
+ dataLabels: {
18
+ enabled: true,
19
+ },
20
+ },
21
+ };
22
+ }
23
+
24
+ getSeries(): SeriesOptionsType[] {
25
+ return getPointSeries(this.analytics, this.config, "column");
26
+ }
27
+
28
+ getXAxis(): XAxisOptions | undefined {
29
+ return {
30
+ type: "category",
31
+ categories: getAllCategories(this.analytics, this.config),
32
+ crosshair: true,
33
+ labels: {
34
+ enabled: true,
35
+ },
36
+ title: { text: "" },
37
+ };
38
+ }
39
+ }
40
+
41
+ export class DHIS2StackedColumnChart extends DHIS2ColumnChart {
42
+ getPlotOptions(): PlotOptions {
43
+ return {
44
+ column: {
45
+ stacking: "normal",
46
+ ...super.getPlotOptions().column,
47
+ },
48
+ };
49
+ }
50
+ }
@@ -0,0 +1,78 @@
1
+ import type {Analytics} from "@hisptz/dhis2-utils";
2
+ import HighCharts from "highcharts";
3
+ import {ChartConfig} from "../types/props";
4
+
5
+ export abstract class DHIS2Chart {
6
+ id: string;
7
+ analytics: Analytics;
8
+ config: ChartConfig;
9
+
10
+ constructor(id: string, analytics: Analytics, config: ChartConfig) {
11
+ this.id = id;
12
+ this.analytics = analytics;
13
+ this.config = config;
14
+ }
15
+
16
+ abstract getHighchartsType(): string;
17
+
18
+ getChartConfig(): HighCharts.ChartOptions {
19
+ return {
20
+ renderTo: this.id,
21
+ zoomType: "xy",
22
+ type: this.getHighchartsType(),
23
+ height: this.config?.height,
24
+ styledMode: false,
25
+ };
26
+ }
27
+
28
+ getOptions(): HighCharts.Options {
29
+ return {
30
+ yAxis: this.getYAxis(),
31
+ chart: this.getChartConfig(),
32
+ colors: this.config?.colors ?? ["#2f7ed8", "#0d233a", "#8bbc21", "#910000", "#1aadce", "#492970", "#f28f43", "#77a1e5", "#c42525", "#a6c96a"],
33
+ series: this.getSeries(),
34
+ plotOptions: this.getPlotOptions(),
35
+ title: { text: "" },
36
+ xAxis: this.getXAxis(),
37
+ exporting: this.getExporting(),
38
+ legend: { enabled: true },
39
+ credits: { enabled: false },
40
+ ...(this.config?.highChartOverrides ?? {}),
41
+ };
42
+ }
43
+
44
+ abstract getSeries(): HighCharts.SeriesOptionsType[];
45
+
46
+ abstract getPlotOptions(): HighCharts.PlotOptions;
47
+
48
+ abstract getXAxis(): HighCharts.XAxisOptions | undefined;
49
+
50
+ getYAxis(): HighCharts.YAxisOptions[] {
51
+ return [
52
+ {
53
+ title: {
54
+ text: "",
55
+ style: { color: "#000000", fontWeight: "normal", fontSize: "14px" },
56
+ },
57
+ labels: { enabled: true, style: { color: "#000000", fontWeight: "normal", fontSize: "14px" } },
58
+ plotLines: [
59
+ { color: "#000000", dashStyle: "Solid", width: 2, zIndex: 1000, label: { text: "" } },
60
+ { color: "#bbbbbb", dashStyle: "Solid", zIndex: 1000, width: 2, label: { text: "" } },
61
+ ],
62
+ },
63
+ ];
64
+ }
65
+
66
+ getExporting(): HighCharts.ExportingOptions {
67
+ const name = this.config?.name ?? "chart";
68
+ return {
69
+ filename: `${name}`,
70
+ sourceWidth: 1200,
71
+ buttons: {
72
+ contextButton: {
73
+ enabled: false,
74
+ },
75
+ },
76
+ };
77
+ }
78
+ }
@@ -0,0 +1,31 @@
1
+ import {PlotOptions, SeriesOptionsType, XAxisOptions} from "highcharts";
2
+ import {getAllCategories, getPointSeries} from "../utils/chart";
3
+ import {DHIS2Chart} from "./index";
4
+
5
+ export class DHIS2LineChart extends DHIS2Chart {
6
+ getHighchartsType(): string {
7
+ return "line";
8
+ }
9
+
10
+ getPlotOptions(): PlotOptions {
11
+ return {
12
+ line: {},
13
+ };
14
+ }
15
+
16
+ getSeries(): SeriesOptionsType[] {
17
+ return getPointSeries(this.analytics, this.config, "line");
18
+ }
19
+
20
+ getXAxis(): XAxisOptions | undefined {
21
+ return {
22
+ type: "category",
23
+ categories: getAllCategories(this.analytics, this.config),
24
+ crosshair: true,
25
+ labels: {
26
+ enabled: true,
27
+ },
28
+ title: { text: "" },
29
+ };
30
+ }
31
+ }