@cdc/chart 4.23.11 → 4.24.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/dist/cdcchart.js +35740 -35027
- package/examples/feature/bar/additional-column-tooltip.json +446 -0
- package/examples/feature/bar/tall-data.json +98 -0
- package/examples/feature/forest-plot/forest-plot.json +63 -19
- package/examples/feature/forest-plot/linear.json +52 -3
- package/examples/feature/forest-plot/log.json +26 -0
- package/examples/feature/forest-plot/logarithmic.json +0 -35
- package/examples/feature/line/line-chart-preliminary.json +393 -0
- package/examples/feature/regions/index.json +9 -5
- package/examples/feature/scatterplot/scatterplot.json +272 -33
- package/index.html +10 -8
- package/package.json +2 -2
- package/src/CdcChart.tsx +70 -234
- package/src/ConfigContext.tsx +6 -0
- package/src/_stories/ChartEditor.stories.tsx +22 -0
- package/src/_stories/ChartLine.preliminary.tsx +19 -0
- package/src/_stories/_mock/pie_config.json +192 -0
- package/src/_stories/_mock/pie_data.json +218 -0
- package/src/_stories/_mock/preliminary_mock.json +346 -0
- package/src/components/{AreaChart.Stacked.jsx → AreaChart/components/AreaChart.Stacked.jsx} +2 -2
- package/src/components/{AreaChart.jsx → AreaChart/components/AreaChart.jsx} +2 -26
- package/src/components/AreaChart/index.tsx +4 -0
- package/src/components/{BarChart.Horizontal.tsx → BarChart/components/BarChart.Horizontal.tsx} +8 -8
- package/src/components/{BarChart.StackedHorizontal.tsx → BarChart/components/BarChart.StackedHorizontal.tsx} +37 -7
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +108 -0
- package/src/components/{BarChart.Vertical.tsx → BarChart/components/BarChart.Vertical.tsx} +53 -70
- package/src/components/BarChart/components/BarChart.jsx +39 -0
- package/src/components/{BarChartType.jsx → BarChart/components/BarChartType.jsx} +0 -2
- package/src/components/BarChart/components/context.tsx +13 -0
- package/src/components/BarChart/index.tsx +3 -0
- package/src/components/{BoxPlot.jsx → BoxPlot/BoxPlot.jsx} +10 -9
- package/src/components/BoxPlot/index.tsx +3 -0
- package/src/components/EditorPanel/EditorPanel.tsx +2776 -0
- package/src/components/EditorPanel/EditorPanelContext.ts +40 -0
- package/src/components/EditorPanel/components/PanelProps.ts +3 -0
- package/src/components/EditorPanel/components/Panels/Panel.BoxPlot.tsx +148 -0
- package/src/components/{ForestPlotSettings.jsx → EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx} +97 -167
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +160 -0
- package/src/components/EditorPanel/components/Panels/Panel.Regions.tsx +168 -0
- package/src/components/{Series.jsx → EditorPanel/components/Panels/Panel.Series.tsx} +4 -4
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +297 -0
- package/src/components/EditorPanel/components/Panels/index.tsx +17 -0
- package/src/components/EditorPanel/components/panels.scss +72 -0
- package/src/components/EditorPanel/editor-panel.scss +739 -0
- package/src/components/EditorPanel/index.tsx +3 -0
- package/src/{hooks → components/EditorPanel}/useEditorPermissions.js +34 -2
- package/src/components/{Forecasting.jsx → Forecasting/Forecasting.jsx} +1 -1
- package/src/components/Forecasting/index.tsx +3 -0
- package/src/components/ForestPlot/ForestPlot.tsx +254 -0
- package/src/components/ForestPlot/ForestPlotProps.ts +7 -0
- package/src/components/ForestPlot/index.tsx +1 -209
- package/src/components/Legend/Legend.Component.tsx +199 -0
- package/src/components/Legend/Legend.tsx +28 -0
- package/src/components/Legend/helpers/createFormatLabels.tsx +140 -0
- package/src/components/Legend/index.tsx +3 -0
- package/src/components/LineChart/LineChartProps.ts +29 -0
- package/src/components/LineChart/components/LineChart.Circle.tsx +147 -0
- package/src/components/LineChart/helpers.ts +45 -0
- package/src/components/LineChart/index.tsx +111 -23
- package/src/components/LinearChart.jsx +55 -72
- package/src/components/PairedBarChart.jsx +4 -2
- package/src/components/{PieChart.jsx → PieChart/PieChart.tsx} +93 -31
- package/src/components/PieChart/index.tsx +3 -0
- package/src/components/Regions/components/Regions.tsx +144 -0
- package/src/components/Regions/index.tsx +3 -0
- package/src/components/{ScatterPlot.jsx → ScatterPlot/ScatterPlot.jsx} +3 -3
- package/src/components/ScatterPlot/index.tsx +3 -0
- package/src/components/{SparkLine.jsx → Sparkline/SparkLine.jsx} +2 -2
- package/src/components/Sparkline/index.tsx +3 -0
- package/src/data/initial-state.js +10 -8
- package/src/helpers/abbreviateNumber.ts +17 -0
- package/src/helpers/computeMarginBottom.ts +55 -0
- package/src/helpers/filterData.ts +18 -0
- package/src/helpers/generateColorsArray.ts +8 -0
- package/src/helpers/getQuartiles.ts +30 -0
- package/src/helpers/handleChartAriaLabels.ts +19 -0
- package/src/helpers/handleLineType.ts +18 -0
- package/src/helpers/lineOptions.ts +18 -0
- package/src/helpers/sort.ts +7 -0
- package/src/helpers/tests/computeMarginBottom.test.ts +20 -0
- package/src/hooks/useBarChart.js +7 -6
- package/src/hooks/useHighlightedBars.js +1 -1
- package/src/hooks/useMinMax.ts +3 -3
- package/src/hooks/useScales.ts +19 -6
- package/src/hooks/{useTooltip.jsx → useTooltip.tsx} +31 -25
- package/src/scss/main.scss +0 -3
- package/src/types/ChartConfig.ts +167 -23
- package/src/types/ChartContext.ts +34 -12
- package/src/types/ForestPlot.ts +7 -14
- package/src/types/Label.ts +7 -0
- package/examples/feature/scatterplot/scatterplot-continuous.csv +0 -17
- package/src/ConfigContext.jsx +0 -5
- package/src/components/BarChart.StackedVertical.tsx +0 -91
- package/src/components/BarChart.jsx +0 -30
- package/src/components/EditorPanel.jsx +0 -3356
- package/src/components/ForestPlot/Readme.md +0 -0
- package/src/components/Legend.jsx +0 -310
- package/src/components/LineChart/LineChart.Circle.tsx +0 -105
- package/src/scss/LinearChart.scss +0 -0
- package/src/scss/editor-panel.scss +0 -745
- package/src/scss/legend.scss +0 -206
- package/src/scss/mixins.scss +0 -0
- package/src/scss/variables.scss +0 -1
- package/src/types/ChartProps.ts +0 -7
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react'
|
|
2
|
+
|
|
3
|
+
export type EditorPanelContext = {
|
|
4
|
+
addNewExclusion?: Function
|
|
5
|
+
updateField?: Function
|
|
6
|
+
// warning messages updated within EditorPanel
|
|
7
|
+
warningMsg?: { maxMsg?: string; minMsg?: string; rightMaxMessage?: string; minMsgRight?: string }
|
|
8
|
+
// current enabled chart types in useEditorPermissions file
|
|
9
|
+
enabledChartTypes?: string[]
|
|
10
|
+
showBarStyleOptions?: boolean
|
|
11
|
+
getDataValueOptions?: Function
|
|
12
|
+
data?: object[]
|
|
13
|
+
// function used on inputs, selects, etc. to update config values.
|
|
14
|
+
getColumns?: Function
|
|
15
|
+
getDataValues?: Function
|
|
16
|
+
handleAddNewHighlightedBar?: Function
|
|
17
|
+
handleHighlightedBarLegendLabel?: Function
|
|
18
|
+
handleUpdateHighlightedBar?: Function
|
|
19
|
+
handleUpdateHighlightedBarColor?: Function
|
|
20
|
+
handleUpdateHighlightedBorderWidth?: Function
|
|
21
|
+
highlightedBarValues?: Function
|
|
22
|
+
highlightedSeriesValues?: Function
|
|
23
|
+
isPaletteReversed?: boolean
|
|
24
|
+
handleRemoveHighlightedBar?: Function
|
|
25
|
+
setLollipopShape?: Function
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const EditorPanelContext = createContext<EditorPanelContext>(null)
|
|
29
|
+
|
|
30
|
+
export const useEditorPanelContext = () => {
|
|
31
|
+
const editorPanelCtx = useContext(EditorPanelContext)
|
|
32
|
+
|
|
33
|
+
if (editorPanelCtx === null) {
|
|
34
|
+
throw new Error('COVE: editor panel context is null.')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return editorPanelCtx
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default EditorPanelContext
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { useContext, FC } from 'react'
|
|
2
|
+
import { AccordionItem, AccordionItemHeading, AccordionItemPanel, AccordionItemButton } from 'react-accessible-accordion'
|
|
3
|
+
import { TextField } from '@cdc/core/components/EditorPanel/Inputs'
|
|
4
|
+
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
5
|
+
import Icon from '@cdc/core/components/ui/Icon'
|
|
6
|
+
import ConfigContext from '../../../../ConfigContext'
|
|
7
|
+
import { useEditorPanelContext } from '../../EditorPanelContext'
|
|
8
|
+
|
|
9
|
+
// types
|
|
10
|
+
import { type PanelProps } from './../PanelProps'
|
|
11
|
+
|
|
12
|
+
const PanelBoxPlot: FC<PanelProps> = props => {
|
|
13
|
+
const { config } = useContext(ConfigContext)
|
|
14
|
+
const { boxplot } = config
|
|
15
|
+
if (config.visualizationType !== 'Box Plot') return
|
|
16
|
+
const { updateField } = useEditorPanelContext()
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<AccordionItem>
|
|
20
|
+
<AccordionItemHeading>
|
|
21
|
+
<AccordionItemButton>{props.name}</AccordionItemButton>
|
|
22
|
+
</AccordionItemHeading>
|
|
23
|
+
<AccordionItemPanel>
|
|
24
|
+
<h4 style={{ fontSize: '18px' }}>Labels for 5-Number Summary</h4>
|
|
25
|
+
|
|
26
|
+
{/* max */}
|
|
27
|
+
<TextField
|
|
28
|
+
type='text'
|
|
29
|
+
value={boxplot.labels.maximum}
|
|
30
|
+
fieldName='maximum'
|
|
31
|
+
section='boxplot'
|
|
32
|
+
subsection='labels'
|
|
33
|
+
label='Maximum'
|
|
34
|
+
updateField={updateField}
|
|
35
|
+
tooltip={
|
|
36
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
37
|
+
<Tooltip.Target>
|
|
38
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
39
|
+
</Tooltip.Target>
|
|
40
|
+
<Tooltip.Content>
|
|
41
|
+
<p>Highest value, excluding outliers</p>
|
|
42
|
+
</Tooltip.Content>
|
|
43
|
+
</Tooltip>
|
|
44
|
+
}
|
|
45
|
+
/>
|
|
46
|
+
|
|
47
|
+
{/* Q3 */}
|
|
48
|
+
<TextField
|
|
49
|
+
type='text'
|
|
50
|
+
value={boxplot.labels.q3}
|
|
51
|
+
fieldName='q3'
|
|
52
|
+
section='boxplot'
|
|
53
|
+
subsection='labels'
|
|
54
|
+
label='Upper Quartile'
|
|
55
|
+
updateField={updateField}
|
|
56
|
+
tooltip={
|
|
57
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
58
|
+
<Tooltip.Target>
|
|
59
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
60
|
+
</Tooltip.Target>
|
|
61
|
+
<Tooltip.Content>
|
|
62
|
+
<p>Represented by top line of box. 25% of data are higher.</p>
|
|
63
|
+
</Tooltip.Content>
|
|
64
|
+
</Tooltip>
|
|
65
|
+
}
|
|
66
|
+
/>
|
|
67
|
+
|
|
68
|
+
{/* median */}
|
|
69
|
+
<TextField
|
|
70
|
+
type='text'
|
|
71
|
+
value={boxplot.labels.median}
|
|
72
|
+
fieldName='median'
|
|
73
|
+
section='boxplot'
|
|
74
|
+
subsection='labels'
|
|
75
|
+
label='Median'
|
|
76
|
+
updateField={updateField}
|
|
77
|
+
tooltip={
|
|
78
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
79
|
+
<Tooltip.Target>
|
|
80
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
81
|
+
</Tooltip.Target>
|
|
82
|
+
<Tooltip.Content>
|
|
83
|
+
<p>Middle data point. Half of data are higher value.</p>
|
|
84
|
+
</Tooltip.Content>
|
|
85
|
+
</Tooltip>
|
|
86
|
+
}
|
|
87
|
+
/>
|
|
88
|
+
|
|
89
|
+
{/* q1 */}
|
|
90
|
+
<TextField
|
|
91
|
+
type='text'
|
|
92
|
+
value={boxplot.labels.q1}
|
|
93
|
+
fieldName='q1'
|
|
94
|
+
section='boxplot'
|
|
95
|
+
subsection='labels'
|
|
96
|
+
label='Lower Quartile'
|
|
97
|
+
updateField={updateField}
|
|
98
|
+
tooltip={
|
|
99
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
100
|
+
<Tooltip.Target>
|
|
101
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
102
|
+
</Tooltip.Target>
|
|
103
|
+
<Tooltip.Content>
|
|
104
|
+
<p>Represented by bottom line of box. 25% of data are lower.</p>
|
|
105
|
+
</Tooltip.Content>
|
|
106
|
+
</Tooltip>
|
|
107
|
+
}
|
|
108
|
+
/>
|
|
109
|
+
|
|
110
|
+
{/* minimum */}
|
|
111
|
+
<TextField
|
|
112
|
+
type='text'
|
|
113
|
+
value={boxplot.labels.minimum}
|
|
114
|
+
fieldName='minimum'
|
|
115
|
+
section='boxplot'
|
|
116
|
+
subsection='labels'
|
|
117
|
+
label='Minimum'
|
|
118
|
+
updateField={updateField}
|
|
119
|
+
tooltip={
|
|
120
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
121
|
+
<Tooltip.Target>
|
|
122
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
123
|
+
</Tooltip.Target>
|
|
124
|
+
<Tooltip.Content>
|
|
125
|
+
<p>Lowest value, excluding outliers</p>
|
|
126
|
+
</Tooltip.Content>
|
|
127
|
+
</Tooltip>
|
|
128
|
+
}
|
|
129
|
+
/>
|
|
130
|
+
<br />
|
|
131
|
+
<h4 style={{ fontSize: '18px' }}>Labels for Additional Measures</h4>
|
|
132
|
+
|
|
133
|
+
{/* iqr */}
|
|
134
|
+
<TextField type='text' value={boxplot.labels.iqr} fieldName='iqr' section='boxplot' subsection='labels' label='Interquartile Range' updateField={updateField} />
|
|
135
|
+
{/* count */}
|
|
136
|
+
<TextField type='text' value={boxplot.labels.total} fieldName='total' section='boxplot' subsection='labels' label='Total' updateField={updateField} />
|
|
137
|
+
{/* mean */}
|
|
138
|
+
<TextField type='text' value={boxplot.labels.mean} fieldName='mean' section='boxplot' subsection='labels' label='Mean' updateField={updateField} />
|
|
139
|
+
{/* outliers */}
|
|
140
|
+
<TextField type='text' value={boxplot.labels.outliers} fieldName='outliers' section='boxplot' subsection='labels' label='Outliers' updateField={updateField} />
|
|
141
|
+
{/* values */}
|
|
142
|
+
<TextField type='text' value={boxplot.labels.values} fieldName='values' section='boxplot' subsection='labels' label='Values' updateField={updateField} />
|
|
143
|
+
</AccordionItemPanel>
|
|
144
|
+
</AccordionItem>
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export default PanelBoxPlot
|
|
@@ -1,120 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import WarningImage from '../images/warning.svg'
|
|
1
|
+
import { useContext, FC } from 'react'
|
|
2
|
+
|
|
3
|
+
// cdc
|
|
5
4
|
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
6
5
|
import Icon from '@cdc/core/components/ui/Icon'
|
|
6
|
+
import { Select, CheckBox, TextField } from '@cdc/core/components/EditorPanel/Inputs'
|
|
7
|
+
import WarningImage from '../../../../images/warning.svg'
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const Select = memo(({ label, value, options, fieldName, section = null, subsection = null, required = false, tooltip, updateField, initial: initialValue, ...attributes }) => {
|
|
11
|
-
let optionsJsx = options.map((optionName, index) => (
|
|
12
|
-
<option value={optionName} key={index}>
|
|
13
|
-
{optionName}
|
|
14
|
-
</option>
|
|
15
|
-
))
|
|
16
|
-
|
|
17
|
-
if (initialValue) {
|
|
18
|
-
optionsJsx.unshift(
|
|
19
|
-
<option value='' key='initial'>
|
|
20
|
-
{initialValue}
|
|
21
|
-
</option>
|
|
22
|
-
)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
<label>
|
|
27
|
-
<span className='edit-label'>
|
|
28
|
-
{label}
|
|
29
|
-
{tooltip}
|
|
30
|
-
</span>
|
|
31
|
-
<select
|
|
32
|
-
className={required && !value ? 'warning' : ''}
|
|
33
|
-
name={fieldName}
|
|
34
|
-
value={value}
|
|
35
|
-
onChange={event => {
|
|
36
|
-
updateField(section, subsection, fieldName, event.target.value)
|
|
37
|
-
}}
|
|
38
|
-
{...attributes}
|
|
39
|
-
>
|
|
40
|
-
{optionsJsx}
|
|
41
|
-
</select>
|
|
42
|
-
</label>
|
|
43
|
-
)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
const CheckBox = memo(({ label, value, fieldName, section = null, subsection = null, tooltip, updateField, ...attributes }) => (
|
|
47
|
-
<label className='checkbox column-heading'>
|
|
48
|
-
<input
|
|
49
|
-
type='checkbox'
|
|
50
|
-
name={fieldName}
|
|
51
|
-
checked={value}
|
|
52
|
-
onChange={e => {
|
|
53
|
-
updateField(section, subsection, fieldName, !value)
|
|
54
|
-
}}
|
|
55
|
-
{...attributes}
|
|
56
|
-
/>
|
|
57
|
-
<span className='edit-label'>
|
|
58
|
-
{label}
|
|
59
|
-
{tooltip}
|
|
60
|
-
</span>
|
|
61
|
-
</label>
|
|
62
|
-
))
|
|
63
|
-
|
|
64
|
-
/* eslint-disable react-hooks/rules-of-hooks */
|
|
65
|
-
const TextField = memo(({ label, tooltip, section = null, subsection = null, fieldName, updateField, value: stateValue, type = 'input', i = null, min = null, ...attributes }) => {
|
|
66
|
-
const [value, setValue] = useState(stateValue)
|
|
67
|
-
|
|
68
|
-
const [debouncedValue] = useDebounce(value, 500)
|
|
69
|
-
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
if ('string' === typeof debouncedValue && stateValue !== debouncedValue) {
|
|
72
|
-
updateField(section, subsection, fieldName, debouncedValue, i)
|
|
73
|
-
}
|
|
74
|
-
}, [debouncedValue]) // eslint-disable-line
|
|
75
|
-
|
|
76
|
-
let name = subsection ? `${section}-${subsection}-${fieldName}` : `${section}-${subsection}-${fieldName}`
|
|
77
|
-
|
|
78
|
-
const onChange = e => {
|
|
79
|
-
if ('number' !== type || min === null) {
|
|
80
|
-
setValue(e.target.value)
|
|
81
|
-
} else {
|
|
82
|
-
if (!e.target.value || min <= parseFloat(e.target.value)) {
|
|
83
|
-
setValue(e.target.value)
|
|
84
|
-
} else {
|
|
85
|
-
setValue(min.toString())
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
let formElement = <input type='text' name={name} onChange={onChange} {...attributes} value={value} />
|
|
91
|
-
|
|
92
|
-
if ('textarea' === type) {
|
|
93
|
-
formElement = <textarea name={name} onChange={onChange} {...attributes} value={value}></textarea>
|
|
94
|
-
}
|
|
9
|
+
// contexts
|
|
10
|
+
import ConfigContext from '../../../../ConfigContext'
|
|
95
11
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
12
|
+
// types
|
|
13
|
+
import { type ChartContext } from '../../../../types/ChartContext'
|
|
14
|
+
import { type PanelProps } from '../PanelProps'
|
|
99
15
|
|
|
100
|
-
|
|
101
|
-
formElement = <input type='date' name={name} onChange={onChange} {...attributes} value={value} />
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return (
|
|
105
|
-
<label>
|
|
106
|
-
<span className='edit-label column-heading'>
|
|
107
|
-
{label}
|
|
108
|
-
{tooltip}
|
|
109
|
-
</span>
|
|
110
|
-
{formElement}
|
|
111
|
-
</label>
|
|
112
|
-
)
|
|
113
|
-
})
|
|
16
|
+
import { AccordionItem, AccordionItemHeading, AccordionItemPanel, AccordionItemButton } from 'react-accessible-accordion'
|
|
114
17
|
|
|
115
|
-
const ForestPlotSettings = () => {
|
|
116
|
-
const { config, rawData: unfilteredData, updateConfig
|
|
18
|
+
const ForestPlotSettings: FC<PanelProps> = ({ name }) => {
|
|
19
|
+
const { config, rawData: unfilteredData, updateConfig } = useContext<ChartContext>(ConfigContext)
|
|
20
|
+
if (config.visualizationType !== 'Forest Plot') return
|
|
117
21
|
|
|
22
|
+
// todo: get from editor context?
|
|
118
23
|
const enforceRestrictions = updatedConfig => {
|
|
119
24
|
if (updatedConfig.orientation === 'horizontal') {
|
|
120
25
|
updatedConfig.labels = false
|
|
@@ -128,6 +33,7 @@ const ForestPlotSettings = () => {
|
|
|
128
33
|
}
|
|
129
34
|
}
|
|
130
35
|
|
|
36
|
+
// todo: get from editor context?
|
|
131
37
|
const getColumns = (filter = true) => {
|
|
132
38
|
let columns = {}
|
|
133
39
|
unfilteredData.forEach(row => {
|
|
@@ -152,6 +58,7 @@ const ForestPlotSettings = () => {
|
|
|
152
58
|
return Object.keys(columns)
|
|
153
59
|
}
|
|
154
60
|
|
|
61
|
+
// todo: editor context?
|
|
155
62
|
const updateField = (section, subsection, fieldName, newValue) => {
|
|
156
63
|
if (section === 'boxplot' && subsection === 'legend') {
|
|
157
64
|
updateConfig({
|
|
@@ -243,11 +150,31 @@ const ForestPlotSettings = () => {
|
|
|
243
150
|
<AccordionItem>
|
|
244
151
|
<AccordionItemHeading>
|
|
245
152
|
<AccordionItemButton>
|
|
246
|
-
|
|
153
|
+
{name}
|
|
247
154
|
{(!config.forestPlot.estimateField || !config.forestPlot.upper || !config.forestPlot.lower) && <WarningImage width='25' className='warning-icon' />}
|
|
248
155
|
</AccordionItemButton>
|
|
249
156
|
</AccordionItemHeading>
|
|
250
157
|
<AccordionItemPanel>
|
|
158
|
+
<Select
|
|
159
|
+
value={config.xAxis.dataKey || ''}
|
|
160
|
+
section='xAxis'
|
|
161
|
+
fieldName='dataKey'
|
|
162
|
+
label='Study Column'
|
|
163
|
+
initial='Select'
|
|
164
|
+
required={true}
|
|
165
|
+
updateField={updateField}
|
|
166
|
+
options={getColumns(false)}
|
|
167
|
+
tooltip={
|
|
168
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
169
|
+
<Tooltip.Target>
|
|
170
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
171
|
+
</Tooltip.Target>
|
|
172
|
+
<Tooltip.Content>
|
|
173
|
+
<p>Select the column or row containing the categories or dates for this axis. </p>
|
|
174
|
+
</Tooltip.Content>
|
|
175
|
+
</Tooltip>
|
|
176
|
+
}
|
|
177
|
+
/>
|
|
251
178
|
<Select
|
|
252
179
|
value={config.forestPlot.type}
|
|
253
180
|
label='Forest Plot Type'
|
|
@@ -311,7 +238,6 @@ const ForestPlotSettings = () => {
|
|
|
311
238
|
<Select
|
|
312
239
|
value={config.forestPlot.shape}
|
|
313
240
|
label='Point Estimate Shape'
|
|
314
|
-
initial={config.forestPlot.shape || 'Select'}
|
|
315
241
|
onChange={e => {
|
|
316
242
|
if (e.target.value !== '' && e.target.value !== 'Select') {
|
|
317
243
|
updateConfig({
|
|
@@ -327,28 +253,6 @@ const ForestPlotSettings = () => {
|
|
|
327
253
|
options={['text', 'circle', 'square']}
|
|
328
254
|
/>
|
|
329
255
|
|
|
330
|
-
<Select
|
|
331
|
-
value={config.forestPlot.radius.scalingColumn}
|
|
332
|
-
label='Scale Radius Column'
|
|
333
|
-
initial={'Select'}
|
|
334
|
-
onChange={e => {
|
|
335
|
-
if (e.target.value !== '' && e.target.value !== 'Select') {
|
|
336
|
-
updateConfig({
|
|
337
|
-
...config,
|
|
338
|
-
forestPlot: {
|
|
339
|
-
...config.forestPlot,
|
|
340
|
-
radius: {
|
|
341
|
-
...config.forestPlot.radius,
|
|
342
|
-
scalingColumn: e.target.value
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
})
|
|
346
|
-
}
|
|
347
|
-
e.target.value = ''
|
|
348
|
-
}}
|
|
349
|
-
options={getColumns(false)}
|
|
350
|
-
/>
|
|
351
|
-
|
|
352
256
|
<Select
|
|
353
257
|
value={config.forestPlot.lower}
|
|
354
258
|
label='Lower CI Column'
|
|
@@ -389,30 +293,30 @@ const ForestPlotSettings = () => {
|
|
|
389
293
|
options={getColumns(false)}
|
|
390
294
|
/>
|
|
391
295
|
|
|
392
|
-
<
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
296
|
+
<label>
|
|
297
|
+
<span className='edit-label column-heading'>
|
|
298
|
+
Pooled Result Column
|
|
299
|
+
<input
|
|
300
|
+
type='text'
|
|
301
|
+
value={config.forestPlot.pooledResult.column || ''}
|
|
302
|
+
label='Pooled Result Row'
|
|
303
|
+
onChange={e => {
|
|
304
|
+
updateConfig({
|
|
305
|
+
...config,
|
|
306
|
+
forestPlot: {
|
|
307
|
+
...config.forestPlot,
|
|
308
|
+
pooledResult: {
|
|
309
|
+
...config.forestPlot.pooledResult,
|
|
310
|
+
column: e.target.value
|
|
311
|
+
}
|
|
406
312
|
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
/>
|
|
313
|
+
})
|
|
314
|
+
e.target.value = ''
|
|
315
|
+
}}
|
|
316
|
+
/>
|
|
317
|
+
</span>
|
|
318
|
+
</label>
|
|
414
319
|
|
|
415
|
-
<CheckBox value={config.forestPlot?.hideDateCategoryCol || false} section='forestPlot' fieldName='hideDateCategoryCol' label='Hide Date Category Column' updateField={updateField} />
|
|
416
320
|
<CheckBox value={config.forestPlot?.lineOfNoEffect?.show || false} section='forestPlot' subsection='lineOfNoEffect' fieldName='show' label='Show Line of No Effect' updateField={updateField} />
|
|
417
321
|
|
|
418
322
|
<br />
|
|
@@ -496,12 +400,45 @@ const ForestPlotSettings = () => {
|
|
|
496
400
|
/>
|
|
497
401
|
</label>
|
|
498
402
|
|
|
403
|
+
<TextField type='number' min={20} max={45} value={config.forestPlot.rowHeight ? config.forestPlot.rowHeight : 10} updateField={updateField} section='forestPlot' fieldName='rowHeight' label='Row Height' placeholder='10' />
|
|
404
|
+
<br />
|
|
405
|
+
<hr />
|
|
406
|
+
<br />
|
|
407
|
+
<h4>Labels Settings</h4>
|
|
408
|
+
<TextField type='text' value={config.forestPlot?.leftLabel || ''} updateField={updateField} section='forestPlot' fieldName='leftLabel' label='Left Label' />
|
|
409
|
+
<TextField type='text' value={config.forestPlot?.rightLabel || ''} updateField={updateField} section='forestPlot' fieldName='rightLabel' label='Right Label' />
|
|
410
|
+
|
|
411
|
+
<br />
|
|
412
|
+
<hr />
|
|
413
|
+
<br />
|
|
414
|
+
<Select
|
|
415
|
+
value={config.forestPlot.radius.scalingColumn}
|
|
416
|
+
label='Weight Column'
|
|
417
|
+
initial={'Select'}
|
|
418
|
+
onChange={e => {
|
|
419
|
+
if (e.target.value !== '' && e.target.value !== 'Select') {
|
|
420
|
+
updateConfig({
|
|
421
|
+
...config,
|
|
422
|
+
forestPlot: {
|
|
423
|
+
...config.forestPlot,
|
|
424
|
+
radius: {
|
|
425
|
+
...config.forestPlot.radius,
|
|
426
|
+
scalingColumn: e.target.value
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
})
|
|
430
|
+
}
|
|
431
|
+
e.target.value = ''
|
|
432
|
+
}}
|
|
433
|
+
options={getColumns(false)}
|
|
434
|
+
/>
|
|
435
|
+
|
|
499
436
|
<label>
|
|
500
437
|
<span className='edit-label column-heading'>Radius Minimum Size</span>
|
|
501
438
|
<input
|
|
502
|
-
min={
|
|
503
|
-
max={
|
|
504
|
-
value={config.forestPlot.radius.min}
|
|
439
|
+
min={3}
|
|
440
|
+
max={6}
|
|
441
|
+
value={config.forestPlot.radius.min || 3}
|
|
505
442
|
onChange={e => {
|
|
506
443
|
updateConfig({
|
|
507
444
|
...config,
|
|
@@ -522,7 +459,7 @@ const ForestPlotSettings = () => {
|
|
|
522
459
|
<label>
|
|
523
460
|
<span className='edit-label column-heading'>Radius Maximum Size</span>
|
|
524
461
|
<input
|
|
525
|
-
min={
|
|
462
|
+
min={7}
|
|
526
463
|
max={10}
|
|
527
464
|
value={config.forestPlot.radius.max}
|
|
528
465
|
onChange={e => {
|
|
@@ -542,13 +479,6 @@ const ForestPlotSettings = () => {
|
|
|
542
479
|
placeholder=' 1'
|
|
543
480
|
/>
|
|
544
481
|
</label>
|
|
545
|
-
<TextField type='number' min={20} max={45} value={config.forestPlot.rowHeight ? config.forestPlot.rowHeight : 10} updateField={updateField} section='forestPlot' fieldName='rowHeight' label='Row Height' placeholder='10' />
|
|
546
|
-
<br />
|
|
547
|
-
<hr />
|
|
548
|
-
<br />
|
|
549
|
-
<h4>Labels Settings</h4>
|
|
550
|
-
<TextField type='text' value={config.forestPlot?.leftLabel || ''} updateField={updateField} section='forestPlot' fieldName='leftLabel' label='Left Label' />
|
|
551
|
-
<TextField type='text' value={config.forestPlot?.rightLabel || ''} updateField={updateField} section='forestPlot' fieldName='rightLabel' label='Right Label' />
|
|
552
482
|
</AccordionItemPanel>
|
|
553
483
|
</AccordionItem>
|
|
554
484
|
)
|