チャートをわかりやすく印刷することは厄介なタスクになりかねせん。大規模なデータを印刷するときは特にそうです。チャートの印刷には、使用事例と要件に応じてさまざまな方法があります。たとえば、チャートのデータ量が少なかったり、詳細なデータポイントではなくデータの全体的なパターンを把握したい場合は、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 デモをダウンロードしてください。