@cdc/chart 4.22.11 → 4.23.1
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.
- package/dist/495.js +3 -0
- package/dist/703.js +1 -0
- package/dist/cdcchart.js +723 -6
- package/examples/box-plot-data.json +71 -0
- package/examples/box-plot.csv +5 -0
- package/examples/{private/yaxis-test.json → box-plot.json} +47 -56
- package/examples/gallery/bar-chart-vertical/combo-line-chart.json +3 -1
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +85 -16
- package/examples/new-data.csv +17 -0
- package/examples/newdata.json +90 -0
- package/package.json +3 -2
- package/src/CdcChart.tsx +150 -94
- package/src/components/BarChart.tsx +156 -226
- package/src/components/BoxPlot.js +92 -0
- package/src/components/DataTable.tsx +28 -12
- package/src/components/EditorPanel.js +151 -104
- package/src/components/Filters.js +131 -0
- package/src/components/Legend.js +8 -1
- package/src/components/LineChart.tsx +64 -13
- package/src/components/LinearChart.tsx +120 -81
- package/src/components/PairedBarChart.tsx +1 -1
- package/src/components/PieChart.tsx +12 -2
- package/src/components/useIntersectionObserver.tsx +9 -7
- package/src/data/initial-state.js +14 -8
- package/src/hooks/useReduceData.ts +8 -5
- package/src/index.html +51 -51
- package/src/scss/DataTable.scss +1 -1
- package/src/scss/main.scss +53 -22
- package/examples/private/filters.json +0 -170
- package/examples/private/line-test-data.json +0 -22
- package/examples/private/line-test-two.json +0 -210
- package/examples/private/line-test.json +0 -102
- package/examples/private/new.json +0 -48800
- package/examples/private/newtest.csv +0 -101
- package/examples/private/shawn.json +0 -1106
- package/examples/private/test.json +0 -10124
- package/examples/private/yaxis-testing.csv +0 -27
- package/examples/private/yaxis.json +0 -28
|
@@ -8,16 +8,19 @@ import LegendCircle from '@cdc/core/components/LegendCircle'
|
|
|
8
8
|
|
|
9
9
|
import Context from '../context'
|
|
10
10
|
|
|
11
|
+
import CoveMediaControls from '@cdc/core/helpers/CoveMediaControls'
|
|
12
|
+
|
|
11
13
|
export default function DataTable() {
|
|
12
|
-
const { rawData, transformedData: data, config, colorScale, parseDate, formatDate, formatNumber: numberFormatter, colorPalettes } = useContext<any>(Context)
|
|
14
|
+
const { rawData, transformedData: data, config, colorScale, parseDate, formatDate, formatNumber: numberFormatter, colorPalettes, imageId } = useContext<any>(Context)
|
|
15
|
+
|
|
16
|
+
// Debugging.
|
|
17
|
+
// if (config.visualizationType === 'Box Plot') return null
|
|
13
18
|
|
|
14
|
-
const legendGlyphSize = 15
|
|
15
|
-
const legendGlyphSizeHalf = legendGlyphSize / 2
|
|
16
19
|
const section = config.orientation === 'horizontal' ? 'yAxis' : 'xAxis'
|
|
17
20
|
const [tableExpanded, setTableExpanded] = useState<boolean>(config.table.expanded)
|
|
18
21
|
const [accessibilityLabel, setAccessibilityLabel] = useState('')
|
|
19
22
|
|
|
20
|
-
const DownloadButton = ({ data }: any) => {
|
|
23
|
+
const DownloadButton = ({ data }: any, type) => {
|
|
21
24
|
const fileName = `${config.title.substring(0, 50)}.csv`
|
|
22
25
|
|
|
23
26
|
const csvData = Papa.unparse(data)
|
|
@@ -31,11 +34,20 @@ export default function DataTable() {
|
|
|
31
34
|
}
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
switch (type) {
|
|
38
|
+
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`}>
|
|
41
|
+
Download Data (CSV)
|
|
42
|
+
</a>
|
|
43
|
+
)
|
|
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
|
+
)
|
|
50
|
+
}
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
// Creates columns structure for the table
|
|
@@ -72,13 +84,13 @@ export default function DataTable() {
|
|
|
72
84
|
}
|
|
73
85
|
]
|
|
74
86
|
|
|
75
|
-
data.forEach(d => {
|
|
87
|
+
data.forEach((d, index) => {
|
|
76
88
|
const newCol = {
|
|
77
89
|
Header: config.runtime[section].type === 'date' ? formatDate(parseDate(d[config.runtime.originalXAxis.dataKey])) : d[config.runtime.originalXAxis.dataKey],
|
|
78
90
|
Cell: ({ row }) => {
|
|
79
91
|
return <>{numberFormatter(d[row.original])}</>
|
|
80
92
|
},
|
|
81
|
-
id: d[config.runtime.originalXAxis.dataKey]
|
|
93
|
+
id: `${d[config.runtime.originalXAxis.dataKey]}--${index}`,
|
|
82
94
|
canSort: true
|
|
83
95
|
}
|
|
84
96
|
|
|
@@ -117,6 +129,11 @@ export default function DataTable() {
|
|
|
117
129
|
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable({ columns: tableColumns, data: tableData, defaultColumn }, useSortBy, useBlockLayout, useResizeColumns)
|
|
118
130
|
return (
|
|
119
131
|
<ErrorBoundary component='DataTable'>
|
|
132
|
+
<CoveMediaControls.Section classes={['download-links']}>
|
|
133
|
+
<CoveMediaControls.Link config={config} />
|
|
134
|
+
{config.table.download && <DownloadButton data={rawData} type='link' />}
|
|
135
|
+
</CoveMediaControls.Section>
|
|
136
|
+
|
|
120
137
|
<section id={config?.title ? `dataTableSection__${config?.title.replace(/\s/g, '')}` : `dataTableSection`} className={`data-table-container`} aria-label={accessibilityLabel}>
|
|
121
138
|
<div
|
|
122
139
|
role='button'
|
|
@@ -206,7 +223,6 @@ export default function DataTable() {
|
|
|
206
223
|
''
|
|
207
224
|
)}
|
|
208
225
|
</div>
|
|
209
|
-
{config.table.download && <DownloadButton data={rawData} />}
|
|
210
226
|
</section>
|
|
211
227
|
</ErrorBoundary>
|
|
212
228
|
)
|
|
@@ -3,19 +3,15 @@ import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'
|
|
|
3
3
|
|
|
4
4
|
import { Accordion, AccordionItem, AccordionItemHeading, AccordionItemPanel, AccordionItemButton } from 'react-accessible-accordion'
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import { useDebounce, useDebouncedCallback } from 'use-debounce'
|
|
6
|
+
import { useDebounce } from 'use-debounce'
|
|
8
7
|
|
|
9
8
|
import Context from '../context'
|
|
10
9
|
import WarningImage from '../images/warning.svg'
|
|
11
10
|
import AdvancedEditor from '@cdc/core/components/AdvancedEditor'
|
|
12
11
|
|
|
13
12
|
import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
14
|
-
import Waiting from '@cdc/core/components/Waiting'
|
|
15
|
-
import QuestionIcon from '@cdc/core/assets/icon-question-circle.svg' //TODO: Update with Icon component
|
|
16
13
|
import { useColorPalette } from '../hooks/useColorPalette'
|
|
17
14
|
|
|
18
|
-
import InputCheckbox from '@cdc/core/components/inputs/InputCheckbox'
|
|
19
15
|
import InputToggle from '@cdc/core/components/inputs/InputToggle'
|
|
20
16
|
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
21
17
|
import Icon from '@cdc/core/components/ui/Icon'
|
|
@@ -25,6 +21,8 @@ import useRightAxis from '../hooks/useRightAxis'
|
|
|
25
21
|
// TODO: Remove unused imports
|
|
26
22
|
// TDOO: Move inline styles to a scss file
|
|
27
23
|
|
|
24
|
+
/* eslint-disable react-hooks/rules-of-hooks */
|
|
25
|
+
|
|
28
26
|
const TextField = memo(({ label, tooltip, section = null, subsection = null, fieldName, updateField, value: stateValue, type = 'input', i = null, min = null, ...attributes }) => {
|
|
29
27
|
const [value, setValue] = useState(stateValue)
|
|
30
28
|
|
|
@@ -34,7 +32,7 @@ const TextField = memo(({ label, tooltip, section = null, subsection = null, fie
|
|
|
34
32
|
if ('string' === typeof debouncedValue && stateValue !== debouncedValue) {
|
|
35
33
|
updateField(section, subsection, fieldName, debouncedValue, i)
|
|
36
34
|
}
|
|
37
|
-
}, [debouncedValue])
|
|
35
|
+
}, [debouncedValue]) // eslint-disable-line
|
|
38
36
|
|
|
39
37
|
let name = subsection ? `${section}-${subsection}-${fieldName}` : `${section}-${subsection}-${fieldName}`
|
|
40
38
|
|
|
@@ -211,17 +209,17 @@ const Regions = memo(({ config, updateConfig }) => {
|
|
|
211
209
|
const headerColors = ['theme-blue', 'theme-purple', 'theme-brown', 'theme-teal', 'theme-pink', 'theme-orange', 'theme-slate', 'theme-indigo', 'theme-cyan', 'theme-green', 'theme-amber']
|
|
212
210
|
|
|
213
211
|
const EditorPanel = () => {
|
|
214
|
-
const { config, updateConfig, transformedData: data, loading, colorPalettes, unfilteredData, excludedData,
|
|
212
|
+
const { config, updateConfig, transformedData: data, loading, colorPalettes, unfilteredData, excludedData, isDashboard, setParentConfig, missingRequiredSections } = useContext(Context)
|
|
215
213
|
|
|
216
|
-
const { minValue, maxValue, existPositiveValue } = useReduceData(config, unfilteredData)
|
|
214
|
+
const { minValue, maxValue, existPositiveValue, isAllLine } = useReduceData(config, unfilteredData)
|
|
217
215
|
const { paletteName, isPaletteReversed, filteredPallets, filteredQualitative, dispatch } = useColorPalette(colorPalettes, config)
|
|
218
216
|
useEffect(() => {
|
|
219
217
|
if (paletteName) updateConfig({ ...config, palette: paletteName })
|
|
220
|
-
}, [paletteName])
|
|
218
|
+
}, [paletteName]) // eslint-disable-line
|
|
221
219
|
|
|
222
220
|
useEffect(() => {
|
|
223
221
|
dispatch({ type: 'GET_PALETTE', payload: colorPalettes, paletteName: config.palette })
|
|
224
|
-
}, [dispatch, config.palette])
|
|
222
|
+
}, [dispatch, config.palette]) // eslint-disable-line
|
|
225
223
|
|
|
226
224
|
// when the visualization type changes we
|
|
227
225
|
// have to update the individual series type & axis details
|
|
@@ -243,7 +241,7 @@ const EditorPanel = () => {
|
|
|
243
241
|
...config,
|
|
244
242
|
series: newSeries
|
|
245
243
|
})
|
|
246
|
-
}, [config.visualizationType])
|
|
244
|
+
}, [config.visualizationType]) // eslint-disable-line
|
|
247
245
|
|
|
248
246
|
const { hasRightAxis } = useRightAxis({ config: config, yMax: config.yAxis.size, data: config.data, updateConfig })
|
|
249
247
|
|
|
@@ -325,7 +323,6 @@ const EditorPanel = () => {
|
|
|
325
323
|
}
|
|
326
324
|
|
|
327
325
|
const [displayPanel, setDisplayPanel] = useState(true)
|
|
328
|
-
const [lollipopColorStyle, setLollipopColorStyle] = useState('two-tone')
|
|
329
326
|
|
|
330
327
|
if (loading) {
|
|
331
328
|
return null
|
|
@@ -442,14 +439,11 @@ const EditorPanel = () => {
|
|
|
442
439
|
const getColumns = (filter = true) => {
|
|
443
440
|
let columns = {}
|
|
444
441
|
|
|
445
|
-
unfilteredData.
|
|
442
|
+
unfilteredData.forEach(row => {
|
|
446
443
|
Object.keys(row).forEach(columnName => (columns[columnName] = true))
|
|
447
444
|
})
|
|
448
445
|
|
|
449
446
|
if (filter) {
|
|
450
|
-
let confidenceUpper = config.confidenceKeys?.upper && config.confidenceKeys?.upper !== '' // TODO: remove?
|
|
451
|
-
let confidenceLower = config.confidenceKeys?.lower && config.confidenceKeys?.lower !== '' // TODO: remove?
|
|
452
|
-
|
|
453
447
|
Object.keys(columns).forEach(key => {
|
|
454
448
|
if (
|
|
455
449
|
(config.series && config.series.filter(series => series.dataKey === key).length > 0) ||
|
|
@@ -471,7 +465,7 @@ const EditorPanel = () => {
|
|
|
471
465
|
if (!data) return []
|
|
472
466
|
const set = new Set()
|
|
473
467
|
for (let i = 0; i < data.length; i++) {
|
|
474
|
-
for (const [key
|
|
468
|
+
for (const [key] of Object.entries(data[i])) {
|
|
475
469
|
set.add(key)
|
|
476
470
|
}
|
|
477
471
|
}
|
|
@@ -480,7 +474,7 @@ const EditorPanel = () => {
|
|
|
480
474
|
|
|
481
475
|
const getDataValues = (dataKey, unique = false) => {
|
|
482
476
|
let values = []
|
|
483
|
-
excludedData.
|
|
477
|
+
excludedData.forEach(e => {
|
|
484
478
|
values.push(e[dataKey])
|
|
485
479
|
})
|
|
486
480
|
return unique ? [...new Set(values)] : values
|
|
@@ -560,7 +554,7 @@ const EditorPanel = () => {
|
|
|
560
554
|
orientation: 'horizontal'
|
|
561
555
|
})
|
|
562
556
|
}
|
|
563
|
-
}, [])
|
|
557
|
+
}, []) // eslint-disable-line
|
|
564
558
|
|
|
565
559
|
useEffect(() => {
|
|
566
560
|
if (config.orientation === 'horizontal') {
|
|
@@ -569,7 +563,7 @@ const EditorPanel = () => {
|
|
|
569
563
|
lollipopShape: config.lollipopShape
|
|
570
564
|
})
|
|
571
565
|
}
|
|
572
|
-
}, [config.isLollipopChart, config.lollipopShape])
|
|
566
|
+
}, [config.isLollipopChart, config.lollipopShape]) // eslint-disable-line
|
|
573
567
|
|
|
574
568
|
const ExclusionsList = useCallback(() => {
|
|
575
569
|
const exclusions = [...config.exclusions.keys]
|
|
@@ -589,18 +583,7 @@ const EditorPanel = () => {
|
|
|
589
583
|
})}
|
|
590
584
|
</ul>
|
|
591
585
|
)
|
|
592
|
-
}, [config])
|
|
593
|
-
|
|
594
|
-
const ErrorWithLolliopChart = ({ message }) => {
|
|
595
|
-
return (
|
|
596
|
-
<section className='waiting'>
|
|
597
|
-
<section className='waiting-container'>
|
|
598
|
-
<h3>Error With Configuration</h3>
|
|
599
|
-
<p>{message}</p>
|
|
600
|
-
</section>
|
|
601
|
-
</section>
|
|
602
|
-
)
|
|
603
|
-
}
|
|
586
|
+
}, [config]) // eslint-disable-line
|
|
604
587
|
|
|
605
588
|
const checkIsLine = type => {
|
|
606
589
|
return type === ('Line' || 'dashed-sm')
|
|
@@ -616,7 +599,14 @@ const EditorPanel = () => {
|
|
|
616
599
|
filterItem.orderedValues = filterOrder
|
|
617
600
|
filterItem.order = 'cust'
|
|
618
601
|
filters[filterIndex] = filterItem
|
|
619
|
-
updateConfig({ ...config, filters })
|
|
602
|
+
updateConfig({ ...config, filters })
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const handleSeriesChange = (idx1, idx2) => {
|
|
606
|
+
let seriesOrder = config.series
|
|
607
|
+
let [movedItem] = seriesOrder.splice(idx1, 1)
|
|
608
|
+
seriesOrder.splice(idx2, 0, movedItem)
|
|
609
|
+
updateConfig({ ...config, series: seriesOrder })
|
|
620
610
|
}
|
|
621
611
|
|
|
622
612
|
if (config.isLollipopChart && config?.series?.length > 1) {
|
|
@@ -658,7 +648,10 @@ const EditorPanel = () => {
|
|
|
658
648
|
case (config.visualizationType === 'Line' || config.visualizationType === 'Spark Line') && enteredValue && parseFloat(enteredValue) > minVal:
|
|
659
649
|
message = 'Value must be less than ' + minValue
|
|
660
650
|
break
|
|
661
|
-
case
|
|
651
|
+
case config.visualizationType === 'Combo' && isAllLine && enteredValue && parseFloat(enteredValue) > minVal:
|
|
652
|
+
message = 'Value must be less than ' + minValue
|
|
653
|
+
break
|
|
654
|
+
case (config.visualizationType === 'Bar' || (config.visualizationType === 'Combo' && !isAllLine)) && enteredValue && minVal > 0 && parseFloat(enteredValue) > 0:
|
|
662
655
|
message = 'Value must be less than or equal to 0'
|
|
663
656
|
break
|
|
664
657
|
case enteredValue && minVal < 0 && parseFloat(enteredValue) > minVal:
|
|
@@ -671,11 +664,10 @@ const EditorPanel = () => {
|
|
|
671
664
|
return { ...prevMsg, minMsg: message }
|
|
672
665
|
})
|
|
673
666
|
}
|
|
674
|
-
|
|
675
667
|
useEffect(() => {
|
|
676
668
|
validateMinValue()
|
|
677
669
|
validateMaxValue()
|
|
678
|
-
}, [minValue, maxValue, config])
|
|
670
|
+
}, [minValue, maxValue, config]) // eslint-disable-line
|
|
679
671
|
|
|
680
672
|
return (
|
|
681
673
|
<ErrorBoundary component='EditorPanel'>
|
|
@@ -709,8 +701,8 @@ const EditorPanel = () => {
|
|
|
709
701
|
config.visualizationType !== 'Pie' && <CheckBox value={config.labels} fieldName='labels' label='Display label on data' updateField={updateField} />
|
|
710
702
|
)}
|
|
711
703
|
{config.visualizationType === 'Pie' && <Select fieldName='pieType' label='Pie Chart Type' updateField={updateField} options={['Regular', 'Donut']} />}
|
|
712
|
-
<TextField value={config.title} fieldName='title' label='Title' updateField={updateField} />
|
|
713
704
|
|
|
705
|
+
<TextField value={config.title} fieldName='title' label='Title' updateField={updateField} />
|
|
714
706
|
<TextField
|
|
715
707
|
value={config.superTitle}
|
|
716
708
|
updateField={updateField}
|
|
@@ -783,7 +775,7 @@ const EditorPanel = () => {
|
|
|
783
775
|
}
|
|
784
776
|
/>
|
|
785
777
|
|
|
786
|
-
{config.
|
|
778
|
+
{config.orientation === 'vertical' && <TextField type='number' value={config.heights.vertical} section='heights' fieldName='vertical' label='Chart Height' updateField={updateField} />}
|
|
787
779
|
</AccordionItemPanel>
|
|
788
780
|
</AccordionItem>
|
|
789
781
|
|
|
@@ -808,69 +800,95 @@ const EditorPanel = () => {
|
|
|
808
800
|
</Tooltip.Content>
|
|
809
801
|
</Tooltip>
|
|
810
802
|
</fieldset>
|
|
811
|
-
<ul className='series-list'>
|
|
812
|
-
{config.series &&
|
|
813
|
-
config.series.map((series, i) => {
|
|
814
|
-
if (config.visualizationType === 'Combo') {
|
|
815
|
-
let changeType = (i, value) => {
|
|
816
|
-
let series = [...config.series]
|
|
817
|
-
series[i].type = value
|
|
818
|
-
|
|
819
|
-
series[i].axis = 'Left'
|
|
820
|
-
|
|
821
|
-
updateConfig({ ...config, series })
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
let typeDropdown = (
|
|
825
|
-
<select
|
|
826
|
-
value={series.type}
|
|
827
|
-
onChange={event => {
|
|
828
|
-
changeType(i, event.target.value)
|
|
829
|
-
}}
|
|
830
|
-
style={{ width: '100px', marginRight: '10px' }}
|
|
831
|
-
>
|
|
832
|
-
<option value='' default>
|
|
833
|
-
Select
|
|
834
|
-
</option>
|
|
835
|
-
<option value='Bar'>Bar</option>
|
|
836
|
-
<option value='Line'>Solid Line</option>
|
|
837
|
-
<option value='dashed-sm'>Small Dashed</option>
|
|
838
|
-
<option value='dashed-md'>Medium Dashed</option>
|
|
839
|
-
<option value='dashed-lg'>Large Dashed</option>
|
|
840
|
-
</select>
|
|
841
|
-
)
|
|
842
803
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
804
|
+
<DragDropContext onDragEnd={({ source, destination }) => handleSeriesChange(source.index, destination.index)}>
|
|
805
|
+
<Droppable droppableId='filter_order'>
|
|
806
|
+
{provided => (
|
|
807
|
+
<ul {...provided.droppableProps} className='series-list' ref={provided.innerRef} style={{ marginTop: '1em' }}>
|
|
808
|
+
{config.series.map((series, i) => {
|
|
809
|
+
if (config.visualizationType === 'Combo') {
|
|
810
|
+
let changeType = (i, value) => {
|
|
811
|
+
let series = [...config.series]
|
|
812
|
+
series[i].type = value
|
|
813
|
+
|
|
814
|
+
series[i].axis = 'Left'
|
|
815
|
+
|
|
816
|
+
updateConfig({ ...config, series })
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
let typeDropdown = (
|
|
820
|
+
<select
|
|
821
|
+
value={series.type}
|
|
822
|
+
onChange={event => {
|
|
823
|
+
changeType(i, event.target.value)
|
|
824
|
+
}}
|
|
825
|
+
style={{ width: '100px', marginRight: '10px' }}
|
|
826
|
+
>
|
|
827
|
+
<option value='' default>
|
|
828
|
+
Select
|
|
829
|
+
</option>
|
|
830
|
+
<option value='Bar'>Bar</option>
|
|
831
|
+
<option value='Line'>Solid Line</option>
|
|
832
|
+
<option value='dashed-sm'>Small Dashed</option>
|
|
833
|
+
<option value='dashed-md'>Medium Dashed</option>
|
|
834
|
+
<option value='dashed-lg'>Large Dashed</option>
|
|
835
|
+
</select>
|
|
836
|
+
)
|
|
837
|
+
|
|
838
|
+
return (
|
|
839
|
+
<Draggable key={series.dataKey} draggableId={`draggableFilter-${series.dataKey}`} index={i}>
|
|
840
|
+
{(provided, snapshot) => (
|
|
841
|
+
<li>
|
|
842
|
+
<div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
|
|
843
|
+
<div className={`series-list__name${series.dataKey.length > 15 ? ' series-list__name--truncate' : ''}`} data-title={series.dataKey}>
|
|
844
|
+
<div className='series-list__name-text'>{series.dataKey}</div>
|
|
845
|
+
</div>
|
|
846
|
+
<span>
|
|
847
|
+
<span className='series-list__dropdown'>{typeDropdown}</span>
|
|
848
|
+
{config.series && config.series.length > 1 && (
|
|
849
|
+
<button className='series-list__remove' onClick={() => removeSeries(series.dataKey)}>
|
|
850
|
+
×
|
|
851
|
+
</button>
|
|
852
|
+
)}
|
|
853
|
+
</span>
|
|
854
|
+
</div>
|
|
855
|
+
</li>
|
|
856
|
+
)}
|
|
857
|
+
</Draggable>
|
|
858
|
+
)
|
|
859
|
+
}
|
|
859
860
|
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
861
|
+
return (
|
|
862
|
+
<Draggable key={series.dataKey} draggableId={`draggableFilter-${series.dataKey}`} index={i}>
|
|
863
|
+
{(provided, snapshot) => (
|
|
864
|
+
<li
|
|
865
|
+
key={series.dataKey}
|
|
866
|
+
className={snapshot.isDragging ? 'currently-dragging' : ''}
|
|
867
|
+
style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)}
|
|
868
|
+
ref={provided.innerRef}
|
|
869
|
+
{...provided.draggableProps}
|
|
870
|
+
{...provided.dragHandleProps}
|
|
871
|
+
>
|
|
872
|
+
{/*<div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>*/}
|
|
873
|
+
<div className='series-list__name' data-title={series.dataKey}>
|
|
874
|
+
<div className='series-list__name--text'>{series.dataKey}</div>
|
|
875
|
+
</div>
|
|
876
|
+
{config.series && config.series.length > 1 && (
|
|
877
|
+
<button className='series-list__remove' onClick={() => removeSeries(series.dataKey)}>
|
|
878
|
+
×
|
|
879
|
+
</button>
|
|
880
|
+
)}
|
|
881
|
+
{/*</div>*/}
|
|
882
|
+
</li>
|
|
883
|
+
)}
|
|
884
|
+
</Draggable>
|
|
885
|
+
)
|
|
886
|
+
})}
|
|
887
|
+
{provided.placeholder}
|
|
888
|
+
</ul>
|
|
889
|
+
)}
|
|
890
|
+
</Droppable>
|
|
891
|
+
</DragDropContext>
|
|
874
892
|
</>
|
|
875
893
|
)}
|
|
876
894
|
|
|
@@ -966,7 +984,7 @@ const EditorPanel = () => {
|
|
|
966
984
|
<AccordionItem>
|
|
967
985
|
<AccordionItemHeading>
|
|
968
986
|
<AccordionItemButton>
|
|
969
|
-
{config.visualizationType !== 'Pie' ? (config.
|
|
987
|
+
{config.visualizationType !== 'Pie' ? (config.orientation !== 'horizontal' ? 'Left Value Axis' : 'Value Axis') : 'Data Format'}
|
|
970
988
|
{config.visualizationType === 'Pie' && !config.yAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
|
|
971
989
|
</AccordionItemButton>
|
|
972
990
|
</AccordionItemHeading>
|
|
@@ -996,7 +1014,7 @@ const EditorPanel = () => {
|
|
|
996
1014
|
{config.visualizationType !== 'Pie' && (
|
|
997
1015
|
<>
|
|
998
1016
|
<TextField value={config.yAxis.label} section='yAxis' fieldName='label' label='Label' updateField={updateField} />
|
|
999
|
-
<CheckBox
|
|
1017
|
+
{config.runtime.seriesKeys && config.runtime.seriesKeys.length === 1 && <CheckBox value={config.isLegendValue} fieldName='isLegendValue' label='Use Legend Value in Hover' updateField={updateField} />}
|
|
1000
1018
|
<TextField value={config.yAxis.numTicks} placeholder='Auto' type='number' section='yAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
|
|
1001
1019
|
<TextField
|
|
1002
1020
|
value={config.yAxis.size}
|
|
@@ -1017,11 +1035,29 @@ const EditorPanel = () => {
|
|
|
1017
1035
|
</Tooltip>
|
|
1018
1036
|
}
|
|
1019
1037
|
/>
|
|
1038
|
+
{config.orientation === 'horizontal' && <TextField value={config.xAxis.labelOffset} section='xAxis' fieldName='labelOffset' label='Label offset' type='number' className='number-narrow' updateField={updateField} />}
|
|
1020
1039
|
{config.orientation !== 'horizontal' && <CheckBox value={config.yAxis.gridLines} section='yAxis' fieldName='gridLines' label='Display Gridlines' updateField={updateField} />}
|
|
1021
1040
|
</>
|
|
1022
1041
|
)}
|
|
1023
1042
|
<span className='divider-heading'>Number Formatting</span>
|
|
1024
1043
|
<CheckBox value={config.dataFormat.commas} section='dataFormat' fieldName='commas' label='Add commas' updateField={updateField} />
|
|
1044
|
+
<CheckBox
|
|
1045
|
+
value={config.dataFormat.abbreviated}
|
|
1046
|
+
section='dataFormat'
|
|
1047
|
+
fieldName='abbreviated'
|
|
1048
|
+
label='Abbreviate Axis Values'
|
|
1049
|
+
updateField={updateField}
|
|
1050
|
+
tooltip={
|
|
1051
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1052
|
+
<Tooltip.Target>
|
|
1053
|
+
<Icon display='question' />
|
|
1054
|
+
</Tooltip.Target>
|
|
1055
|
+
<Tooltip.Content>
|
|
1056
|
+
<p>{`This option abbreviates very large or very small numbers on the value axis`}</p>
|
|
1057
|
+
</Tooltip.Content>
|
|
1058
|
+
</Tooltip>
|
|
1059
|
+
}
|
|
1060
|
+
/>
|
|
1025
1061
|
<TextField value={config.dataFormat.roundTo} type='number' section='dataFormat' fieldName='roundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
|
|
1026
1062
|
<div className='two-col-inputs'>
|
|
1027
1063
|
<TextField
|
|
@@ -1390,6 +1426,7 @@ const EditorPanel = () => {
|
|
|
1390
1426
|
</Tooltip>
|
|
1391
1427
|
}
|
|
1392
1428
|
/>
|
|
1429
|
+
<CheckBox value={config.legend.showLegendValuesTooltip} section='legend' fieldName='showLegendValuesTooltip' label='Show Legend Values in Tooltip' updateField={updateField} />
|
|
1393
1430
|
|
|
1394
1431
|
{config.visualizationType === 'Bar' && config.visualizationSubType === 'regular' && config.runtime.seriesKeys.length === 1 && (
|
|
1395
1432
|
<Select value={config.legend.colorCode} section='legend' fieldName='colorCode' label='Color code by category' initial='Select' updateField={updateField} options={getDataValueOptions(data)} />
|
|
@@ -1528,7 +1565,7 @@ const EditorPanel = () => {
|
|
|
1528
1565
|
|
|
1529
1566
|
{config.series?.some(series => series.type === 'Bar' || series.type === 'Paired Bar') && <Select value={config.barHasBorder} fieldName='barHasBorder' label='Bar Borders' updateField={updateField} options={['true', 'false']} />}
|
|
1530
1567
|
|
|
1531
|
-
|
|
1568
|
+
<CheckBox value={config.animate} fieldName='animate' label='Animate Visualization' updateField={updateField} />
|
|
1532
1569
|
|
|
1533
1570
|
{/*<CheckBox value={config.animateReplay} fieldName="animateReplay" label="Replay Animation When Filters Are Changed" updateField={updateField} />*/}
|
|
1534
1571
|
|
|
@@ -1536,6 +1573,7 @@ const EditorPanel = () => {
|
|
|
1536
1573
|
<Select value={config.lineDatapointStyle} fieldName='lineDatapointStyle' label='Line Datapoint Style' updateField={updateField} options={['hidden', 'hover', 'always show']} />
|
|
1537
1574
|
)}
|
|
1538
1575
|
|
|
1576
|
+
{/* eslint-disable */}
|
|
1539
1577
|
<label className='header'>
|
|
1540
1578
|
<span className='edit-label'>Header Theme</span>
|
|
1541
1579
|
<ul className='color-palette'>
|
|
@@ -1555,6 +1593,7 @@ const EditorPanel = () => {
|
|
|
1555
1593
|
<label>
|
|
1556
1594
|
<span className='edit-label'>Chart Color Palette</span>
|
|
1557
1595
|
</label>
|
|
1596
|
+
{/* eslint-enable */}
|
|
1558
1597
|
{/* <InputCheckbox fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} /> */}
|
|
1559
1598
|
<InputToggle fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} />
|
|
1560
1599
|
<span>Sequential</span>
|
|
@@ -1644,9 +1683,9 @@ const EditorPanel = () => {
|
|
|
1644
1683
|
/>
|
|
1645
1684
|
</>
|
|
1646
1685
|
)}
|
|
1647
|
-
{config.orientation === 'horizontal' && config.yAxis.labelPlacement !== 'On Bar' && <TextField type='number' value={config.barHeight || '25'} fieldName='barHeight' label='Bar Thickness' updateField={updateField} min='15' />}
|
|
1686
|
+
{config.orientation === 'horizontal' && !config.isLollipopChart && config.yAxis.labelPlacement !== 'On Bar' && <TextField type='number' value={config.barHeight || '25'} fieldName='barHeight' label=' Bar Thickness' updateField={updateField} min='15' />}
|
|
1648
1687
|
{((config.visualizationType === 'Bar' && config.orientation !== 'horizontal') || config.visualizationType === 'Combo') && <TextField value={config.barThickness} type='number' fieldName='barThickness' label='Bar Thickness' updateField={updateField} />}
|
|
1649
|
-
|
|
1688
|
+
{config.orientation === 'horizontal' && <TextField type='number' value={config.barSpace || '20'} fieldName='barSpace' label='Bar Space' updateField={updateField} min='0' />}
|
|
1650
1689
|
{(config.visualizationType === 'Bar' || config.visualizationType === 'Line' || config.visualizationType === 'Combo') && <CheckBox value={config.topAxis.hasLine} section='topAxis' fieldName='hasLine' label='Add Top Axis Line' updateField={updateField} />}
|
|
1651
1690
|
|
|
1652
1691
|
{config.visualizationType === 'Spark Line' && (
|
|
@@ -1658,6 +1697,11 @@ const EditorPanel = () => {
|
|
|
1658
1697
|
<CheckBox value={config.visual?.hideBackgroundColor} section='visual' fieldName='hideBackgroundColor' label='Hide Background Color' updateField={updateField} />
|
|
1659
1698
|
</div>
|
|
1660
1699
|
)}
|
|
1700
|
+
|
|
1701
|
+
{(config.visualizationType === 'Line' || config.visualizationType === 'Combo') && <CheckBox value={config.showLineSeriesLabels} fieldName='showLineSeriesLabels' label='Append Series Name to End of Line Charts' updateField={updateField} />}
|
|
1702
|
+
{(config.visualizationType === 'Line' || config.visualizationType === 'Combo') && config.showLineSeriesLabels && (
|
|
1703
|
+
<CheckBox value={config.colorMatchLineSeriesLabels} fieldName='colorMatchLineSeriesLabels' label='Match Series Color to Name at End of Line Charts' updateField={updateField} />
|
|
1704
|
+
)}
|
|
1661
1705
|
</AccordionItemPanel>
|
|
1662
1706
|
</AccordionItem>
|
|
1663
1707
|
|
|
@@ -1706,6 +1750,9 @@ const EditorPanel = () => {
|
|
|
1706
1750
|
{config.table.limitHeight && <TextField value={config.table.height} section='table' fieldName='height' label='Data Table Height' type='number' min='0' max='500' placeholder='Height(px)' updateField={updateField} />}
|
|
1707
1751
|
<CheckBox value={config.table.expanded} section='table' fieldName='expanded' label='Expanded by Default' updateField={updateField} />
|
|
1708
1752
|
<CheckBox value={config.table.download} section='table' fieldName='download' label='Display Download Button' updateField={updateField} />
|
|
1753
|
+
<CheckBox value={config.table.showDownloadUrl} section='table' fieldName='showDownloadUrl' label='Display Link to Dataset' updateField={updateField} />
|
|
1754
|
+
{/* <CheckBox value={config.table.showDownloadImgButton} section='table' fieldName='showDownloadImgButton' label='Display Image Button' updateField={updateField} /> */}
|
|
1755
|
+
{/* <CheckBox value={config.table.showDownloadPdfButton} section='table' fieldName='showDownloadPdfButton' label='Display PDF Button' updateField={updateField} /> */}
|
|
1709
1756
|
<TextField value={config.table.label} section='table' fieldName='label' label='Label' updateField={updateField} />
|
|
1710
1757
|
{config.visualizationType !== 'Pie' && <TextField value={config.table.indexLabel} section='table' fieldName='indexLabel' label='Index Column Header' updateField={updateField} />}
|
|
1711
1758
|
</AccordionItemPanel>
|