Bar Chart

Prompt
Are you passionate about data visualization? Your challenge is to craft a Bar Chart using React.
The question's aim is to develop a bar chart component in React. This component will efficiently display a vertical bar chart derived from a structured array of data. Each element in this array will transform into a distinct bar in the chart, with its height proportional to the ticket count associated with each department.
What makes this bar chart stand out is its use of color. Each bar will be uniquely colored based on a predefined color code.
You can use the api.js
file in the server folder to retrieve the mock data for rendering your bar chart. This data also includes colour
information.
Example

Playground (Prompt 1)
You can use the getData
function to fetch the chart data. This function returns a promise which resolves with the chartData. Remember to handle this promise correctly, typically using .then()
method or async-await
syntax.
To determine the maximum height among all the bars in your chart, consider using the Math.max
function combined with the .map
method. For example, you can calculate the maximum height like this
const maxHeight = Math.max(
...items.map((item) => item.ticketCount)
);
The reason for calculating the maximum bar height (maxHeight) is to use it as a reference for scaling the height of all other bars. By knowing the maximum height, you can proportionally calculate the height of each bar relative to this maximum, ensuring that all bar heights are accurately represented in your chart.
Solution (Prompt 1)
Common Pitfalls
- Fetching the Data: The
getData
function is returning a new Promise which gets resolved after 100 milliseconds with the data array. If the engineer isn't familiar with how Promises work or how they are used to manage asynchronous operations in JavaScript, this might be confusing. - Calculating Bar Height: You need to calculate the height relative to maxHeight. For example, if the height is 80 and the maxHeight is 200, the
getHeight
function takes two parameters:height
andmaxHeight
. It calculates (80 / 200) * 100, which equals 40%. Therefore, the function returns the string "40%". - Styling Bar Chart: If you are giving the height of a bar in percentages, which is most likely to be the case, then the parent container of a bar needs to have some fixed height for the bar to appear.
My Attempt (Prompt 1)
Prompt 2: Sorting
- We would like to add a select menu above the chart which provides the option to sort the bars in ascending, descending or default order.
- The styling of the dropdown does not matter, we are only concerned about the functionality here.
Playground (Prompt 2)
Implement a function that sorts the chart items by their values. Use a parameter to determine the sorting order - ascending or descending. You might find array sorting methods and conditional logic useful here.
Think about a way to dynamically sort your chart items without the need for an extra state. Could a function that sorts items just before rendering be useful? Also, consider keeping your sorting logic separate from the bar chart component for better modularity and reusability.
Solution (Prompt 2)
Common Pitfalls
- Mutating while Sorting: It is generally recommended to create a copy of the array before sorting it.
This ensures that the original array remains unchanged, preserving data integrity and preventing unwanted side effects.
const originalArray = [3, 1, 2];const sortedArray = [...originalArray].sort();
- onChange: The
<select />
element is not as commonly used as other form inputs in React applications. As a result, some developers may unintentionally use theonClick
event handler on the<select />
element, which does not provide the desired functionality. Instead, it is important to use theonChange
event handler to accurately capture the selected value of the<select />
element.
Note
Accessibility: The "name" key provided in the response of the API can be used for accessibility purposes.
My Attempt (Prompt 2)
Prompt 3: Data of any shape
Data rarely comes in exactly the format we need it. We want to adapt any data structure to work with a single BarChart component. The only assumption is that each data item provided to the chart will have:
- A color property
- A property that can map to the bar label
- A property that can map to the bar value
// These different data shapes should work with the same chart component:
const ticketData = [
{ name: 'Bugs', ticketCount: 45, colour: 'red' },
];
const salesData = [
{ product: 'Laptop', revenue: 1500, barColor: 'blue' },
];
Playground (Prompt 3)
To make your chart adaptable to data of any shape, think about introducing a transformation function. This function should take each data item and convert it into a standardized format for the chart. For instance, it could extract and rename specific properties, ensuring each item has a consistent structure with a color, label, and value. You might use this transformation within the chart component to process the data just before it's rendered.
Solution (Prompt 3)
My Attempt (Prompt 3)
Prompt 4: Advanced Questions
How do we represent huge and tiny values effectively on the same chart?
Add tooltips or data labels to the chart to provide additional information. This enables users to see the actual values when hovering over or clicking on the bars, helping them interpret the tiny and huge values more accurately.
Discussion on alternative rendering methods like Canvas or SVG?
SVG (Scalable Vector Graphics)
Advantages | Considerations |
---|---|
Since SVG elements are part of the DOM, they can be directly interacted with using JavaScript or React events. | SVG rendering can become slower when dealing with a large number of elements, as each element adds to the DOM tree. |
SVG supports accessibility features, allowing you to provide text alternatives and descriptions for chart elements. | Animations and transitions in SVG can be more resource-intensive compared to Canvas. |
Canvas:
Advantages | Considerations |
---|---|
Canvas renders directly onto a bitmap, making it faster for rendering a large number of elements or complex visualizations. | Since Canvas renders pixels directly, it does not provide built-in DOM features like accessibility or direct interaction with individual elements. |
Once drawn on the canvas, the elements do not affect the performance since they are not part of the DOM. | Complex shapes and interactions may require more effort to implement compared to SVG. |
Canvas is suitable for creating interactive and dynamic charts with smooth animations. |
Interviewer Criteria
HTML/CSS
- Does my layout accurately match the provided image?
- Did you style the UI quickly (10 minutes or less)?
- Did I consider using the
name
node from chart data for improving accessbility? - Are my CSS class names both self-explanatory and meaningful?
JavaScript
- Was I successful in demonstrating my ability to fetch data from a mock API?
- Was I able to sort the chart items in both ascending and descending order cleanly?
- Do I know how the JavaScript
sort
method works? - Have I leveraged ES6 features efficiently, such as let, const, arrow functions, and destructuring?
- Are my variable and function names descriptive, maintaining a consistent naming convention?
- How swiftly was I able to develop the logic for identifying the bar with maximum height without significant obstacles or delays?
- Was I able to cleanly calculate the height of bars relative to the one with maximum height?
React
- Have I used the key prop appropriately on all iterated elements, ensuring efficient and correct re-rendering?
- Have I considered handling the
loading
anderror
state when fetching the data? - Did I lift the state appropriately, such as lifting the
mode
state to theApp
to calculate the sorted chart items? - Did I derive the sorted chart items from chart items, instead of creating another state for storing sorted chart items?
- Am I comfortable using React hooks?
- Am I comfortable and proficient in using function components?
Component Architecture
- Did I create separate components for
<BarChart />
,<Bar />
, and<Controls />
? - Are the names of my classes, functions, handlers, and components clear and understandable?
Performance
- Am I able to discuss how to accommodate many data points without compromising the visual integrity and performance of the chart?
Time Checkpoints
- 10:00 AM
Interview starts 👥
- 10:03 AM
Prompt given by the interviewer
- 10:05 AM
Candidate reads the prompt, asks clarifying questions, and starts coding
- 10:10 AM
Data fetched from mock server and stored in state
- 10:20 AM
Chart rendered
- 10:30 AM
Styling completed
- 10:35 AM
Sorting logic implemented
- 10:50 AM
Support for data of any shape added
- 10:55 AM
Discussion with interviewer
- 11:00 AM
Interview ends ✅
Table of Contents
- Prompt
- Example
- Playground (Prompt 1)
- Solution (Prompt 1)
- My Attempt (Prompt 1)
- Prompt 2: Sorting
- Playground (Prompt 2)
- Solution (Prompt 2)
- My Attempt (Prompt 2)
- Prompt 3: Data of any shape
- Playground (Prompt 3)
- Solution (Prompt 3)
- My Attempt (Prompt 3)
- Prompt 4: Advanced Questions
- Interviewer Criteria
- Time Checkpoints