Hello,
This is the screenshot of the page which I am trying to add to my pdf
This is what I am getting in the pdf
Hi Nikhitha,
We tried to replicate the reported issue at our end. We tried the following ways to reproduce the issue:
Checked with the latest chart version 26.2.12.
Checked on Mobile, Web, and Windows platforms.
Checked with all the LegendPosition types and legend ChartAlignment type.
Checked with the legendItemBuilder.
Checked with all legend overflowMode types.
Unfortunately, we are not able to reproduce the reported issue. If you still face the issue with latest version 26.2.12, we kindly request you to try to replicate the reported issue in the below attached test sample and provide us with more details regarding the specific scenario in which you are encountering this issue. This will help us to assist you more effectively.
Output:
Regards,
Preethika Selvam.
Hello Preethika,
Thank You for your reply
The place where I am showing the graph is a different from where I want to create the pdf
so I am using screenshot.captureFromWidget() to create the pdf
I have attached the zip file , which u can use to reproduce the issue
Hi Nikhitha,
We have analyzed your code snippet and found that the screenshot only included the chart itself without considering its additional components, such as the legend. To resolve this, we ensured that the ScreenshotController was correctly capturing the entire widget, including the legend, by using ScreenshotController.capture with an appropriate pixel ratio to include all details. By making these adjustments, we ensured that the complete widget, including the legend, was captured, and correctly rendered in the PDF. We have shared the modified code snippet, sample, and output for your reference.
Code snippet:
|
ScreenshotController screenshotController = ScreenshotController();
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Chart to PDF'), ), body: Screenshot( controller: screenshotController, child: const Center(child: ExportChartToPdf()), ), floatingActionButton: FloatingActionButton( onPressed: () async { // Delay to ensure the widget is fully rendered await Future.delayed(const Duration(milliseconds: 500)); screenshotController .capture( pixelRatio: 3.0) // Capture with the specified pixel ratio .then((Uint8List? image) { if (image != null) { _renderPDF(image); } }); }, child: const Icon(Icons.picture_as_pdf), ), ); } }
class ExportChartToPdf extends StatefulWidget { const ExportChartToPdf({Key? key}) : super(key: key);
@override ExportChartToPdfState createState() => ExportChartToPdfState(); }
class ExportChartToPdfState extends State<ExportChartToPdf> { late List<ChartSampleData> _chartData1; late List<ChartSampleData> _chartData2; late List<ChartSampleData> _chartData3;
@override void initState() { _chartData1 = <ChartSampleData>[ ChartSampleData(x: DateTime(2024, 1, 1), y: 350), ChartSampleData(x: DateTime(2024, 2, 1), y: 280), ChartSampleData(x: DateTime(2024, 3, 1), y: 330), ChartSampleData(x: DateTime(2024, 4, 1), y: 320), ChartSampleData(x: DateTime(2024, 5, 1), y: 400), ]; _chartData2 = <ChartSampleData>[ ChartSampleData(x: DateTime(2024, 1, 1), y: 300), ChartSampleData(x: DateTime(2024, 2, 1), y: 250), ChartSampleData(x: DateTime(2024, 3, 1), y: 310), ChartSampleData(x: DateTime(2024, 4, 1), y: 290), ChartSampleData(x: DateTime(2024, 5, 1), y: 380), ]; _chartData3 = <ChartSampleData>[ ChartSampleData(x: DateTime(2024, 1, 1), y: 370), ChartSampleData(x: DateTime(2024, 2, 1), y: 260), ChartSampleData(x: DateTime(2024, 3, 1), y: 340), ChartSampleData(x: DateTime(2024, 4, 1), y: 310), ChartSampleData(x: DateTime(2024, 5, 1), y: 420), ]; super.initState(); }
@override Widget build(BuildContext context) { return SfCartesianChart( legend: const Legend( isVisible: true, position: LegendPosition.top, overflowMode: LegendItemOverflowMode.wrap, ), primaryXAxis: const DateTimeCategoryAxis( title: AxisTitle(text: 'Date'), ), primaryYAxis: const NumericAxis( title: AxisTitle(text: 'Values'), ), axes: const <ChartAxis>[ NumericAxis( name: 'yAxis', opposedPosition: true, title: AxisTitle(text: 'Secondary Y Axis'), ), ], series: <LineSeries<ChartSampleData, DateTime>>[ LineSeries<ChartSampleData, DateTime>( animationDuration: 0, dataSource: _chartData1, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y, name: 'Series 1', color: Colors.blue, ), LineSeries<ChartSampleData, DateTime>( animationDuration: 0, dataSource: _chartData2, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y, name: 'Series 2', color: Colors.green, ), LineSeries<ChartSampleData, DateTime>( animationDuration: 0, dataSource: _chartData3, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y, name: 'Series 3', color: Colors.red, ), LineSeries<ChartSampleData, DateTime>( animationDuration: 0, dataSource: _chartData1, xValueMapper: (ChartSampleData data, _) => data.x, yValueMapper: (ChartSampleData data, _) => data.y, name: 'Series 1 (Duplicate)', color: Colors.pink, ), ], ); } }
class ChartSampleData { ChartSampleData({this.x, this.y}); final DateTime? x; final num? y; }
Future<void> _renderPDF(Uint8List image) async { final PdfBitmap bitmap = PdfBitmap(image); final PdfDocument document = PdfDocument(); document.pageSettings.size = Size(bitmap.width.toDouble(), bitmap.height.toDouble()); final PdfPage page = document.pages.add(); final Size pageSize = page.getClientSize(); page.graphics .drawImage(bitmap, Rect.fromLTWH(0, 0, pageSize.width, pageSize.height)); final List<int> bytes = document.saveSync(); document.dispose();
final Directory directory = await getApplicationSupportDirectory(); final String path = directory.path; File file = File('$path/Output.pdf'); await file.writeAsBytes(bytes, flush: true); OpenFile.open('$path/Output.pdf'); } |
Output:
Please let us know if you need any further assistance.
Regards,
Preethika Selvam.
Hello,
Thank you for your fast response,
According to your solution you are adding the graph to the widget tree,
I don't what the graph to visible to the user, I am developing a report the users can download which includes a table and respective graph ,That is why I am using screenshot.captureFromWidget() , is there any way I can do this?
Hi Nikhitha,
As per our current implementation, the toImage method is accessible only through the SfCartesianChartState. To access the toImage method, the chart must be rendered, as it relies on the current state of the chart. If the chart has not been rendered or is not visible, the current state will be null, preventing access to the toImage method. Therefore, it's necessary to render the chart in the view to convert it into an image.
UG Link: https://help.syncfusion.com/flutter/cartesian-charts/export-cartesian-chart#export-pdf
However, in your case, when using the screenshot widget instead of the toImage method, attempting to export the chart to PDF without rendering it on the screen will result in the screenshot capturing only the chart itself, excluding additional components such as the legend. Therefore, in this scenario as well, it is necessary to render the chart in the view to accurately capture all elements as an image.
Please let us know if you need any further assistance.
Regards,
Preethika Selvam.
Hello Preethika,
Thank you for your response
I found a method to make it work , basically I fixed the colors of the graph and drew my own legend on the pdf
Hi Nikhitha,
Most Welcome. Kindly get back to us if you have further queries. We are always happy to assist you.
Regards,
S Thilip Chandru.