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

Unable to save BarChart to image

4 Answers 123 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Simon
Top achievements
Rank 1
Simon asked on 29 Jul 2011, 01:28 AM
I used the following in a console app to create and save Chart to png.
It works for LineSeries but the BarSeries is missing.
Please help.



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

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            Processor processor = new Processor();
            processor.Process();
        }
    }

    public class Processor
    {
        private SaveChartProcessor _ruleProcessor = new SaveChartProcessor();
        public void Process()
        {
            var processRuleThread = new Thread(workerThreadProcessRule);
            processRuleThread.Start();
        }

        private void workerThreadProcessRule()
        {
            _ruleProcessor.SaveImage();
        }
    }


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

        public void processChartImageWorker()
        {
            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();   //<-LineSeries works
            sm1.SeriesDefinition = new BarSeriesDefinition();      //<-BarSeries doesn't work
            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 BarSeriesDefinition();
            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;

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

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

4 Answers, 1 is accepted

Sort by
0
Simon
Top achievements
Rank 1
answered on 01 Aug 2011, 09:10 PM
Hello? please confirm whether this is a bug or not. only bar chart is having issues.
0
Sia
Telerik team
answered on 03 Aug 2011, 12:35 PM
Hello Simon,

Currently there is a limitation with our bar series. When you export it, you need to add custom style to it which you cannot achieve in a console application. Please check the attached solution.

Kind regards,
Sia
the Telerik team

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

0
Simon
Top achievements
Rank 1
answered on 03 Aug 2011, 11:06 PM
Do not agree.
1. This should be treated as a bug that needs to be fixed.
2. As for workaround, it is possible to load the style from xaml in console app. Posted the codes as below for others.

I have no control out of the application type. I can only own a component that gets called by the main application.

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Threading;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Charting;
 
namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            Processor processor = new Processor();
            processor.Process();
        }
    }
 
    public class Processor
    {
        private SaveChartProcessor _ruleProcessor = new SaveChartProcessor();
        public void Process()
        {
            var processRuleThread = new Thread(workerThreadProcessRule);
            processRuleThread.Start();
        }
 
        private void workerThreadProcessRule()
        {
            _ruleProcessor.SaveImage();
        }
    }
 
 
    public class SaveChartProcessor
    {
        public Style LoadXAMLMethod()
        {
            try
            {
                StreamReader mysr = new StreamReader("BarStyle.xaml");
                Page rootObject = XamlReader.Load(mysr.BaseStream) as Page;
                var grid = rootObject.FindName("LayoutRoot") as Grid;
                return grid.Resources["ExportStyle"] as Style;
            }
            catch (FileNotFoundException ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
 
            return null;
        }
 
        public void SaveImage()
        {
            var newThread = new Thread(processChartImageWorker);
            newThread.SetApartmentState(ApartmentState.STA);
            newThread.Start();
        }
 
        public void processChartImageWorker()
        {
            var chart = new RadChart();
            chart.BeginInit();
 
            chart.Width = 640;
            chart.Height = 480;
            chart.DefaultView.ChartArea.EnableAnimations = false;
            Style barStyle = LoadXAMLMethod();
 
            SeriesMapping sm1 = new SeriesMapping();
            //sm1.SeriesDefinition = new LineSeriesDefinition();   //<-LineSeries works
            sm1.SeriesDefinition = new BarSeriesDefinition() { ItemStyle = barStyle };      //<-BarSeries doesn't work
            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 BarSeriesDefinition();
            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;
 
            string path = "d:\\newpic.png";
 
            chart.Dispatcher.Invoke(
                    new Action(() =>
                    {
                        chart.Save(path);
                    }),
                    DispatcherPriority.Normal);
        }
    }
}


<Page
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Title="Page1">
    <Grid x:Name="LayoutRoot">
        <Grid.Resources>
            <system:Double x:Key="BarRadiusX">0</system:Double>
            <system:Double x:Key="BarRadiusY">0</system:Double>
            <system:Double x:Key="BarMaskRadius">0</system:Double>
 
            <SolidColorBrush x:Key="BarMaskStroke" Color="Transparent" />
            <system:Double x:Key="BarMaskStrokeThickness">0</system:Double>
            <LinearGradientBrush x:Key="BarMaskBrush"  EndPoint="1,0.5" StartPoint="0,0.5">
                <GradientStop Color="#00FFFFFF"/>
                <GradientStop Color="#00FFFFFF" Offset="1"/>
                <GradientStop Color="#19FFFFFF" Offset="0.2"/>
                <GradientStop Color="#B2FFFFFF" Offset="0.2"/>
            </LinearGradientBrush>
            <SolidColorBrush x:Key="BarOpacityMaskBrush" Color="#FF000000" />
            <SolidColorBrush x:Key="BarTopMaskBrush" Color="Transparent" />
 
            <Style x:Key="ExportStyle" TargetType="telerik:Bar">
                <Setter Property="Template" >
                    <Setter.Value>
                        <ControlTemplate TargetType="telerik:Bar">
                            <Canvas Opacity="1"  x:Name="PART_MainContainer">
                                <Rectangle x:Name="PART_DefiningGeometry"                                   
                               Height="{TemplateBinding ItemActualHeight}"
                               Width="{TemplateBinding ItemActualWidth}"
                               Style="{TemplateBinding ItemStyle}"
                               RadiusX="{StaticResource BarRadiusX}"
                               RadiusY="{StaticResource BarRadiusY}" />
                                <Rectangle Height="{TemplateBinding ItemActualHeight}"
                               Width="{TemplateBinding ItemActualWidth}"
                               RadiusX="{StaticResource BarMaskRadius}"
                               RadiusY="{StaticResource BarMaskRadius}"
                               OpacityMask="{StaticResource BarOpacityMaskBrush}"
                               Fill="{StaticResource BarMaskBrush}"
                               Stroke="{StaticResource BarMaskStroke}"
                               StrokeThickness="{StaticResource BarMaskStrokeThickness}" />
                                <Rectangle x:Name="PART_SelectedState"
                                   Height="{TemplateBinding ItemActualHeight}"
                                   Width="{TemplateBinding ItemActualWidth}"
                                   RadiusX="{StaticResource BarRadiusX}"
                                   RadiusY="{StaticResource BarRadiusY}"
                                   Fill="{StaticResource BarTopMaskBrush}" />
                            </Canvas>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
    </Grid>
</Page>


0
Sia
Telerik team
answered on 08 Aug 2011, 09:53 AM
Hello Simon,

We are happy to hear that you managed to resolve your problem.

The issue can be found in our Public Issues Tracking system where you track its progress.

Greetings,
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
Simon
Top achievements
Rank 1
Share this question
or