FlexChart for WinForms
印刷

チャートをわかりやすく印刷することは厄介なタスクになりかねせん。大規模なデータを印刷するときは特にそうです。チャートの印刷には、使用事例と要件に応じてさまざまな方法があります。たとえば、チャートのデータ量が少なかったり、詳細なデータポイントではなくデータの全体的なパターンを把握したい場合は、1 ページにチャートを 1 つ印刷だけでよいでしょう。一方、チャートを詳細に検討する場合は、各ページに 1 つずつチャートを表示したり、1 つのチャートのサブチャートやストリップチャートを複数ページに表示することができます。

チャートの印刷

FlexChart では、C1.Chart.FlexChart.Printing アセンブリを使用して印刷を実行できます。このアセンブリは、C1.Chart.FlexChart.Printing という名前の製品サンプルをビルドし、プロジェクト内の obj\Debug フォルダにアクセスすることで取得できます。このアセンブリは、FlexChart の印刷を実現する ChartPrinter クラスを提供します。以下のセクションで、このクラスをさまざまな印刷シナリオで使用する方法について説明します。

メモ: ComponentOneC1ControlPanel.exe を使用して WinForms Edition をインストールする際にサンプルをインストールした場合、「C1.Chart.FlexChart.Printing」サンプルは、システムの \Documents\ComponentOne Samples\WinForms\v4.5.2\C1FlexChart\CS\FlexChartPrint にあります。

単一ページの印刷

FlexChart では、上記の ChartPrinter クラスのインスタンスを作成して、1 つのチャートを 1 ページに印刷できます。 コンストラクタは 2 つのパラメータを受け取ります。1 つは対象の FlexChart インスタンスで、もう 1 つは印刷ダイアログを表示するかどうかを示すブール値です。次に、PrintScale 列挙を使用して、印刷時にチャートの拡大縮小を調整するかどうかを指定します。この列挙では、使用可能なスペースに合わせて、チャートの拡大縮小を none(なし)、fit(自動調整)、stretch(引き伸ばし)、zoom(ズーム)に設定できます。または、カスタムページおよびプリンタ設定、グレースケールなどを要件に合わせて設定してから、PrintScale などの設定をパラメータとして受け取る PrintCtrl メソッドを呼び出すこともできます。

private void btnPrint_Click(object sender, EventArgs e)
{
    // ChatPrinterを作成します
    ChartPrinter chartPrinter = new ChartPrinter(flexChart1, true);

    // ページ設定を行います
    if (PageSettngs == null)
        PageSettngs = new PageSettings() { Landscape = true };

    // デフォルトのページ設定をカスタムページ設定に置き換えます
    chartPrinter.PageSettingsProp = PageSettngs;

    // デフォルトのプリンタ設定をカスタムプリンタ設定に置き換えます
    if (PrinterSettngs != null)
    {
        chartPrinter.PrintSettingsProp = PrinterSettngs;
    }

    // 四角形に応じてFlexChartのサイズを変更するかどうかを設定します
    ChartPrinter.PrintScale pscale =
        (ChartPrinter.PrintScale)Enum.Parse(typeof(ChartPrinter.PrintScale), "None");

    // グレースケールで印刷するかどうかを設定します
    chartPrinter.UseGrayScale = false;

    bool usePrintPreview = true;
    bool printAsBitmap = false;

    // 特定のプリンタとページ設定でFlexChartを印刷します
    chartPrinter.PrintCtrl(pscale, new Rectangle(100,200,400,400), PageSettngs, printAsBitmap, usePrintPreview);
}
Private Sub btnPrint_Click(sender As Object, e As EventArgs)
     ' ChatPrinterを作成します
     Dim chartPrinter As New ChartPrinter(flexChart1, True)

     ' ページ設定を行います
     If PageSettngs Is Nothing Then
          PageSettngs = New PageSettings() With {
             .Landscape = True
          }
     End If

     ' デフォルトのページ設定をカスタムページ設定に置き換えます
     chartPrinter.PageSettingsProp = PageSettngs

     ' デフォルトのプリンタ設定をカスタムプリンタ設定に置き換えます
     If PrinterSettngs IsNot Nothing Then
          chartPrinter.PrintSettingsProp = PrinterSettngs
     End If

     ' 四角形に応じてFlexChartのサイズを変更するかどうかを設定します
     Dim pscale As ChartPrinter.PrintScale = CType([Enum].Parse(GetType(ChartPrinter.PrintScale), "None"), ChartPrinter.PrintScale)

     ' グレースケールで印刷するかどうかを設定します
     chartPrinter.UseGrayScale = False

     Dim usePrintPreview As Boolean = True
     Dim printAsBitmap As Boolean = False

     ' 特定のプリンタとページ設定でFlexChartを印刷します
     chartPrinter.PrintCtrl(pscale, New Rectangle(100, 200, 400, 400), PageSettngs, printAsBitmap, usePrintPreview)
