This is a migrated thread and some comments may be shown as answers.

How to generate chart image without showing it?

5 Answers 197 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Simon
Top achievements
Rank 1
Simon asked on 22 Jul 2011, 07:06 PM

I would like to generate the charts without actually showing it (in a WPF application), and then save them to image.

However, when I run, I hit  the InvalidOperationException

5 Answers, 1 is accepted

Sort by
0
Simon
Top achievements
Rank 1
answered on 26 Jul 2011, 02:27 AM
Got some sample code. I hit 
                    InvalidOperationException: "The calling thread cannot access this object because a different thread owns it."

at this line:

                     chart.Save(path);

Please let me know what I can do to avoid this.

MainWindow.xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Content="Save Graph" Height="22" HorizontalAlignment="Left" Margin="423,277,0,0" Name="button1" VerticalAlignment="Top" Width="80" Click="button1_Click" />
    </Grid>
</Window>


MainWindow.xaml.cs:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Charting;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            SaveChartProcessor _ruleProcessor = new SaveChartProcessor();
            _ruleProcessor.SaveImage();
        }
    }

    public class SaveChartProcessor
    {
        public void SaveImage()
        {
            var newThread = new Thread(processChartImageWorker);
            newThread.SetApartmentState(ApartmentState.STA);
            newThread.Start();
        }

        public void processChartImageWorker()
        {
            RadChart chart = GetChart();

            string path = "d:\\newpic.png";

            chart.Dispatcher.Invoke(
                    new Action(() =>
                    {
                        chart.Save(path);
                    }),
                    DispatcherPriority.Normal);
        }

        public RadChart GetChart()
        {
            var chart = new RadChart();
            chart.BeginInit();

            chart.Width = 640;
            chart.Height = 480;
            chart.DefaultView.ChartArea.EnableAnimations = false;

            SeriesMapping sm1 = new SeriesMapping();
            sm1.SeriesDefinition = new LineSeriesDefinition();
            sm1.LegendLabel = "Line Series 1";
            sm1.CollectionIndex = 0;
            ItemMapping im1 = new ItemMapping();
            im1.DataPointMember = DataPointMember.YValue;
            sm1.ItemMappings.Add(im1);
            SeriesMapping sm2 = new SeriesMapping();
            sm2.SeriesDefinition = new LineSeriesDefinition();
            sm2.LegendLabel = "Line Series 2";
            sm2.CollectionIndex = 1;
            ItemMapping im2 = new ItemMapping();
            im2.DataPointMember = DataPointMember.YValue;
            sm2.ItemMappings.Add(im2);

            // Force chart to measure itseft so it provides the actual width and height to export
            chart.Measure(new System.Windows.Size(chart.Width, chart.Height));
            chart.Arrange(new System.Windows.Rect(chart.DesiredSize));

            chart.SeriesMappings.Add(sm1);
            chart.SeriesMappings.Add(sm2);

            chart.EndInit();

            var itemsSource = new List<double>[] { new List<double> { 9, 2, 3, 4 }, new List<double> { 5, 7, 3, 4 } };
            chart.ItemsSource = itemsSource;
            return chart;
        }
    }
}
0
Simon
Top achievements
Rank 1
answered on 26 Jul 2011, 07:06 PM
Why no one reply? Can some one help?
0
Sia
Telerik team
answered on 28 Jul 2011, 12:25 PM
Hi Simon,

First of all, please excuse us for our late reply.
You can find a possible solution in the attached files. There a RadChart is added to the visual tree but in hidden container. Please let us know whether this is appropriate for your scenario.

Regards,
Sia
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Simon
Top achievements
Rank 1
answered on 28 Jul 2011, 06:55 PM
No, I can't do this in my UI thread. In my case, I have to put the logic in a different class that doens't implement WPF window. I need to  spin out a separate thread that calls this class and this class has a function that create the RadChart then save it as image. can you try to modify my codes to see if you can get it working?
0
Sia
Telerik team
answered on 03 Aug 2011, 07:29 AM
Hi Simon,

Please expect soon our answer in the other forum thread concerning the same issue.

Thank you,
Sia
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get now >>

Tags
Chart
Asked by
Simon
Top achievements
Rank 1
Answers by
Simon
Top achievements
Rank 1
Sia
Telerik team
Share this question
or