React Custom Components: Normalizing Numeric Data for Range-Based Visualization
I recently worked on a project that dealt with a considerable amount of numeric data. One of our goals was to design a graphical representation of data across multiple scales.
Understanding the Problem
We used Material-UI (MUI) library for our React front-end application. While MUI allows us to customize its component to a large scale, there is a downside. The more you customize its components, the more complex the code and application becomes. Additionally there is a limit to what extent a component can be customize.
A Preliminary Solution
One of the range scale we needed to add had a very custom design which was challenging to implement using the MUI slider. To solve this problem, I created a custom scale component and used the min-max normalization technique to accurately plot the data points in the given range.
Normalization
Normalization is a process used to transform values that lies in different scale to one standard scale. It is a concept often used in machine learning and statistics to convert all the variables into a range of [0,1].
Formula: x normalized = (x — x minimum) / (x maximum — x minimum)
Creating a Custom Range Scale Component
let’s consider the following sample data array called marks which we will be displaying on our custom scale.
const marks = [
{ value: 10000, label: "$10,000" },
{ value: 15000, label: "$15,000" },
{ value: 18000, label: "$18,000" },
{ value: 20000, label: "$20,000" }
];
Then we will create a basic scale line component on which our marks will be accurately displayed. I am using MUI’s styled component to Customize my div component but ,you can also add in-line styling to your div component.
const Line = styled("div")(() => ({
width: "100%",
height: "2px",
backgroundColor: "purple"
}));
Next, we will write our Normalized function that we will use in our range scale component :
const NormalizeFunction = (value: number, min: number, max: number): number => {
if (value === 0 || value < min || value > max) return 0;
const range = max - min;
const normalizedValue = (value - min) / range;
return Math.abs(normalizedValue);
};
We will use this normalization function to transform currency values into a scale of 0 to 1. By doing this, we can simplify our range rather than using large currency figures. Eventually, we’ll be able to plot our marks based on these normalized values.
Next we will determine the start position, end position and the width of our component using the above function:
const startPostion = NormalizeFunction(10000, 10000, 20000);
const endPosition = NormalizeFunction(20000, 10000, 20000);
const width = endPosition - startPostion;
Now we will use the above function in our custom range scale component:
const CustomRangeScale = () => {
return (
<div
style={{
display: 'flex',
position: "relative",
alignItems: 'center',
marginLeft: `${startPostion * 100}%`,
width: `${width * 100}%`,
}}
>
{marks.map((item, index) => {
const normalizedValue = NormalizeFunction(item.value, 10000, 20000);
const positionLeft = normalizedValue * 100;
return (
<React.Fragment key={item.value}>
{index !== 0 && <Line style={{ width: '100%' }} />}
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
position: 'absolute',
left: `${positionLeft}%`,
}}
>
<Tooltip title={item.label}>
<CircleIcon color='secondary' sx={{ fontSize: '10px' }} />
</Tooltip>
</div>
</React.Fragment>
);
})}
</div>
);
};
By setting the div component’s position as absolute and setting the left position we can plot the marks in our scale accurately. I am also using MUI tool-tip to display the label when we hover on the point but, this step is optional.
If you look at the MUI slider component and the custom scale component side by side, you will see that both marks are on the exact same location and the custom scale has plotted the marks accuracy.
Conclusion
Through normalization techniques, we can create our own custom range scale components. This is especially useful for intricate design implementations that might be challenging to achieve using standard UI library components.
About Humda Zainab
- LinkedIn Profile — https://www.linkedin.com/in/humda-zainab-764963209/
About Red Buffer
- Website — https://redbuffer.ai/
- Linkedin Page — linkedin.com/company/red-buffer
References for learning
- https://mui.com/material-ui/getting-started/ — Getting started with Material UI
- https://mui.com/material-ui/react-slider/ — Material UI — react slider