The legend is visible in syncfusion chart page but not when the screenshot of the same is added to the pdf

Hello,

This is the screenshot of the page which I am trying to add to my pdf

Image_2195_1725383153859

This is what I am getting in the pdf

Image_7923_1725383115610


7 Replies

PS Preethika Selvam Syncfusion Team September 4, 2024 01:09 PM UTC

Hi Nikhitha,


We tried to replicate the reported issue at our end. We tried the following ways to reproduce the issue:



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.


Attachment: fr194295_49f641d4.zip


NS Nikhitha Sriram September 4, 2024 02:09 PM UTC

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



Attachment: syncfusion_ac1d9a1a.zip


PS Preethika Selvam Syncfusion Team September 5, 2024 01:57 PM UTC

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.


Attachment: fr194295_(2)_2d8db8a5.zip


NS Nikhitha Sriram September 5, 2024 02:48 PM UTC

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?



PS Preethika Selvam Syncfusion Team September 6, 2024 09:33 AM UTC

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.



NS Nikhitha Sriram September 8, 2024 07:43 AM UTC

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 



TC Thilip Chandru Soundraraj Syncfusion Team September 9, 2024 06:07 AM UTC

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.



Loader.
Up arrow icon