React Chart Component Implementation
You are tasked with building reusable chart components in React using TypeScript. This challenge will test your ability to create flexible, data-driven UI elements that can visualize information effectively. This is a fundamental skill for many web applications that need to display data trends, statistics, or any form of quantitative information.
Problem Description
Your goal is to implement two distinct chart components: a BarChart and a LineChart. Both components will accept an array of data points and render them visually.
Key Requirements:
-
BarChartComponent:- Accepts a
dataprop, which is an array of objects. Each object should have at least alabel(string) and avalue(number). - Renders a series of vertical bars, where the height of each bar corresponds to its
value. - Each bar should be labeled with its
label. - The chart should have a clear visual representation of the x-axis (labels) and y-axis (values).
- The bars should be visually distinct and easy to interpret.
- Accepts a
-
LineChartComponent:- Accepts a
dataprop, which is an array of objects. Similar to theBarChart, each object should have at least alabel(string, representing the x-axis point) and avalue(number, representing the y-axis point). - Renders a line connecting the data points.
- Each data point should be clearly marked (e.g., with a small circle).
- The chart should have a clear visual representation of the x-axis (labels) and y-axis (values).
- The line should smoothly connect the points.
- Accepts a
General Requirements for both components:
- TypeScript: All components and types must be written in TypeScript.
- Reusability: Components should be designed to be reusable with different datasets and potentially customizable via props (though extensive customization is not required for this challenge).
- Basic Styling: Apply basic CSS for clarity and readability. You can assume a basic container with some padding.
- Responsiveness (Basic): The charts should attempt to scale reasonably within their parent container.
- No External Charting Libraries: You are expected to implement the rendering logic yourself, without using libraries like Chart.js, Recharts, Nivo, etc. This means using basic HTML elements (e.g.,
div,svgelements if you choose that route) and CSS for rendering.
Expected Behavior:
- Given an input data array, the components should render the corresponding visual representation.
- The chart's axes and labels should be clear.
- Bars in
BarChartshould be proportional to their values. - The line in
LineChartshould accurately connect the data points.
Edge Cases to Consider:
- Empty Data: What happens if the
dataprop is an empty array? - Zero or Negative Values: How should zero or negative values be handled in the charts? (For simplicity, assume non-negative values for the primary implementation, but consider how you would handle them).
- Single Data Point: How does each chart behave with only one data point?
Examples
Example 1: Bar Chart
Input Data:
[
{ label: 'Jan', value: 65 },
{ label: 'Feb', value: 59 },
{ label: 'Mar', value: 80 },
{ label: 'Apr', value: 81 },
{ label: 'May', value: 56 }
]
Output:
A BarChart component that renders five vertical bars.
- The "Jan" bar has a height proportional to 65.
- The "Feb" bar has a height proportional to 59.
- The "Mar" bar has a height proportional to 80.
- The "Apr" bar has a height proportional to 81.
- The "May" bar has a height proportional to 56. Each bar is labeled below it with its respective month. The y-axis implicitly scales to accommodate the maximum value (81).
Example 2: Line Chart
Input Data:
[
{ label: 'Mon', value: 10 },
{ label: 'Tue', value: 15 },
{ label: 'Wed', value: 12 },
{ label: 'Thu', value: 18 },
{ label: 'Fri', value: 20 }
]
Output:
A LineChart component that renders a line connecting five points.
- The first point is at x-axis position "Mon" and y-axis value 10.
- The second point is at x-axis position "Tue" and y-axis value 15.
- And so on, connecting all five points. Each point is marked, and the line visually represents the trend across the days. The y-axis implicitly scales to accommodate the maximum value (20).
Example 3: Bar Chart with Empty Data
Input Data: []
Output:
A BarChart component that renders nothing, or a message indicating "No data available."
Constraints
- The
dataarray will contain between 0 and 50 data points. labelstrings will not exceed 10 characters.valuenumbers will be non-negative integers between 0 and 1000.- The charting components should render within a container with a maximum width of 600px and a maximum height of 400px.
- Rendering time should be under 100ms for any valid input within the constraints.
Notes
- You can use
divelements and CSS for layout and styling. Alternatively, you might consider using SVG for more precise control over shapes and lines, butdivs are perfectly acceptable. - Think about how to determine the maximum value in your dataset to scale the chart heights and line positions appropriately.
- Consider how to map labels to positions on the x-axis.
- For simplicity, you don't need to implement interactive features like tooltips or zooming.
- The focus is on accurate data representation and component structure.
- For the
LineChart, you'll need a way to draw lines. This can be achieved with CSS borders or, more effectively, with SVG<line>or<path>elements if you opt for an SVG approach.