Print

Printing a readable chart could be a tricky task, especially, while printing charts with large data. Depending on the use case and requirement, there can be multiple ways in which a chart can be printed. For instance, printing a chart on a single page is a good idea when chart has less data or you want to understand the overall pattern of data without knowing the detailed data points. On the other hand, when you want to study chart details, you can display one chart on each page or even a single chart divided into sub-charts or strip charts on multiple pages.

printing a chart

In FlexChart, you can carry out printing by using the C1.Chart.FlexChart.Printing assembly that can be obtained by building the product sample named C1.Chart.FlexChart.Printing and accessing obj\Debug folder inside the project. This assembly provides the ChartPrinter class to achieve printing in FlexChart. The sections below discuss how this class can be used in various printing scenarios.

Note: C1.Chart.FlexChart.Printing sample is located at \Documents\ComponentOne Samples\WinForms\v4.5.2\C1FlexChart\CS\FlexChartPrint on your system, if you have installed the samples while installing WinForms Edition using ComponentOneC1ControlPanel.exe.

Single Page Printing

In FlexChart, you can print a chart on a single page by creating an instance of the above-mentioned ChartPrinter class. The constructor takes two parameters, one is the target FlexChart instance and other one is a Boolean value that indicates whether to display the print dialog or not. You, then need to specify whether you need to scale the chart for printing by using the PrintScale enumeration which lets you set the chart scaling to none, fit, stretch and zoom according to the available space. You can also opt to set the custom page and printer settings, grayscale etc. as per the requirement and then call the PrintCtrl method which accepts PrintScale and some of the settings as its parameters.

private void btnPrint_Click(object sender, EventArgs e)
{
    //create Printer FlexChart
    ChartPrinter chartPrinter = new ChartPrinter(flexChart1, true);

    //set settings for page
    if (PageSettngs == null)
        PageSettngs = new PageSettings() { Landscape = true };

    //replace default page settings with custom page settings
    chartPrinter.PageSettingsProp = PageSettngs;

    //replace default printer settings with custom printer settings, if any
    if (PrinterSettngs != null)
    {
        chartPrinter.PrintSettingsProp = PrinterSettngs;
    }

    //set whether or not to resize FlexChart according to the print rectangle
    ChartPrinter.PrintScale pscale =
        (ChartPrinter.PrintScale)Enum.Parse(typeof(ChartPrinter.PrintScale), "None");

    //set whether to print in GrayScale or not
    chartPrinter.UseGrayScale = false;

    bool usePrintPreview = true;
    bool printAsBitmap = false;

    //print FlexChart with specific printer and page settings
    chartPrinter.PrintCtrl(pscale, new Rectangle(100,200,400,400), PageSettngs, printAsBitmap, usePrintPreview);
}

Multi-page Printing

There can be various scenarios in which a chart or charts are required to be printed on multiple pages. To achieve the multi-page printing, we need to use the above-mentioned ChartPrinter class in conjunction with the PrintDocument class. The PrintDocument class, along with the settings related to the print, provides the PrintPage event which is required to implement the main printing job. You can use PrinterCtrlToPage method of the ChartPrinter class, DrawChart method of the FlexChart class or DrawImage method of the Graphics class as per the layout requirements. In this example, we have demonstrated how to print a single chart on multiple pages in the form of sub-charts.

Printing multiple pages

