@cdc/data-bite 4.24.2 → 4.24.3

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,6 @@
1
+ [
2
+ {
3
+ "Text": "Number of Deaths",
4
+ "Value": "4736"
5
+ }
6
+ ]
@@ -0,0 +1,6 @@
1
+ [
2
+ {
3
+ "Text": "Number of EMS Responses",
4
+ "Value": "467136"
5
+ }
6
+ ]
@@ -0,0 +1,110 @@
1
+ {
2
+ "type": "data-bite",
3
+ "data": [
4
+ {
5
+ "Text": "Number of EMS Responses",
6
+ "Value": "467136"
7
+ }
8
+ ],
9
+ "dataBite": "",
10
+ "dataFunction": "Max",
11
+ "dataColumn": "Value",
12
+ "bitePosition": "Left",
13
+ "biteFontSize": 24,
14
+ "fontSize": "medium",
15
+ "biteBody": "",
16
+ "imageData": {
17
+ "display": "none",
18
+ "url": "",
19
+ "alt": "",
20
+ "options": []
21
+ },
22
+ "dataFormat": {
23
+ "roundToPlace": "",
24
+ "commas": true,
25
+ "prefix": "",
26
+ "suffix": ""
27
+ },
28
+ "biteStyle": "gradient",
29
+ "filters": [],
30
+ "subtext": "",
31
+ "title": "Total number of suicide EMS responses",
32
+ "theme": "theme-blue",
33
+ "shadow": false,
34
+ "visual": {
35
+ "border": false,
36
+ "accent": false,
37
+ "background": false,
38
+ "hideBackgroundColor": false,
39
+ "borderColorTheme": false
40
+ },
41
+ "general": {
42
+ "isCompactStyle": false
43
+ },
44
+ "showTitle": true,
45
+ "enableTooltips": true,
46
+ "enableStoryNodes": true,
47
+ "legend": {
48
+ "hide": true
49
+ },
50
+ "heights": {
51
+ "vertical": 300,
52
+ "horizontal": 369.59999999999997
53
+ },
54
+ "xAxis": {
55
+ "anchors": [],
56
+ "type": "categorical",
57
+ "showTargetLabel": true,
58
+ "targetLabel": "Target",
59
+ "hideAxis": true,
60
+ "hideLabel": true,
61
+ "hideTicks": true,
62
+ "size": "59",
63
+ "tickRotation": 0,
64
+ "min": "",
65
+ "max": "",
66
+ "labelColor": "#333",
67
+ "tickLabelColor": "#333",
68
+ "tickColor": "#333",
69
+ "numTicks": "",
70
+ "labelOffset": 180,
71
+ "axisPadding": 0,
72
+ "target": 0,
73
+ "dataKey": "Disposition",
74
+ "label": "X Axis Example Label"
75
+ },
76
+ "series": [
77
+ {
78
+ "dataKey": "Type of Treatment",
79
+ "type": "Bar"
80
+ },
81
+ {
82
+ "dataKey": "Final Outcome",
83
+ "type": "Bar"
84
+ },
85
+ {
86
+ "dataKey": "Number of Patients",
87
+ "type": "Bar"
88
+ }
89
+ ],
90
+ "table": {
91
+ "label": "Sankey Data Table",
92
+ "expanded": true,
93
+ "limitHeight": false,
94
+ "height": "",
95
+ "caption": "",
96
+ "showDownloadUrl": true,
97
+ "showDataTableLink": true,
98
+ "indexLabel": "Disposition",
99
+ "download": true,
100
+ "showVertical": true,
101
+ "show": true
102
+ },
103
+ "footnotes": "**Counts fewer than 20 are suppressed for confidentiality reasons.<br></br><br><strong>Footnotes</strong></br> 2022 Biospatial Emergency Medical Services (EMS) records. Biospatial combines electronic EMS patient care records with other electronic healthcare data. EMS records are generated by medics to document prehospital care and collected according to the National EMS Information System (NEMSIS) standard. Currently the Biospatial platform receives EMS data from 24 full states and 18 partial states.",
104
+ "visualizationType": "Sankey",
105
+ "validated": 4.23,
106
+ "runtime": {
107
+ "uniqueId": 1706633133063,
108
+ "editorErrorMessage": ""
109
+ }
110
+ }
package/index.html CHANGED
@@ -11,7 +11,7 @@
11
11
  </head>
