@hisptz/dhis2-analytics 1.0.48 → 1.0.51

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 (127) hide show
  1. package/.gitignore +5 -0
  2. package/build/cjs/components/ChartAnalytics/ChartAnalytics.test.js +1 -1
  3. package/build/cjs/components/ChartAnalytics/models/bar.js +24 -0
  4. package/build/cjs/components/ChartAnalytics/models/index.js +1 -1
  5. package/build/cjs/components/ChartAnalytics/utils/chart.js +5 -0
  6. package/build/es/components/ChartAnalytics/ChartAnalytics.test.js +1 -1
  7. package/build/es/components/ChartAnalytics/models/bar.js +16 -0
  8. package/build/es/components/ChartAnalytics/models/index.js +1 -1
  9. package/build/es/components/ChartAnalytics/utils/chart.js +5 -0
  10. package/build/types/components/ChartAnalytics/models/bar.d.ts +8 -0
  11. package/build/types/components/ChartAnalytics/types/props.d.ts +1 -1
  12. package/d2.config.js +8 -0
  13. package/i18n/en.pot +439 -0
  14. package/package.json +5 -5
  15. package/src/components/ChartAnalytics/ChartAnalytics.test.tsx +51 -0
  16. package/src/components/ChartAnalytics/components/DownloadMenu/components/Menu.tsx +48 -0
  17. package/src/components/ChartAnalytics/components/DownloadMenu/constants/menu.ts +38 -0
  18. package/src/components/ChartAnalytics/components/DownloadMenu/index.tsx +65 -0
  19. package/src/components/ChartAnalytics/components/DownloadMenu/interfaces/menu.ts +1 -0
  20. package/src/components/ChartAnalytics/hooks/useChart.ts +35 -0
  21. package/src/components/ChartAnalytics/index.tsx +28 -0
  22. package/src/components/ChartAnalytics/models/bar.ts +20 -0
  23. package/src/components/ChartAnalytics/models/column.ts +52 -0
  24. package/src/components/ChartAnalytics/models/index.ts +111 -0
  25. package/src/components/ChartAnalytics/models/line.ts +31 -0
  26. package/src/components/ChartAnalytics/models/multi-series.ts +115 -0
  27. package/src/components/ChartAnalytics/models/pie.ts +54 -0
  28. package/src/components/ChartAnalytics/services/export.ts +38 -0
  29. package/src/components/ChartAnalytics/styles/custom-highchart.css +48 -0
  30. package/src/components/ChartAnalytics/types/props.tsx +48 -0
  31. package/src/components/ChartAnalytics/utils/chart.ts +128 -0
  32. package/src/components/CircularProgressDashboard/CircularProgressIndicator.test.tsx +9 -0
  33. package/src/components/CircularProgressDashboard/index.tsx +36 -0
  34. package/src/components/CircularProgressDashboard/types/props.tsx +17 -0
  35. package/src/components/CustomPivotTable/components/Table/index.tsx +23 -0
  36. package/src/components/CustomPivotTable/components/TableBody/TableBody.module.css +12 -0
  37. package/src/components/CustomPivotTable/components/TableBody/index.tsx +96 -0
  38. package/src/components/CustomPivotTable/components/TableHeaders/TableHeaders.module.css +10 -0
  39. package/src/components/CustomPivotTable/components/TableHeaders/index.tsx +94 -0
  40. package/src/components/CustomPivotTable/index.tsx +63 -0
  41. package/src/components/CustomPivotTable/interfaces/index.ts +1 -0
  42. package/src/components/CustomPivotTable/services/engine.ts +102 -0
  43. package/src/components/CustomPivotTable/state/engine.tsx +22 -0
  44. package/src/components/Map/components/EarthEngineLayerConfiguration/EarthEngineLayerConfigModal.stories.tsx +28 -0
  45. package/src/components/Map/components/EarthEngineLayerConfiguration/EarthEngineLayerConfiguration.stories.tsx +34 -0
  46. package/src/components/Map/components/EarthEngineLayerConfiguration/index.tsx +412 -0
  47. package/src/components/Map/components/MapArea/index.tsx +83 -0
  48. package/src/components/Map/components/MapArea/interfaces/index.ts +39 -0
  49. package/src/components/Map/components/MapControls/components/CustomControl/index.tsx +24 -0
  50. package/src/components/Map/components/MapControls/components/DownloadControl/index.tsx +11 -0
  51. package/src/components/Map/components/MapControls/components/FullscreenControl/index.tsx +7 -0
  52. package/src/components/Map/components/MapControls/index.tsx +24 -0
  53. package/src/components/Map/components/MapLayer/components/BoundaryLayer/hooks/useBoundaryData.ts +7 -0
  54. package/src/components/Map/components/MapLayer/components/BoundaryLayer/index.tsx +55 -0
  55. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/components/EarthEngineLegend.tsx +74 -0
  56. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/constants/index.ts +430 -0
  57. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/hooks/index.ts +34 -0
  58. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/index.tsx +185 -0
  59. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/interfaces/index.ts +56 -0
  60. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/services/api.js +34241 -0
  61. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/services/engine.ts +431 -0
  62. package/src/components/Map/components/MapLayer/components/GoogleEngineLayer/utils/index.ts +105 -0
  63. package/src/components/Map/components/MapLayer/components/LegendArea/LegendArea.module.css +12 -0
  64. package/src/components/Map/components/MapLayer/components/LegendArea/components/LegendCardHeader/index.tsx +17 -0
  65. package/src/components/Map/components/MapLayer/components/LegendArea/index.tsx +167 -0
  66. package/src/components/Map/components/MapLayer/components/PointLayer/components/PointLegend/index.tsx +44 -0
  67. package/src/components/Map/components/MapLayer/components/PointLayer/hooks/index.ts +8 -0
  68. package/src/components/Map/components/MapLayer/components/PointLayer/index.tsx +36 -0
  69. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/components/BubbleLegend/components/Bubble.tsx +48 -0
  70. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/components/BubbleLegend/components/Bubbles.tsx +150 -0
  71. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/components/BubbleLegend/index.tsx +39 -0
  72. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Bubble/index.tsx +57 -0
  73. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Choropleth/components/ChoroplethLegend.tsx +43 -0
  74. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/Choropleth/index.tsx +38 -0
  75. package/src/components/Map/components/MapLayer/components/ThematicLayer/components/CustomTooltip/index.tsx +26 -0
  76. package/src/components/Map/components/MapLayer/components/ThematicLayer/hooks/config.ts +10 -0
  77. package/src/components/Map/components/MapLayer/components/ThematicLayer/index.tsx +46 -0
  78. package/src/components/Map/components/MapLayer/components/ThematicLayer/styles/legends.css +62 -0
  79. package/src/components/Map/components/MapLayer/index.tsx +32 -0
  80. package/src/components/Map/components/MapLayer/interfaces/index.ts +139 -0
  81. package/src/components/Map/components/MapProvider/components/MapLayerProvider/hooks/index.tsx +368 -0
  82. package/src/components/Map/components/MapProvider/components/MapLayerProvider/index.tsx +105 -0
  83. package/src/components/Map/components/MapProvider/hooks/index.ts +14 -0
  84. package/src/components/Map/components/MapProvider/index.tsx +93 -0
  85. package/src/components/Map/components/MapUpdater/index.tsx +8 -0
  86. package/src/components/Map/components/ThematicLayerConfiguration/ThematicLayerConfigModal.stories.tsx +28 -0
  87. package/src/components/Map/components/ThematicLayerConfiguration/ThematicLayerConfiguration.stories.tsx +34 -0
  88. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/components/ColorScale/index.tsx +24 -0
  89. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/constants/colors.ts +433 -0
  90. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/index.tsx +50 -0
  91. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/styles/ColorScale.module.css +15 -0
  92. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/styles/ColorScaleSelect.module.css +12 -0
  93. package/src/components/Map/components/ThematicLayerConfiguration/components/ColorScaleSelect/utils/colors.ts +91 -0
  94. package/src/components/Map/components/ThematicLayerConfiguration/components/CustomLegend/index.tsx +45 -0
  95. package/src/components/Map/components/ThematicLayerConfiguration/components/IndicatorSelectorModal/index.tsx +47 -0
  96. package/src/components/Map/components/ThematicLayerConfiguration/components/LegendSetSelector/index.tsx +57 -0
  97. package/src/components/Map/components/ThematicLayerConfiguration/index.tsx +248 -0
  98. package/src/components/Map/constants/colors.ts +434 -0
  99. package/src/components/Map/constants/legendSet.ts +19 -0
  100. package/src/components/Map/hooks/map.ts +47 -0
  101. package/src/components/Map/index.tsx +65 -0
  102. package/src/components/Map/interfaces/index.ts +57 -0
  103. package/src/components/Map/state/index.tsx +31 -0
  104. package/src/components/Map/utils/colors.ts +95 -0
  105. package/src/components/Map/utils/helpers.ts +15 -0
  106. package/src/components/Map/utils/map.ts +150 -0
  107. package/src/components/SingleValueContainer/SingleValueContainer.test.tsx +24 -0
  108. package/src/components/SingleValueContainer/components/SingleValueItem/SingleValueItem.tsx +46 -0
  109. package/src/components/SingleValueContainer/components/SingleValueItem/SingleValuePercentage.tsx +12 -0
  110. package/src/components/SingleValueContainer/index.tsx +37 -0
  111. package/src/components/SingleValueContainer/styles/SingleValueContainer.module.css +39 -0
  112. package/src/components/SingleValueContainer/types/props.tsx +16 -0
  113. package/src/components/Visualization/components/AnalyticsDataProvider/index.tsx +76 -0
  114. package/src/components/Visualization/components/DimensionsProvider/index.tsx +51 -0
  115. package/src/components/Visualization/components/LayoutProvider/index.tsx +34 -0
  116. package/src/components/Visualization/components/VisualizationDimensionSelector/index.tsx +59 -0
  117. package/src/components/Visualization/components/VisualizationProvider/index.tsx +31 -0
  118. package/src/components/Visualization/components/VisualizationSelector/index.tsx +157 -0
  119. package/src/components/Visualization/components/VisualizationTypeProvider/index.tsx +40 -0
  120. package/src/components/Visualization/components/VisualizationTypeSelector/index.tsx +46 -0
  121. package/src/components/Visualization/index.tsx +103 -0
  122. package/src/index.ts +6 -0
  123. package/src/locales/en/translations.json +138 -0
  124. package/src/locales/index.js +16 -0
  125. package/tsconfig.build.json +46 -0
  126. package/tsconfig.json +51 -0
  127. package/LICENSE +0 -29