End Sub

複数ページの印刷

1 つまたは複数のチャートを複数のページで印刷する必要があるシナリオはさまざま考えられます。 複数ページの印刷を実行するには、上記の ChartPrinter クラスを PrintDocument と組み合わせて使用する必要があります。PrintDocument クラスは、印刷関連の設定と共に、メインの印刷ジョブを実装するために必要な PrintPage イベントを提供します。レイアウト要件に応じて、ChartPrinter クラスの PrinterCtrlToPage メソッド、FlexChart クラスの DrawChart メソッド、または Graphics クラスの DrawImage メソッドを使用できます。この例では、1 つのチャートを複数のページにサブチャート形式で印刷する方法を示します。

複数のページの印刷

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;

    // チャートを印刷する際の制限を決定します
    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)
         {
              // 現在の軸制限を保存します
              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)
         {
              // 各チャートまたはページは異なるFlexChartインスタンスを使用できますが、
              // この場合、単一のFlexChartインスタンスのサブセットが使用されます
              ChartPrinter chartPrinter = new ChartPrinter(ShowAxisY, true);

              // チャートは、prinPageEventArgsで指定されているように、左上のページマージン
              // を基準にした座標を想定して四角形内に描画されます
              // 空の四角形は、ページ上の限定された四角形ではなく、ページ全体を示します
              Rectangle rect = new Rectangle(0, 0, 0, 0);

              printPageEventArgs.HasMorePages = pageNumber < 30;       
              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)
              {
                   // 次のページに向けて設定します
                   ShowAxisY.AxisX.Min += increment;
                   ShowAxisY.AxisX.Max += increment;
              }
         }
         else
         {
              bool morepages = pageNumber < 8;
              printPageEventArgs.HasMorePages = morepages;
         }
    };

    pd.EndPrint += (pageSender, endPrintEventArgs) =>
    {
         if(ShowAxis)
         {
              // 軸の制限を復元します
              ShowAxisY.AxisX.Max = maxFlex;
              ShowAxisY.AxisX.Min = minFlex;
              ShowAxisY.AxisY.Max = maxFlexY;
              ShowAxisY.AxisY.Min = minFlexY;
         }
         else
         {
              bitmapLeft = 0;
         }
        // プレビューダイアログからの次の印刷のためにリセットします
        pageNumber = 0;
    };

    ChartPrinter.ChartPreviewDialogEx(pd, true);
    pd.Dispose();
}
Private Sub btnSubCharts_Click(sender As Object, e As EventArgs)
     If PageSettngs Is Nothing Then
          PageSettngs = New PageSettings() With {
            .Landscape = True
          }
     End If

     Dim pd As New PrintDocument()
     pd.DefaultPageSettings = PageSettngs
     pd.PrinterSettings = PrinterSettngs

     Dim pageNumber As Integer = 0

     ' チャートを印刷する際の制限を決定します
     Dim pageCount As Integer = 8
     Dim minXValue As Double = 0
     Dim maxXValue As Double = ShowAxisY.AxisX.ActualMax

     Dim increment As Double = (maxXValue - minXValue) / pageCount

     Dim minFlex As Double = Double.NaN, maxFlex As Double = Double.NaN
     Dim minFlexY As Double = Double.NaN, maxFlexY As Double = Double.NaN
     Dim bitmapLeft As Integer = 0

     AddHandler pd.BeginPrint, Sub()
                                    If ShowAxis Then
                                         ' 現在の軸制限を保存します
                                         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
                                    End If
                                    pageNumber = 0

                               End Sub

     AddHandler pd.PrintPage, Sub(pageSender, printPageEventArgs)
                                   pageNumber += 1

                                   If ShowAxis Then
                                        ' 各チャートまたはページは異なるFlexChartインスタンスを使用できますが、
                                        ' この場合、単一のFlexChartインスタンスのサブセットが使用されます
                                        Dim chartPrinter__1 As New ChartPrinter(ShowAxisY, True)

                                        ' チャートは、prinPageEventArgsで指定されているように、左上のページマージン
                                        ' を基準にした座標を想定して四角形内に描画されます
                                        ' 空の四角形は、ページ上の限定された四角形ではなく、ページ全体を示します
                                        Dim rect As New Rectangle(0, 0, 0, 0)

                                        printPageEventArgs.HasMorePages = pageNumber < 30
                                        chartPrinter__1.PrinterCtrlToPage(pd, printPageEventArgs, ChartPrinter.PrintScale.Fit, rect, False)
                                   Else
                                        Dim pageWidth As Integer = PageSettngs.Bounds.Width - PageSettngs.Margins.Left - PageSettngs.Margins.Right
                                        Dim pageHeight As Integer = PageSettngs.Bounds.Height - PageSettngs.Margins.Top - PageSettngs.Margins.Bottom
                                        Dim bitMapWidth As Integer = pageCount * pageWidth
                                        Dim bitMapHeight As Integer = pageHeight
                                        Dim incremnt As Integer = bitMapWidth \ pageCount
                                        Dim bitmap As New Bitmap(bitMapWidth, bitMapHeight)
                                        Using gr As Graphics = Graphics.FromImage(bitmap)
                                             Me.ShowAxisY.DrawChart(gr, New Size(bitMapWidth, bitMapHeight))
                                        End Using
                                        Dim g As Graphics = 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
                                   End If
                                   If ShowAxis Then
                                        Dim morePages__2 As Boolean = ShowAxisY.AxisX.Max < maxXValue
                                        printPageEventArgs.HasMorePages = morePages__2
                                        If morePages__2 Then
                                             ' 次のページに向けて設定します
                                             ShowAxisY.AxisX.Min += increment
                                             ShowAxisY.AxisX.Max += increment
                                        End If
                                   Else
                                        Dim morepages__3 As Boolean = pageNumber < 8
                                        printPageEventArgs.HasMorePages = morepages__3
                                   End If

                              End Sub

     AddHandler pd.EndPrint, Sub()
                                  If ShowAxis Then
                                       ' 軸の制限を復元します
                                       ShowAxisY.AxisX.Max = maxFlex
                                       ShowAxisY.AxisX.Min = minFlex
                                       ShowAxisY.AxisY.Max = maxFlexY
                                       ShowAxisY.AxisY.Min = minFlexY
                                  Else
                                       bitmapLeft = 0
                                  End If
                                  ' プレビューダイアログからの次の印刷のためにリセットします
                                  pageNumber = 0

                             End Sub

     ChartPrinter.ChartPreviewDialogEx(pd, True)
                                  pd.Dispose()
                             End Sub

その他の印刷シナリオと詳細な実装方法については、コントロールに付属する FlexChartExplorer サンプルを参照してください。この機能の実際の動作を見るには、Mescius Web サイトから FlexChartExplorer デモをダウンロードしてください。