12
12
  <body>
13
13
  <!-- Original -->
14
- <div class="react-container" data-config="/examples/example-config.json"></div>
14
+ <div class="react-container" data-config="/examples/sankey-example-data.json"></div>
15
15
 
16
16
  <!-- DATA PRESENTATION GALLERY: https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/data_bites.html#examples -->
17
17
  <!-- <div class="react-container" data-config="/examples/gallery/calculated-average.json"></div> -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdc/data-bite",
3
- "version": "4.24.2",
3
+ "version": "4.24.3",
4
4
  "description": "React component for displaying a single piece of data in a card module",
5
5
  "moduleName": "CdcDataBite",
6
6
  "main": "dist/cdcdatabite",
@@ -26,7 +26,7 @@
26
26
  "license": "Apache-2.0",
27
27
  "homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
28
28
  "dependencies": {
29
- "@cdc/core": "^4.24.2",
29
+ "@cdc/core": "^4.24.3",
30
30
  "chroma": "0.0.1",
31
31
  "chroma-js": "^2.1.0",
32
32
  "html-react-parser": "^3.0.8",
@@ -39,5 +39,5 @@
39
39
  "react": "^18.2.0",
40
40
  "react-dom": "^18.2.0"
41
41
  },
42
- "gitHead": "edde49c96dee146de5e3a4537880b1bcf4dbee08"
42
+ "gitHead": "9c7ef7ca74f2d2a1e04d923b133fe0fc557a62bf"
43
43
  }
@@ -10,6 +10,7 @@ import EditorPanel from './components/EditorPanel'
10
10
  import Loading from '@cdc/core/components/Loading'
11
11
  import Title from '@cdc/core/components/ui/Title'
12
12
  import CircleCallout from './components/CircleCallout'
13
+ import GradientBite from './components/GradientBite'
13
14
 
14
15
  // external
15
16
  import ResizeObserver from 'resize-observer-polyfill'
@@ -507,9 +508,19 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
507
508
 
508
509
  return (
509
510
  <Context.Provider value={{ config, updateConfig, loading, data: config.data, setParentConfig, isDashboard }}>
510
- <div className={classNames.join(' ')} ref={outerContainerRef}>
511
- {body}
512
- </div>
511
+ {biteStyle !== 'gradient' && (
512
+ <div className={classNames.join(' ')} ref={outerContainerRef}>
513
+ {body}
514
+ </div>
515
+ )}
516
+ {'gradient' === biteStyle && (
517
+ <div className={classNames.join(' ')} ref={outerContainerRef}>
518
+ {isEditor && <EditorPanel />}
519
+ <div className={isEditor ? 'spacing-wrapper' : ''}>
520
+ <GradientBite label={config.title} value={calculateDataBite()} />
521
+ </div>
522
+ </div>
523
+ )}
513
524
  </Context.Provider>
514
525
  )
515
526
  }
@@ -535,7 +546,8 @@ export const BITE_LOCATIONS = {
535
546
  split: 'Split Graphic and Message',
536
547
  title: 'Value above Message',
537
548
  body: 'Value before Message',
538
- end: 'Value after Message'
549
+ end: 'Value after Message',
550
+ gradient: 'Gradient'
539
551
  }
540
552
 
541
553
  export const IMAGE_POSITION_LEFT = 'Left'
@@ -8,6 +8,7 @@ import WarningImage from '@cdc/core/assets/icon-warning-circle.svg'
8
8
  import Tooltip from '@cdc/core/components/ui/Tooltip'
9
9
  import Icon from '@cdc/core/components/ui/Icon'
10
10
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
11
+ import { updateFieldFactory } from '@cdc/core/helpers/updateFieldFactory'
11
12
  import { BITE_LOCATIONS, DATA_FUNCTIONS, IMAGE_POSITIONS, DATA_OPERATORS } from '../CdcDataBite'
12
13
 
