SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, iOS Chart, Android Chart and JavaScript Chart Components
Hello chaps. I’ve modified the examples found in the “Offscreen rendering” post to scale a chart for printing, works great for my line serieses. I’ve made it nice and generic because I was hoping to just hand over a second chart with the other type of series being used – a FastMountainRenderableSeries, but whilst that looks great on the screen, none of the points render when it’s printed. The surface itself does, but not the data in the series. I’ve created a UserControl:
<UserControl x:Class="SciChart.MultiAxes.View.Charting.MyChartView" xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc=" http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:scichart=" http://schemas.abtsoftware.co.uk/scichart" xmlns:utilconv="clr-namespace:MyUtility.Converters;assembly=MyUtility" xmlns:d=" http://schemas.microsoft.com/expression/blend/2008" > <Grid> <scichart:SciChartSurface x:Name="sciChartSurface" Background="White" scichart:ThemeManager.Theme="Chrome" DataSet="{Binding HistogramData,Mode=TwoWay}"> <scichart:SciChartSurface.RenderableSeries> <scichart:FastMountainRenderableSeries SeriesColor="Black" AreaColor="Black" /> </scichart:SciChartSurface.RenderableSeries> <scichart:SciChartSurface.XAxis> <scichart:NumericAxis AxisTitle="Standard Deviation" DrawMinorGridLines="False" DrawMinorTicks="False" > <scichart:NumericAxis.VisibleRange> <scichart:DoubleRange Min="-6.000" Max="6.000" /> </scichart:NumericAxis.VisibleRange> </scichart:NumericAxis> </scichart:SciChartSurface.XAxis> <scichart:SciChartSurface.YAxis> <scichart:NumericAxis AxisAlignment="Left" AutoRange="True" DrawMinorGridLines="False" DrawMajorGridLines="False" /> </scichart:SciChartSurface.YAxis> <scichart:SciChartSurface.ChartModifier> <scichart:ModifierGroup> <scichart:RubberBandXyZoomModifier IsXAxisOnly="True" /> <scichart:ZoomExtentsModifier ExecuteOn="MouseDoubleClick" /> </scichart:ModifierGroup> </scichart:SciChartSurface.ChartModifier> <scichart:SciChartSurface.Annotations> <scichart:VerticalLineAnnotation VerticalAlignment="Stretch" ShowLabel="False" Stroke="#bb27AAE1" StrokeThickness="2" X1="4" Y1="0" /> <scichart:VerticalLineAnnotation VerticalAlignment="Stretch" ShowLabel="False" Stroke="#bb27AAE1" StrokeThickness="2" X1="-4" Y1="0" /> <scichart:TextAnnotation Text="{Binding StandardDeviation,StringFormat=Standard Deviation: {0}}" X1="0.000" Y1="0.000" CoordinateMode="Relative" HorizontalAnchorPoint="Left" VerticalAnchorPoint="Top" AnnotationCanvas="AboveChart" FontSize="12" FontWeight="Normal" Foreground="#ff000000"/> <scichart:TextAnnotation Text="{Binding ExceedanceCount,StringFormat=Number of Exceedances: {0}}" X1="0.000" Y1="0.050" CoordinateMode="Relative" HorizontalAnchorPoint="Left" VerticalAnchorPoint="Top" AnnotationCanvas="AboveChart" FontSize="12" FontWeight="Normal" Foreground="#ff000000"/> <scichart:TextAnnotation Text="{Binding Kurtosis,StringFormat=Kurtosis: {0}}" X1="0.000" Y1="0.100" CoordinateMode="Relative" HorizontalAnchorPoint="Left" VerticalAnchorPoint="Top" AnnotationCanvas="AboveChart" FontSize="12" FontWeight="Normal" Foreground="#ff000000"/> </scichart:SciChartSurface.Annotations> </scichart:SciChartSurface> </Grid> </UserControl>
And the interesting parts of the code:
<pre class="brush: csharp; gutter: true; first-line: 1; highlight: []; html-script: false">
public partial class MyChartView : UserControl, IPrintChart
{
// …
public void Prepare(Rect renderBox)
{
this.BeginInit();
this.Width = renderBox.Width;
this.Height = renderBox.Height;
this.sciChartSurface.OnLoad();
this.EndInit();
this.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
this.Arrange(renderBox);
this.UpdateLayout();
}
Then in my VM:
private readonly IPrintChart _chart; public Visual GetPage(int pageNumber) { var transformedVisual = new DrawingVisual(); if (pageNumber == 0) { this._chart.Prepare(new Rect(0d, 0d, this.PageSize.Height, this.PageSize.Width)); var sourceBitmap = BitmapUtility.ExportElementToBitmap(this._chart.AsFrameworkElement()); var targetBitmap = new RenderTargetBitmap((int)this.PageSize.Width, (int)this.PageSize.Height, sourceBitmap.DpiX, sourceBitmap.DpiY, PixelFormats.Default); var finalTransform = new TransformGroup(); // prepare the transform finalTransform.Children.Add(new RotateTransform(-90d)); finalTransform.Children.Add(new TranslateTransform(0, this.PageSize.Height)); // use an image control to manipulate and layout using canvas Image rotatedImage = new Image { Stretch = Stretch.None, Source = sourceBitmap, RenderTransform = finalTransform }; Canvas container = new Canvas(); container.Children.Add(rotatedImage); container.Arrange(new Rect(0d, 0d, sourceBitmap.PixelWidth, sourceBitmap.PixelHeight)); // render into final bitmap targetBitmap.Render(container); // finally, draw the image into the outgoing visual object using (DrawingContext drawingContext = transformedVisual.RenderOpen()) { drawingContext.DrawImage(targetBitmap, new Rect(0d, 0d, this.PageSize.Width, this.PageSize.Height)); } } return transformedVisual; }
(You might recognise large chunks of it ;->)
I’ve got a whole standalone demo project (in fact an updated version of the project you’ve already seen for the multi-axis scaling example) but it’s a bit too domain-specific to put into the public’s hands as it is so I’ll email it if useful???
The data I pass into the control for print is a copy of the one used for displaying, so it isn’t a problem with the points/series being tied to a different surface, in case you wondered … ???
This is v1.5 beta in VS 2012 on Windows 8 x64.
Thanks for your help,
AC
Update: Since this is a frequently asked question, we’ve created a tutorial on Render to Bitmap, Screen Capture of Charts & XPS Printing.
http://http://www.scichart.com/screenshots-xps-printing-x-axis-text-labels/
Best regards,
SciChart Support
Please login first to submit.