Saving chart as image

Charts for WPF Forum

Posted 9 years ago by Chris Ray
Version: 13.1.0580

Hello gents. I need to be able to generate a chart in code and subsequently export it as an image. I figured I could do this just using WPF even if there was no explicit support for it in Actipro Charts. I'm very close, as I have it rendering a basic chart as a PNG on my file system. Problem is that to make it work I have to set a timer, wait a random amount of time, and then run the code to export. If I try to export immediately after creation, I get an image with a border, but no data. I'm thinking it might have something to do with animations, based on the stackoverflow question that I got the render code from.

My goal is to be able to generate charts in code, then immediately obtain a MemoryStream of the PNG image of that chart, no hokey timers... Is this possible using the current Actipro Charts?

I have a fully operational project demonstrating the problem which I will send to the support email address right after creating this thread. Here is the code, however, so that others can see.

<Window x:Class="ChartToPngTest.MainWindow"
        Title="MainWindow" Height="350" Width="525">
    <Grid x:Name="mainGrid">


using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using ActiproSoftware.Windows.Controls.Charts;

namespace ChartToPngTest
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
        XYChart chart;
        public MainWindow()

            chart = new XYChart();
            chart.Width = 500;
            chart.Height = 200;
            chart.IsAxisBaselineVisible = true;
            chart.GridLineMajorVisibility = GridLineVisibility.Y;
            chart.LabelCollisionMode = LabelCollisionMode.Stacked;

            var xaxis = new XYDoubleAxis();
            xaxis.AreMajorTicksVisible = true;
            xaxis.TickMajorInterval = 1000;

            var yaxis = new XYDoubleAxis();
            yaxis.AreMajorTicksVisible = true;
            yaxis.TickMajorInterval = 1;


            var ls = new LineSeries();
            var lsl = new List<XvsY>();
            for (int i = 0; i < 10; i++)
                lsl.Add(new XvsY(i * 1000, 9 + ((double)i / 10 * (i % 2 == 0 ? 1 : -1)))); //dont ask...

            ls.ItemsSource = lsl;
            ls.XPath = "X";
            ls.YPath = "Y";


            //WritePng(); //generates a png that looks like it has a border, but no data
            this.Loaded += new RoutedEventHandler(Window1_Loaded); //waits 2 seconds, then runs WritePng()... this works.

        System.Windows.Threading.DispatcherTimer snapshotTimer;
        void Window1_Loaded(object sender, RoutedEventArgs e)
            this.snapshotTimer = new System.Windows.Threading.DispatcherTimer();
            this.snapshotTimer.Interval = TimeSpan.FromSeconds(2);
            this.snapshotTimer.Tick += new EventHandler(snapshotTimer_Tick);
            this.snapshotTimer.IsEnabled = true;

        void snapshotTimer_Tick(object sender, EventArgs e)
            this.snapshotTimer.IsEnabled = false;

        private void WritePng()
            chart.Measure(new Size(chart.Width, chart.Height));
            chart.Arrange(new Rect(new Size(chart.Width, chart.Height)));
            RenderTargetBitmap rtb = new RenderTargetBitmap((int)chart.Width, (int)chart.Height, 96, 96, PixelFormats.Pbgra32);
            PngBitmapEncoder png = new PngBitmapEncoder();
            string file = System.IO.Path.GetTempFileName() + ".png";
            using (System.IO.Stream stream = System.IO.File.Create(file))

    struct XvsY
        public double X { get; set; }
        public double Y { get; set; }

        public XvsY(double X, double Y)
            : this()
            this.X = X;
            this.Y = Y;


Thank you,


Comments (2)

Answer - Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA

Hi Chris,

Unfortunately I don't have a workaround for the current release -- however, in the next maintenance release, due to some restructuring with our Measure / Arrange logic, you'll be able to just wait for the XYChart.Loaded event and render your bitmap without the use of timers.

Actipro Software Support

Posted 9 years ago by Chris Ray

Alright well, until this release comes out, as well as the reverse Y axis issue I posted about earlier are resolved I'll be forced to continue with the other control set. :-/ I'll be waiting patiently.

The latest build of this product (v22.1.2) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.