Skip to content

Commit e128cca

Browse files
refactor: move getPrecision to numbers file and rename fns (#3128)
Refactor work: * getPrecision will be used by geojson layers, so it has been moved from utils/earthEngine to utils/numbers * numberPrecision has been renamed to clearly reflect that a function is being returned * unit tests added for some functions in util/numbers * removed old files from the previous DataTable, as they are no longer in use * in classify remove exports that are not used outside of the file, and comment unused function
1 parent 3f9e667 commit e128cca

12 files changed

Lines changed: 155 additions & 180 deletions

File tree

i18n/en.pot

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ msgstr ""
55
"Content-Type: text/plain; charset=utf-8\n"
66
"Content-Transfer-Encoding: 8bit\n"
77
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
8-
"POT-Creation-Date: 2024-02-12T09:30:18.362Z\n"
9-
"PO-Revision-Date: 2024-02-12T09:30:18.362Z\n"
8+
"POT-Creation-Date: 2024-02-21T10:12:14.838Z\n"
9+
"PO-Revision-Date: 2024-02-21T10:12:14.838Z\n"
1010

1111
msgid "Untitled map, {{date}}"
1212
msgstr "Untitled map, {{date}}"

src/components/datatable/ColorCell.js

Lines changed: 0 additions & 23 deletions
This file was deleted.

src/components/datatable/ColumnHeader.js

Lines changed: 0 additions & 27 deletions
This file was deleted.

src/components/datatable/EarthEngineColumns.js

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/components/datatable/useTableData.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import {
99
FACILITY_LAYER,
1010
} from '../../constants/layers.js'
1111
import { numberValueTypes } from '../../constants/valueTypes.js'
12-
import { hasClasses, getPrecision } from '../../util/earthEngine.js'
12+
import { hasClasses } from '../../util/earthEngine.js'
1313
import { filterData } from '../../util/filter.js'
1414
import { isValidUid } from '../../util/helpers.js'
15-
import { numberPrecision } from '../../util/numbers.js'
15+
import { getRoundToPrecisionFn, getPrecision } from '../../util/numbers.js'
1616

1717
const ASCENDING = 'asc'
1818

@@ -123,15 +123,15 @@ const getEarthEngineHeaders = ({ aggregationType, legend, data }) => {
123123
customFields = items.map(({ id, name }) => ({
124124
name,
125125
dataKey: String(id),
126-
roundFn: numberPrecision(2),
126+
roundFn: getRoundToPrecisionFn(2),
127127
type: TYPE_NUMBER,
128128
}))
129129
} else if (Array.isArray(aggregationType) && aggregationType.length) {
130130
customFields = aggregationType.map((type) => {
131131
let roundFn = null
132132
if (data?.length) {
133133
const precision = getPrecision(data.map((d) => d[type]))
134-
roundFn = numberPrecision(precision)
134+
roundFn = getRoundToPrecisionFn(precision)
135135
}
136136
return {
137137
name: toTitleCase(`${type} ${title}`),

src/components/map/layers/earthEngine/EarthEnginePopup.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ import { CircularLoader } from '@dhis2/ui'
33
import PropTypes from 'prop-types'
44
import React from 'react'
55
import { getEarthEngineAggregationType } from '../../../../constants/aggregationTypes.js'
6-
import { hasClasses, getPrecision } from '../../../../util/earthEngine.js'
7-
import { numberPrecision } from '../../../../util/numbers.js'
6+
import { hasClasses } from '../../../../util/earthEngine.js'
7+
import {
8+
getRoundToPrecisionFn,
9+
getPrecision,
10+
} from '../../../../util/numbers.js'
811
import Popup from '../../Popup.js'
912
import styles from './styles/EarthEnginePopup.module.css'
1013

@@ -20,7 +23,7 @@ const EarthEnginePopup = (props) => {
2023

2124
if (values) {
2225
if (classes) {
23-
const valueFormat = numberPrecision(isPercentage ? 2 : 0)
26+
const valueFormat = getRoundToPrecisionFn(isPercentage ? 2 : 0)
2427

2528
table = (
2629
<table className={styles.table}>
@@ -66,7 +69,7 @@ const EarthEnginePopup = (props) => {
6669

6770
// Returns the value format (precision) for an aggregation type
6871
const getValueFormat = (type) =>
69-
numberPrecision(
72+
getRoundToPrecisionFn(
7073
getPrecision(
7174
Object.values(data)
7275
.map((ou) =>

src/components/orgunits/OrgUnitInfo.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import i18n from '@dhis2/d2-i18n'
33
import { IconDimensionOrgUnit16 } from '@dhis2/ui'
44
import PropTypes from 'prop-types'
55
import React from 'react'
6-
import { numberPrecision } from '../../util/numbers.js'
6+
import { getRoundToPrecisionFn } from '../../util/numbers.js'
77
import { formatDate } from '../../util/time.js'
88
import ListItem from '../core/ListItem.js'
99
import styles from './styles/OrgUnitInfo.module.css'
1010

11-
export const coordFormat = numberPrecision(6) // Meter precision for longitude an latitude
11+
export const coordFormat = getRoundToPrecisionFn(6) // Meter precision for longitude an latitude
1212

1313
/*
1414
* Displays the fixed information for an org unit together with org unit groups (above) and metadata attributes (below)

src/loaders/earthEngineLoader.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { getOrgUnitsFromRows } from '../util/analytics.js'
66
import { hasClasses, getPeriodNameFromFilter } from '../util/earthEngine.js'
77
import { getDisplayProperty } from '../util/helpers.js'
88
import { toGeoJson } from '../util/map.js'
9-
import { numberPrecision } from '../util/numbers.js'
9+
import { getRoundToPrecisionFn } from '../util/numbers.js'
1010
import {
1111
getCoordinateField,
1212
addAssociatedGeometries,
@@ -171,7 +171,7 @@ export const createLegend = ({ min, max, palette }) => {
171171
const colors = palette.split(',')
172172
const step = (max - min) / (colors.length - (min > 0 ? 2 : 1))
173173
const precision = precisionRound(step, max)
174-
const valueFormat = numberPrecision(precision)
174+
const valueFormat = getRoundToPrecisionFn(precision)
175175

176176
let from = min
177177
let to = valueFormat(min + step)

src/util/__tests__/numbers.spec.js

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { formatCount, getPrecision } from '../numbers.js'
2+
3+
describe('numbers', () => {
4+
describe('formatCount', () => {
5+
it('should return the original count for numbers less than 1000', () => {
6+
expect(formatCount(500)).toEqual(500)
7+
})
8+
9+
it('should format numbers between 1000 and 9500 with one decimal place and a "k"', () => {
10+
expect(formatCount(3300)).toEqual('3.3k')
11+
})
12+
13+
it('should round numbers between 9500 and 999500 to the nearest thousand and add a "k"', () => {
14+
expect(formatCount(33000)).toEqual('33k')
15+
})
16+
17+
it('should format numbers between 999500 and 1950000 with one decimal place and a "M"', () => {
18+
expect(formatCount(1300000)).toEqual('1.3M')
19+
})
20+
21+
it('should round numbers greater than 1950000 to the nearest million and add a "M"', () => {
22+
expect(formatCount(33000000)).toEqual('33M')
23+
})
24+
})
25+
26+
describe('getPrecision', () => {
27+
it('returns 0 for empty array', () => {
28+
expect(getPrecision([])).toEqual(0)
29+
})
30+
31+
it('returns 0 with absValue >=10000', () => {
32+
expect(getPrecision([10000, 10011, 10020, 10030])).toEqual(0)
33+
})
34+
35+
it('returns 0 with absValue >=1000 and gapValue > 10', () => {
36+
expect(getPrecision([1010, 1000, 1050, 1030])).toEqual(0)
37+
})
38+
39+
it('returns 1 with absValue >=1000 and gapValue <= 10', () => {
40+
expect(getPrecision([1000, 1001.135, 1002, 1003])).toEqual(1)
41+
})
42+
43+
it('returns 1 with absValue >=100 and gapValue > 1', () => {
44+
expect(getPrecision([100, 106, 102, 103])).toEqual(1)
45+
})
46+
47+
it('returns 2 with absValue >=100 and gapValue <= 1', () => {
48+
expect(getPrecision([100.67, 100.1, 100.2, 100.3])).toEqual(2)
49+
})
50+
51+
it('returns 2 with absValue >=10 and gapValue > 0.1', () => {
52+
expect(getPrecision([20.99, 10.1, 10.2, 10.3])).toEqual(2)
53+
})
54+
55+
it('returns 3 with absValue >=10 and gapValue <= 0.1', () => {
56+
expect(getPrecision([10.02, 10.01, 10.03, 10])).toEqual(3)
57+
})
58+
59+
it('returns 3 with absValue >=1 and gapValue > 0.01', () => {
60+
expect(getPrecision([8, 8.07, 8.02, 8.03])).toEqual(3)
61+
})
62+
63+
it('returns 4 with absValue >=1 and gapValue <= 0.01', () => {
64+
expect(getPrecision([1, 1.001, 1.002, 1.003])).toEqual(4)
65+
})
66+
67+
it('returns 4 with absValue <1 and gapValue > 0.001', () => {
68+
expect(getPrecision([0.888, 0.101, 0.102, 0.103])).toEqual(4)
69+
})
70+
71+
it('returns 5 with absValue <1 and gapValue <= 0.001', () => {
72+
expect(getPrecision([0.1, 0.1001, 0.1002, 0.1003])).toEqual(5)
73+
})
74+
75+
it('returns 1 with negative max and absValue >=100 and gapValue > 1', () => {
76+
expect(getPrecision([100, -106, 102, 103])).toEqual(1)
77+
})
78+
79+
it('returns 2 with negative max and absValue >=100 and gapValue <= 1', () => {
80+
expect(getPrecision([-100.67, -100.1, -100.2, -100.3])).toEqual(2)
81+
})
82+
})
83+
})

src/util/classify.js

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
CLASSIFICATION_EQUAL_INTERVALS,
55
CLASSIFICATION_EQUAL_COUNTS,
66
} from '../constants/layers.js'
7-
import { numberPrecision } from './numbers.js'
7+
import { getRoundToPrecisionFn } from './numbers.js'
88

99
// Returns legend item where a value belongs
1010
export const getLegendItemForValue = (legendItems, value) => {
@@ -30,25 +30,27 @@ export const getLegendItems = (values, method, numClasses) => {
3030
return bins
3131
}
3232

33-
export const getClassBins = (values, method, numClasses) => {
34-
const minValue = values[0]
35-
const maxValue = values[values.length - 1]
36-
let bins
33+
// This function is not in use, but keeping it
34+
// just in case it's needed in the future
35+
// export const getClassBins = (values, method, numClasses) => {
36+
// const minValue = values[0]
37+
// const maxValue = values[values.length - 1]
38+
// let bins
3739

38-
if (method === CLASSIFICATION_EQUAL_INTERVALS) {
39-
bins = getEqualIntervals(minValue, maxValue, numClasses)
40-
} else if (method === CLASSIFICATION_EQUAL_COUNTS) {
41-
bins = getQuantiles(values, numClasses)
42-
}
40+
// if (method === CLASSIFICATION_EQUAL_INTERVALS) {
41+
// bins = getEqualIntervals(minValue, maxValue, numClasses)
42+
// } else if (method === CLASSIFICATION_EQUAL_COUNTS) {
43+
// bins = getQuantiles(values, numClasses)
44+
// }
4345

44-
return bins
45-
}
46+
// return bins
47+
// }
4648

47-
export const getEqualIntervals = (minValue, maxValue, numClasses) => {
49+
const getEqualIntervals = (minValue, maxValue, numClasses) => {
4850
const bins = []
4951
const binSize = (maxValue - minValue) / numClasses
5052
const precision = precisionRound(binSize, maxValue)
51-
const valueFormat = numberPrecision(precision)
53+
const valueFormat = getRoundToPrecisionFn(precision)
5254

5355
for (let i = 0; i < numClasses; i++) {
5456
const startValue = minValue + i * binSize
@@ -63,7 +65,7 @@ export const getEqualIntervals = (minValue, maxValue, numClasses) => {
6365
return bins
6466
}
6567

66-
export const getQuantiles = (values, numClasses) => {
68+
const getQuantiles = (values, numClasses) => {
6769
const minValue = values[0]
6870
const maxValue = values[values.length - 1]
6971
const bins = []
@@ -72,7 +74,7 @@ export const getQuantiles = (values, numClasses) => {
7274
(maxValue - minValue) / numClasses,
7375
maxValue
7476
)
75-
const valueFormat = numberPrecision(precision)
77+
const valueFormat = getRoundToPrecisionFn(precision)
7678

7779
let binLastValPos = binCount === 0 ? 0 : binCount
7880

0 commit comments

Comments
 (0)