@cdc/chart 4.23.7 → 4.23.8

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 (38) hide show
  1. package/LICENSE +201 -0
  2. package/dist/cdcchart.js +27964 -26942
  3. package/examples/feature/__data__/area-chart-date-apple.json +5122 -0
  4. package/examples/feature/__data__/city-temperature.json +2198 -0
  5. package/examples/feature/area/area-chart-category.json +45 -45
  6. package/examples/feature/area/area-chart-date-apple.json +10376 -0
  7. package/examples/feature/area/area-chart-date-city-temperature.json +4528 -0
  8. package/examples/feature/area/area-chart-date.json +111 -3
  9. package/examples/feature/forest-plot/broken.json +700 -0
  10. package/examples/feature/forest-plot/data.csv +24 -0
  11. package/examples/feature/forest-plot/forest-plot.json +717 -0
  12. package/examples/feature/pie/planet-pie-example-config.json +1 -1
  13. package/examples/private/confidence_interval_test.json +248 -0
  14. package/examples/private/tooltip-issue.json +45275 -0
  15. package/index.html +13 -11
  16. package/package.json +4 -3
  17. package/src/CdcChart.jsx +24 -14
  18. package/src/components/AreaChart.jsx +84 -59
  19. package/src/components/BarChart.Horizontal.jsx +251 -0
  20. package/src/components/BarChart.StackedHorizontal.jsx +118 -0
  21. package/src/components/BarChart.StackedVertical.jsx +93 -0
  22. package/src/components/BarChart.Vertical.jsx +204 -0
  23. package/src/components/BarChart.jsx +14 -674
  24. package/src/components/BarChartType.jsx +15 -0
  25. package/src/components/BrushHandle.jsx +17 -0
  26. package/src/components/DataTable.jsx +63 -21
  27. package/src/components/EditorPanel.jsx +351 -303
  28. package/src/components/ForestPlot.jsx +191 -0
  29. package/src/components/ForestPlotSettings.jsx +508 -0
  30. package/src/components/LineChart.jsx +2 -2
  31. package/src/components/LinearChart.jsx +115 -310
  32. package/src/data/initial-state.js +43 -0
  33. package/src/hooks/useBarChart.js +186 -0
  34. package/src/hooks/useEditorPermissions.js +218 -0
  35. package/src/hooks/useMinMax.js +15 -3
  36. package/src/hooks/useScales.js +45 -2
  37. package/src/hooks/useTooltip.jsx +407 -0
  38. package/src/scss/main.scss +7 -0
@@ -0,0 +1,15 @@
1
+ import React from 'react'
2
+
3
+ import BarChartStackedVertical from './BarChart.StackedVertical'
4
+ import BarChartStackedHorizontal from './BarChart.StackedHorizontal'
5
+ import BarChartVertical from './BarChart.Vertical'
6
+ import BarChartHorizontal from './BarChart.Horizontal'
7
+
8
+ const BarChartType = {
9
+ Vertical: BarChartVertical,
10
+ Horizontal: BarChartHorizontal,
11
+ StackedVertical: BarChartStackedVertical,
12
+ StackedHorizontal: BarChartStackedHorizontal
13
+ }
14
+
15
+ export default BarChartType
@@ -0,0 +1,17 @@
1
+ import { Group } from '@visx/group'
2
+
3
+ const BrushHandle = props => {
4
+ const { x, height, isBrushActive } = props
5
+ const pathWidth = 8
6
+ const pathHeight = 15
7
+ if (!isBrushActive) {
8
+ return null
9
+ }
10
+ return (
11
+ <Group left={x + pathWidth / 2} top={(height - pathHeight) / 2}>
12
+ <path fill='#f2f2f2' d='M -4.5 0.5 L 3.5 0.5 L 3.5 15.5 L -4.5 15.5 L -4.5 0.5 M -1.5 4 L -1.5 12 M 0.5 4 L 0.5 12' stroke='#999999' strokeWidth='1' style={{ cursor: 'ew-resize' }} />
13
+ </Group>
14
+ )
15
+ }
16
+
17
+ export default BrushHandle
@@ -7,6 +7,7 @@ import { colorPalettesChart } from '@cdc/core/data/colorPalettes'
7
7
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
8
8
  import LegendCircle from '@cdc/core/components/LegendCircle'
