Bar Chart Examples
Publication-quality bar charts with support for vertical and horizontal orientations.
Type Interface
import type { BaseChartProps, ChartChangeEvent, Formatter } from '../../types';
/**
* Columnar data for bar charts, just data no styling.
*/
export interface BarData {
/** Bar labels (x-axis for vertical, y-axis for horizontal) */
label: string[];
/** Bar values (heights for vertical, widths for horizontal) */
value: number[];
/** Optional colors for each bar (falls back to barColor or default palette) */
color?: string[];
}
export interface BarChartProps extends BarData, Omit<BaseChartProps, "legendFontSize"> {
/** X-axis label */
xLabel?: string;
/** Y-axis label */
yLabel?: string;
/** Chart title */
title?: string;
/** Show grid lines */
grid?: boolean;
/** Grid line color */
gridColor?: string;
/** Bar orientation */
orientation?: 'vertical' | 'horizontal';
/** Default color for all bars (overridden by colors array) */
barColor?: string;
/** Bar width as fraction of available space (0-1) */
barWidth?: number;
/** Show value labels on bars */
showLabels?: boolean;
/** Minimum Y value */
yMin?: number;
/** Maximum Y value */
yMax?: number;
/** Use canvas rendering instead of SVG */
canvas?: boolean;
/** Custom X-axis formatter */
xFormat?: Formatter;
/** Custom Y-axis formatter */
yFormat?: Formatter;
/** Callback for bar interactions */
onChange?: (event: ChartChangeEvent) => void;
/** Currently selected bar indices */
selectedIndices?: number[];
/** Callback when selection changes */
onSelectionChange?: (selectedIndices: number[]) => void;
/** Allow multiple selections (default: true) */
multiSelect?: boolean;
/** Custom overlays and children */
children?: React.ReactNode;
}
Layout & Spacing
Bar charts support flexible layout customization through margin and padding props:
padding: Uniform spacing on all sides (shorthand)margin: Fine-grained control with{ top, right, bottom, left }
Examples
// Uniform padding <BarChart padding={30} label={['A', 'B']} value={[10, 20]} /> // Custom margins per side <BarChart margin={{ top: 20, right: 40, bottom: 50, left: 60 }} label={['A', 'B']} value={[10, 20]} />
The padding prop provides a convenient shorthand for setting equal margins on all sides, while margin allows precise control over each side individually. When both are provided, margin takes precedence.
Default margin: { top: 40, right: 20, bottom: 50, left: 60 }
Default Margin
Compact (padding=20)
Custom Margin
import { BarChart } from '@vuer-ai/vuer-viz';
export default function CustomPaddingExample() {
const data = {
label: ['React', 'Vue', 'Angular', 'Svelte', 'Solid'],
value: [42, 28, 21, 12, 8],
};
return (
<div style={{ display: 'flex', gap: '20px', flexWrap: 'wrap' }}>
<div>
<h3 style={{ fontSize: '14px', marginBottom: '10px' }}>Default Margin</h3>
<BarChart
{...data}
width={250}
height={200}
title="Framework Usage"
yLabel="Percentage"
grid={true}
/>
</div>
<div>
<h3 style={{ fontSize: '14px', marginBottom: '10px' }}>Compact (padding=20)</h3>
<BarChart
{...data}
width={250}
height={200}
padding={20}
title="Framework Usage"
yLabel="Percentage"
grid={true}
/>
</div>
<div>
<h3 style={{ fontSize: '14px', marginBottom: '10px' }}>Custom Margin</h3>
<BarChart
{...data}
width={250}
height={200}
margin={{ top: 30, right: 10, bottom: 60, left: 80 }}
title="Framework Usage"
yLabel="Percentage (%)"
xLabel="Framework"
grid={true}
/>
</div>
</div>
);
}
Vertical Bar Chart
A simple vertical bar chart with grid lines.
import { BarChart } from '@vuer-ai/vuer-viz';
export default function VerticalBarExample() {
return (
<BarChart
label={['A', 'B', 'C', 'D', 'E']}
value={[23, 45, 12, 67, 34]}
title="Sample Data"
xLabel="Categories"
yLabel="Values"
grid
/>
);
}
Horizontal Bar Chart
A horizontal bar chart with values displayed.
import { BarChart } from '@vuer-ai/vuer-viz';
export default function HorizontalBarExample() {
return (
<BarChart
label={['Python', 'JavaScript', 'TypeScript', 'Rust', 'Go']}
value={[85, 72, 68, 45, 56]}
title="Language Popularity"
xLabel="Score"
yLabel="Language"
orientation="horizontal"
grid
showLabels={true}
/>
);
}
Custom Colors with Values
Bar chart with custom colors per bar.
import { BarChart } from '@vuer-ai/vuer-viz';
export default function ColoredBarExample() {
return (
<BarChart
label={['Q1', 'Q2', 'Q3', 'Q4']}
value={[120, 145, 98, 178]}
color={['#0000ff', '#00ff00', '#ff0000', '#ffff00']}
title="Quarterly Revenue"
xLabel="Quarter"
yLabel="Revenue ($K)"
grid
showLabels={true}
/>
);
}
Event Handling & Selection API
BarChart supports interactive selection, allowing users to click bars to select/deselect them. This is useful for building data exploration interfaces where users can inspect details of specific bars.
Basic Selection
import { useState } from 'react'; import { BarChart } from '@vuer-ai/vuer-viz'; function MyChart() { const [selectedIndices, setSelectedIndices] = useState<number[]>([]); return ( <BarChart label={['Q1', 'Q2', 'Q3', 'Q4']} value={[120, 145, 98, 178]} selectedIndices={selectedIndices} onSelectionChange={setSelectedIndices} multiSelect={true} // Allow multiple selections (default) /> ); }
Selection Behavior
- Visual Feedback: Selected bars maintain full opacity while unselected bars fade to 30% opacity
- Click to Toggle: Click a bar to select it; click again to deselect
- Multi-select Mode: When
multiSelect={true}(default), you can select multiple bars - Single-select Mode: When
multiSelect={false}, only one bar can be selected at a time - Stroke Highlight: Selected bars show a 2px stroke outline for clear visual indication
Programmatic Control
You can programmatically control selections:
// Select specific bars setSelectedIndices([0, 2, 4]); // Clear all selections setSelectedIndices([]); // Select all bars setSelectedIndices(labels.map((_, i) => i)); // Select top N by value const selectTopN = (n: number) => { const sorted = values .map((val, i) => ({ index: i, value: val })) .sort((a, b) => b.value - a.value) .slice(0, n) .map(item => item.index); setSelectedIndices(sorted); };
Selection with Table Example
Interactive bar chart with a table showing selected items. Click bars to select/deselect them and view details in the table below.
Selected Products (0)
| Product | Sales ($K) |
|---|---|
| this table is empty | |
import { BarChart } from '@vuer-ai/vuer-viz';
import { useState } from 'react';
// Sample product sales data
const productData = {
label: ['Laptops', 'Phones', 'Tablets', 'Monitors', 'Keyboards', 'Mice', 'Headphones'],
value: [2450, 3890, 1560, 980, 650, 420, 1120],
color: ['#0000ff', '#00ff00', '#ff0000', '#ffff00', '#ff00ff', '#00ffff', '#ff8800'],
};
export default function SelectionWithTableExample() {
const [selectedIndices, setSelectedIndices] = useState<number[]>([]);
// Get selected products
const selectedProducts = selectedIndices.map(i => ({
label: productData.label[i],
value: productData.value[i],
color: productData.color[i],
}));
return (
<div className="space-y-6">
{/* Bar Chart */}
<div>
<BarChart
label={productData.label}
value={productData.value}
color={productData.color}
title="Product Sales (Click bars to select)"
xLabel="Product"
yLabel="Sales ($K)"
grid
selectedIndices={selectedIndices}
onSelectionChange={setSelectedIndices}
multiSelect={true}
/>
</div>
{/* Selected Products Table */}
<div>
<h3 className="text-lg font-semibold mb-3">
Selected Products ({selectedProducts.length})
</h3>
<div className="overflow-x-auto">
<table className="min-w-full border border-gray-300 dark:border-gray-700">
<thead className="bg-gray-100 dark:bg-gray-800">
<tr>
<th className="px-4 py-2 text-left border-b border-gray-300 dark:border-gray-700">
Product
</th>
<th className="px-4 py-2 text-left border-b border-gray-300 dark:border-gray-700">
Sales ($K)
</th>
</tr>
</thead>
<tbody>
{selectedProducts.length === 0 ? (
<tr>
<td
colSpan={2}
className="px-4 py-8 text-center text-gray-400 dark:text-gray-600 italic"
>
this table is empty
</td>
</tr>
) : (
selectedProducts.map((product, idx) => (
<tr
key={product.label}
className={idx % 2 === 0 ? 'bg-white dark:bg-gray-900' : 'bg-gray-50 dark:bg-gray-800'}
>
<td className="px-4 py-2 border-b border-gray-200 dark:border-gray-700 font-mono">
<span
className="inline-block w-3 h-3 rounded-full mr-2"
style={{ backgroundColor: product.color }}
/>
{product.label}
</td>
<td className="px-4 py-2 border-b border-gray-200 dark:border-gray-700 font-semibold">
${product.value.toLocaleString()}
</td>
</tr>
))
)}
</tbody>
</table>
</div>
</div>
{/* Controls */}
<div className="flex gap-3 text-sm">
<button
onClick={() => setSelectedIndices([])}
className="px-3 py-1.5 bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 rounded"
disabled={selectedProducts.length === 0}
>
Clear Selection
</button>
<button
onClick={() => setSelectedIndices(productData.label.map((_, i) => i))}
className="px-3 py-1.5 bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 rounded"
>
Select All
</button>
<button
onClick={() => {
// Select top 3 by sales
const sorted = productData.value
.map((val, i) => ({ index: i, value: val }))
.sort((a, b) => b.value - a.value)
.slice(0, 3)
.map(item => item.index);
setSelectedIndices(sorted);
}}
className="px-3 py-1.5 bg-blue-500 hover:bg-blue-600 text-white rounded"
>
Select Top 3
</button>
</div>
</div>
);
}