@@ -0,0 +1,185 @@
1
+ import {capitalize, find, head, isEmpty, sortBy} from "lodash";
2
+ import React, {useMemo, useRef} from "react";
3
+ import {GeoJSON, LayerGroup, LayersControl, Popup, TileLayer, Tooltip} from "react-leaflet";
4
+ import {useBoundaryData} from "../BoundaryLayer/hooks/useBoundaryData";
5
+ import useGoogleEngineLayer from "./hooks";
6
+ import {MapOrgUnit} from "../../../../interfaces";
7
+ import {highlightFeature, resetHighlight} from "../../../../utils/map";
8
+ import {defaultStyle, highlightStyle} from "../BoundaryLayer";
9
+ import {useQuery} from "react-query";
10
+ import {CenteredContent, CircularLoader, Divider} from "@dhis2/ui";
11
+ import i18n from "@dhis2/d2-i18n";
12
+ import {CustomGoogleEngineLayer} from "../../interfaces";
13
+
14
+ function formatValues(value: number): string {
15
+ return Intl.NumberFormat("en-GB", { maximumFractionDigits: 2 }).format(value);
16
+ }
17
+
18
+ function getUnit(unit?: string) {
19
+ if (unit === "percentage") {
20
+ return "%";
21
+ }
22
+ }
23
+
24
+ function Legend({
25
+ header,
26
+ legends,
27
+ value,
28
+ unit,
29
+ }: {
30
+ header: number;
31
+ legends: { id: number | string; color: string; name: string }[];
32
+ value: number;
33
+ unit?: string;
34
+ }) {
35
+ const legend = find(legends, ["id", header]);
36
+
37
+ return (
38
+ <div className="row gap-8 space-between">
39
+ <div className="row gap-8">
40
+ <div className="legend-item-color" style={{ backgroundColor: legend?.color }} />
41
+ <div>{legend?.name}</div>
42
+ </div>
43
+ <span>
44
+ {formatValues(value)}
45
+ {getUnit(unit)}
46
+ </span>
47
+ </div>
48
+ );
49
+ }
50
+
51
+ function AggregationView({ header, value }: { header: string; value: number }) {
52
+ return (
53
+ <div className="row space-between">
54
+ <span>{capitalize(header.toString())}</span>
55
+ <span>{formatValues(value)}</span>
56
+ </div>
57
+ );
58
+ }
59
+
60
+ function EarthEnginePopup({ layer, orgUnit, loading, error }: { layer?: CustomGoogleEngineLayer; orgUnit: MapOrgUnit; loading: boolean; error?: string }) {
61
+ const engine = layer?.engine;
62
+ const legends = layer?.engine?.options?.legend?.items;
63
+ const data = engine?.getAggregation(orgUnit)?.data;
64
+ const unit = layer?.engine?.options?.unit ?? head(layer?.engine?.options.aggregations);
65
+
66
+ const aggregations = useMemo(() => {
67
+ if (!isEmpty(legends)) {
68
+ return sortBy(
69
+ Object.keys(data ?? {}).map((key) => {
70
+ return {
71
+ id: parseInt(key),
72
+ value: data[key],
73
+ };
74
+ }),
75
+ ["value"]
76
+ ).reverse();
77
+ }
78
+ return data ?? {};
79
+ }, [data]);
80
+
81
+ if (loading) {
82
+ return (
83
+ <div style={{ width: 200, height: 200 }}>
84
+ <CenteredContent>
85
+ <CircularLoader extrasmall />
86
+ </CenteredContent>
87
+ </div>
88
+ );
89
+ }
90
+
91
+ if (error) {
92
+ return (
93
+ <div>
94
+ <h3 style={{ margin: "0" }}>{orgUnit.name}</h3>
95
+ <Divider margin={"0"} />
96
+ <div className="column gap-8">
97
+ <div className="column">
98
+ <b>{layer?.options?.name}</b>
99
+ <div>{layer?.options?.unit}</div>
100
+ </div>
101
+ <div className="column">
102
+ <p>{i18n.t("Could not get aggregate data")}</p>
103
+ <p>{error}</p>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ );
108
+ }
109
+
110
+ return (
111
+ <div>
112
+ <h3 style={{ margin: "0" }}>{orgUnit.name}</h3>
113
+ <Divider margin={"0"} />
114
+ <div className="column gap-8">
115
+ <div className="column">
116
+ <b>{layer?.options?.name}</b>
117
+ <div>{layer?.options?.unit ?? unit}</div>
118
+ </div>
119
+ {data && (
120
+ <div className="column">
121
+ {Array.isArray(aggregations)
122
+ ? aggregations?.map(({ id, value }) => (
123
+ <Legend key={`${orgUnit.id}-legend-details-${id}`} legends={legends ?? []} value={value} header={id} unit={unit} />
124
+ ))
125
+ : Object.keys(aggregations)?.map((key) => (
126
+ <AggregationView key={`${orgUnit.id}-aggregate-details-${key}`} header={key} value={aggregations[key]} />
127
+ ))}
128
+ </div>
129
+ )}
130
+ </div>
131
+ </div>
132
+ );
133
+ }
134
+
135
+ function EarthEngineArea({ area, layer, loading, error }: { area: MapOrgUnit; layer?: CustomGoogleEngineLayer; loading: boolean; error?: string }) {
136
+ const ref = useRef<any>();
137
+
138
+ return (
139
+ <GeoJSON
140
+ ref={ref}
141
+ data={area.geoJSON}
142
+ interactive
143
+ eventHandlers={{
144
+ mouseover: (e) => highlightFeature(e, highlightStyle),
145
+ mouseout: (e) => resetHighlight(e, defaultStyle),
146
+ }}
147
+ key={`${area.id}-polygon`}
148
+ pathOptions={defaultStyle}>
149
+ <Tooltip>{area.name}</Tooltip>
150
+ <Popup minWidth={100}>
151
+ <EarthEnginePopup error={error} layer={layer} orgUnit={area} loading={loading} />
152
+ </Popup>
153
+ </GeoJSON>
154
+ );
155
+ }
156
+
157
+ export default function GoogleEngineLayer({ layerId }: { layerId: string }) {
158
+ const layer = useGoogleEngineLayer(layerId);
159
+ const { name, type, enabled, url, options, engine } = layer ?? {};
160
+ const { isLoading: loadingAggregateData, error } = useQuery([engine], async () => engine?.getAggregations(), {
161
+ suspense: false,
162
+ });
163
+ const orgUnits = useBoundaryData();
164
+
165
+ if (!url) return null;
166
+
167
+ return (
168
+ <LayersControl.Overlay checked={enabled} name={name ?? capitalize(type)}>
169
+ <LayerGroup>
170
+ <TileLayer id={options?.id} url={url} />
171
+ {orgUnits?.map((area: MapOrgUnit) => {
172
+ return (
173
+ <EarthEngineArea
174
+ error={(error as any)?.toString() as string | undefined}
175
+ loading={loadingAggregateData}
176
+ key={`${area.id}-polygon`}
177
+ area={area}
178
+ layer={layer}
179
+ />
180
+ );
181
+ })}
182
+ </LayerGroup>
183
+ </LayersControl.Overlay>
184
+ );
185
+ }
@@ -0,0 +1,56 @@
1
+ import {MapOrgUnit} from "../../../../../interfaces";
2
+
3
+ export interface EarthEngineToken {
4
+ access_token: string;
5
+ client_id: string;
6
+ expires_in: number;
7
+ }
8
+
9
+ export type RefreshToken = () => Promise<{ token: EarthEngineToken }>;
10
+ export type DatasetType = "Image" | "ImageCollection" | "Feature" | "FeatureCollection";
11
+
12
+ export interface EarthEngineOptions {
13
+ layer: "earthEngine";
14
+ type: DatasetType;
15
+ id: string;
16
+ datasetId: string;
17
+ name: string;
18
+ unit?: string;
19
+ description: string;
20
+ source: string;
21
+ sourceUrl: string;
22
+ img: string;
23
+ defaultAggregations?: string[];
24
+ maxAggregations?: number;
25
+ periodType?: string;
26
+ filters?: string[];
27
+ legend?: {
28
+ items: { id: number; name: string; color: string }[];
29
+ };
30
+ legacy?: boolean;
31
+ mosaic?: boolean;
32
+ bands?: {
33
+ id: string;
34
+ name: any;
35
+ multiple?: boolean;
36
+ }[];
37
+ mask?: boolean;
38
+ selectedBands?: string[];
39
+ params?: {
40
+ min: number;
41
+ max: number;
42
+ palette: string;
43
+ };
44
+ opacity: number;
45
+ notice?: string;
46
+ error?: string;
47
+ tokenType: "Bearer";
48
+ aggregations?: string[];
49
+ tileScale?: number;
50
+ methods?: Record<string, any>;
51
+ }
52
+
53
+ export interface GoogleEngineComponentProps {
54
+ options: EarthEngineOptions;
55
+ orgUnits: MapOrgUnit[];
56
+ }