9
9
  import Icon from '@cdc/core/components/ui/Icon'
10
+ import { DataTransform } from '@cdc/core/helpers/DataTransform'
10
11
 
11
12
  import ConfigContext from '../ConfigContext'
12
13
 
@@ -19,6 +20,7 @@ export default function DataTable() {
19
20
  const [tableExpanded, setTableExpanded] = useState(config.table.expanded)
20
21
  const [accessibilityLabel, setAccessibilityLabel] = useState('')
21
22
  const isLegendBottom = ['sm', 'xs', 'xxs'].includes(currentViewport)
23
+ const transform = new DataTransform()
22
24
 
23
25
  const DownloadButton = ({ data }, type) => {
24
26
  const fileName = `${config.title.substring(0, 50)}.csv`
@@ -34,19 +36,13 @@ export default function DataTable() {
34
36
  }
35
37
  }
36
38
 
39
+ // - trying to eliminate console error that occurs if formatted with prettier
40
+ // prettier-ignore
37
41
  switch (type) {
38
42
  case 'download':
39
- return (
40
- <a download={fileName} onClick={saveBlob} href={`data:text/csv;base64,${Base64.encode(csvData)}`} aria-label='Download this data in a CSV file format.' className={`btn btn-download no-border margin-sm`}>
41
- Download Data (CSV)
42
- </a>
43
- )
43
+ return (<a download={fileName} onClick={saveBlob} href={`data:text/csv;base64,${Base64.encode(csvData)}`} aria-label='Download this data in a CSV file format.' className={`btn btn-download no-border margin-sm`}>Download Data (CSV)</a>)
44
44
  default:
45
- return (
46
- <a download={fileName} onClick={saveBlob} href={`data:text/csv;base64,${Base64.encode(csvData)}`} aria-label='Download this data in a CSV file format.' className={`no-border`}>
47
- Download Data (CSV)
48
- </a>
49
- )
45
+ return (<a download={fileName} onClick={saveBlob} href={`data:text/csv;base64,${Base64.encode(csvData)}`} aria-label='Download this data in a CSV file format.' className={`no-border`}>Download Data (CSV)</a>)
50
46
  }
51
47
  }
52
48
 
@@ -93,7 +89,7 @@ export default function DataTable() {
93
89
  ]
94
90
  : [
95
91
  {
96
- Header: '',
92
+ Header: ' ',
97
93
  Cell: ({ row }) => {
98
94
  const getSeriesLabel = () => {
99
95
  let userUpdatedSeriesName = config.series.filter(series => series.dataKey === row.original)?.[0]?.name
@@ -121,7 +117,9 @@ export default function DataTable() {
121
117
  </>
122
118
  )
123
119
  },
124
- id: 'series-label'
120
+ id: 'series-label',
121
+ sortType: 'custom',
122
+ canSort: true
125
123
  }
126
124
  ]
127
125
  if (config.visualizationType !== 'Box Plot') {
@@ -151,6 +149,7 @@ export default function DataTable() {
151
149
  return <>{numberFormatter(d[row.original], resolvedAxis)}</>
152
150
  },
153
151
  id: `${d[config.runtime.originalXAxis.dataKey]}--${index}`,
152
+ sortType: 'custom',
154
153
  canSort: true
155
154
  }
156
155
 
@@ -222,7 +221,52 @@ export default function DataTable() {
222
221
  }),
223
222
  []
224
223
  )
