barChart function
Simple pure-SVG bar chart component.
Renders a lightweight, high-performance bar chart without external charting dependencies.
Implementation
BloomNode barChart({
required List<ChartDataPoint> data,
double? maxValue,
double height = 160,
String? color,
String extraClassName = '',
}) {
if (data.isEmpty) {
return Div(
className: cn([
'h-40 flex items-center justify-center text-xs text-[var(--text-muted)] border border-dashed border-[var(--border)] rounded-[var(--radius-md)]',
extraClassName,
]),
text: 'No data available',
);
}
final computedMax = maxValue ??
(data.map((d) => d.value).reduce(math.max) > 0
? data.map((d) => d.value).reduce(math.max)
: 1.0);
final chartHeight = height;
final plotHeight = chartHeight - 28.0;
final barWidth = 24.0;
final gap = 16.0;
final totalWidth = (data.length * (barWidth + gap)) + gap;
final barColor = color ?? 'var(--primary)';
final bars = <BloomNode>[];
// Grid line at bottom of plot
bars.add(El(
'line',
attrs: {
'x1': '0',
'y1': '$plotHeight',
'x2': '$totalWidth',
'y2': '$plotHeight',
'stroke': 'var(--border)',
'stroke-width': '1',
},
));
for (var i = 0; i < data.length; i++) {
final item = data[i];
final normalized = (item.value / computedMax).clamp(0.0, 1.0);
final barH = (normalized * (plotHeight - 10.0)).clamp(2.0, plotHeight);
final x = gap + i * (barWidth + gap);
final y = plotHeight - barH;
// Bar rectangle
bars.add(El(
'rect',
attrs: {
'x': '$x',
'y': '$y',
'width': '$barWidth',
'height': '$barH',
'rx': '3',
'fill': barColor,
},
));
// Label under bar
bars.add(El(
'text',
attrs: {
'x': '${x + barWidth / 2}',
'y': '${chartHeight - 8}',
'text-anchor': 'middle',
'font-size': '10',
'font-family': 'var(--font-sans)',
'fill': 'var(--text-muted)',
},
text: item.label,
));
}
return Div(
attrs: const {'data-slot': 'bar-chart'},
className: cn([
'w-full overflow-x-auto p-3 bg-[var(--card)] border border-[var(--border)] rounded-[var(--radius-lg)] shadow-[var(--shadow-card)]',
extraClassName,
]),
children: [
El(
'svg',
attrs: {
'viewBox': '0 0 $totalWidth $chartHeight',
'width': '$totalWidth',
'height': '$chartHeight',
'aria-label': 'Bar chart',
},
className: 'overflow-visible',
children: bars,
),
],
);
}