Box and Whisker Plot Example
Non-interactive Box and Whisker plot
Code
import { useContext, useMemo } from 'react';
import { PlotContext, Scale, BoxAndWhiskerPlot} from '@bezda/rhp-core';
import { BW_PLOT_DEFAULT_TEMPLATE } from '@bezda/rhp-core'; //import template
import { useObservable } from '@legendapp/state/react';
export const BoxAndWhiskerPlotExample = () => {
// Obtain the 5 state observables
const {plotData, dataMax, theme, orientation, vars} = useContext(PlotContext);
// Setup initial data
const nonformatedData = useObservable([[1, 3, 9, 10], [2, 3, 15, 20], [5, 9, 16, 18], [3, 4, 7, 9], [10, 18, 22, 25], [12, 14, 18, 22], [15, 20, 26, 27]]);
const spacing = useObservable(5);
const dataOrderIndex = useObservable(2); // 0: order by first whisker position, 1: by first quartile/bar start position, 2: by third quartile/bar end position, 3: by last whisker position
useMemo(() => {
plotData.set(convertBWData(nonformatedData.peek()));
dataMax.set(30);
vars.set({
"color": ["#9fa2a4","#5adae8", "#a5aeb5", "#dbe7eb", "#7688ab", "#aec7d3", "#c9ced3", "#577590", "brown", "gray", "black"],
"cloud-img-src": ['/react-html-plots/stratocumulus.jpg','/react-html-plots/cumulonimbus.jpg', '/react-html-plots/altocumulus.jpg', '/react-html-plots/cirrus.jpg', '/react-html-plots/nimbostratus.jpg', '/react-html-plots/cumulus1.jpg', '/react-html-plots/cirrocumulus.jpg'],
"last-whisker-pos": [], //BoxAndWhiskerPlot component uses this for storing the value/position of the last whisker for optional use in the template
"clouds":['stratocumulus', 'cumulonimbus' , 'altocumulus', 'cirrus', 'nimbostratus', 'cumulus', 'cirrocumulus'],
});
}, []);
return (
<PlotContext.Provider value={{ plotData: plotData, dataMax: dataMax, orientation: orientation, theme: theme, vars: vars}}>
<div
id='plot'
className='plot'
style={{
position: "relative",
marginTop: "1rem",
paddingBottom: "1.8rem",
borderRadius: "0.5rem",
backgroundColor: "#ffffff11",
boxShadow: "rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 1px 3px 1px"
}}
>
<Scale
id='scale_1'
width='100%'
height='600px'
spacing={spacing}
dataMaxLimit={100}
decorationWidth='6rem'
style={{
marginTop: "1.5rem",
position: "absolute",
paddingBottom: "1.2rem",
paddingRight: "0.3rem"
}}
CSS={"& .bar-dec-cont > .decoration > div {border-left: 4px solid var(--sl-color-text)!important; color: var(--sl-color-text)!important;}& .full-bar > .decoration {border-right: 4px solid var(--sl-color-text)!important;}& .bar {border-left: 4px solid rgba(var(--rhp-color-text-rgb-0), 0.3)!important;}& .bar:first-child {border-left: none!important;}& .bar > div {color: rgba(var(--rhp-color-text-rgb-0), 0.3)!important;}"}
/>
<BoxAndWhiskerPlot
id='bw_plot_1'
width='100%'
height='600px'
dataIndexForOrdering={dataOrderIndex}
boxWhiskerTemplate={BW_PLOT_DEFAULT_TEMPLATE}
style={{
paddingBottom: "0.5rem",
paddingTop: "2.5rem",
marginTop: "0.5rem",
paddingRight: "0.3rem"
}}
CSS={"& .full-bar:hover .decoration>.image {border: 5px solid var(--sl-color-accent-high)!important;}& .full-bar .decoration>.image {border: 4px solid var(--sl-color-text)!important;}& .full-bar:hover .decoration>div {color: var(--sl-color-accent-high)!important;} & .full-bar:hover div div.box {border: 5px solid var(--sl-color-accent-high)!important;color: var(--sl-color-accent-high)!important; font-weight: 500} & .full-bar:hover div div.whisker {border: 3px solid var(--sl-color-accent-high)!important;}& .bar {transition-property: flex!important;}& .bar > div {transition: border-color 0.4s ease-in-out, color 0.4s ease-in-out!important;}& .bar > .whisker {transition: border-color 0.4s ease-in-out!important;}"}
/>
</div>
</PlotContext.Provider>
);
}
A few things to note about the above example:
- Both the
<Scale>
and<BoxAndWhiskerPlot>
components are wrapped in a<PlotContext.Provider>
component. This is necessary for the components to share the same state observables (provided by the context) which allows the two to adjust to the same data and thereby keep in-sync with each other. - Both the
<Scale>
and<BoxAndWhiskerPlot>
components are placed inside a container<div>
element. The container element has aposition: relative
style applied to it. This is necessary to place the scale underneath/behind the Box and Whisker plot. - Uses the default template for Box and Whisker plots provided by rhp (
BW_PLOT_DEFAULT_TEMPLATE
) - By not providing a template for the Scale component, the component’s default template is implicitly used.
- Custom styling is applied to the Scale and BoxAndWhiskerPlot components using both the
style
prop and theCSS
prop. The latter allows the use of some features found in scss such as nested selectors which is useful for targeting nested elements. TheCSS
prop was used in this example for demonstration purposes. When there are many customizations, it is recommended to directly alter the template instead. - The
dataIndexForOrdering
prop is used to specify the index of each inner data array to use for ordering the Box and Whiskers. The value of 2 used in this example corresponds to the third quartile of the data. The other options are 0: order by first whisker position, 1: by first quartile/bar start position, 3: by last whisker position. - The
dataMaxLimit
prop is used to specify the maximum value the scale can stretch to. This is useful for when the data is dynamic and the scale needs to be updated to reflect the new data. ThedataMax
observable is used to update the scale’s maximum value. ThedataMaxLimit
prop is optional and defaults to 100. - The
spacing
prop is used to specify the spacing between divisions/ticks in the scale. - The format of the data that
<BoxAndWhiskerPlot>
expects is very similar to if not the same as what a stacked bar chart/plot expects. The first value in each inner array is the width of the space before the first tick (think of an invisible bar there), the second value is the width of the first whisker, the third value is the width of the bar that stretches from the lower quartile to the upper quartile, the fourth value is the width of the whisker that follows at the end. If the typical format is prefered, rhp provides a conversion function calledconvertBWData
.