225
- const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable({ columns: tableColumns, data: tableData, defaultColumn }, useSortBy, useBlockLayout, useResizeColumns)
224
+ const upIcon = (
225
+ <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 5'>
226
+ <path d='M0 5l5-5 5 5z' />
227
+ </svg>
228
+ )
229
+ const downIcon = (
230
+ <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 5'>
231
+ <path d='M0 0l5 5 5-5z' />
232
+ </svg>
233
+ )
234
+
235
+ const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable(
236
+ {
237
+ columns: tableColumns,
238
+ data: tableData,
239
+ defaultColumn,
240
+ disableSortRemove: true, // otherwise 3rd click on header removes sorting entirely
241
+ sortTypes: {
242
+ custom: (rowA, rowB, columnId) => {
243
+ // rowA.original - is the row data field name to access the value
244
+ // columnId = the column indicator
245
+ let dataKey = config.xAxis.dataKey
246
+ let colObj = config.data.filter(obj => {
247
+ return obj[dataKey] === columnId.split('--')[0] // have to remove index
248
+ })
249
+ if (colObj === undefined || colObj[0] === undefined) {
250
+ return -1
251
+ }
252
+ // NOW we can get the sort values
253
+ const a = transform.cleanDataPoint(colObj[0][rowA.original]) // issue was that a was UNDEFINED therefore it CANT SORT
254
+ const b = transform.cleanDataPoint(colObj[0][rowB.original])
255
+
256
+ if (a === undefined) {
257
+ return -1
258
+ }
259
+ if (!isNaN(Number(a)) && !isNaN(Number(b))) {
260
+ return Number(a) - Number(b)
261
+ }
262
+ return a.localeCompare(b)
263
+ }
264
+ }
265
+ },
266
+ useSortBy,
267
+ useBlockLayout,
268
+ useResizeColumns
269
+ )
226
270
 
227
271
  // sort continuous x axis scaling for data tables, ie. xAxis should read 1,2,3,4,5
228
272
  if (config.xAxis.type === 'continuous' && headerGroups) {
@@ -236,7 +280,7 @@ export default function DataTable() {
236
280
  {config.table.download && <DownloadButton data={rawData} type='link' />}
237
281
  </MediaControls.Section>
238
282
 
239
- <section style={{ marginTop: !isLegendBottom ? config.dynamicMarginTop + 'px' : '0px' }} id={config?.title ? `dataTableSection__${config?.title.replace(/\s/g, '')}` : `dataTableSection`} className={`data-table-container`} aria-label={accessibilityLabel}>
283
+ <section style={{ marginTop: !isLegendBottom ? config.dynamicMarginTop / 4 + 'px' : '0px' }} id={config?.title ? `dataTableSection__${config?.title.replace(/\s/g, '')}` : `dataTableSection`} className={`data-table-container`} aria-label={accessibilityLabel}>
240
284
  <div
241
285
  role='button'
242
286
  className={tableExpanded ? 'data-table-heading' : 'collapsed data-table-heading'}
@@ -259,6 +303,7 @@ export default function DataTable() {
259
303
  <thead>
260
304
  {headerGroups.map((headerGroup, index) => (
261
305
  <tr {...headerGroup.getHeaderGroupProps()} key={`headerGroups--${index}`}>
306
+ {' '}
262
307
  {headerGroup.headers.map((column, index) => (
263
308
  <th
264
309
  tabIndex='0'
@@ -267,14 +312,11 @@ export default function DataTable() {
267
312
  role='columnheader'
268
313
  scope='col'
269
314
  {...column.getHeaderProps(column.getSortByToggleProps())}
270
- className={column.isSorted ? (column.isSortedDesc ? 'sort sort-desc' : 'sort sort-asc') : 'sort'}
271
- {...(column.isSorted ? (column.isSortedDesc ? { 'aria-sort': 'descending' } : { 'aria-sort': 'ascending' }) : null)}
315
+ className={column.isSorted && column.isSortedDesc ? 'sort sort-desc' : 'sort sort-asc'}
316
+ {...(column.isSorted && column.isSortedDesc ? { 'aria-sort': 'descending' } : { 'aria-sort': 'ascending' })}
272
317
  >
273
- {index === 0 ? (config.table.indexLabel ? config.table.indexLabel : column.render('Header')) : column.render('Header')}
274
- <button>
275
- <span className='cdcdataviz-sr-only'>{`Sort by ${typeof column.render('Header') === 'string' ? column.render('Header').toLowerCase() : column.render('Header')} in ${column.isSorted ? (column.isSortedDesc ? 'descending' : 'ascending') : 'no'} `} order</span>
276
- </button>
277
- <div {...column.getResizerProps()} className='resizer' />
318
+ {column.render('Header')}
319
+ {column.isSorted && <span className={'sort-icon'}>{column.isSortedDesc ? downIcon : upIcon}</span>}
278
320
  </th>
279
321
  ))}
280
322
  </tr>