private void btnSubCharts_Click(object sender, EventArgs e)
{
    if (PageSettngs == null)
       PageSettngs = new PageSettings { Landscape = true };

    PrintDocument pd = new PrintDocument();
    pd.DefaultPageSettings = PageSettngs;
    pd.PrinterSettings = PrinterSettngs;

    int pageNumber = 0;

    // determine the limits over which the chart should be printed.
    int pageCount = 4;
    double minXValue = 0;
    double maxXValue = ShowAxisY.AxisX.ActualMax;

    double increment = (maxXValue - minXValue) / pageCount;

    double minFlex = double.NaN, maxFlex = double.NaN;
    double minFlexY = double.NaN, maxFlexY = double.NaN;
    int bitmapLeft = 0;

    pd.BeginPrint += (pageSender, beginPrintEventArgs) =>
    {
         if(ShowAxis)
         {
              // save the current axis limits
              minFlex = ShowAxisY.AxisX.Min;
              maxFlex = ShowAxisY.AxisX.Max;
              minFlexY = ShowAxisY.AxisY.Min;
              maxFlexY = ShowAxisY.AxisY.Max;

              ShowAxisY.AxisX.Min = minXValue;
              ShowAxisY.AxisX.Max = increment;
              ShowAxisY.AxisY.Min = ShowAxisY.AxisY.ActualMin;
              ShowAxisY.AxisY.Max = ShowAxisY.AxisY.ActualMax;
         }              
         else
         {
              bitmapLeft = 0;
         }
        pageNumber = 0;
    };

    pd.PrintPage += (pageSender, printPageEventArgs) =>
    {
         pageNumber++;

         if (ShowAxis)
         {
              // Each chart or page could use a different FlexChart instance, but in this case
              // subsets of a single FlexChart instance is used.
              ChartPrinter chartPrinter = new ChartPrinter(ShowAxisY, true);

              // The chart is drawn within the rectangle assuming coordinates relative
              // to the Top-Left page margin as specified in the prinPageEventArgs.
              // An empty rectangle indicates a full page rather than a limited
              // rectangle on the page.
              Rectangle rect = new Rectangle(0, 0, 0, 0);

              printPageEventArgs.HasMorePages = pageNumber < 30;       // sanity check to avoid endless loop.
              chartPrinter.PrinterCtrlToPage(pd, printPageEventArgs, ChartPrinter.PrintScale.Fit, rect, false);
         }
         else
         {
              int pageWidth = PageSettngs.Bounds.Width - PageSettngs.Margins.Left - PageSettngs.Margins.Right;
              int pageHeight = PageSettngs.Bounds.Height - PageSettngs.Margins.Top - PageSettngs.Margins.Bottom;
              int bitMapWidth = pageCount * pageWidth;
              int bitMapHeight = pageHeight;
              int incremnt = bitMapWidth / pageCount;
              Bitmap bitmap = new Bitmap(bitMapWidth, bitMapHeight);
              using (Graphics gr = Graphics.FromImage(bitmap))
              {
                   this.ShowAxisY.DrawChart(gr, new Size(bitMapWidth, bitMapHeight));
              }
              Graphics g = printPageEventArgs.Graphics;
              g.DrawImage(bitmap,
                  new Rectangle(PageSettngs.Margins.Left, PageSettngs.Margins.Top, incremnt, bitMapHeight),
                  new Rectangle(bitmapLeft, 0, incremnt, bitMapHeight),
                  GraphicsUnit.Pixel);

              bitmapLeft += incremnt;
         }
         if(ShowAxis)
         {
              bool morePages = ShowAxisY.AxisX.Max < maxXValue;
              printPageEventArgs.HasMorePages = morePages;
              if (morePages)
              {
                   // set up for the next page.
                   ShowAxisY.AxisX.Min += increment;
                   ShowAxisY.AxisX.Max += increment;
              }
         }
         else
         {
              bool morepages = pageNumber < 8;
              printPageEventArgs.HasMorePages = morepages;
         }
    };

    pd.EndPrint += (pageSender, endPrintEventArgs) =>
    {
         if(ShowAxis)
         {
              // restore the axis limits
              ShowAxisY.AxisX.Max = maxFlex;
              ShowAxisY.AxisX.Min = minFlex;
              ShowAxisY.AxisY.Max = maxFlexY;
              ShowAxisY.AxisY.Min = minFlexY;
         }
         else
         {
              bitmapLeft = 0;
         }
        // reset for next print from preview dialog.
        pageNumber = 0;
    };

    ChartPrinter.ChartPreviewDialogEx(pd, true);
    pd.Dispose();
}

For more printing scenarios and detailed implementation, see FlexChartExplorer sample which is shipped with the control. To see this feature in action, you can also download the FlexChartExplorer demo from our website.