Blinkit React Machine Coding Round II -SDE-1 Interview Experience (2025)
The Round-1 interview experience is documented here.
In Round-2, I was asked to build a Bar Graph component from scratch using React, without any charting libraries. The problem was broken into three incremental parts:
Press enter or click to view image in full size
Part 1️⃣: Proportional Bar Heights 📊
Challenge: Render bars with relative heights where the tallest bar = 100% and others scale proportionally.
Part 2️⃣: Dynamic Sorting 🔄
Challenge: Add ascending/descending sort controls to reorder bars by height.
Part 3️⃣: Interactive Hover Tooltip 🔼
Challenge: Show real-time data (item name, height value, percentage) based on exact mouse position within each bar.
Press enter or click to view image in full size
// GIVEN INPUT DATA
[
{
item: "item 1",
height: 40,
color: "green"
},
{
item: "item 2",
height: 80,
color: "yellow"
},
{
item: "item 3",
height: 60,
color: "blue"
}
]
i) Rendering Bars with Relative Heights Simple Explanation 🚀
- The data contains raw height values, which cannot be used directly to draw bars on the screen.
Step 1: Find the Tallest Bar
- First, we find the maximum height in the data. This helps us decide how tall the bars should be.
const maxHeight = Math.max(...data.map(d => d.height))
Step 2: Scale Bars Proportionally
const CONTAINER_HEIGHT = 300 // Define once
const barHeight = (bar.height / maxHeight) * CONTAINER_HEIGHT // main step
// Later in JSX:
<div style={{ height: CONTAINER_HEIGHT }}>
The key challenge is making bars scale proportionally. If one bar has height 80 and another has 40, the second should be exactly half as tall visually.
. Calculate each bar as a percentage of the max.
. Multiply by a constant ie container height (300px in our case) to get pixel values
The rule: Whatever you take as CONTAINER_HEIGHT and multiply by here must also be equal the height in your container div.
<div style={{
display: 'flex',
alignItems: 'flex-end', // Aligns bars to bottom
height: 300,
gap: 20,
}}>
Quick memory trick: alignItems = "How should items align in the perpendicular direction
- The Flexbox magic is in
alignItems: 'flex-end'- this makes all bars sit on the same baseline, just like a real graph.
📝 Complete Code Part 1
import React from 'react'
import ReactDOM from 'react-dom'
function App() {
const data = [
{item: 'Item 1', height: 40, color: 'green'},
{item: 'Item 2', height: 80, color: 'yellow'},
{item: 'Item 3', height: 60, color: 'blue'},
]
const maxHeight = Math.max(...data.map((d) => d.height))
const CONTAINER_HEIGHT = 300 // take any constant value based on layout
return (
<div style={{padding: 20}}>
<h3>Bar Graph</h3>
<div
style={{
display: 'flex',
alignItems: 'flex-end',
height: CONTAINER_HEIGHT,
borderBottom: '2px solid black',
gap: 20,
}}
>
{data.map((bar, index) => {
const barHeight = (bar.height / maxHeight) * CONTAINER_HEIGHT
return (
<div
key={index}
style={{
flex: 1,
textAlign: 'center',
}}
>
<div>{bar.height}</div>
<div
style={{
height: barHeight,
width: '100%',
backgroundColor: bar.color,
}}
/>
<div>{bar.item}</div>
</div>
)
})}
</div>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
ii) Sorting Bars Explanation and Implementation📊
Press enter or click to view image in full size
- Bar data is stored in React state, so changing its order updates the UI automatically.
- Sorting is implemented by reordering the data array based on the
heightproperty of each bar. - Before sorting, a shallow copy of the array is created using the spread operator (
[...]).
i) This is important because React state should never be mutated directly.
ii) Creating a copy ensures predictable re-renders.
- JavaScript’s built-in
Array.sort()method is used with a custom comparator function:
i) a.height - b.height → ascending order
ii) b.height - a.height → descending order
- After sorting,
setData()triggers a re-render and bars appear in the new order.
📝 Complete Code Part 2
import React, {useState} from 'react'
import ReactDOM from 'react-dom'
function App() {
const [data, setData] = useState([
{item: 'Item 1', height: 40, color: 'green'},
{item: 'Item 2', height: 80, color: 'yellow'},
{item: 'Item 3', height: 60, color: 'blue'},
])
const maxHeight = Math.max(...data.map((d) => d.height))
const sortAscending = () => {
setData([...data].sort((a, b) => a.height - b.height))
}
const sortDescending = () => {
setData([...data].sort((a, b) => b.height - a.height))
}
return (
<div style={{padding: 20}}>
<h3>Bar Graph</h3>
{/* Buttons */}
<div style={{marginBottom: 30}}>
<button
onClick={sortAscending}
style={{marginRight: 10, padding: '8px 16px'}}
>
Sort Ascending
</button>
<button onClick={sortDescending} style={{padding: '8px 16px'}}>
Sort Descending
</button>
</div>
{/* Chart */}
<div
style={{
display: 'flex',
alignItems: 'flex-end',
height: 300,
borderBottom: '2px solid black',
gap: 20,
paddingTop: 20,
}}
>
{data.map((bar, index) => {
const barHeight = (bar.height / maxHeight) * 250
return (
<div
key={index}
style={{
flex: 1,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<div style={{marginBottom: 5}}>{bar.height}</div>
<div
style={{
height: barHeight,
width: '100%',
backgroundColor: bar.color,
}}
/>
<div style={{marginTop: 5}}>{bar.item}</div>
</div>
)
})}
</div>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))
iii) ToolTip on Hover Solution with Explanation📊
Press enter or click to view image in full size
- Tooltip data is stored in React state ie (item name, height, percentage, mouse position)
nullwhen not hovering = no tooltip shows
const [tooltip, setTooltip] = useState(null)
- When the mouse moves over any bar:
i) The bar’s position is calculated using getBoundingClientRect()
ii) Mouse distance from the bottom of the bar is found
const rect = e.currentTarget.getBoundingClientRect() // bar's postion const mouseY = e.clientY - rect.top //mouse's position
rect.top= distance from top of pagerect.height= bar's pixel heighte.clientY= mouse Y position on entire pagerect.top= bar's top edge position- Mouse position (pixels) is converted into the actual bar value.
- The hovered value is converted into a percentage of the bar.
- Tooltip follows the mouse using
clientXandclientY. - Tooltip disappears when the mouse leaves the bar.
pointerEvents: noneensures the tooltip doesn’t block mouse movement.- 📝 Complete Code Part 3
import React, {useState} from 'react'
import ReactDOM from 'react-dom'
function App() {
const data = [
{item: 'Item 1', height: 40, color: 'green'},
{item: 'Item 2', height: 80, color: 'yellow'},
{item: 'Item 3', height: 60, color: 'blue'},
]
const [tooltip, setTooltip] = useState(null)
const maxHeight = Math.max(...data.map((d) => d.height))
const CONTAINER_HEIGHT = 300
const handleMouseMove = (e, bar, barHeight) => {
// Get the bar element's position
const rect = e.currentTarget.getBoundingClientRect()
// Calculate how far from the bottom of the bar the mouse is
const mouseY = e.clientY - rect.top
const distanceFromBottom = rect.height - mouseY
// Convert pixel position to actual height value
const hoveredHeight = (distanceFromBottom / barHeight) * bar.height
// Calculate percentage within this bar
const percentage = ((hoveredHeight / bar.height) * 100).toFixed(1)
setTooltip({
item: bar.item,
hoveredHeight: hoveredHeight.toFixed(1),
percentage: percentage,
x: e.clientX,
y: e.clientY,
})
}
const handleMouseLeave = () => {
setTooltip(null)
}
return (
<div style={{padding: 20}}>
<h3>Bar Graph</h3>
<div
style={{
display: 'flex',
alignItems: 'flex-end',
height: CONTAINER_HEIGHT,
borderBottom: '2px solid black',
gap: 20,
marginTop: 40,
}}
>
{data.map((bar, index) => {
const barHeight = (bar.height / maxHeight) * CONTAINER_HEIGHT
return (
<div
key={index}
style={{
flex: 1,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<div style={{marginBottom: 5}}>{bar.height}</div>
<div
style={{
height: barHeight,
width: '100%',
backgroundColor: bar.color,
cursor: 'pointer',
transition: 'opacity 0.2s',
opacity: tooltip ? 0.8 : 1,
}}
onMouseMove={(e) => handleMouseMove(e, bar, barHeight)}
onMouseLeave={handleMouseLeave}
/>
<div style={{marginTop: 5}}>{bar.item}</div>
</div>
)
})}
</div>
{/* Tooltip that follows mouse */}
{tooltip && (
<div
style={{
position: 'fixed',
left: tooltip.x + 15,
top: tooltip.y - 10,
backgroundColor: '#333',
color: 'white',
padding: '8px 12px',
borderRadius: '4px',
fontSize: '14px',
whiteSpace: 'nowrap',
pointerEvents: 'none',
zIndex: 1000,
}}
>
<div style={{fontWeight: 'bold'}}>{tooltip.item}</div>
<div>At Height: {tooltip.hoveredHeight}</div>
<div>Percentage: {tooltip.percentage}%</div>
</div>
)}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('root'))

Comments ...
No Comments Yet ...Add One