@cdc/chart 4.25.11 → 4.26.2
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/CLAUDE.local.md +79 -0
- package/dist/{cdcchart-dgT_1dIT.es.js → cdcchart-DQ00cQCm.es.js} +1 -20
- package/dist/cdcchart.js +51401 -50814
- package/examples/default.json +378 -0
- package/examples/feature/__data__/horizon-chart-data.json +373 -0
- package/examples/feature/annotations/index.json +3 -6
- package/examples/feature/horizon/horizon-chart.json +395 -0
- package/examples/feature/pie/planet-pie-example-config.json +48 -2
- package/examples/line-chart-states.json +1085 -0
- package/examples/private/123.json +694 -0
- package/examples/private/DEV-12100.json +1303 -0
- package/examples/private/anchor-issue.json +4094 -0
- package/examples/private/backwards-slider.json +10430 -0
- package/examples/private/cat-y.json +1235 -0
- package/examples/private/data-points.json +228 -0
- package/examples/private/georgia.csv +160 -0
- package/examples/private/height.json +3915 -0
- package/examples/private/links.json +569 -0
- package/examples/private/quadrant.txt +30 -0
- package/examples/private/test-forecast.json +5510 -0
- package/examples/private/timeline-data.json +1 -0
- package/examples/private/timeline.json +389 -0
- package/examples/private/warming-stripe-test.json +2578 -0
- package/examples/private/warming-stripes.json +4763 -0
- package/examples/radar-chart-simple.json +133 -0
- package/examples/radar-chart.json +148 -0
- package/examples/tech-adoption-with-links.json +560 -0
- package/index.html +1 -36
- package/package.json +59 -60
- package/src/CdcChartComponent.tsx +206 -89
- package/src/_stories/Chart.Anchors.stories.tsx +10 -0
- package/src/_stories/Chart.BoxPlot.stories.tsx +7 -0
- package/src/_stories/Chart.CI.stories.tsx +13 -0
- package/src/_stories/Chart.Combo.stories.tsx +17 -0
- package/src/_stories/Chart.CustomColors.stories.tsx +4 -0
- package/src/_stories/Chart.DynamicSeries.stories.tsx +19 -0
- package/src/_stories/Chart.Filters.stories.tsx +4 -0
- package/src/_stories/Chart.Forecast.stories.tsx +4 -0
- package/src/_stories/Chart.HTMLInDataTable.stories.tsx +22 -0
- package/src/_stories/Chart.Legend.Gradient.stories.tsx +28 -0
- package/src/_stories/Chart.Patterns.stories.tsx +4 -0
- package/src/_stories/Chart.PreserveDecimals.stories.tsx +25 -0
- package/src/_stories/Chart.Regions.Categorical.stories.tsx +161 -0
- package/src/_stories/Chart.Regions.DateScale.stories.tsx +216 -0
- package/src/_stories/Chart.Regions.DateTimeScale.stories.tsx +312 -0
- package/src/_stories/Chart.ScatterPlot.stories.tsx +4 -0
- package/src/_stories/Chart.SmallMultiples.stories.tsx +16 -0
- package/src/_stories/Chart.stories.tsx +45 -0
- package/src/_stories/Chart.tooltip.stories.tsx +7 -0
- package/src/_stories/ChartAnnotation.stories.tsx +10 -0
- package/src/_stories/ChartAxisLabels.stories.tsx +4 -0
- package/src/_stories/ChartAxisTitles.stories.tsx +10 -0
- package/src/_stories/ChartBar.Editor.stories.tsx +11 -6
- package/src/_stories/ChartBrush.Editor.stories.tsx +295 -0
- package/src/_stories/ChartBrush.Matrix.Continuous.stories.tsx +41 -0
- package/src/_stories/ChartBrush.Matrix.Date.stories.tsx +114 -0
- package/src/_stories/ChartBrush.Matrix.DateTime.stories.tsx +78 -0
- package/src/_stories/ChartBrush.stories.tsx +57 -0
- package/src/_stories/ChartEditor.Editor.stories.tsx +3 -5
- package/src/_stories/ChartEditor.stories.tsx +7 -0
- package/src/_stories/ChartLine.QuadrantAngles.stories.tsx +89 -0
- package/src/_stories/ChartLine.Suppression.stories.tsx +7 -0
- package/src/_stories/ChartLine.Symbols.stories.tsx +4 -0
- package/src/_stories/ChartPrefixSuffix.stories.tsx +46 -1
- package/src/_stories/TechAdoptionWithLinks.stories.tsx +34 -0
- package/src/_stories/_mock/brush_continuous.json +86 -0
- package/src/_stories/_mock/brush_date_large.json +176 -0
- package/src/_stories/_mock/brush_enabled.json +326 -0
- package/src/_stories/_mock/brush_mock.json +2 -69
- package/src/_stories/_mock/horizontal-bars-dynamic-y-axis.json +413 -0
- package/src/_stories/_mock/line_chart_angle_near_zero_fall.json +195 -0
- package/src/_stories/_mock/line_chart_angle_near_zero_rise.json +195 -0
- package/src/_stories/_mock/line_chart_angle_q1_steep_upward.json +195 -0
- package/src/_stories/_mock/line_chart_angle_q2_gentle_downward.json +195 -0
- package/src/_stories/_mock/line_chart_angle_q3_steep_downward.json +195 -0
- package/src/_stories/_mock/line_chart_angle_q4_gentle_upward.json +195 -0
- package/src/_stories/_mock/line_chart_quadrant_angles.json +264 -0
- package/src/components/Annotations/components/AnnotationDraggable.styles.css +11 -17
- package/src/components/Annotations/components/AnnotationDraggable.tsx +240 -116
- package/src/components/Annotations/components/AnnotationDropdown.styles.css +1 -2
- package/src/components/Annotations/components/AnnotationDropdown.tsx +8 -12
- package/src/components/Annotations/components/AnnotationList.styles.css +4 -10
- package/src/components/Annotations/components/AnnotationList.tsx +5 -4
- package/src/components/Annotations/components/findNearestDatum.ts +75 -85
- package/src/components/Annotations/helpers/getVisibleAnnotations.ts +38 -0
- package/src/components/AreaChart/components/AreaChart.Stacked.jsx +1 -2
- package/src/components/Axis/BottomAxis.tsx +270 -0
- package/src/components/Axis/Categorical.Axis.tsx +6 -7
- package/src/components/Axis/LeftAxis.tsx +404 -0
- package/src/components/Axis/LeftAxisGridlines.tsx +77 -0
- package/src/components/Axis/PairedBarAxis.tsx +186 -0
- package/src/components/Axis/README.md +94 -0
- package/src/components/Axis/RightAxis.tsx +108 -0
- package/src/components/Axis/axis.constants.ts +21 -0
- package/src/components/Axis/index.ts +7 -0
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +178 -24
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +3 -1
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +1 -0
- package/src/components/BarChart/components/BarChart.Vertical.tsx +6 -8
- package/src/components/BarChart/components/BarChart.tsx +7 -1
- package/src/components/BarChart/components/context.tsx +1 -0
- package/src/components/BarChart/helpers/useBarChart.ts +14 -2
- package/src/components/Brush/BrushSelector.tsx +1390 -0
- package/src/components/Brush/MiniChartPreview.tsx +400 -0
- package/src/components/DeviationBar.jsx +9 -7
- package/src/components/EditorPanel/EditorPanel.tsx +2734 -2595
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +60 -22
- package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +56 -34
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +137 -30
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +2 -0
- package/src/components/EditorPanel/components/Panels/Panel.Radar.tsx +353 -0
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +0 -1
- package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +30 -25
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +42 -28
- package/src/components/EditorPanel/components/Panels/index.tsx +2 -0
- package/src/components/EditorPanel/useEditorPermissions.ts +81 -39
- package/src/components/HorizonChart/HorizonChart.tsx +131 -0
- package/src/components/HorizonChart/components/HorizonBand.tsx +160 -0
- package/src/components/HorizonChart/helpers/calculateHorizonBands.ts +27 -0
- package/src/components/HorizonChart/helpers/getHorizonLayerColors.ts +40 -0
- package/src/components/HorizonChart/index.tsx +3 -0
- package/src/components/Legend/Legend.Component.tsx +52 -4
- package/src/components/Legend/Legend.tsx +4 -3
- package/src/components/Legend/LegendValueRange.tsx +77 -0
- package/src/components/Legend/helpers/createFormatLabels.tsx +164 -2
- package/src/components/Legend/helpers/generateValueRanges.ts +92 -0
- package/src/components/Legend/helpers/index.ts +10 -6
- package/src/components/LineChart/helpers/README.md +292 -0
- package/src/components/LineChart/helpers/labelPositioning.test.ts +245 -0
- package/src/components/LineChart/helpers/labelPositioning.ts +304 -0
- package/src/components/LineChart/index.tsx +44 -8
- package/src/components/LinearChart/README.md +109 -0
- package/src/components/LinearChart/VisualizationRenderer.tsx +267 -0
- package/src/components/LinearChart/linearChart.constants.ts +84 -0
- package/src/components/LinearChart/tests/LinearChart.test.tsx +201 -0
- package/src/components/LinearChart/tests/mockConfigContext.ts +129 -0
- package/src/components/LinearChart/utils/tickFormatting.ts +146 -0
- package/src/components/LinearChart.tsx +338 -1082
- package/src/components/PairedBarChart.jsx +20 -3
- package/src/components/PieChart/PieChart.tsx +1 -1
- package/src/components/RadarChart/RadarAxis.tsx +78 -0
- package/src/components/RadarChart/RadarChart.tsx +298 -0
- package/src/components/RadarChart/RadarGrid.tsx +64 -0
- package/src/components/RadarChart/RadarPolygon.tsx +91 -0
- package/src/components/RadarChart/helpers.ts +83 -0
- package/src/components/RadarChart/index.tsx +3 -0
- package/src/components/Regions/components/Regions.tsx +365 -122
- package/src/components/ScatterPlot/ScatterPlot.jsx +2 -2
- package/src/components/SmallMultiples/SmallMultipleTile.tsx +5 -1
- package/src/components/WarmingStripes/WarmingStripes.tsx +230 -0
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +35 -0
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.tsx +104 -0
- package/src/components/WarmingStripes/index.tsx +3 -0
- package/src/data/initial-state.js +17 -2
- package/src/helpers/calculateHorizontalBarCategoryLabelWidth.ts +57 -0
- package/src/helpers/getExcludedData.ts +4 -0
- package/src/helpers/getMinMax.ts +12 -7
- package/src/helpers/handleChartAriaLabels.ts +19 -19
- package/src/helpers/handleLineType.ts +22 -18
- package/src/helpers/sizeHelpers.ts +0 -20
- package/src/helpers/smallMultiplesHelpers.ts +1 -1
- package/src/hooks/useChartHoverAnalytics.tsx +10 -9
- package/src/hooks/useProgrammaticTooltip.ts +23 -2
- package/src/hooks/useScales.ts +18 -1
- package/src/hooks/useTooltip.tsx +34 -10
- package/src/scss/DataTable.scss +0 -4
- package/src/scss/main.scss +22 -3
- package/src/selectors/README.md +68 -0
- package/src/store/chart.reducer.ts +2 -0
- package/src/test/CdcChart.test.jsx +1 -1
- package/src/types/ChartConfig.ts +21 -0
- package/src/types/ChartContext.ts +1 -0
- package/src/types/Horizon.ts +64 -0
- package/src/types/Label.ts +1 -0
- package/src/utils/analyticsTracking.ts +19 -0
- package/LICENSE +0 -201
- package/src/components/Annotations/components/helpers/index.tsx +0 -46
- package/src/components/Brush/BrushChart.tsx +0 -128
- package/src/components/Brush/BrushController.tsx +0 -71
- package/src/components/Brush/types.tsx +0 -8
- package/src/components/BrushChart.tsx +0 -223
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { useContext, FC } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
AccordionItem,
|
|
4
|
+
AccordionItemHeading,
|
|
5
|
+
AccordionItemPanel,
|
|
6
|
+
AccordionItemButton
|
|
7
|
+
} from 'react-accessible-accordion'
|
|
8
|
+
import { TextField, Select, CheckBox } from '@cdc/core/components/EditorPanel/Inputs'
|
|
9
|
+
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
10
|
+
import Icon from '@cdc/core/components/ui/Icon'
|
|
11
|
+
import ConfigContext from '../../../../ConfigContext'
|
|
12
|
+
import { useEditorPanelContext } from '../../EditorPanelContext'
|
|
13
|
+
import { type PanelProps } from './../PanelProps'
|
|
14
|
+
import { ChartContext } from '../../../../types/ChartContext'
|
|
15
|
+
|
|
16
|
+
const PanelRadar: FC<PanelProps> = props => {
|
|
17
|
+
const { config, rawData } = useContext<ChartContext>(ConfigContext)
|
|
18
|
+
const { updateField } = useEditorPanelContext()
|
|
19
|
+
|
|
20
|
+
if (config.visualizationType !== 'Radar') return null
|
|
21
|
+
|
|
22
|
+
const radar = config.radar || {}
|
|
23
|
+
|
|
24
|
+
// Get available columns from the data
|
|
25
|
+
const getColumns = () => {
|
|
26
|
+
if (!rawData || rawData.length === 0) return []
|
|
27
|
+
return Object.keys(rawData[0])
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<AccordionItem>
|
|
32
|
+
<AccordionItemHeading>
|
|
33
|
+
<AccordionItemButton>{props.name}</AccordionItemButton>
|
|
34
|
+
</AccordionItemHeading>
|
|
35
|
+
<AccordionItemPanel>
|
|
36
|
+
{/* Data Settings */}
|
|
37
|
+
<fieldset className='fieldset'>
|
|
38
|
+
<legend style={{ fontSize: '16px', fontWeight: 'bold', marginBottom: '10px' }}>Data Settings</legend>
|
|
39
|
+
|
|
40
|
+
<Select
|
|
41
|
+
value={config.xAxis?.dataKey || ''}
|
|
42
|
+
section='xAxis'
|
|
43
|
+
fieldName='dataKey'
|
|
44
|
+
label='Category Column'
|
|
45
|
+
initial='Select'
|
|
46
|
+
required={true}
|
|
47
|
+
updateField={updateField}
|
|
48
|
+
options={getColumns()}
|
|
49
|
+
tooltip={
|
|
50
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
51
|
+
<Tooltip.Target>
|
|
52
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
53
|
+
</Tooltip.Target>
|
|
54
|
+
<Tooltip.Content>
|
|
55
|
+
<p>Select the column containing category labels for each axis of the radar chart.</p>
|
|
56
|
+
</Tooltip.Content>
|
|
57
|
+
</Tooltip>
|
|
58
|
+
}
|
|
59
|
+
/>
|
|
60
|
+
</fieldset>
|
|
61
|
+
|
|
62
|
+
{/* Number Formatting */}
|
|
63
|
+
<fieldset className='fieldset' style={{ marginTop: '20px' }}>
|
|
64
|
+
<legend style={{ fontSize: '16px', fontWeight: 'bold', marginBottom: '10px' }}>Number Formatting</legend>
|
|
65
|
+
|
|
66
|
+
<CheckBox
|
|
67
|
+
value={config.dataFormat?.commas}
|
|
68
|
+
section='dataFormat'
|
|
69
|
+
fieldName='commas'
|
|
70
|
+
label='Add Commas'
|
|
71
|
+
updateField={updateField}
|
|
72
|
+
tooltip={
|
|
73
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
74
|
+
<Tooltip.Target>
|
|
75
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
76
|
+
</Tooltip.Target>
|
|
77
|
+
<Tooltip.Content>
|
|
78
|
+
<p>Add commas to numeric values in tooltips and data table.</p>
|
|
79
|
+
</Tooltip.Content>
|
|
80
|
+
</Tooltip>
|
|
81
|
+
}
|
|
82
|
+
/>
|
|
83
|
+
|
|
84
|
+
<TextField
|
|
85
|
+
value={config.dataFormat?.roundTo ?? 0}
|
|
86
|
+
type='number'
|
|
87
|
+
section='dataFormat'
|
|
88
|
+
fieldName='roundTo'
|
|
89
|
+
label='Round to Decimal Point'
|
|
90
|
+
updateField={updateField}
|
|
91
|
+
min={0}
|
|
92
|
+
/>
|
|
93
|
+
|
|
94
|
+
<div className='two-col-inputs'>
|
|
95
|
+
<TextField
|
|
96
|
+
value={config.dataFormat?.prefix || ''}
|
|
97
|
+
section='dataFormat'
|
|
98
|
+
fieldName='prefix'
|
|
99
|
+
label='Prefix'
|
|
100
|
+
updateField={updateField}
|
|
101
|
+
tooltip={
|
|
102
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
103
|
+
<Tooltip.Target>
|
|
104
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
105
|
+
</Tooltip.Target>
|
|
106
|
+
<Tooltip.Content>
|
|
107
|
+
<p>Enter a data prefix (such as "$"), if applicable.</p>
|
|
108
|
+
</Tooltip.Content>
|
|
109
|
+
</Tooltip>
|
|
110
|
+
}
|
|
111
|
+
/>
|
|
112
|
+
<TextField
|
|
113
|
+
value={config.dataFormat?.suffix || ''}
|
|
114
|
+
section='dataFormat'
|
|
115
|
+
fieldName='suffix'
|
|
116
|
+
label='Suffix'
|
|
117
|
+
updateField={updateField}
|
|
118
|
+
tooltip={
|
|
119
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
120
|
+
<Tooltip.Target>
|
|
121
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
122
|
+
</Tooltip.Target>
|
|
123
|
+
<Tooltip.Content>
|
|
124
|
+
<p>Enter a data suffix (such as "%"), if applicable.</p>
|
|
125
|
+
</Tooltip.Content>
|
|
126
|
+
</Tooltip>
|
|
127
|
+
}
|
|
128
|
+
/>
|
|
129
|
+
</div>
|
|
130
|
+
</fieldset>
|
|
131
|
+
|
|
132
|
+
{/* Grid Settings */}
|
|
133
|
+
<fieldset className='fieldset' style={{ marginTop: '20px' }}>
|
|
134
|
+
<legend style={{ fontSize: '16px', fontWeight: 'bold', marginBottom: '10px' }}>Grid Settings</legend>
|
|
135
|
+
|
|
136
|
+
<TextField
|
|
137
|
+
type='number'
|
|
138
|
+
value={radar.gridRings ?? 5}
|
|
139
|
+
fieldName='gridRings'
|
|
140
|
+
section='radar'
|
|
141
|
+
label='Number of Grid Rings'
|
|
142
|
+
updateField={updateField}
|
|
143
|
+
min={3}
|
|
144
|
+
max={10}
|
|
145
|
+
tooltip={
|
|
146
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
147
|
+
<Tooltip.Target>
|
|
148
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
149
|
+
</Tooltip.Target>
|
|
150
|
+
<Tooltip.Content>
|
|
151
|
+
<p>Number of concentric rings in the grid (3-10)</p>
|
|
152
|
+
</Tooltip.Content>
|
|
153
|
+
</Tooltip>
|
|
154
|
+
}
|
|
155
|
+
/>
|
|
156
|
+
|
|
157
|
+
<CheckBox
|
|
158
|
+
value={radar.showGridRings ?? true}
|
|
159
|
+
fieldName='showGridRings'
|
|
160
|
+
section='radar'
|
|
161
|
+
label='Show Grid Rings'
|
|
162
|
+
updateField={updateField}
|
|
163
|
+
/>
|
|
164
|
+
|
|
165
|
+
<Select
|
|
166
|
+
value={radar.gridRingStyle ?? 'polygons'}
|
|
167
|
+
fieldName='gridRingStyle'
|
|
168
|
+
section='radar'
|
|
169
|
+
label='Grid Style'
|
|
170
|
+
updateField={updateField}
|
|
171
|
+
options={['polygons', 'circles']}
|
|
172
|
+
tooltip={
|
|
173
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
174
|
+
<Tooltip.Target>
|
|
175
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
176
|
+
</Tooltip.Target>
|
|
177
|
+
<Tooltip.Content>
|
|
178
|
+
<p>Shape of the grid rings - polygons match the data shape, circles are rounded</p>
|
|
179
|
+
</Tooltip.Content>
|
|
180
|
+
</Tooltip>
|
|
181
|
+
}
|
|
182
|
+
/>
|
|
183
|
+
</fieldset>
|
|
184
|
+
|
|
185
|
+
{/* Scale Settings */}
|
|
186
|
+
<fieldset className='fieldset' style={{ marginTop: '20px' }}>
|
|
187
|
+
<legend style={{ fontSize: '16px', fontWeight: 'bold', marginBottom: '10px' }}>Scale Settings</legend>
|
|
188
|
+
|
|
189
|
+
<TextField
|
|
190
|
+
type='number'
|
|
191
|
+
value={radar.scaleMin ?? 0}
|
|
192
|
+
fieldName='scaleMin'
|
|
193
|
+
section='radar'
|
|
194
|
+
label='Minimum Value'
|
|
195
|
+
updateField={updateField}
|
|
196
|
+
tooltip={
|
|
197
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
198
|
+
<Tooltip.Target>
|
|
199
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
200
|
+
</Tooltip.Target>
|
|
201
|
+
<Tooltip.Content>
|
|
202
|
+
<p>Minimum value for the radar scale (center point)</p>
|
|
203
|
+
</Tooltip.Content>
|
|
204
|
+
</Tooltip>
|
|
205
|
+
}
|
|
206
|
+
/>
|
|
207
|
+
|
|
208
|
+
<TextField
|
|
209
|
+
type='number'
|
|
210
|
+
value={radar.scaleMax ?? ''}
|
|
211
|
+
fieldName='scaleMax'
|
|
212
|
+
section='radar'
|
|
213
|
+
label='Maximum Value'
|
|
214
|
+
updateField={updateField}
|
|
215
|
+
placeholder='Auto-calculated'
|
|
216
|
+
tooltip={
|
|
217
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
218
|
+
<Tooltip.Target>
|
|
219
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
220
|
+
</Tooltip.Target>
|
|
221
|
+
<Tooltip.Content>
|
|
222
|
+
<p>Maximum value for the radar scale. Leave empty to auto-calculate from data.</p>
|
|
223
|
+
</Tooltip.Content>
|
|
224
|
+
</Tooltip>
|
|
225
|
+
}
|
|
226
|
+
/>
|
|
227
|
+
</fieldset>
|
|
228
|
+
|
|
229
|
+
{/* Visual Settings */}
|
|
230
|
+
<fieldset className='fieldset' style={{ marginTop: '20px' }}>
|
|
231
|
+
<legend style={{ fontSize: '16px', fontWeight: 'bold', marginBottom: '10px' }}>Visual Settings</legend>
|
|
232
|
+
|
|
233
|
+
<CheckBox
|
|
234
|
+
value={radar.showFill ?? false}
|
|
235
|
+
fieldName='showFill'
|
|
236
|
+
section='radar'
|
|
237
|
+
label='Show Fill'
|
|
238
|
+
updateField={updateField}
|
|
239
|
+
tooltip={
|
|
240
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
241
|
+
<Tooltip.Target>
|
|
242
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
243
|
+
</Tooltip.Target>
|
|
244
|
+
<Tooltip.Content>
|
|
245
|
+
<p>Fill the polygon area with color. When off, only the outline is shown.</p>
|
|
246
|
+
</Tooltip.Content>
|
|
247
|
+
</Tooltip>
|
|
248
|
+
}
|
|
249
|
+
/>
|
|
250
|
+
|
|
251
|
+
{(radar.showFill ?? false) && (
|
|
252
|
+
<TextField
|
|
253
|
+
type='number'
|
|
254
|
+
value={radar.fillOpacity ?? 0.3}
|
|
255
|
+
fieldName='fillOpacity'
|
|
256
|
+
section='radar'
|
|
257
|
+
label='Fill Opacity'
|
|
258
|
+
updateField={updateField}
|
|
259
|
+
min={0}
|
|
260
|
+
max={1}
|
|
261
|
+
step={0.1}
|
|
262
|
+
tooltip={
|
|
263
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
264
|
+
<Tooltip.Target>
|
|
265
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
266
|
+
</Tooltip.Target>
|
|
267
|
+
<Tooltip.Content>
|
|
268
|
+
<p>Opacity of the polygon fill (0 = transparent, 1 = solid)</p>
|
|
269
|
+
</Tooltip.Content>
|
|
270
|
+
</Tooltip>
|
|
271
|
+
}
|
|
272
|
+
/>
|
|
273
|
+
)}
|
|
274
|
+
|
|
275
|
+
<TextField
|
|
276
|
+
type='number'
|
|
277
|
+
value={radar.strokeWidth ?? 2}
|
|
278
|
+
fieldName='strokeWidth'
|
|
279
|
+
section='radar'
|
|
280
|
+
label='Stroke Width'
|
|
281
|
+
updateField={updateField}
|
|
282
|
+
min={1}
|
|
283
|
+
max={5}
|
|
284
|
+
tooltip={
|
|
285
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
286
|
+
<Tooltip.Target>
|
|
287
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
288
|
+
</Tooltip.Target>
|
|
289
|
+
<Tooltip.Content>
|
|
290
|
+
<p>Width of the polygon outline</p>
|
|
291
|
+
</Tooltip.Content>
|
|
292
|
+
</Tooltip>
|
|
293
|
+
}
|
|
294
|
+
/>
|
|
295
|
+
|
|
296
|
+
<CheckBox
|
|
297
|
+
value={radar.showPoints ?? true}
|
|
298
|
+
fieldName='showPoints'
|
|
299
|
+
section='radar'
|
|
300
|
+
label='Show Data Points'
|
|
301
|
+
updateField={updateField}
|
|
302
|
+
tooltip={
|
|
303
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
304
|
+
<Tooltip.Target>
|
|
305
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
306
|
+
</Tooltip.Target>
|
|
307
|
+
<Tooltip.Content>
|
|
308
|
+
<p>Display circular markers at each data point vertex</p>
|
|
309
|
+
</Tooltip.Content>
|
|
310
|
+
</Tooltip>
|
|
311
|
+
}
|
|
312
|
+
/>
|
|
313
|
+
|
|
314
|
+
{(radar.showPoints ?? true) && (
|
|
315
|
+
<TextField
|
|
316
|
+
type='number'
|
|
317
|
+
value={radar.pointRadius ?? 4}
|
|
318
|
+
fieldName='pointRadius'
|
|
319
|
+
section='radar'
|
|
320
|
+
label='Point Size'
|
|
321
|
+
updateField={updateField}
|
|
322
|
+
min={2}
|
|
323
|
+
max={10}
|
|
324
|
+
/>
|
|
325
|
+
)}
|
|
326
|
+
|
|
327
|
+
<TextField
|
|
328
|
+
type='number'
|
|
329
|
+
value={radar.axisLabelOffset ?? 15}
|
|
330
|
+
fieldName='axisLabelOffset'
|
|
331
|
+
section='radar'
|
|
332
|
+
label='Axis Label Offset'
|
|
333
|
+
updateField={updateField}
|
|
334
|
+
min={5}
|
|
335
|
+
max={50}
|
|
336
|
+
tooltip={
|
|
337
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
338
|
+
<Tooltip.Target>
|
|
339
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
340
|
+
</Tooltip.Target>
|
|
341
|
+
<Tooltip.Content>
|
|
342
|
+
<p>Distance between axis endpoint and label</p>
|
|
343
|
+
</Tooltip.Content>
|
|
344
|
+
</Tooltip>
|
|
345
|
+
}
|
|
346
|
+
/>
|
|
347
|
+
</fieldset>
|
|
348
|
+
</AccordionItemPanel>
|
|
349
|
+
</AccordionItem>
|
|
350
|
+
)
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export default PanelRadar
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useContext, FC } from 'react'
|
|
1
|
+
import { useContext, FC, useMemo } from 'react'
|
|
2
2
|
import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'
|
|
3
3
|
import {
|
|
4
4
|
AccordionItem,
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { TextField, Select, CheckBox } from '@cdc/core/components/EditorPanel/Inputs'
|
|
12
12
|
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
13
13
|
import Icon from '@cdc/core/components/ui/Icon'
|
|
14
|
+
import { useDataColumns } from '@cdc/core/hooks/useDataColumns'
|
|
14
15
|
|
|
15
16
|
// contexts
|
|
16
17
|
import { ChartContext } from './../../../../types/ChartContext.js'
|
|
@@ -25,30 +26,30 @@ const PanelSmallMultiples: FC<PanelProps> = props => {
|
|
|
25
26
|
const { updateField } = useEditorPanelContext()
|
|
26
27
|
const { visSupportsSmallMultiples } = useEditorPermissions()
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
rawData?.forEach(row => {
|
|
31
|
-
Object.keys(row).forEach(columnName => (columns[columnName] = true))
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
if (filter) {
|
|
35
|
-
const { lower, upper } = config.confidenceKeys || {}
|
|
36
|
-
Object.keys(columns).forEach(key => {
|
|
37
|
-
if (
|
|
38
|
-
(config.series && config.series.filter(series => series.dataKey === key).length > 0) ||
|
|
39
|
-
(config.confidenceKeys &&
|
|
40
|
-
Object.keys(config.confidenceKeys).includes(key) &&
|
|
41
|
-
((lower && upper) || lower || upper) &&
|
|
42
|
-
key !== lower &&
|
|
43
|
-
key !== upper)
|
|
44
|
-
) {
|
|
45
|
-
delete columns[key]
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
}
|
|
29
|
+
// Extract column names from data with memoization (replaces getColumns)
|
|
30
|
+
const allColumns = useDataColumns(rawData)
|
|
49
31
|
|
|
50
|
-
|
|
51
|
-
|
|
32
|
+
// Filter out series columns and confidence key columns (except lower and upper)
|
|
33
|
+
const filteredColumns = useMemo(() => {
|
|
34
|
+
const { lower, upper } = config.confidenceKeys || {}
|
|
35
|
+
return allColumns.filter(key => {
|
|
36
|
+
// Filter out series columns
|
|
37
|
+
if (config.series && config.series.some(series => series.dataKey === key)) {
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
40
|
+
// Filter out confidence key columns (except lower and upper)
|
|
41
|
+
if (
|
|
42
|
+
config.confidenceKeys &&
|
|
43
|
+
Object.keys(config.confidenceKeys).includes(key) &&
|
|
44
|
+
((lower && upper) || lower || upper) &&
|
|
45
|
+
key !== lower &&
|
|
46
|
+
key !== upper
|
|
47
|
+
) {
|
|
48
|
+
return false
|
|
49
|
+
}
|
|
50
|
+
return true
|
|
51
|
+
})
|
|
52
|
+
}, [allColumns, config.series, config.confidenceKeys])
|
|
52
53
|
|
|
53
54
|
return (
|
|
54
55
|
<>
|
|
@@ -91,7 +92,7 @@ const PanelSmallMultiples: FC<PanelProps> = props => {
|
|
|
91
92
|
label='Tile By Column'
|
|
92
93
|
initial='Select Column'
|
|
93
94
|
updateField={updateField}
|
|
94
|
-
options={
|
|
95
|
+
options={filteredColumns}
|
|
95
96
|
/>
|
|
96
97
|
)}
|
|
97
98
|
|
|
@@ -184,6 +185,8 @@ const PanelSmallMultiples: FC<PanelProps> = props => {
|
|
|
184
185
|
value={currentOrderType}
|
|
185
186
|
options={tileOrderOptions}
|
|
186
187
|
label='Tile Order'
|
|
188
|
+
fieldName='tileOrderType'
|
|
189
|
+
section='smallMultiples'
|
|
187
190
|
updateField={(_section, _subsection, _fieldName, value) => {
|
|
188
191
|
handleOrderTypeChange(value)
|
|
189
192
|
}}
|
|
@@ -244,6 +247,8 @@ const PanelSmallMultiples: FC<PanelProps> = props => {
|
|
|
244
247
|
}
|
|
245
248
|
]}
|
|
246
249
|
label='Color Mode'
|
|
250
|
+
fieldName='colorMode'
|
|
251
|
+
section='smallMultiples'
|
|
247
252
|
updateField={(_section, _subsection, _fieldName, value) => {
|
|
248
253
|
updateConfig({
|
|
249
254
|
...config,
|
|
@@ -241,6 +241,27 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
241
241
|
updateField={updateField}
|
|
242
242
|
options={['Same as Line', 'Lighter than Line']}
|
|
243
243
|
/>
|
|
244
|
+
<CheckBox
|
|
245
|
+
value={config.general?.useIntelligentLineChartLabels ?? false}
|
|
246
|
+
section='general'
|
|
247
|
+
fieldName='useIntelligentLineChartLabels'
|
|
248
|
+
label='Use Intelligent Label Positioning'
|
|
249
|
+
updateField={updateField}
|
|
250
|
+
tooltip={
|
|
251
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
252
|
+
<Tooltip.Target>
|
|
253
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
254
|
+
</Tooltip.Target>
|
|
255
|
+
<Tooltip.Content>
|
|
256
|
+
<p>
|
|
257
|
+
Automatically positions data labels to avoid overlapping with line segments based on the direction
|
|
258
|
+
and location of data points. When disabled, all labels are positioned above and centered on their
|
|
259
|
+
data points.
|
|
260
|
+
</p>
|
|
261
|
+
</Tooltip.Content>
|
|
262
|
+
</Tooltip>
|
|
263
|
+
}
|
|
264
|
+
/>
|
|
244
265
|
<CheckBox
|
|
245
266
|
value={!(config as LineChartConfig).isolatedDotsSameSize}
|
|
246
267
|
fieldName='isolatedDotsSameSize'
|
|
@@ -319,16 +340,21 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
319
340
|
colorIndices={[2, 4, 6]}
|
|
320
341
|
className='color-palette'
|
|
321
342
|
/>
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
343
|
+
|
|
344
|
+
{config.visualizationType !== 'Warming Stripes' && (
|
|
345
|
+
<>
|
|
346
|
+
<span>Colorblind Safe</span>
|
|
347
|
+
<PaletteSelector
|
|
348
|
+
palettes={accessibleColors}
|
|
349
|
+
colorPalettes={colorPalettes}
|
|
350
|
+
config={config}
|
|
351
|
+
onPaletteSelect={handlePaletteSelection}
|
|
352
|
+
selectedPalette={getCurrentPaletteName(config)}
|
|
353
|
+
colorIndices={[2, 3, 5]}
|
|
354
|
+
className='color-palette'
|
|
355
|
+
/>
|
|
356
|
+
</>
|
|
357
|
+
)}
|
|
332
358
|
</>
|
|
333
359
|
)}
|
|
334
360
|
|
|
@@ -393,7 +419,6 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
393
419
|
}}
|
|
394
420
|
label='Custom Color Order'
|
|
395
421
|
minColors={1}
|
|
396
|
-
maxColors={20}
|
|
397
422
|
/>
|
|
398
423
|
</div>
|
|
399
424
|
)}
|
|
@@ -516,28 +541,17 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
516
541
|
/>
|
|
517
542
|
</>
|
|
518
543
|
)}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
config.yAxis.labelPlacement !== 'On Bar' && (
|
|
544
|
+
|
|
545
|
+
{(config.orientation !== 'horizontal' || config.visualizationType === 'Combo') &&
|
|
546
|
+
config.visualizationType !== 'Warming Stripes' && (
|
|
523
547
|
<TextField
|
|
548
|
+
value={config.barThickness}
|
|
524
549
|
type='number'
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
label=' Bar Thickness'
|
|
550
|
+
fieldName='barThickness'
|
|
551
|
+
label='Bar Thickness'
|
|
528
552
|
updateField={updateField}
|
|
529
|
-
min={15}
|
|
530
553
|
/>
|
|
531
554
|
)}
|
|
532
|
-
{(config.orientation !== 'horizontal' || config.visualizationType === 'Combo') && (
|
|
533
|
-
<TextField
|
|
534
|
-
value={config.barThickness}
|
|
535
|
-
type='number'
|
|
536
|
-
fieldName='barThickness'
|
|
537
|
-
label='Bar Thickness'
|
|
538
|
-
updateField={updateField}
|
|
539
|
-
/>
|
|
540
|
-
)}
|
|
541
555
|
{visSupportsBarSpace() && (
|
|
542
556
|
<TextField
|
|
543
557
|
type='number'
|
|
@@ -5,6 +5,7 @@ import General from './Panel.General'
|
|
|
5
5
|
import BoxPlot from './Panel.BoxPlot'
|
|
6
6
|
import Visual from './Panel.Visual'
|
|
7
7
|
import Sankey from './Panel.Sankey'
|
|
8
|
+
import Radar from './Panel.Radar'
|
|
8
9
|
import Annotate from './Panel.Annotate'
|
|
9
10
|
import PatternSettings from './Panel.PatternSettings'
|
|
10
11
|
import SmallMultiples from './Panel.SmallMultiples'
|
|
@@ -17,6 +18,7 @@ const Panels = {
|
|
|
17
18
|
BoxPlot,
|
|
18
19
|
Visual,
|
|
19
20
|
Sankey,
|
|
21
|
+
Radar,
|
|
20
22
|
Annotate,
|
|
21
23
|
PatternSettings,
|
|
22
24
|
SmallMultiples
|