13
14
  const TextField = memo(({ label, section = null, subsection = null, fieldName, updateField, value: stateValue, tooltip, type = 'input', i = null, min = null, max = null, ...attributes }) => {
@@ -131,46 +132,8 @@ const EditorPanel = memo(() => {
131
132
  const { config, updateConfig, loading, data, setParentConfig, isDashboard } = useContext(Context)
132
133
 
133
134
  const [displayPanel, setDisplayPanel] = useState(true)
134
- const enforceRestrictions = updatedConfig => {
135
- //If there are any dependencies between fields, etc../
136
- }
137
-
138
- const updateField = (section, subsection, fieldName, newValue) => {
139
- // Top level
140
- if (null === section && null === subsection) {
141
- let updatedConfig = { ...config, [fieldName]: newValue }
142
-
143
- if ('filterColumn' === fieldName) {
144
- updatedConfig.filterValue = ''
145
- }
146
-
147
- enforceRestrictions(updatedConfig)
148
-
149
- updateConfig(updatedConfig)
150
- return
151
- }
152
-
153
- const isArray = Array.isArray(config[section])
154
135
 
155
- let sectionValue = isArray ? [...config[section], newValue] : { ...config[section], [fieldName]: newValue }
156
-
157
- if (null !== subsection) {
158
- if (isArray) {
159
- sectionValue = [...config[section]]
160
- sectionValue[subsection] = { ...sectionValue[subsection], [fieldName]: newValue }
161
- } else if (typeof newValue === 'string') {
162
- sectionValue[subsection] = newValue
163
- } else {
164
- sectionValue = { ...config[section], [subsection]: { ...config[section][subsection], [fieldName]: newValue } }
165
- }
166
- }
167
-
168
- let updatedConfig = { ...config, [section]: sectionValue }
169
-
170
- enforceRestrictions(updatedConfig)
171
-
172
- updateConfig(updatedConfig)
173
- }
136
+ const updateField = updateFieldFactory(config, updateConfig, true)
174
137
 
175
138
  const missingRequiredSections = () => {
176
139
  //Whether to show error message if something is required to show a data-bite and isn't filled in
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import '../scss/kpi.scss';
3
+
4
+ export const KPIComponent = ({label, value}) => {
5
+ return (
6
+ <div className="kpi-container">
7
+ <div className="kpi-content">
8
+ <div className="label-container">
9
+ <span className="label"><strong>{label}</strong></span>
10
+ </div>
11
+ <div className="value-container">
12
+ <span className="value"><strong>{value}</strong></span>
13
+ </div>
14
+ </div>
15
+ </div>
16
+ );
17
+ };
18
+
19
+ export default KPIComponent
@@ -0,0 +1,68 @@
1
+ .kpi-container {
2
+ border-radius: 10px;
3
+ border: 1px solid rgba(0,0,0,.25) !important;
4
+ box-sizing: border-box;
5
+ box-shadow: 0 4px 4px rgba(0,0,0,.25);
6
+ display: flex;
7
+ padding: 5px !important;
8
+ height: 70px;
9
+ width: 100%;
10
+ }
11
+
12
+ .kpi-content {
13
+ background: linear-gradient(90deg, rgba(8,132,136,1) 19%, rgba(255,255,255,1) 74%);
14
+ border-radius: 10px;
15
+ display: flex;
16
+ flex: 1;
17
+ }
18
+
19
+ .label-container,
20
+ .value-container {
21
+ display: flex;
22
+ width: 100%;
23
+ height: 100%;
24
+ align-items: center;
25
+ }
26
+
27
+ .label-container {
28
+ padding-left: 30px !important;
29
+ }
30
+
31
+ .value-container {
32
+ justify-content: center;
33
+ }
34
+
35
+ .label {
36
+ color: white;
37
+ font-size: 18px;
38
+ }
39
+
40
+
41
+ .value {
42
+ color: brown;
43
+ font-size: 24px;
44
+ }
45
+
46
+
47
+ //small
48
+ @media only screen and (min-width:768px) and (max-width:991px){
49
+ .label {
50
+ font-size: 14px;
51
+ }
52
+ .value {
53
+ font-size: 20px;
54
+ }
55
+ }
56
+ //xs
57
+ @media only screen and (max-width:767px){
58
+ .label-container {
59
+ justify-content: flex-start;
60
+ padding-left: 10px !important;
61
+ }
62
+ .label {
63
+ font-size: 10px;
64
+ }
65
+ .value {
66
+ font-size: 14px;
67
+ }
68
+ }