@cdc/chart 4.26.2 → 4.26.4
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/CONFIG.md +169 -0
- package/README.md +42 -17
- package/dist/cdcchart.js +39419 -35180
- package/examples/__data__/data-with-metadata.json +10 -0
- package/examples/feature/bar/additional-column-tooltip.json +3 -3
- package/examples/feature/deviation/planet-deviation-config.json +2 -2
- package/examples/feature/paired-bar/paired-bar-example.json +2 -2
- package/examples/feature/pie/planet-pie-example-config.json +2 -1
- package/examples/feature/tests-case-rate/case-rate-example-config.json +2 -2
- package/examples/feature/tests-covid/covid-confidence-example-config.json +2 -2
- package/examples/feature/tests-covid/covid-example-config.json +2 -2
- package/examples/feature/tests-cutoff/cutoff-example-config.json +2 -2
- package/examples/feature/tests-non-numerics/planet-pie-example-config-nonnumeric.json +2 -2
- package/examples/metadata-variables.json +58 -0
- package/examples/minimal-example.json +24 -0
- package/examples/private/test2.json +35012 -0
- package/package.json +4 -4
- package/src/CdcChart.tsx +8 -4
- package/src/CdcChartComponent.tsx +326 -290
- package/src/_stories/Chart.CustomColors.smoke.stories.tsx +97 -0
- package/src/_stories/Chart.Defaults.smoke.stories.tsx +95 -0
- package/src/_stories/{Chart.HTMLInDataTable.stories.tsx → Chart.HTMLInDataTable.smoke.stories.tsx} +10 -0
- package/src/_stories/Chart.Minimal.smoke.stories.tsx +25 -0
- package/src/_stories/{Chart.SmallMultiples.stories.tsx → Chart.SmallMultiples.smoke.stories.tsx} +17 -1
- package/src/_stories/Chart.SmallestLeftAxisMax.smoke.stories.tsx +64 -0
- package/src/_stories/{Chart.stories.tsx → Chart.smoke.stories.tsx} +48 -2
- package/src/_stories/{Chart.tooltip.stories.tsx → Chart.tooltip.smoke.stories.tsx} +68 -0
- package/src/_stories/ChartBar.Editor.stories.tsx +177 -115
- package/src/_stories/ChartBrush.Editor.stories.tsx +11 -25
- package/src/_stories/ChartEditor.Editor.stories.tsx +24 -1
- package/src/_stories/{Chart.CustomColors.stories.tsx → ChartLine.DashedDates.smoke.stories.tsx} +4 -4
- package/src/_stories/_mock/line_chart_dashed_dates.json +276 -0
- package/src/_stories/_mock/paired-bar-abbr.json +421 -0
- package/src/_stories/_mock/paired-bar.json +1 -1
- package/src/_stories/_mock/pie_custom_colors.json +268 -0
- package/src/_stories/_mock/smallest_left_axis_max.json +104 -0
- package/src/components/Annotations/components/AnnotationDraggable.styles.css +10 -10
- package/src/components/Annotations/components/AnnotationDraggable.tsx +1 -1
- package/src/components/Annotations/components/AnnotationDropdown.styles.css +1 -1
- package/src/components/Annotations/components/AnnotationList.styles.css +11 -11
- package/src/components/AreaChart/components/AreaChart.Stacked.jsx +10 -2
- package/src/components/Axis/BottomAxis.tsx +10 -3
- package/src/components/Axis/LeftAxis.tsx +2 -4
- package/src/components/Axis/LeftAxisGridlines.tsx +1 -3
- package/src/components/Axis/PairedBarAxis.tsx +10 -4
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +21 -33
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +21 -35
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +21 -36
- package/src/components/BarChart/components/BarChart.Vertical.tsx +21 -34
- package/src/components/BarChart/components/BarChart.tsx +2 -6
- package/src/components/BarChart/helpers/getPatternUrl.ts +94 -0
- package/src/components/BarChart/helpers/tests/getPatternUrl.test.ts +134 -0
- package/src/components/BarChart/helpers/useBarChart.ts +4 -1
- package/src/components/BoxPlot/BoxPlot.Vertical.tsx +3 -3
- package/src/components/Brush/BrushSelector.tsx +2 -1
- package/src/components/Brush/MiniChartPreview.tsx +21 -26
- package/src/components/EditorPanel/EditorPanel.tsx +692 -954
- package/src/components/EditorPanel/EditorPanelContext.ts +1 -1
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +218 -167
- package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +0 -78
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +39 -1
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +169 -135
- package/src/components/EditorPanel/components/Panels/Panel.Regions.tsx +154 -109
- package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +3 -3
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +95 -28
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +45 -42
- package/src/components/EditorPanel/editor-panel.scss +1 -1
- package/src/components/EditorPanel/useEditorPermissions.ts +1 -10
- package/src/components/Forecasting/Forecasting.tsx +2 -2
- package/src/components/ForestPlot/ForestPlot.tsx +26 -22
- package/src/components/HorizonChart/HorizonChart.tsx +10 -2
- package/src/components/HoverLine/HoverLine.tsx +6 -8
- package/src/components/Legend/Legend.Component.tsx +4 -4
- package/src/components/Legend/LegendGroup/LegendGroup.styles.css +9 -4
- package/src/components/Legend/LegendGroup/LegendGroup.tsx +3 -1
- package/src/components/Legend/helpers/createFormatLabels.tsx +3 -2
- package/src/components/Legend/helpers/index.ts +0 -2
- package/src/components/LineChart/LineChartProps.ts +1 -0
- package/src/components/LineChart/components/LineChart.BumpCircle.tsx +3 -2
- package/src/components/LineChart/index.tsx +11 -4
- package/src/components/LinearChart/VisualizationRenderer.tsx +11 -1
- package/src/components/LinearChart/tests/LinearChart.test.tsx +224 -0
- package/src/components/LinearChart/tests/mockConfigContext.ts +2 -0
- package/src/components/LinearChart.tsx +124 -47
- package/src/components/PairedBarChart.jsx +2 -2
- package/src/components/PieChart/PieChart.tsx +30 -13
- package/src/components/RadarChart/RadarChart.tsx +1 -1
- package/src/components/Regions/components/Regions.tsx +36 -26
- package/src/components/Sankey/components/Sankey.tsx +3 -3
- package/src/components/Sankey/sankey.scss +1 -1
- package/src/components/ScatterPlot/ScatterPlot.jsx +19 -17
- package/src/components/SmallMultiples/SmallMultipleTile.tsx +1 -0
- package/src/components/SmallMultiples/SmallMultiples.css +5 -5
- package/src/components/Sparkline/components/SparkLine.tsx +1 -1
- package/src/components/Sparkline/index.scss +4 -2
- package/src/components/WarmingStripes/WarmingStripes.tsx +5 -3
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +8 -8
- package/src/data/initial-state.js +24 -14
- package/src/data/legacy-defaults.ts +18 -0
- package/src/helpers/abbreviateNumber.ts +24 -17
- package/src/helpers/calculateLeftYAxisWidth.ts +193 -0
- package/src/helpers/getChartPatternId.ts +17 -0
- package/src/helpers/getMinMax.ts +16 -2
- package/src/helpers/seriesColumnSettings.ts +114 -0
- package/src/helpers/tests/countNumOfTicks.test.ts +77 -0
- package/src/helpers/tests/seriesColumnSettings.test.ts +84 -0
- package/src/helpers/tests/tooltipHelpers.test.ts +151 -0
- package/src/helpers/tooltipHelpers.ts +176 -0
- package/src/hooks/useHighlightedBars.ts +9 -16
- package/src/hooks/useProgrammaticTooltip.ts +16 -2
- package/src/hooks/useRightAxis.ts +14 -0
- package/src/hooks/useScales.ts +92 -56
- package/src/hooks/useSmallMultipleSynchronization.ts +3 -4
- package/src/hooks/useTooltip.tsx +186 -40
- package/src/scss/main.scss +152 -79
- package/src/test/CdcChart.test.jsx +26 -2
- package/src/types/ChartConfig.ts +5 -0
- package/tests/fixtures/chart-config-with-metadata.json +29 -0
- package/tests/fixtures/data-with-metadata.json +10 -0
- package/examples/chart-regression-2.json +0 -2360
- package/examples/feature/__data__/age-adjusted-rates.json +0 -1486
- package/examples/feature/__data__/city-temperature.json +0 -2198
- package/examples/feature/bar/Barchart_with_negative.json +0 -34
- package/examples/feature/boxplot/box-plot-data.json +0 -71
- package/examples/feature/boxplot/boxplot-data.json +0 -156
- package/examples/feature/combo/combochart-categories_are_numbers .json +0 -18
- package/examples/feature/forest-plot/log.json +0 -26
- package/examples/feature/tests-date-exclusions/date-exclusions-data.json +0 -162
- package/examples/region-issue.json +0 -2065
- package/examples/xaxis.json +0 -493
- /package/examples/feature/bar/{tall-data.json → __data__/tall-data.json} +0 -0
- /package/examples/feature/deviation/{planet-deviation-data.json → __data__/planet-deviation-data.json} +0 -0
- /package/examples/feature/paired-bar/{paired-bar-data.json → __data__/paired-bar-data.json} +0 -0
- /package/examples/feature/paired-bar/{paired-bar-formatted.json → __data__/paired-bar-formatted.json} +0 -0
- /package/examples/feature/tests-case-rate/{case-rate-example-data.json → __data__/case-rate-example-data.json} +0 -0
- /package/examples/feature/tests-covid/{covid-example-data-confidence.json → __data__/covid-example-data-confidence.json} +0 -0
- /package/examples/feature/tests-covid/{covid-example-data.json → __data__/covid-example-data.json} +0 -0
- /package/examples/feature/tests-cutoff/{cutoff-example-data.json → __data__/cutoff-example-data.json} +0 -0
- /package/examples/feature/tests-non-numerics/{planet-example-data-nonnumeric.json → __data__/planet-example-data-nonnumeric.json} +0 -0
- /package/src/_stories/{Chart.Anchors.stories.tsx → Chart.Anchors.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.BoxPlot.stories.tsx → Chart.BoxPlot.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.CI.stories.tsx → Chart.CI.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Combo.stories.tsx → Chart.Combo.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.DynamicSeries.stories.tsx → Chart.DynamicSeries.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Filters.stories.tsx → Chart.Filters.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Forecast.stories.tsx → Chart.Forecast.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Legend.Gradient.stories.tsx → Chart.Legend.Gradient.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Patterns.stories.tsx → Chart.Patterns.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.PreserveDecimals.stories.tsx → Chart.PreserveDecimals.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Regions.Categorical.stories.tsx → Chart.Regions.Categorical.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Regions.DateScale.stories.tsx → Chart.Regions.DateScale.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Regions.DateTimeScale.stories.tsx → Chart.Regions.DateTimeScale.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.ScatterPlot.stories.tsx → Chart.ScatterPlot.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartAnnotation.stories.tsx → ChartAnnotation.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartAxisLabels.stories.tsx → ChartAxisLabels.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartAxisTitles.stories.tsx → ChartAxisTitles.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartBrush.Matrix.Continuous.stories.tsx → ChartBrush.Matrix.Continuous.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartBrush.Matrix.Date.stories.tsx → ChartBrush.Matrix.Date.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartBrush.Matrix.DateTime.stories.tsx → ChartBrush.Matrix.DateTime.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartBrush.stories.tsx → ChartBrush.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartLine.QuadrantAngles.stories.tsx → ChartLine.QuadrantAngles.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartLine.Suppression.stories.tsx → ChartLine.Suppression.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartLine.Symbols.stories.tsx → ChartLine.Symbols.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartPrefixSuffix.stories.tsx → ChartPrefixSuffix.smoke.stories.tsx} +0 -0
- /package/src/_stories/{TechAdoptionWithLinks.stories.tsx → TechAdoptionWithLinks.smoke.stories.tsx} +0 -0
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { memo, useContext } from 'react'
|
|
2
|
+
import { Draggable } from '@hello-pangea/dnd'
|
|
2
3
|
import { useEditorPermissions } from '../../useEditorPermissions.js'
|
|
3
4
|
import {
|
|
5
|
+
Accordion,
|
|
4
6
|
AccordionItem,
|
|
5
7
|
AccordionItemHeading,
|
|
6
8
|
AccordionItemPanel,
|
|
7
9
|
AccordionItemButton
|
|
8
10
|
} from 'react-accessible-accordion'
|
|
9
11
|
import { type ChartConfig } from '../../../../types/ChartConfig.js'
|
|
12
|
+
import GroupedList from '@cdc/core/components/EditorPanel/GroupedList'
|
|
10
13
|
import { TextField, Select } from '@cdc/core/components/EditorPanel/Inputs'
|
|
11
14
|
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
12
15
|
import Icon from '@cdc/core/components/ui/Icon'
|
|
16
|
+
import Button from '@cdc/core/components/elements/Button'
|
|
13
17
|
import { type ChartContext } from '../../../../types/ChartContext.js'
|
|
14
18
|
import { type PanelProps } from '../PanelProps.js'
|
|
15
19
|
import ConfigContext from '../../../../ConfigContext.js'
|
|
@@ -53,129 +57,170 @@ const RegionSettings = memo(({ config, updateConfig }: { config: ChartConfig; up
|
|
|
53
57
|
updateConfig({ ...config, regions })
|
|
54
58
|
}
|
|
55
59
|
|
|
60
|
+
const moveRegion = (sourceIndex, destinationIndex) => {
|
|
61
|
+
const regions = config.regions ? [...config.regions] : []
|
|
62
|
+
const [movedRegion] = regions.splice(sourceIndex, 1)
|
|
63
|
+
regions.splice(destinationIndex, 0, movedRegion)
|
|
64
|
+
updateConfig({ ...config, regions })
|
|
65
|
+
}
|
|
66
|
+
|
|
56
67
|
const fromOptions = ['Fixed', 'Previous Days']
|
|
57
68
|
const toOptions = ['Last Date', 'Fixed']
|
|
58
69
|
|
|
59
70
|
return (
|
|
60
71
|
<>
|
|
61
|
-
|
|
62
|
-
config.regions
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
72
|
+
<GroupedList
|
|
73
|
+
items={config.regions}
|
|
74
|
+
label='Regions'
|
|
75
|
+
droppableId='chart-regions-order'
|
|
76
|
+
onDragEnd={({ source, destination }) => {
|
|
77
|
+
if (!destination || source.index === destination.index) return
|
|
78
|
+
moveRegion(source.index, destination.index)
|
|
79
|
+
}}
|
|
80
|
+
renderItem={({ label, color, from, to, background, range = 'Custom' }, i) => (
|
|
81
|
+
<Draggable key={`region-${i}`} draggableId={`region-${i}`} index={i}>
|
|
82
|
+
{(provided, snapshot) => (
|
|
83
|
+
<div
|
|
84
|
+
className={snapshot.isDragging ? 'currently-dragging' : ''}
|
|
85
|
+
style={provided.draggableProps.style}
|
|
86
|
+
ref={provided.innerRef}
|
|
87
|
+
{...provided.draggableProps}
|
|
88
|
+
{...provided.dragHandleProps}
|
|
89
|
+
>
|
|
90
|
+
<Accordion allowZeroExpanded preExpanded={['panel']}>
|
|
91
|
+
<AccordionItem uuid='panel' className='series-item series-item--chart'>
|
|
92
|
+
<AccordionItemHeading className='series-item__title'>
|
|
93
|
+
<AccordionItemButton className='accordion__button'>
|
|
94
|
+
<Icon display='move' size={15} style={{ cursor: 'default' }} />
|
|
95
|
+
{label || `Region ${i + 1}`}
|
|
96
|
+
</AccordionItemButton>
|
|
97
|
+
</AccordionItemHeading>
|
|
98
|
+
<AccordionItemPanel>
|
|
99
|
+
<div className='series-item__panel-actions'>
|
|
100
|
+
<Button
|
|
101
|
+
type='button'
|
|
102
|
+
variant='danger'
|
|
103
|
+
size='sm'
|
|
104
|
+
className='grouped-list__remove'
|
|
105
|
+
onClick={event => {
|
|
106
|
+
event.preventDefault()
|
|
107
|
+
removeColumn(i)
|
|
108
|
+
}}
|
|
109
|
+
>
|
|
110
|
+
Remove
|
|
111
|
+
</Button>
|
|
112
|
+
</div>
|
|
113
|
+
<TextField value={label} label='Region Label' fieldName='label' i={i} updateField={updateField} />
|
|
114
|
+
<div className='two-col-inputs'>
|
|
115
|
+
<TextField
|
|
116
|
+
value={color}
|
|
117
|
+
label='Text Color'
|
|
118
|
+
fieldName='color'
|
|
119
|
+
updateField={(section, subsection, fieldName, value) => regionUpdate(fieldName, value, i)}
|
|
120
|
+
/>
|
|
121
|
+
<TextField
|
|
122
|
+
value={background}
|
|
123
|
+
label='Background'
|
|
124
|
+
fieldName='background'
|
|
125
|
+
updateField={(section, subsection, fieldName, value) => regionUpdate(fieldName, value, i)}
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
|
|
129
|
+
<Select
|
|
130
|
+
value={config.regions[i].fromType ?? 'Fixed'}
|
|
131
|
+
label='Minimum Region Type'
|
|
132
|
+
initial={'Select'}
|
|
133
|
+
required={true}
|
|
134
|
+
onChange={e => {
|
|
135
|
+
if (e.target.value !== '' && e.target.value !== 'Select') {
|
|
136
|
+
const newRegions = [...config.regions]
|
|
137
|
+
newRegions[i].fromType = e.target.value
|
|
138
|
+
updateConfig({
|
|
139
|
+
...config,
|
|
140
|
+
regions: newRegions
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
e.target.value = ''
|
|
144
|
+
}}
|
|
145
|
+
options={fromOptions}
|
|
146
|
+
/>
|
|
147
|
+
|
|
148
|
+
{(config.regions[i].fromType === 'Fixed' ||
|
|
149
|
+
config.regions[i].fromType === 'Previous Days' ||
|
|
150
|
+
!config.regions[i].fromType) && (
|
|
151
|
+
<>
|
|
152
|
+
<TextField
|
|
153
|
+
value={from}
|
|
154
|
+
label={
|
|
155
|
+
config.regions[i].fromType === 'Fixed' || !config.regions[i]?.fromType
|
|
156
|
+
? 'From Value'
|
|
157
|
+
: 'Previous Number of Days'
|
|
158
|
+
}
|
|
159
|
+
fieldName='from'
|
|
160
|
+
updateField={(section, subsection, fieldName, value) => regionUpdate(fieldName, value, i)}
|
|
161
|
+
tooltip={
|
|
162
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
163
|
+
<Tooltip.Target>
|
|
164
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
165
|
+
</Tooltip.Target>
|
|
166
|
+
<Tooltip.Content>
|
|
167
|
+
<p>
|
|
168
|
+
When using categorical (linear scale) match the data set value. When using date
|
|
169
|
+
(linear / date time scale) match the x-axis value.
|
|
170
|
+
</p>
|
|
171
|
+
</Tooltip.Content>
|
|
172
|
+
</Tooltip>
|
|
173
|
+
}
|
|
174
|
+
/>
|
|
175
|
+
</>
|
|
176
|
+
)}
|
|
177
|
+
|
|
178
|
+
<Select
|
|
179
|
+
value={config.regions[i].toType ?? 'Fixed'}
|
|
180
|
+
label='Maximum Region Type'
|
|
181
|
+
initial={'Select'}
|
|
182
|
+
required={true}
|
|
183
|
+
onChange={e => {
|
|
184
|
+
if (e.target.value !== '' && e.target.value !== 'Select') {
|
|
185
|
+
const newRegions = [...config.regions]
|
|
186
|
+
newRegions[i].toType = e.target.value
|
|
187
|
+
updateConfig({
|
|
188
|
+
...config,
|
|
189
|
+
regions: newRegions
|
|
190
|
+
})
|
|
191
|
+
}
|
|
192
|
+
e.target.value = ''
|
|
193
|
+
}}
|
|
194
|
+
options={toOptions}
|
|
195
|
+
/>
|
|
196
|
+
|
|
197
|
+
{(config.regions[i].toType === 'Fixed' || !config.regions[i].toType) && (
|
|
198
|
+
<TextField
|
|
199
|
+
value={to}
|
|
200
|
+
label='To Value'
|
|
201
|
+
fieldName='to'
|
|
202
|
+
updateField={(section, subsection, fieldName, value) => regionUpdate(fieldName, value, i)}
|
|
203
|
+
/>
|
|
204
|
+
)}
|
|
205
|
+
</AccordionItemPanel>
|
|
206
|
+
</AccordionItem>
|
|
207
|
+
</Accordion>
|
|
208
|
+
</div>
|
|
165
209
|
)}
|
|
166
|
-
</
|
|
167
|
-
)
|
|
210
|
+
</Draggable>
|
|
211
|
+
)}
|
|
212
|
+
/>
|
|
168
213
|
{!config.regions && <p style={{ textAlign: 'center' }}>There are currently no regions.</p>}
|
|
169
|
-
<
|
|
214
|
+
<Button
|
|
170
215
|
type='button'
|
|
171
|
-
|
|
216
|
+
variant='editor-primary'
|
|
172
217
|
onClick={e => {
|
|
173
218
|
e.preventDefault()
|
|
174
219
|
addColumn()
|
|
175
220
|
}}
|
|
176
221
|
>
|
|
177
222
|
Add Region
|
|
178
|
-
</
|
|
223
|
+
</Button>
|
|
179
224
|
</>
|
|
180
225
|
)
|
|
181
226
|
})
|
|
@@ -115,16 +115,16 @@ const SankeySettings: React.FC<PanelProps> = props => {
|
|
|
115
115
|
</div>
|
|
116
116
|
))}
|
|
117
117
|
{data?.storyNodeText?.length < 3 && (
|
|
118
|
-
<
|
|
118
|
+
<Button
|
|
119
119
|
type='button'
|
|
120
|
-
|
|
120
|
+
variant='editor-primary'
|
|
121
121
|
onClick={e => {
|
|
122
122
|
e.preventDefault()
|
|
123
123
|
addStoryNode()
|
|
124
124
|
}}
|
|
125
125
|
>
|
|
126
126
|
Add StoryNode
|
|
127
|
-
</
|
|
127
|
+
</Button>
|
|
128
128
|
)}
|
|
129
129
|
{config.data?.[0]?.tooltips?.length > 0 && (
|
|
130
130
|
<CheckBox
|
|
@@ -8,8 +8,10 @@ import { colorPalettesChartV1, colorPalettesChartV2, sequentialPalettes } from '
|
|
|
8
8
|
import { updatePaletteNames } from '@cdc/core/helpers/updatePaletteNames'
|
|
9
9
|
import { getColorPaletteVersion } from '@cdc/core/helpers/getColorPaletteVersion'
|
|
10
10
|
import Icon from '@cdc/core/components/ui/Icon'
|
|
11
|
-
import { Select } from '@cdc/core/components/EditorPanel/Inputs'
|
|
11
|
+
import { CheckBox, Select, TextField } from '@cdc/core/components/EditorPanel/Inputs'
|
|
12
|
+
import Button from '@cdc/core/components/elements/Button'
|
|
12
13
|
import { buildForecastPaletteOptions } from '../../../../helpers/buildForecastPaletteOptions'
|
|
14
|
+
import { getSeriesColumnConfig, upsertSeriesColumnConfig } from '../../../../helpers/seriesColumnSettings'
|
|
13
15
|
|
|
14
16
|
// Third Party
|
|
15
17
|
import {
|
|
@@ -19,7 +21,7 @@ import {
|
|
|
19
21
|
AccordionItemPanel,
|
|
20
22
|
AccordionItemButton
|
|
21
23
|
} from 'react-accessible-accordion'
|
|
22
|
-
import { Draggable
|
|
24
|
+
import { Draggable } from '@hello-pangea/dnd'
|
|
23
25
|
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
24
26
|
|
|
25
27
|
const SeriesContext = React.createContext({})
|
|
@@ -374,8 +376,8 @@ const SeriesDropdownConfidenceInterval = props => {
|
|
|
374
376
|
)
|
|
375
377
|
})}
|
|
376
378
|
</Accordion>
|
|
377
|
-
<
|
|
378
|
-
|
|
379
|
+
<Button
|
|
380
|
+
variant='editor-primary'
|
|
379
381
|
onClick={e => {
|
|
380
382
|
e.preventDefault()
|
|
381
383
|
let copiedIndex = null
|
|
@@ -396,7 +398,7 @@ const SeriesDropdownConfidenceInterval = props => {
|
|
|
396
398
|
}}
|
|
397
399
|
>
|
|
398
400
|
Add Confidence Interval Group
|
|
399
|
-
</
|
|
401
|
+
</Button>
|
|
400
402
|
</fieldset>
|
|
401
403
|
</div>
|
|
402
404
|
)
|
|
@@ -538,6 +540,84 @@ const SeriesDisplayInTooltip = props => {
|
|
|
538
540
|
)
|
|
539
541
|
}
|
|
540
542
|
|
|
543
|
+
const SeriesColumnSettings = props => {
|
|
544
|
+
const { series } = props
|
|
545
|
+
const { config, updateConfig } = useContext(ConfigContext)
|
|
546
|
+
const { columnConfig } = getSeriesColumnConfig(config.columns || {}, series.dataKey)
|
|
547
|
+
|
|
548
|
+
const updateSeriesColumn = (fieldName, value) => {
|
|
549
|
+
const columns = upsertSeriesColumnConfig(config.columns || {}, series.dataKey, {
|
|
550
|
+
[fieldName]: value
|
|
551
|
+
})
|
|
552
|
+
|
|
553
|
+
updateConfig({
|
|
554
|
+
...config,
|
|
555
|
+
columns
|
|
556
|
+
})
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
return (
|
|
560
|
+
<>
|
|
561
|
+
<span className='divider-heading'>Series Column Settings</span>
|
|
562
|
+
<TextField
|
|
563
|
+
value={columnConfig.label || ''}
|
|
564
|
+
section='seriesColumn'
|
|
565
|
+
subsection={series.dataKey}
|
|
566
|
+
fieldName='label'
|
|
567
|
+
label='Label'
|
|
568
|
+
updateField={(_section, _subsection, _fieldName, value) => updateSeriesColumn('label', value)}
|
|
569
|
+
/>
|
|
570
|
+
<div className='three-col'>
|
|
571
|
+
<TextField
|
|
572
|
+
value={columnConfig.prefix || ''}
|
|
573
|
+
section='seriesColumn'
|
|
574
|
+
subsection={series.dataKey}
|
|
575
|
+
fieldName='prefix'
|
|
576
|
+
label='Prefix'
|
|
577
|
+
updateField={(_section, _subsection, _fieldName, value) => updateSeriesColumn('prefix', value)}
|
|
578
|
+
/>
|
|
579
|
+
<TextField
|
|
580
|
+
value={columnConfig.suffix || ''}
|
|
581
|
+
section='seriesColumn'
|
|
582
|
+
subsection={series.dataKey}
|
|
583
|
+
fieldName='suffix'
|
|
584
|
+
label='Suffix'
|
|
585
|
+
updateField={(_section, _subsection, _fieldName, value) => updateSeriesColumn('suffix', value)}
|
|
586
|
+
/>
|
|
587
|
+
<TextField
|
|
588
|
+
type='number'
|
|
589
|
+
value={columnConfig.roundToPlace ?? 0}
|
|
590
|
+
section='seriesColumn'
|
|
591
|
+
subsection={series.dataKey}
|
|
592
|
+
fieldName='roundToPlace'
|
|
593
|
+
label='Round'
|
|
594
|
+
updateField={(_section, _subsection, _fieldName, value) =>
|
|
595
|
+
updateSeriesColumn('roundToPlace', Number(value) || 0)
|
|
596
|
+
}
|
|
597
|
+
/>
|
|
598
|
+
</div>
|
|
599
|
+
<CheckBox
|
|
600
|
+
value={columnConfig.commas || false}
|
|
601
|
+
section='seriesColumn'
|
|
602
|
+
subsection={series.dataKey}
|
|
603
|
+
fieldName='commas'
|
|
604
|
+
label='Add Commas to Numbers'
|
|
605
|
+
updateField={(_section, _subsection, _fieldName, value) => updateSeriesColumn('commas', value)}
|
|
606
|
+
/>
|
|
607
|
+
{config.table.showVertical && (
|
|
608
|
+
<CheckBox
|
|
609
|
+
value={columnConfig.dataTable ?? true}
|
|
610
|
+
section='seriesColumn'
|
|
611
|
+
subsection={series.dataKey}
|
|
612
|
+
fieldName='dataTable'
|
|
613
|
+
label='Show in Data Table'
|
|
614
|
+
updateField={(_section, _subsection, _fieldName, value) => updateSeriesColumn('dataTable', value)}
|
|
615
|
+
/>
|
|
616
|
+
)}
|
|
617
|
+
</>
|
|
618
|
+
)
|
|
619
|
+
}
|
|
620
|
+
|
|
541
621
|
const SeriesButtonRemove = props => {
|
|
542
622
|
const { config, updateConfig } = useContext(ConfigContext)
|
|
543
623
|
const { series, index } = props
|
|
@@ -573,7 +653,7 @@ const SeriesButtonRemove = props => {
|
|
|
573
653
|
}
|
|
574
654
|
}
|
|
575
655
|
|
|
576
|
-
const handleRemoveSeries = (e, series
|
|
656
|
+
const handleRemoveSeries = (e, series) => {
|
|
577
657
|
e.preventDefault()
|
|
578
658
|
removeSeries(series.dataKey)
|
|
579
659
|
}
|
|
@@ -581,9 +661,9 @@ const SeriesButtonRemove = props => {
|
|
|
581
661
|
return (
|
|
582
662
|
config.series &&
|
|
583
663
|
config.series.length > 1 && (
|
|
584
|
-
<
|
|
664
|
+
<Button variant='danger' size='sm' className='grouped-list__remove' onClick={e => handleRemoveSeries(e, series)}>
|
|
585
665
|
Remove
|
|
586
|
-
</
|
|
666
|
+
</Button>
|
|
587
667
|
)
|
|
588
668
|
)
|
|
589
669
|
}
|
|
@@ -631,12 +711,15 @@ const SeriesItem = props => {
|
|
|
631
711
|
>
|
|
632
712
|
<Icon display='move' size={15} style={{ cursor: 'default' }} />
|
|
633
713
|
{series.dataKey}
|
|
634
|
-
<Series.Button.Remove series={series} index={i} />
|
|
635
714
|
</AccordionItemButton>
|
|
636
715
|
</AccordionItemHeading>
|
|
637
716
|
{chartsWithOptions.includes(config.visualizationType) && (
|
|
638
717
|
<AccordionItemPanel>
|
|
718
|
+
<div className='series-item__panel-actions'>
|
|
719
|
+
<Series.Button.Remove series={series} index={i} />
|
|
720
|
+
</div>
|
|
639
721
|
<Series.Input.Name series={series} index={i} />
|
|
722
|
+
<Series.Input.ColumnSettings series={series} index={i} />
|
|
640
723
|
{showDynamicCategory && (
|
|
641
724
|
<>
|
|
642
725
|
<Select
|
|
@@ -693,22 +776,6 @@ const SeriesItem = props => {
|
|
|
693
776
|
)
|
|
694
777
|
}
|
|
695
778
|
|
|
696
|
-
const SeriesList = props => {
|
|
697
|
-
const { series, getItemStyle, sortableItemStyles, chartsWithOptions } = props
|
|
698
|
-
return series.map((series, i) => {
|
|
699
|
-
return (
|
|
700
|
-
<SeriesItem
|
|
701
|
-
getItemStyle={getItemStyle}
|
|
702
|
-
sortableItemStyles={sortableItemStyles}
|
|
703
|
-
chartsWithOptions={chartsWithOptions}
|
|
704
|
-
series={series}
|
|
705
|
-
index={i}
|
|
706
|
-
key={`series-list-${i}`}
|
|
707
|
-
/>
|
|
708
|
-
)
|
|
709
|
-
})
|
|
710
|
-
}
|
|
711
|
-
|
|
712
779
|
const Series = {
|
|
713
780
|
Wrapper: SeriesWrapper,
|
|
714
781
|
Dropdown: {
|
|
@@ -722,7 +789,8 @@ const Series = {
|
|
|
722
789
|
},
|
|
723
790
|
Input: {
|
|
724
791
|
Name: SeriesInputName,
|
|
725
|
-
Weight: SeriesInputWeight
|
|
792
|
+
Weight: SeriesInputWeight,
|
|
793
|
+
ColumnSettings: SeriesColumnSettings
|
|
726
794
|
},
|
|
727
795
|
Checkbox: {
|
|
728
796
|
DisplayInTooltip: SeriesDisplayInTooltip
|
|
@@ -730,8 +798,7 @@ const Series = {
|
|
|
730
798
|
Button: {
|
|
731
799
|
Remove: SeriesButtonRemove
|
|
732
800
|
},
|
|
733
|
-
Item: SeriesItem
|
|
734
|
-
List: SeriesList
|
|
801
|
+
Item: SeriesItem
|
|
735
802
|
}
|
|
736
803
|
|
|
737
804
|
export default Series
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { useContext, FC, useMemo } from 'react'
|
|
2
|
-
import _ from 'lodash'
|
|
3
2
|
import cloneConfig from '@cdc/core/helpers/cloneConfig'
|
|
4
3
|
|
|
5
4
|
// external libraries
|
|
@@ -31,13 +30,16 @@ import { LineChartConfig } from '../../../../types/ChartConfig'
|
|
|
31
30
|
import { PaletteSelector, DeveloperPaletteRollback } from '@cdc/core/components/PaletteSelector'
|
|
32
31
|
import { HeaderThemeSelector } from '@cdc/core/components/HeaderThemeSelector'
|
|
33
32
|
import { CustomColorsEditor } from '@cdc/core/components/CustomColorsEditor'
|
|
33
|
+
import StyleTreatmentSection from '@cdc/core/components/EditorPanel/sections/StyleTreatmentSection'
|
|
34
34
|
import { getColorScale } from '../../../../helpers/getColorScale'
|
|
35
|
-
import '@cdc/core/
|
|
35
|
+
import { ENABLE_CHART_MAP_TP5_TREATMENT_SELECTION, ENABLE_CHART_VISUAL_SETTINGS } from '@cdc/core/helpers/constants'
|
|
36
|
+
import '@cdc/core/components/EditorPanel/editor.scss'
|
|
36
37
|
import './panelVisual.styles.css'
|
|
37
38
|
|
|
38
39
|
const PanelVisual: FC<PanelProps> = props => {
|
|
39
40
|
const { config, updateConfig, colorPalettes, twoColorPalette } = useContext<ChartContext>(ConfigContext)
|
|
40
41
|
const { visual } = config
|
|
42
|
+
const styleTreatment = config.titleStyle === 'legacy' && !visual?.tp5Treatment ? 'legacy' : 'tp5'
|
|
41
43
|
|
|
42
44
|
const { setLollipopShape, updateField, handlePaletteSelection, handleTwoColorPaletteSelection } =
|
|
43
45
|
useEditorPanelContext()
|
|
@@ -89,12 +91,44 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
|
|
94
|
+
const handleStyleTreatmentChange = (value: string) => {
|
|
95
|
+
const useTp5Treatment = value === 'tp5'
|
|
96
|
+
|
|
97
|
+
updateConfig({
|
|
98
|
+
...config,
|
|
99
|
+
titleStyle: useTp5Treatment ? 'small' : 'legacy',
|
|
100
|
+
visual: {
|
|
101
|
+
...config.visual,
|
|
102
|
+
tp5Treatment: useTp5Treatment,
|
|
103
|
+
border: useTp5Treatment ? false : config.visual?.border,
|
|
104
|
+
borderColorTheme: useTp5Treatment ? false : config.visual?.borderColorTheme,
|
|
105
|
+
accent: useTp5Treatment ? false : config.visual?.accent
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
92
110
|
return (
|
|
93
111
|
<AccordionItem className='panel-visual'>
|
|
94
112
|
<AccordionItemHeading>
|
|
95
113
|
<AccordionItemButton>Visual</AccordionItemButton>
|
|
96
114
|
</AccordionItemHeading>
|
|
97
115
|
<AccordionItemPanel>
|
|
116
|
+
<HeaderThemeSelector selectedTheme={config.theme} onThemeSelect={theme => updateConfig({ ...config, theme })} />
|
|
117
|
+
{ENABLE_CHART_VISUAL_SETTINGS && (
|
|
118
|
+
<StyleTreatmentSection
|
|
119
|
+
styleTreatment={styleTreatment}
|
|
120
|
+
onStyleTreatmentChange={handleStyleTreatmentChange}
|
|
121
|
+
showStyleTreatment={ENABLE_CHART_MAP_TP5_TREATMENT_SELECTION}
|
|
122
|
+
border={visual?.border}
|
|
123
|
+
borderColorTheme={visual?.borderColorTheme}
|
|
124
|
+
accent={visual?.accent}
|
|
125
|
+
background={visual?.background}
|
|
126
|
+
hideBackgroundColor={visual?.hideBackgroundColor}
|
|
127
|
+
showBackground={config.visualizationType === 'Spark Line'}
|
|
128
|
+
showHideBackgroundColor={config.visualizationType === 'Spark Line'}
|
|
129
|
+
updateField={updateField}
|
|
130
|
+
/>
|
|
131
|
+
)}
|
|
98
132
|
{(config.barStyle === 'lollipop' || config.isLollipopChart) && (
|
|
99
133
|
<>
|
|
100
134
|
<fieldset className='header'>
|
|
@@ -272,7 +306,6 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
272
306
|
/>
|
|
273
307
|
</>
|
|
274
308
|
)}
|
|
275
|
-
<HeaderThemeSelector selectedTheme={config.theme} onThemeSelect={theme => updateConfig({ ...config, theme })} />
|
|
276
309
|
{(visSupportsNonSequentialPallete() || visSupportsNonSequentialPallete()) && (
|
|
277
310
|
<>
|
|
278
311
|
<label>
|
|
@@ -573,45 +606,6 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
573
606
|
updateField={updateField}
|
|
574
607
|
/>
|
|
575
608
|
)}
|
|
576
|
-
{config.visualizationType === 'Spark Line' && (
|
|
577
|
-
<div className='cove-accordion__panel-section checkbox-group'>
|
|
578
|
-
<CheckBox
|
|
579
|
-
value={visual?.border}
|
|
580
|
-
section='visual'
|
|
581
|
-
fieldName='border'
|
|
582
|
-
label='Show Border'
|
|
583
|
-
updateField={updateField}
|
|
584
|
-
/>
|
|
585
|
-
<CheckBox
|
|
586
|
-
value={visual?.borderColorTheme}
|
|
587
|
-
section='visual'
|
|
588
|
-
fieldName='borderColorTheme'
|
|
589
|
-
label='Use Border Color Theme'
|
|
590
|
-
updateField={updateField}
|
|
591
|
-
/>
|
|
592
|
-
<CheckBox
|
|
593
|
-
value={visual?.accent}
|
|
594
|
-
section='visual'
|
|
595
|
-
fieldName='accent'
|
|
596
|
-
label='Use Accent Style'
|
|
597
|
-
updateField={updateField}
|
|
598
|
-
/>
|
|
599
|
-
<CheckBox
|
|
600
|
-
value={visual?.background}
|
|
601
|
-
section='visual'
|
|
602
|
-
fieldName='background'
|
|
603
|
-
label='Use Theme Background Color'
|
|
604
|
-
updateField={updateField}
|
|
605
|
-
/>
|
|
606
|
-
<CheckBox
|
|
607
|
-
value={visual?.hideBackgroundColor}
|
|
608
|
-
section='visual'
|
|
609
|
-
fieldName='hideBackgroundColor'
|
|
610
|
-
label='Hide Background Color'
|
|
611
|
-
updateField={updateField}
|
|
612
|
-
/>
|
|
613
|
-
</div>
|
|
614
|
-
)}
|
|
615
609
|
{(config.visualizationType === 'Line' || config.visualizationType === 'Combo') && (
|
|
616
610
|
<CheckBox
|
|
617
611
|
value={config.showLineSeriesLabels}
|
|
@@ -690,6 +684,15 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
690
684
|
}
|
|
691
685
|
/>
|
|
692
686
|
</label>
|
|
687
|
+
{isCoveDeveloperMode() && (
|
|
688
|
+
<CheckBox
|
|
689
|
+
value={visual?.highlightWrappers}
|
|
690
|
+
section='visual'
|
|
691
|
+
fieldName='highlightWrappers'
|
|
692
|
+
label='Highlight Layout Wrappers'
|
|
693
|
+
updateField={updateField}
|
|
694
|
+
/>
|
|
695
|
+
)}
|
|
693
696
|
</AccordionItemPanel>
|
|
694
697
|
</AccordionItem>
|
|
695
698
|
)
|