@cdc/core 4.23.4 → 4.23.6

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.
@@ -0,0 +1,139 @@
1
+ import numberFromString from '@cdc/core/helpers/numberFromString'
2
+
3
+ const abbreviateNumber = num => {
4
+ let unit = ''
5
+ let absNum = Math.abs(num)
6
+
7
+ if (absNum >= 1e9) {
8
+ unit = 'B'
9
+ num = num / 1e9
10
+ } else if (absNum >= 1e6) {
11
+ unit = 'M'
12
+ num = num / 1e6
13
+ } else if (absNum >= 1e3) {
14
+ unit = 'K'
15
+ num = num / 1e3
16
+ }
17
+
18
+ return num + unit
19
+ }
20
+
21
+ // Format numeric data based on settings in config
22
+ const formatNumber = (num, axis, shouldAbbreviate = false, config = null) => {
23
+ if (!config) console.error('no config found in formatNumber')
24
+ // if num is NaN return num
25
+ if (isNaN(num) || !num) return num
26
+ // Check if the input number is negative
27
+ const isNegative = num < 0
28
+
29
+ // If the input number is negative, take the absolute value
30
+ if (isNegative) {
31
+ num = Math.abs(num)
32
+ }
33
+
34
+ // destructure dataFormat values
35
+ let {
36
+ dataFormat: { commas, abbreviated, roundTo, prefix, suffix, rightRoundTo, bottomRoundTo, rightPrefix, rightSuffix, bottomPrefix, bottomSuffix, bottomAbbreviated }
37
+ } = config
38
+
39
+ // check if value contains comma and remove it. later will add comma below.
40
+ if (String(num).indexOf(',') !== -1) num = num.replaceAll(',', '')
41
+
42
+ let original = num
43
+ let stringFormattingOptions
44
+ if (axis === 'left') {
45
+ stringFormattingOptions = {
46
+ useGrouping: config.dataFormat.commas ? true : false,
47
+ minimumFractionDigits: roundTo ? Number(roundTo) : 0,
48
+ maximumFractionDigits: roundTo ? Number(roundTo) : 0
49
+ }
50
+ }
51
+
52
+ if (axis === 'right') {
53
+ stringFormattingOptions = {
54
+ useGrouping: config.dataFormat.rightCommas ? true : false,
55
+ minimumFractionDigits: rightRoundTo ? Number(rightRoundTo) : 0,
56
+ maximumFractionDigits: rightRoundTo ? Number(rightRoundTo) : 0
57
+ }
58
+ }
59
+
60
+ if (axis === 'bottom') {
61
+ stringFormattingOptions = {
62
+ useGrouping: config.dataFormat.bottomCommas ? true : false,
63
+ minimumFractionDigits: bottomRoundTo ? Number(bottomRoundTo) : 0,
64
+ maximumFractionDigits: bottomRoundTo ? Number(bottomRoundTo) : 0
65
+ }
66
+ }
67
+
68
+ num = numberFromString(num)
69
+
70
+ if (isNaN(num)) {
71
+ config.runtime.editorErrorMessage = `Unable to parse number from data ${original}. Try reviewing your data and selections in the Data Series section.`
72
+ return original
73
+ }
74
+
75
+ if (!config.dataFormat) return num
76
+ if (config.dataCutoff) {
77
+ let cutoff = numberFromString(config.dataCutoff)
78
+
79
+ if (num < cutoff) {
80
+ num = cutoff
81
+ }
82
+ }
83
+
84
+ // When we're formatting the left axis
85
+ // Use commas also updates bars and the data table
86
+ // We can't use commas when we're formatting the dataFormatted number
87
+ // Example: commas -> 12,000; abbreviated -> 12k (correct); abbreviated & commas -> 12 (incorrect)
88
+ //
89
+ // Edge case for small numbers with decimals
90
+ // - if roundTo undefined which means it is blank, then do not round
91
+
92
+ if ((axis === 'left' && commas && abbreviated && shouldAbbreviate) || (axis === 'bottom' && commas && abbreviated && shouldAbbreviate)) {
93
+ num = num // eslint-disable-line
94
+ } else {
95
+ num = num.toLocaleString('en-US', stringFormattingOptions)
96
+ }
97
+ let result = ''
98
+
99
+ if (abbreviated && axis === 'left' && shouldAbbreviate) {
100
+ num = abbreviateNumber(parseFloat(num))
101
+ }
102
+
103
+ if (bottomAbbreviated && axis === 'bottom' && shouldAbbreviate) {
104
+ num = abbreviateNumber(parseFloat(num))
105
+ }
106
+
107
+ if (prefix && axis === 'left') {
108
+ result += prefix
109
+ }
110
+
111
+ if (rightPrefix && axis === 'right') {
112
+ result += rightPrefix
113
+ }
114
+
115
+ if (bottomPrefix && axis === 'bottom') {
116
+ result += bottomPrefix
117
+ }
118
+
119
+ result += num
120
+
121
+ if (suffix && axis === 'left') {
122
+ result += suffix
123
+ }
124
+
125
+ if (rightSuffix && axis === 'right') {
126
+ result += rightSuffix
127
+ }
128
+
129
+ if (bottomSuffix && axis === 'bottom') {
130
+ result += bottomSuffix
131
+ }
132
+ if (isNegative) {
133
+ result = '-' + result
134
+ }
135
+
136
+ return String(result)
137
+ }
138
+
139
+ export { formatNumber }
@@ -0,0 +1,15 @@
1
+ // If config key names or position in the config have been changed with a version change,
2
+ // process those config entries and format old values into new
3
+ import update_4_23 from './ver/4.23'
4
+
5
+ // 4.23.6 ------------------------------------------------------
6
+ const coveUpdateWorker = async config => {
7
+ let genConfig = config
8
+
9
+ // v4.23
10
+ genConfig = await update_4_23(genConfig)
11
+
12
+ return genConfig
13
+ }
14
+
15
+ export default coveUpdateWorker
@@ -14,10 +14,20 @@ export default async function (url, visualizationType = '') {
14
14
  data = await fetch(url.href)
15
15
  .then(response => response.text())
16
16
  .then(responseText => {
17
+ // for every comma NOT inside quotes, replace with a pipe delimiter
18
+ // - this will let commas inside the quotes not be parsed as a new column
19
+ // - Limitation: if a delimiter other than comma is used in the csv this will break
20
+ // Examples of other delimiters that would break: tab
21
+ responseText = responseText.replace(/(".*?")|,/g, (...m) => m[1] || '|')
22
+ // now strip the double quotes
23
+ responseText = responseText.replace(/["]+/g, '')
17
24
  const parsedCsv = Papa.parse(responseText, {
25
+ //quotes: "true", // dont need these
26
+ //quoteChar: "'", // has no effect that I can tell
18
27
  header: true,
19
- dynamicTyping: true,
20
- skipEmptyLines: true
28
+ skipEmptyLines: true,
29
+ delimiter: '|', // we are using pipe symbol as delimiter so setting this explicitly for Papa.parse
30
+ dynamicTyping: false
21
31
  })
22
32
  return parsedCsv.data
23
33
  })
@@ -28,7 +28,7 @@ export default function validateFipsCodeLength(stateOrData) {
28
28
  }
29
29
 
30
30
  // Only includes data - get column name from somewhere else
31
- if (Array.isArray(stateOrData)) {
31
+ if (Array.isArray(stateOrData) && stateOrData.length > 0) {
32
32
  let columns = Object.keys(stateOrData[0])
33
33
 
34
34
  let potentialColumnNames = ['fips', 'FIPS', 'fips codes', 'FIPS CODES', 'Fips Codes', 'fips Codes', 'Fips codes', 'FIPS Codes']
@@ -0,0 +1,10 @@
1
+ const update_4_23 = async config => {
2
+ const ver = 4.23
3
+
4
+ let newConfig = { ...config }
5
+
6
+ newConfig.validated = ver
7
+ return newConfig
8
+ }
9
+
10
+ export default update_4_23
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdc/core",
3
- "version": "4.23.4",
3
+ "version": "4.23.6",
4
4
  "description": "Core components, styles, hooks, and helpers, for the CDC Open Visualization project",
5
5
  "moduleName": "CdcCore",
6
6
  "main": "dist/cdccore",
@@ -30,5 +30,5 @@
30
30
  "react": "^18.2.0",
31
31
  "react-dom": "^18.2.0"
32
32
  },
33
- "gitHead": "dcd395d76f70b2d113f2b4c6fe50a52522655cd1"
33
+ "gitHead": "aaed0388b487adfeb3e7e278b4ce74df09cbaade"
34
34
  }
@@ -39,6 +39,7 @@ table.data-table {
39
39
  border-collapse: collapse;
40
40
  overflow: auto;
41
41
  appearance: none;
42
+ table-layout: fixed;
42
43
  * {
43
44
  box-sizing: border-box;
44
45
  }
@@ -172,6 +173,15 @@ table.data-table {
172
173
  margin-left: 5px;
173
174
  }
174
175
  }
176
+
177
+ .boxplot-td {
178
+ //display: inline-block;
179
+ //box-sizing: border-box;
180
+ table-layout: fixed;
181
+ width: 200;
182
+ //min-width: 150px;
183
+ //max-width: 400px;
184
+ }
175
185
  }
176
186
 
177
187
  .no-data {
@@ -2,9 +2,9 @@
2
2
  display: block;
3
3
  position: relative;
4
4
  padding: 0.5em 0.5em;
5
- border-width: 1px;
6
- border-style: solid;
7
- border-color: #cbcbcb;
5
+ border-width: 1px !important; // intentional use of !important for CDC
6
+ border-style: solid !important; // intentional use of !important for CDC
7
+ border-color: #cbcbcb !important; // intentional use of !important for CDC
8
8
  border-radius: 0.1875rem;
9
9
  transition: border-color 200ms $transition-expo-out;
10
10
  font-family: sans-serif;
@@ -21,7 +21,7 @@
21
21
  border-radius: 0 0 3px 3px;
22
22
 
23
23
  &.no-borders {
24
- border: none;
24
+ border: none !important;
25
25
  }
26
26
 
27
27
  .cdc-data-bite-inner-container:not(.component--has-title) .cove-component__content:not(.no-borders) {