chartSvg function
Generates a self-contained SVG, which remains vector graphics in the PDF.
Implementation
String chartSvg(ReportElement chart, Map<String, dynamic> data) {
final points = chartData(chart, data);
final width = chart.width.clamp(1, 10000);
final height = chart.height.clamp(1, 10000);
if (points.isEmpty) {
return '<svg xmlns="http://www.w3.org/2000/svg" width="$width" height="$height"/>';
}
String color(int index) =>
'#${(chart.chartColors[index % chart.chartColors.length] & 0xffffff).toRadixString(16).padLeft(6, '0')}';
String esc(String value) => value
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>');
final content = StringBuffer();
final max = points
.map((point) => point.$2.abs())
.fold<double>(0, (a, b) => a > b ? a : b);
final plotHeight = height - (chart.chartShowLabels ? 28 : 8);
if (chart.chartType == ChartType.pie) {
final total = points.fold<double>(0, (sum, point) => sum + point.$2.abs());
final radius = (width < plotHeight ? width : plotHeight) * .4;
final cx = width / 2, cy = plotHeight / 2;
var angle = -1.57079632679;
for (final entry in points.indexed) {
final sweep = total == 0 ? 0 : entry.$2.$2.abs() / total * 6.28318530718;
final x1 = cx + radius * math.cos(angle), y1 = cy + radius * math.sin(angle);
final x2 = cx + radius * math.cos(angle + sweep),
y2 = cy + radius * math.sin(angle + sweep);
final large = sweep > 3.14159265359 ? 1 : 0;
content.write(
'<path d="M $cx $cy L $x1 $y1 A $radius $radius 0 $large 1 $x2 $y2 Z" fill="${color(entry.$1)}"/>',
);
angle += sweep;
}
} else {
final slot = width / points.length;
final coords = <String>[];
for (final entry in points.indexed) {
final x = slot * entry.$1 + slot / 2;
final y =
plotHeight -
(max == 0 ? 0 : entry.$2.$2.abs() / max * (plotHeight - 8));
if (chart.chartType == ChartType.bar) {
content.write(
'<rect x="${x - slot * .32}" y="$y" width="${slot * .64}" height="${plotHeight - y}" fill="${color(entry.$1)}"/>',
);
} else {
coords.add('$x,$y');
content.write(
'<circle cx="$x" cy="$y" r="3" fill="${color(entry.$1)}"/>',
);
}
if (chart.chartShowLabels) {
content.write(
'<text x="$x" y="${height - 8}" text-anchor="middle" font-size="9">${esc(entry.$2.$1)}</text>',
);
}
}
if (coords.isNotEmpty) {
content.write(
'<polyline points="${coords.join(' ')}" fill="none" stroke="${color(0)}" stroke-width="2"/>',
);
}
}
return '<svg xmlns="http://www.w3.org/2000/svg" width="$width" height="$height">$content</svg>';
}