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 Reactwithout 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 height property 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)
  • null when 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 page
  • rect.height = bar's pixel height
  • e.clientY = mouse Y position on entire page
  • rect.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 clientX and clientY.
  • Tooltip disappears when the mouse leaves the bar.
  • pointerEvents: none ensures 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'))

 

Shhreyyyaa

Written by Shhreyyyaa


Comments ...


No Comments Yet ...Add One