Pre loader

Off-screen/Bitmap rendering


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:d=""  >
        <scichart:SciChartSurface x:Name="sciChartSurface" Background="White" scichart:ThemeManager.Theme="Chrome" DataSet="{Binding HistogramData,Mode=TwoWay}">
                <scichart:FastMountainRenderableSeries SeriesColor="Black" AreaColor="Black" />

                <scichart:NumericAxis AxisTitle="Standard Deviation" DrawMinorGridLines="False" DrawMinorTicks="False" >
                        <scichart:DoubleRange Min="-6.000" Max="6.000" />

                <scichart:NumericAxis AxisAlignment="Left" AutoRange="True" DrawMinorGridLines="False" DrawMajorGridLines="False" />

                    <scichart:RubberBandXyZoomModifier IsXAxisOnly="True" />
                    <scichart:ZoomExtentsModifier ExecuteOn="MouseDoubleClick" />

                <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"/>


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.Width = renderBox.Width;
        this.Height = renderBox.Height;
        this.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

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.Arrange(new Rect(0d, 0d, sourceBitmap.PixelWidth, sourceBitmap.PixelHeight));
                // render into final bitmap

                // 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,

  • You must to post comments

Update: Since this is a frequently asked question, we’ve created a tutorial on Render to Bitmap, Screen Capture of Charts & XPS Printing.


Best regards,
SciChart Support

  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.

Try SciChart Today

Start a trial and discover why we are the choice
of demanding developers worldwide

Start TrialCase Studies