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

Create chart in code behind

7 Answers 336 Views
ChartView
This is a migrated thread and some comments may be shown as answers.
Cleanwatts
Top achievements
Rank 1
Cleanwatts asked on 01 Feb 2016, 07:14 PM

I’m developing a service where I need to create a chart using only code behind. The chart will then be exported to a bitmap and inserted into a RadDocument.

My code is:

Grid grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
 
RadCartesianChart chart = new RadCartesianChart();
chart.Grid = new CartesianChartGrid
             {
                 MajorLinesVisibility = GridLineVisibility.Y,
                 StripLinesVisibility = GridLineVisibility.Y
             };
 
chart.HorizontalAxis = new CategoricalAxis { PlotMode = AxisPlotMode.BetweenTicks };
chart.VerticalAxis = new LinearAxis { Minimum = 0, MajorTickLength = 5, Title = "Y axis title" };
 
// create series
for (int i = 0; i < series.Count; i++)
{
    LineSeries lineSeries = new LineSeries
                            {
                                Stroke = new SolidColorBrush(series[i].Color),
                                LegendSettings = new SeriesLegendSettings { Title = series[i].Title }
                            };
 
    foreach (var value in series[i].Values)
    {
        lineSeries.DataPoints.Add(new CategoricalDataPoint { Category = value.X, Value = value.Y });
    }
 
    chart.Series.Add(lineSeries);
}
 
RadLegend legend = new RadLegend
                   {
                       HorizontalAlignment = HorizontalAlignment.Center,
                       VerticalAlignment = VerticalAlignment.Bottom,
                       Items = chart.LegendItems
                   };
 
string panelTemplate = @"<ItemsPanelTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">" +
                       @"<StackPanel Orientation=""Horizontal""/>" +
                       @"</ItemsPanelTemplate>";
legend.ItemsPanel = (ItemsPanelTemplate)XamlReader.Parse(panelTemplate);
 
chart.SetValue(Grid.RowProperty, 0);
grid.Children.Add(chart);
 
legend.SetValue(Grid.RowProperty, 1);
grid.Children.Add(legend);
 
Size chartSize = new Size(width, height);
grid.Measure(chartSize);
grid.Arrange(new Rect(new Point(0, 0), chartSize));
 
grid.UpdateLayout();
 
RenderTargetBitmap bitmapRender = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
bitmapRender.Render(grid);
 
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapRender));
 
encoder.Save(stream);

If I set a breakpoint where the RadLegend is created, I can see that the series I’ve created have been added to chart.Series but chart.LegendItems is empty.

If I continue and export the chart to a bitmap I get an empty image.

All the code seems to be alright, what am I doing wrong?


 
 

7 Answers, 1 is accepted

Sort by
0
Petar Marchev
Telerik team
answered on 02 Feb 2016, 11:34 AM
Hi,

I suspect that the chart is not printed because you do not call the begin and end init methods. The legend is not exported because it requires an additional layout pass. This is so that the legend markers can get the adequate brushes (which may be delayed when bindings are used). So, the chart really waits for an additional frame, and at the time of the export, the chart has not yet produced legend items. Both of these can be easily worked around. I am attaching a project and a snapshot of the result. See in the project how the PrepareElementForExport method is used to address both of these peculiarities.

Let us know if all goes well or if you need further assistance.

Regards,
Petar Marchev
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Cleanwatts
Top achievements
Rank 1
answered on 02 Feb 2016, 05:04 PM

Thank you for your reply. It has partially solved my problem: I was using the assemblies from the Binaries.NoXaml folder, using those files I get a transparent image. When I changed the references in my project to use the assemblies in the Binaries folder the chart showed up in the image.

However, I could not make the legend show. The workaround in your sample project does not work since I am using a Console Application (during developement, it wll be moved to a service) and your example is using a WPF Application. I have created and a project using your sample code inside a Console Application that does not show the legend:

 

static void Main(string[] args)
{
    using (FileStream stream = File.Create("chart.png"))
    {
        Task createTask = StartSTATask(() => BuildSTAChart(stream));
        createTask.Wait();
    }
}
 
[STAThread]
private static Grid BuildSTAChart(Stream stream)
{
    Grid host = new Grid();
 
    RadCartesianChart chart = BuildChart();
    host.Children.Add(chart);
 
    RadLegend legend = BuildChartLegend(chart);
    host.Children.Add(legend);
 
    PrepareElementForExport(host, 500, 300);
    Telerik.Windows.Media.Imaging.ExportExtensions.ExportToImage(host, stream, new PngBitmapEncoder());
 
    return host;
}
 
public static Task<T> StartSTATask<T>(Func<T> func)
{
    var tcs = new TaskCompletionSource<T>();
    Thread thread = new Thread(() =>
    {
        try
        {
            tcs.SetResult(func());
        }
        catch (Exception ex)
        {
            tcs.SetException(ex);
        }
    });
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    return tcs.Task;
}

The rest of the code is the same as in your sample project.

Can I try anything else to try to make the legend show, or should I start looking for alternatives?

Regrads,

 Luis Barreira

0
Petar Marchev
Telerik team
answered on 03 Feb 2016, 08:10 AM
Hi Luis,

I tried running the code in a console application and still the legend gets exported. I am attaching the project I tested with and an image that was output. Let us know if you get the same behavior on your side or if you need further assistance.

Regards,
Petar Marchev
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Cleanwatts
Top achievements
Rank 1
answered on 03 Feb 2016, 12:01 PM

Hi Petar, 

After looking at your code, which is the same as mine, I was finally able to find the difference: the version of the .Net Framework used. Your code uses 4.0, mine uses 4.5.1.

If I change the framework version on my code to 4.0, it works as expected; if I change the framework version on your code to 4.5.1 then the legend does not show (even when using the libs from the WPF40 folder).

This is an acceptable solution only for the test project. The project where I'm including the charts is part of a very large solution and changing it back to 4.0 is not an option. Looks like for now I'm having to come up with some alternative to the legend.

Regards,

Luis Barreira

0
Petar Marchev
Telerik team
answered on 04 Feb 2016, 02:48 PM
Hello Luis,

Indeed when I change the target framework and the legend does not get exported. I can see that the LegendItems collection of the chart is empty, so it seems that we were unable to force the chart to produce legend items. We will look into this and see if we can improve this part of the chart. The only work around I can suggest at this moment is for you not to use the LegendSettings. You can manually create the legend items and feed the RadLegend yourself. Let us know how it goes.

Regards,
Petar Marchev
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Milena
Telerik team
answered on 05 Feb 2016, 09:31 AM
Hello Luis,

I'm happy to inform you that we will include this improvement in the ChartView with the upcoming Q2 2016 SP1 Release, which is scheduled for this month. I hope that you will be able to upgrade to the latest version and get the desired behavior. 

Regards,
Milena
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Cleanwatts
Top achievements
Rank 1
answered on 05 Feb 2016, 02:33 PM

Thank you both for your help.

I have come up with a temporary solution that works for now. I will try using the RadLegend again when the next version is available.

Regards,

Luis Barreira

Tags
ChartView
Asked by
Cleanwatts
Top achievements
Rank 1
Answers by
Petar Marchev
Telerik team
Cleanwatts
Top achievements
Rank 1
Milena
Telerik team
Share this question
or