@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
|
@@ -274,16 +274,7 @@ export const useEditorPermissions = () => {
|
|
|
274
274
|
}
|
|
275
275
|
|
|
276
276
|
const visSupportsRegions = () => {
|
|
277
|
-
const disabledCharts = [
|
|
278
|
-
'Forest Plot',
|
|
279
|
-
'Horizon Chart',
|
|
280
|
-
'Pie',
|
|
281
|
-
'Paired Bar',
|
|
282
|
-
'Radar',
|
|
283
|
-
'Spark Line',
|
|
284
|
-
'Sankey',
|
|
285
|
-
'Warming Stripes'
|
|
286
|
-
]
|
|
277
|
+
const disabledCharts = ['Forest Plot', 'Pie', 'Paired Bar', 'Radar', 'Spark Line', 'Sankey', 'Warming Stripes']
|
|
287
278
|
if (disabledCharts.includes(visualizationType)) return false
|
|
288
279
|
return true
|
|
289
280
|
}
|
|
@@ -110,7 +110,7 @@ const prepareForecastData = (
|
|
|
110
110
|
return segments.length > 0 ? segments : [sortedData]
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
const Forecasting = ({ xScale, yScale, height, width, handleTooltipMouseOver, handleTooltipMouseOff }) => {
|
|
113
|
+
const Forecasting = ({ xScale, yScale, height, width, yAxisWidth, handleTooltipMouseOver, handleTooltipMouseOff }) => {
|
|
114
114
|
const { transformedData: data, rawData, config, seriesHighlight, parseDate } = useContext(ConfigContext)
|
|
115
115
|
const { xAxis, yAxis, legend, runtime } = config
|
|
116
116
|
const DEBUG = false
|
|
@@ -143,7 +143,7 @@ const Forecasting = ({ xScale, yScale, height, width, handleTooltipMouseOver, ha
|
|
|
143
143
|
return (
|
|
144
144
|
data && (
|
|
145
145
|
<ErrorBoundary component='ForecastingChart'>
|
|
146
|
-
<Group className='forecasting-items' key='forecasting-items-wrapper' left={
|
|
146
|
+
<Group className='forecasting-items' key='forecasting-items-wrapper' left={yAxisWidth}>
|
|
147
147
|
{runtime.forecastingSeriesKeys?.map((group, index) => {
|
|
148
148
|
if (!group || !group.stages) return false
|
|
149
149
|
return group.stages.map((stage, stageIndex) => {
|
|
@@ -26,7 +26,7 @@ const ForestPlot = ({
|
|
|
26
26
|
handleTooltipMouseOver,
|
|
27
27
|
forestPlotRightLabelRef
|
|
28
28
|
}: ForestPlotProps) => {
|
|
29
|
-
const {
|
|
29
|
+
const { transformedData: data, updateConfig } = useContext<ChartContext>(ConfigContext)
|
|
30
30
|
const { forestPlot } = config as ChartConfig
|
|
31
31
|
const labelPosition = config.xAxis.tickWidthMax + 10
|
|
32
32
|
const [initialLogTicksSet, setInitialLogTicks] = useState(false)
|
|
@@ -90,7 +90,9 @@ const ForestPlot = ({
|
|
|
90
90
|
}
|
|
91
91
|
}, [config.forestPlot.type])
|
|
92
92
|
|
|
93
|
-
const pooledData =
|
|
93
|
+
const pooledData = data.find(d => d[config.xAxis.dataKey] === config.forestPlot.pooledResult.column)
|
|
94
|
+
const [plotStart, plotEnd] = [...xScale.range()].sort((a, b) => a - b)
|
|
95
|
+
const plotWidth = plotEnd - plotStart
|
|
94
96
|
|
|
95
97
|
const regressionPoints = pooledData
|
|
96
98
|
? [
|
|
@@ -112,12 +114,12 @@ const ForestPlot = ({
|
|
|
112
114
|
|
|
113
115
|
const topLine = [
|
|
114
116
|
{ x: 0, y: topMarginOffset },
|
|
115
|
-
{ x:
|
|
117
|
+
{ x: plotEnd, y: topMarginOffset }
|
|
116
118
|
]
|
|
117
119
|
|
|
118
120
|
const bottomLine = [
|
|
119
121
|
{ x: 0, y: height },
|
|
120
|
-
{ x:
|
|
122
|
+
{ x: plotEnd, y: height }
|
|
121
123
|
]
|
|
122
124
|
|
|
123
125
|
type Columns = {
|
|
@@ -289,30 +291,21 @@ const ForestPlot = ({
|
|
|
289
291
|
{forestPlot.regression.description}
|
|
290
292
|
</Text>
|
|
291
293
|
)}
|
|
292
|
-
|
|
293
|
-
<Bar
|
|
294
|
-
key='forest-plot-tooltip-area'
|
|
295
|
-
className='forest-plot-tooltip-area'
|
|
296
|
-
width={width}
|
|
297
|
-
height={height}
|
|
298
|
-
fill={false ? 'red' : 'transparent'}
|
|
299
|
-
fillOpacity={0.5}
|
|
300
|
-
onMouseMove={e => handleTooltipMouseOver(e, data)}
|
|
301
|
-
onMouseOut={handleTooltipMouseOff}
|
|
302
|
-
/>
|
|
303
294
|
</Group>
|
|
304
295
|
<Line
|
|
305
296
|
from={topLine[0]}
|
|
306
297
|
to={topLine[1]}
|
|
307
|
-
style={{ stroke: '
|
|
298
|
+
style={{ stroke: '#333', strokeWidth: 1 }}
|
|
308
299
|
className='forestplot__top-line'
|
|
309
300
|
/>
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
301
|
+
{config.xAxis.hideAxis && (
|
|
302
|
+
<Line
|
|
303
|
+
from={bottomLine[0]}
|
|
304
|
+
to={bottomLine[1]}
|
|
305
|
+
style={{ stroke: '#333', strokeWidth: 1 }}
|
|
306
|
+
className='forestplot__bottom-line'
|
|
307
|
+
/>
|
|
308
|
+
)}
|
|
316
309
|
|
|
317
310
|
{/* column data */}
|
|
318
311
|
{columnsOnChart.map((column, colIndex) => {
|
|
@@ -400,6 +393,17 @@ const ForestPlot = ({
|
|
|
400
393
|
{forestPlot.rightLabel}
|
|
401
394
|
</Text>
|
|
402
395
|
)}
|
|
396
|
+
<Bar
|
|
397
|
+
key='forest-plot-tooltip-area'
|
|
398
|
+
className='forest-plot-tooltip-area'
|
|
399
|
+
x={0}
|
|
400
|
+
width={width}
|
|
401
|
+
height={height}
|
|
402
|
+
fill={false ? 'red' : 'transparent'}
|
|
403
|
+
fillOpacity={0.5}
|
|
404
|
+
onMouseMove={e => handleTooltipMouseOver(e, data)}
|
|
405
|
+
onMouseOut={handleTooltipMouseOff}
|
|
406
|
+
/>
|
|
403
407
|
</>
|
|
404
408
|
)
|
|
405
409
|
}
|
|
@@ -23,13 +23,21 @@ type HorizonChartProps = {
|
|
|
23
23
|
yScale: any
|
|
24
24
|
xMax: number
|
|
25
25
|
yMax: number
|
|
26
|
+
yAxisWidth: number
|
|
26
27
|
handleTooltipMouseOver: (e: any, additionalData?: any) => void
|
|
27
28
|
handleTooltipMouseOff: () => void
|
|
28
29
|
tooltipData?: any
|
|
29
30
|
showTooltip?: boolean
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
const HorizonChart = ({
|
|
33
|
+
const HorizonChart = ({
|
|
34
|
+
xScale,
|
|
35
|
+
xMax,
|
|
36
|
+
yMax,
|
|
37
|
+
yAxisWidth,
|
|
38
|
+
handleTooltipMouseOver,
|
|
39
|
+
handleTooltipMouseOff
|
|
40
|
+
}: HorizonChartProps) => {
|
|
33
41
|
// Get data and config from context
|
|
34
42
|
const { transformedData: data, config, colorScale, rawData, parseDate } = useContext(ConfigContext)
|
|
35
43
|
|
|
@@ -94,7 +102,7 @@ const HorizonChart = ({ xScale, xMax, yMax, handleTooltipMouseOver, handleToolti
|
|
|
94
102
|
|
|
95
103
|
return (
|
|
96
104
|
<ErrorBoundary component='HorizonChart'>
|
|
97
|
-
<Group className='horizon-chart' key='horizon-wrapper' left={
|
|
105
|
+
<Group className='horizon-chart' key='horizon-wrapper' left={yAxisWidth} height={Number(yMax)}>
|
|
98
106
|
{seriesKeys.map((seriesKey, index) => {
|
|
99
107
|
const rowY = getRowY(index)
|
|
100
108
|
return (
|
|
@@ -9,9 +9,10 @@ type HoverLineProps = {
|
|
|
9
9
|
yMax?: number
|
|
10
10
|
point: { x: number; y: number }
|
|
11
11
|
orientation: 'horizontal' | 'vertical'
|
|
12
|
+
yAxisWidth: number
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
const HoverLine: React.FC<HoverLineProps> = ({ tooltipData, xMax, yMax, point, orientation }) => {
|
|
15
|
+
const HoverLine: React.FC<HoverLineProps> = ({ tooltipData, xMax, yMax, point, orientation, yAxisWidth }) => {
|
|
15
16
|
const { config } = useContext(ConfigContext)
|
|
16
17
|
const { verticalHoverLine, horizontalHoverLine } = config.visual
|
|
17
18
|
const { visualizationType } = config
|
|
@@ -23,8 +24,9 @@ const HoverLine: React.FC<HoverLineProps> = ({ tooltipData, xMax, yMax, point, o
|
|
|
23
24
|
const showHorizontalHoverLine = horizontalHoverLine || (horizontalHoverLine && isScatterPlot)
|
|
24
25
|
|
|
25
26
|
const getX = () => {
|
|
26
|
-
if (point.x
|
|
27
|
-
if (
|
|
27
|
+
if (point.x < yAxisWidth) return yAxisWidth
|
|
28
|
+
if (xMax === undefined) return point.x
|
|
29
|
+
if (point.x > xMax + yAxisWidth) return xMax + yAxisWidth
|
|
28
30
|
return point.x
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -52,11 +54,7 @@ const HoverLine: React.FC<HoverLineProps> = ({ tooltipData, xMax, yMax, point, o
|
|
|
52
54
|
if (isHorizontal) {
|
|
53
55
|
return (
|
|
54
56
|
showHorizontalHoverLine && (
|
|
55
|
-
<Group
|
|
56
|
-
key={`tooltipLine-horizontal${point.y}${point.x}`}
|
|
57
|
-
className='horizontal-tooltip-line'
|
|
58
|
-
left={config.yAxis.size ? config.yAxis.size : 0}
|
|
59
|
-
>
|
|
57
|
+
<Group key={`tooltipLine-horizontal${point.y}${point.x}`} className='horizontal-tooltip-line' left={yAxisWidth}>
|
|
60
58
|
<Line
|
|
61
59
|
from={{ x: 0, y: getY() }}
|
|
62
60
|
to={{ x: xMax, y: getY() }}
|
|
@@ -117,8 +117,8 @@ const Legend: React.FC<LegendProps> = forwardRef(
|
|
|
117
117
|
>
|
|
118
118
|
{(legend.label || legend.description) && (
|
|
119
119
|
<div className={legend.description ? 'mb-3' : 'mb-2'}>
|
|
120
|
-
{legend.label && <h3 className='fw-bold'>{parse(legend.label)}</h3>}
|
|
121
|
-
{legend.description && <p className='mt-2'>{parse(legend.description)}</p>}
|
|
120
|
+
{legend.label && <h3 className='fw-bold cove-prose'>{parse(legend.label)}</h3>}
|
|
121
|
+
{legend.description && <p className='mt-2 cove-prose'>{parse(legend.description)}</p>}
|
|
122
122
|
</div>
|
|
123
123
|
)}
|
|
124
124
|
<LegendGradient
|
|
@@ -242,7 +242,7 @@ const Legend: React.FC<LegendProps> = forwardRef(
|
|
|
242
242
|
</>
|
|
243
243
|
)}
|
|
244
244
|
</>
|
|
245
|
-
<LegendLabel align='left' className='m-0'>
|
|
245
|
+
<LegendLabel align='left' className='m-0 cove-prose'>
|
|
246
246
|
{parse(label.text)}
|
|
247
247
|
</LegendLabel>
|
|
248
248
|
</LegendItem>
|
|
@@ -361,7 +361,7 @@ const Legend: React.FC<LegendProps> = forwardRef(
|
|
|
361
361
|
/>
|
|
362
362
|
</svg>
|
|
363
363
|
</span>
|
|
364
|
-
<LegendLabel align='left' className='m-0'>
|
|
364
|
+
<LegendLabel align='left' className='m-0 cove-prose'>
|
|
365
365
|
{parse(String((pattern as any)?.label || key))}
|
|
366
366
|
</LegendLabel>
|
|
367
367
|
</LegendItem>
|
|
@@ -6,25 +6,30 @@
|
|
|
6
6
|
margin-bottom: 0.5rem;
|
|
7
7
|
|
|
8
8
|
.group-item .visx-legend-label {
|
|
9
|
-
font-weight: 400;
|
|
10
9
|
font-size: 0.889rem;
|
|
10
|
+
font-weight: 400;
|
|
11
11
|
margin-bottom: 0.5rem;
|
|
12
12
|
}
|
|
13
13
|
.group-label {
|
|
14
|
-
font-weight: 500;
|
|
15
14
|
font-family: Nunito, sans-serif;
|
|
16
15
|
font-size: 1rem;
|
|
16
|
+
font-weight: 500;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
.legend-group-grid {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-wrap: wrap;
|
|
23
|
+
}
|
|
24
|
+
|
|
20
25
|
.legend-group.top,
|
|
21
26
|
.legend-group.bottom {
|
|
22
27
|
grid-gap: 10px;
|
|
23
28
|
|
|
24
29
|
&.group-item {
|
|
30
|
+
align-items: flex-start;
|
|
25
31
|
display: flex;
|
|
26
32
|
flex-direction: column;
|
|
27
|
-
align-items: flex-start;
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
& .inactive {
|
|
@@ -32,9 +37,9 @@
|
|
|
32
37
|
transition: 0.2s all;
|
|
33
38
|
}
|
|
34
39
|
& .highlighted {
|
|
40
|
+
border-radius: 1px;
|
|
35
41
|
outline: 1px solid #005ea2;
|
|
36
42
|
outline-offset: 5px;
|
|
37
|
-
border-radius: 1px;
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
}
|
|
@@ -32,7 +32,7 @@ const LegendGroup = ({ formatLabels }) => {
|
|
|
32
32
|
|
|
33
33
|
const groups: string[] = getSubGroups(data, config.legend.groupBy)
|
|
34
34
|
|
|
35
|
-
const classNames = ['legend-group', 'container', config.legend.position, currentViewport
|
|
35
|
+
const classNames = ['legend-group', 'legend-group-grid', 'container', config.legend.position, currentViewport]
|
|
36
36
|
|
|
37
37
|
const gridCol =
|
|
38
38
|
currentViewport === 'xs'
|
|
@@ -47,6 +47,8 @@ const LegendGroup = ({ formatLabels }) => {
|
|
|
47
47
|
|
|
48
48
|
let classNameItem = ['legend-group group-item', isSigleCol]
|
|
49
49
|
|
|
50
|
+
if (groups.length === 0) return null
|
|
51
|
+
|
|
50
52
|
return (
|
|
51
53
|
<div className={classNames.join(' ')}>
|
|
52
54
|
{groups.map(group => {
|
|
@@ -17,7 +17,8 @@ import { FaStar } from 'react-icons/fa'
|
|
|
17
17
|
import { Label } from '../../../types/Label'
|
|
18
18
|
import { ColorScale, TransformedData } from '../../../types/ChartContext'
|
|
19
19
|
import { ChartConfig } from '../../../types/ChartConfig'
|
|
20
|
-
import
|
|
20
|
+
import cloneDeep from 'lodash/cloneDeep'
|
|
21
|
+
import sortBy from 'lodash/sortBy'
|
|
21
22
|
import { scaleSequential } from 'd3-scale'
|
|
22
23
|
import { interpolateRgbBasis } from 'd3-interpolate'
|
|
23
24
|
import { filterChartColorPalettes } from '@cdc/core/helpers/filterColorPalettes'
|
|
@@ -173,7 +174,7 @@ export const createFormatLabels =
|
|
|
173
174
|
|
|
174
175
|
const sortVertical = labels =>
|
|
175
176
|
legend.verticalSorted
|
|
176
|
-
?
|
|
177
|
+
? sortBy(cloneDeep(labels), label => {
|
|
177
178
|
const match = label.datum?.match(/-?\d+(\.\d+)?/)
|
|
178
179
|
return match ? parseFloat(match[0]) : Number.MAX_SAFE_INTEGER
|
|
179
180
|
})
|
|
@@ -40,8 +40,6 @@ export const getMarginBottom = (isLegendBottom, config) => {
|
|
|
40
40
|
|
|
41
41
|
if (isLegendTop) marginBottom = 27
|
|
42
42
|
|
|
43
|
-
if (isLegendTop && config.yAxis?.inlineLabel) marginBottom += 9
|
|
44
|
-
|
|
45
43
|
if (isLegendBottom) marginBottom += 9
|
|
46
44
|
|
|
47
45
|
if (hasSuppression) marginBottom += 40
|
|
@@ -10,10 +10,11 @@ type LineChartBumpCircleProp = {
|
|
|
10
10
|
xScale: any
|
|
11
11
|
yScale: any
|
|
12
12
|
parseDate: any
|
|
13
|
+
yAxisWidth: number
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
const LineChartBumpCircle = (props: LineChartBumpCircleProp) => {
|
|
16
|
-
const { config, xScale, yScale, parseDate } = props
|
|
17
|
+
const { config, xScale, yScale, parseDate, yAxisWidth } = props
|
|
17
18
|
|
|
18
19
|
// get xScale and yScale...
|
|
19
20
|
if (!config?.runtime?.series) return
|
|
@@ -55,7 +56,7 @@ const LineChartBumpCircle = (props: LineChartBumpCircleProp) => {
|
|
|
55
56
|
let axis_dataKey = d[config.xAxis.dataKey]
|
|
56
57
|
return (
|
|
57
58
|
<React.Fragment key={`bump-circle-${series_dataKey}-${dataIndex}`}>
|
|
58
|
-
<Group left={
|
|
59
|
+
<Group left={yAxisWidth}>
|
|
59
60
|
{series_dataKey && (
|
|
60
61
|
<>
|
|
61
62
|
<circle
|
|
@@ -36,6 +36,7 @@ const LineChart = (props: LineChartProps) => {
|
|
|
36
36
|
xScale,
|
|
37
37
|
yMax,
|
|
38
38
|
yScale,
|
|
39
|
+
yAxisWidth,
|
|
39
40
|
} = props
|
|
40
41
|
|
|
41
42
|
// prettier-ignore
|
|
@@ -55,7 +56,7 @@ const LineChart = (props: LineChartProps) => {
|
|
|
55
56
|
|
|
56
57
|
return (
|
|
57
58
|
<ErrorBoundary component='LineChart'>
|
|
58
|
-
<Group left={
|
|
59
|
+
<Group left={yAxisWidth} className='line-chart-group'>
|
|
59
60
|
{/* left - expects a number not a string */}
|
|
60
61
|
{(config.runtime.lineSeriesKeys || config.runtime.seriesKeys).map((seriesKey, index) => {
|
|
61
62
|
const seriesData = config.runtime.series.find(item => item.dataKey === seriesKey)
|
|
@@ -264,7 +265,7 @@ const LineChart = (props: LineChartProps) => {
|
|
|
264
265
|
}
|
|
265
266
|
styles={createStyles({
|
|
266
267
|
preliminaryData: config.preliminaryData,
|
|
267
|
-
data:
|
|
268
|
+
data: _data,
|
|
268
269
|
stroke: colorScale(config.runtime.seriesLabels[seriesKey]),
|
|
269
270
|
strokeWidth: seriesData.weight || 2,
|
|
270
271
|
handleLineType,
|
|
@@ -496,7 +497,7 @@ const LineChart = (props: LineChartProps) => {
|
|
|
496
497
|
</Text>
|
|
497
498
|
)}
|
|
498
499
|
</Group>
|
|
499
|
-
<Group left={
|
|
500
|
+
<Group left={yAxisWidth} className='glyph-tooltip-group'>
|
|
500
501
|
<Group key={`tooltip-group`} display={'block'}>
|
|
501
502
|
{/* tooltips */}
|
|
502
503
|
<Bar
|
|
@@ -543,7 +544,13 @@ const LineChart = (props: LineChartProps) => {
|
|
|
543
544
|
</Group>
|
|
544
545
|
</Group>
|
|
545
546
|
{config.visualizationType === 'Bump Chart' && (
|
|
546
|
-
<LineChartBumpCircle
|
|
547
|
+
<LineChartBumpCircle
|
|
548
|
+
config={config}
|
|
549
|
+
xScale={xScale}
|
|
550
|
+
yScale={yScale}
|
|
551
|
+
parseDate={parseDate}
|
|
552
|
+
yAxisWidth={yAxisWidth}
|
|
553
|
+
/>
|
|
547
554
|
)}
|
|
548
555
|
</ErrorBoundary>
|
|
549
556
|
)
|
|
@@ -76,13 +76,16 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
|
|
|
76
76
|
)}
|
|
77
77
|
|
|
78
78
|
{/* Paired Bar Chart */}
|
|
79
|
-
{visualizationType === 'Paired Bar' &&
|
|
79
|
+
{visualizationType === 'Paired Bar' && (
|
|
80
|
+
<PairedBarChart originalWidth={parentWidth} width={xMax} height={yMax} yAxisWidth={yAxisWidth} />
|
|
81
|
+
)}
|
|
80
82
|
|
|
81
83
|
{/* Scatter Plot */}
|
|
82
84
|
{visualizationType === 'Scatter Plot' && (
|
|
83
85
|
<ScatterPlot
|
|
84
86
|
xScale={xScale}
|
|
85
87
|
yScale={yScale}
|
|
88
|
+
yAxisWidth={yAxisWidth}
|
|
86
89
|
getXAxisData={getXAxisData}
|
|
87
90
|
getYAxisData={getYAxisData}
|
|
88
91
|
xMax={xMax}
|
|
@@ -102,6 +105,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
|
|
|
102
105
|
yScale={yScale}
|
|
103
106
|
xMax={xMax}
|
|
104
107
|
yMax={yMax}
|
|
108
|
+
yAxisWidth={yAxisWidth}
|
|
105
109
|
synchronizedXValue={synchronizedXValue}
|
|
106
110
|
showTooltip={showTooltip}
|
|
107
111
|
handleTooltipMouseOff={handleTooltipMouseOff}
|
|
@@ -115,6 +119,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
|
|
|
115
119
|
yScale={yScale}
|
|
116
120
|
xMax={xMax}
|
|
117
121
|
yMax={yMax}
|
|
122
|
+
yAxisWidth={yAxisWidth}
|
|
118
123
|
handleTooltipMouseOver={handleTooltipMouseOver}
|
|
119
124
|
handleTooltipMouseOff={handleTooltipMouseOff}
|
|
120
125
|
tooltipData={tooltipData}
|
|
@@ -132,6 +137,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
|
|
|
132
137
|
max={max}
|
|
133
138
|
xScale={xScale}
|
|
134
139
|
yScale={yScale}
|
|
140
|
+
yAxisWidth={yAxisWidth}
|
|
135
141
|
/>
|
|
136
142
|
)}
|
|
137
143
|
|
|
@@ -156,6 +162,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
|
|
|
156
162
|
yScale={yScale}
|
|
157
163
|
yMax={yMax}
|
|
158
164
|
xMax={xMax}
|
|
165
|
+
yAxisWidth={yAxisWidth}
|
|
159
166
|
chartRef={svgRef}
|
|
160
167
|
width={xMax}
|
|
161
168
|
height={yMax}
|
|
@@ -193,6 +200,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
|
|
|
193
200
|
<LineChart
|
|
194
201
|
xScale={xScale}
|
|
195
202
|
yScale={yScale}
|
|
203
|
+
yAxisWidth={yAxisWidth}
|
|
196
204
|
getXAxisData={getXAxisData}
|
|
197
205
|
getYAxisData={getYAxisData}
|
|
198
206
|
xMax={xMax}
|
|
@@ -211,6 +219,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
|
|
|
211
219
|
<LineChart
|
|
212
220
|
xScale={xScale}
|
|
213
221
|
yScale={yScale}
|
|
222
|
+
yAxisWidth={yAxisWidth}
|
|
214
223
|
getXAxisData={getXAxisData}
|
|
215
224
|
getYAxisData={getYAxisData}
|
|
216
225
|
xMax={xMax}
|
|
@@ -229,6 +238,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
|
|
|
229
238
|
tooltipData={tooltipData}
|
|
230
239
|
xScale={xScale}
|
|
231
240
|
yScale={yScale}
|
|
241
|
+
yAxisWidth={yAxisWidth}
|
|
232
242
|
width={xMax}
|
|
233
243
|
height={yMax}
|
|
234
244
|
xScaleNoPadding={xScaleNoPadding}
|