What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
The most practical way to make a bar graph in React.js is to install Recharts and compose its declarative BarChart, Bar, axis, grid, tooltip and responsive components. The example below starts with a working chart, then covers responsive sizing, grouped and stacked data, accessibility, production behavior, troubleshooting and an API alternative for rendered screenshots.
Build a working React bar graph
Recharts is a React-and-D3 chart library with native SVG output and composable components. Create or open a React application, install the package, and add a chart component.
npm install recharts
The following component is runnable in a current React project:
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
Legend
} from 'recharts';
const data = [
{ name: 'A', value: 12 },
{ name: 'B', value: 19 },
{ name: 'C', value: 7 }
];
export default function Example() {
return (
<section aria-labelledby="sales-chart-title">
<h2 id="sales-chart-title">Quarterly values</h2>
<div style={{ width: '100%', height: 320 }}>
<ResponsiveContainer width="100%" height="100%">
<BarChart data={data} margin={{ top: 16, right: 20, left: 8, bottom: 8 }}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Bar dataKey="value" name="Value" fill="#2563eb" />
</BarChart>
</ResponsiveContainer>
</div>
</section>
);
}
dataKey tells each axis or bar which object property to read. Keep numeric values as numbers, not formatted strings, so scales, tooltips and sorting work correctly.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minute#1 Best Overall
Use a fixed chart height in the layout
ResponsiveContainer measures its parent with the browser’s ResizeObserver. A percentage width is useful only when the parent has a usable height. Without one, the chart can render at zero height.
.chart-frame {
width: 100%;
height: 320px;
}
@media (max-width: 600px) {
.chart-frame { height: 240px; }
}
Projects that must support browsers without ResizeObserver need a compatible polyfill. Alternatively, use the responsive option on BarChart when your CSS sizing strategy already supplies dimensions.
Choose grouped or stacked bars
Grouped bars for side-by-side comparison
Give each series its own Bar. This makes values for the same category easy to compare directly.
const data = [
{ month: 'Jan', desktop: 120, mobile: 90 },
{ month: 'Feb', desktop: 140, mobile: 110 },
{ month: 'Mar', desktop: 130, mobile: 125 }
];
<BarChart data={data}>
<XAxis dataKey="month" />
<YAxis />
<Tooltip />
<Legend />
<Bar dataKey="desktop" fill="#2563eb" />
<Bar dataKey="mobile" fill="#16a34a" />
</BarChart>
Stacked bars for part-to-whole relationships
Use the same stackId on bars that form one total. Stacking is appropriate for composition, such as paid versus organic traffic, but can make individual segment comparisons harder.
Recommended Free Tools
<Bar dataKey="paid" stackId="total" fill="#7c3aed" />
<Bar dataKey="organic" stackId="total" fill="#f59e0b" />
Decide based on the question your reader must answer: side-by-side differences favor grouping; contribution to a total favors stacking. Also consider the number of series, label density and available width.
Make scales and labels truthful
Set a deliberate domain
The default Y-axis domain is calculated from the data. For values where a zero baseline matters, explicitly include zero:
<YAxis domain={[0, 'dataMax']} />
For percentages or known limits, use a fixed domain such as [0, 100]. Avoid truncating a bar chart’s baseline unless the visual treatment is clearly disclosed; a shortened baseline can exaggerate small differences.
Format ticks and tooltips
const number = new Intl.NumberFormat('en-US');
<YAxis tickFormatter={(value) => number.format(value)} />
<Tooltip formatter={(value) => number.format(value)} />
Long category names need shorter labels, rotated ticks or a wider chart. Do not remove visible axis labels merely to avoid overlap; they provide context that a color legend cannot replace.
Add values on bars safely
The Bar API supports labels, active-bar styling, animation controls, minimum point size and custom SVG-compatible labels. Custom labels must render SVG elements such as <text>; HTML elements such as <div> are invalid inside the chart’s SVG.
<Bar
dataKey="value"
fill="#2563eb"
label={{ position: 'top' }}
minPointSize={3}
/>
Use minPointSize carefully: it improves visibility for tiny nonzero values but changes their visual length. Explain that choice in the surrounding text when precision is important.
Rank #3
Accessibility for React bar charts
Recharts 3 enables accessibilityLayer by default for supported Cartesian charts, including BarChart. It adds keyboard navigation and screen-reader support. Keep the default enabled unless you have a tested reason to change it.
Provide context outside the SVG
- Give the chart a meaningful heading, as in the example’s
aria-labelledbyrelationship. - Keep visible X- and Y-axis labels and units.
- Use sufficient color contrast and do not encode the only distinction with color.
- Provide a text alternative or data table when exact values matter.
Keep tooltip announcements concise
The default tooltip acts as a live region. If you replace it, expose a concise status rather than dumping every datum into an announcement:
function AccessibleTooltip({ active, payload, label }) {
if (!active || !payload?.length) return null;
return (
<div role="status" aria-live="polite">
{label}: {payload[0].value}
</div>
);
}
Use aria-live="assertive" only when an update genuinely requires immediate interruption. Test keyboard focus, screen-reader output and reduced-motion settings with the actual data and labels used in production.
Responsive behavior and mobile layouts
- Give the chart wrapper a real height in pixels,
remor another resolvable CSS unit. - Set
ResponsiveContainer width="100%" height="100%"inside that wrapper. - Reserve horizontal space for Y-axis ticks, legends and margins.
- On narrow screens, shorten category labels or provide a horizontal scrolling region rather than allowing text to collide.
- Verify the chart after sidebars open, fonts load and the layout changes; these events trigger ResizeObserver measurements.
If the chart is conditionally rendered in a hidden tab or collapsed panel, measure it after it becomes visible. A zero-width measurement can persist until the parent resizes.
Animation, server rendering and performance
For the Bar component, isAnimationActive="auto" disables animation during server-side rendering and respects the user’s prefers-reduced-motion preference. You can turn animation off explicitly for dashboards that update frequently:
Rank #4
<Bar dataKey="value" isAnimationActive={false} />
For large datasets, aggregate values before rendering, avoid recreating large arrays on every render, and render only the series users need. A bar chart is a poor fit for thousands of individual categories; paginate, filter or switch to a visualization designed for dense data. Memoize expensive data preparation, but do not memoize blindly—measure the actual render path.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Common failures and fixes
Nothing appears
- Parent has no height: add a definite height to the wrapper.
- Parent is hidden: render or resize after the tab, dialog or accordion opens.
- Wrong key: ensure
dataKeyexactly matches the object property and values are numeric.
Bars are all zero or malformed
Check for strings such as "1,200", null values and inconsistent property names. Normalize API data before passing it to Recharts:
const chartData = apiRows.map((row) => ({
name: row.label,
value: Number(row.amount) || 0
}));
Labels overlap or disappear
Increase chart width, rotate or abbreviate ticks, adjust margin, or move the legend. For a custom label, return SVG nodes—not HTML—and confirm its coordinates remain inside the plot area.
Tooltip or keyboard behavior is confusing
Keep the accessibility layer enabled, supply a chart title, and test focus order. Replace the tooltip only when the custom component preserves a concise live-region announcement.
Animation causes motion or hydration differences
Honor reduced-motion preferences and use isAnimationActive={false} when deterministic output is more important than transition effects. In server-rendered applications, rely on the documented automatic behavior or disable animation explicitly.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesBest Value
Capture a React chart for documentation or testing
A browser screenshot is useful for visual regression tests, release notes and support tickets. Capture the fully loaded state, including any data-fetching completion and responsive breakpoint you want to verify. If you need a PDF, use a browser print flow or an API that renders the page rather than trying to convert SVG manually.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP tools—take_screenshot, get_page_info and capture_pdf—work with Claude, Cursor and other MCP clients.
One GET request returns PNG, JPEG, WebP or PDF. See the ScreenshotNeo API documentation for all options, including viewport and device presets, full-page lazy-image loading, CSS-selector element capture, custom JavaScript and CSS, waits, headers, cookies, blocking rules, geolocation, dark mode, resizing, caching, signed links, asynchronous webhooks and bulk capture.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free, and every feature is included on every plan. Create a free ScreenshotNeo account.
Frequently Asked Questions
Can I use Recharts with TypeScript?
Yes. Define an interface for each row and type the data array before passing it to the chart; the Recharts component props then catch misspelled keys during development.
Should a bar chart start at zero?
Usually, yes when bar length represents magnitude. Use a nonzero domain only for a deliberate analytical comparison and make the scale visible so readers are not misled.
How do I show an empty state?
Check the data array before rendering the chart and display an explanatory message such as “No values for this period.” Do not render an axis-only chart that implies zero data.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

