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

issue when creating image on background

3 Answers 111 Views
ChartView
This is a migrated thread and some comments may be shown as answers.
Yonggu Kang
Top achievements
Rank 1
Iron
Yonggu Kang asked on 23 Mar 2014, 11:31 AM
Hi telerik,

I'm creating images,actually byte array, from 4 RadCartesianCharts at server side without user intervention
with parallel task using STA thread at each chart,in which saves byte array into DB
and re-assembled to bitmap image at client side to display on WPF view.
Among 4 images,others works great except 1 specific chart,which composed of only annotations.

It is incomplete at first time missing some annotaions,however, when I try re-creating
then it shows completely. All calculation procedure and every variable to draw chart is same.
Pls see attached images comparing 2 images.

Creating chart is as follows;
RadCartesianChart cartChart = GetChart(GraphTypeEnums.OGR);
 
     // decide x axis
     cartChart.HorizontalAxis = new LinearAxis() { Maximum = _calculus.XMax, Minimum = _calculus.XMin, MajorStep = 1, Title = "나이" };
     // decide y max
     cartChart.VerticalAxis = new LinearAxis() { Maximum = _calculus.YMax, Minimum = _calculus.YMin, MajorStep = 1, Title = "AMH(ng/ml)" };
 
     // draw when only allowable
     if (AnalysisCalculator.AmhResultAllowable(_age))
     {
         // no series value but chart needs a series.
         ScatterLineSeries scatterSeries = new ScatterLineSeries() { Stroke = new SolidColorBrush(Colors.Black), StrokeThickness = 2 };
         scatterSeries.XValueBinding = new PropertyNameDataPointBinding() { PropertyName = "Age" };
         scatterSeries.YValueBinding = new PropertyNameDataPointBinding() { PropertyName = "Num" };
         // 1 point of (0,0)
         scatterSeries.ItemsSource = CordXy.GetACGList(0, 0);
         cartChart.Series.Add(scatterSeries);
 
         DoubleCollection aray = new DoubleCollection(new double[] { 1, 1 });
 
         // amh line
         cartChart.Annotations.Add(
                 new CartesianGridLineAnnotation
                 {
                     Axis = cartChart.VerticalAxis,
                     Value = _calculus.AmhLineVal,
 
                     Stroke = new SolidColorBrush(Colors.Black),
                     StrokeThickness = 2,
                     DashArray = aray
                 });
 
         // age line
         cartChart.Annotations.Add(
                 new CartesianGridLineAnnotation
                 {
                     Axis = cartChart.HorizontalAxis,
                     Value = _resultRoot.MedianAge,
 
                     Stroke = new SolidColorBrush(Colors.Black),
                     StrokeThickness = 2,
                     DashArray = aray
                 });
 
         // amh range
         cartChart.Annotations.Add(
                 new CartesianMarkedZoneAnnotation
                 {
                     HorizontalFrom = _calculus.IntAge - 0.2,
                     HorizontalTo = _calculus.IntAge + 0.2,
                     VerticalFrom = _calculus.FVMax,
                     VerticalTo = _calculus.FVMin,
 
                     Fill = new SolidColorBrush(Colors.DarkGray)
                 });
 
         // value range
         cartChart.Annotations.Add(
                 new CartesianMarkedZoneAnnotation
                 {
                     HorizontalFrom = _calculus.IntAge - 0.2,
                     HorizontalTo = _calculus.IntAge + 0.2,
 
                     VerticalFrom = _calculus.RVMax,
                     VerticalTo = _calculus.RVMin,
 
                     Fill = new SolidColorBrush(_calculus.Normal ? Colors.Blue : Colors.Red)
                 });
 
         // mark top indicator
         cartChart.Annotations.Add(
                     new CartesianCustomLineAnnotation
                     {
                         HorizontalFrom = _calculus.IntAge - 0.2 + (_calculus.Normal ? 0 : -0.2),
                         HorizontalTo = _calculus.IntAge + 0.2 + (_calculus.Normal ? 0.2 : 0),
 
                         VerticalFrom = _calculus.RVMax,
                         VerticalTo = _calculus.RVMax,
 
                         Stroke = new SolidColorBrush(Colors.Black),
                         StrokeThickness = 2
                     });
 
         // boottom indicator
         cartChart.Annotations.Add(
                 new CartesianCustomLineAnnotation
                 {
                     HorizontalFrom = _calculus.IntAge - 0.2 + (_calculus.Normal ? -0.2 : 0),
                     HorizontalTo = _calculus.IntAge + 0.2 + (_calculus.Normal ? 0 : 0.2),
 
                     VerticalFrom = _calculus.RVMin,
                     VerticalTo = _calculus.RVMin,
 
                     Stroke = new SolidColorBrush(Colors.Black),
                     StrokeThickness = 2
                 });
     }


Follwoing is to convert byte array with chart.
private byte[] GetImageBytes(RadCartesianChart chart)
      {
          chart.Measure(new System.Windows.Size(chart.Width, chart.Height));
          chart.Arrange(new System.Windows.Rect(new System.Windows.Point(0, 0), chart.DesiredSize));
 
          using (var stream = new MemoryStream())
          {
              Telerik.Windows.Media.Imaging.ExportExtensions.ExportToImage(chart, stream, new PngBitmapEncoder());
              return stream.ToArray();
          }
      }

Any advice would be highly appreciated.

TIA

Kang

3 Answers, 1 is accepted

Sort by
0
Accepted
Petar Marchev
Telerik team
answered on 25 Mar 2014, 10:03 AM
Hi YongKoo,

We have never claimed that our ChartView control will work with this kind of image export. The reason for this is that the framework is not really designed to export elements that are not fully laid out, i.e. attached to the visual tree, measured, arranged and rendered. Yes, in most scenarios it does work, however this is not a promise that all will work.

We can probably work this around. Can you please open a Support Ticket and send to us a small project that contains only this chart and that reproduces this behavior so that we can investigate and look for solutions. The only thing I can currently suggest you try is to delay the exporting. This means that the GetImageBytes will become to be async and you will need to use Dispatcher.BeginInvoke right before the
ExportToImage method.

But again if you send to us a project which we can examine, we might be able to find another, more pleasant, solution to this issue.

Regards,
Petar Marchev
Telerik
 

Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.

 
0
Yonggu Kang
Top achievements
Rank 1
Iron
answered on 29 Mar 2014, 08:21 AM
Hi Petar,

Thank you for your kind info.
I found a bug when creating sample project that some values are not
completed on Task before creating chart.
However, when tried to load test after fixing bug, the result was terrible.
This is served by web service and when shoots several hundreads rqst on testing,
the server resource drained completely,so I decided to change GDI+ iso RadChart
because as you pointed out, I'm not certain what's going on inside of control without u.i
and it feels harder to me than manually creating graph with GDI+.
The performance is far better and no more resource leak found.

TIA

Kang





0
Petar Marchev
Telerik team
answered on 31 Mar 2014, 08:41 AM
Hello Kang,

We are glad that you have found a solution. Let us know if you need further assistance.

Regards,
Petar Marchev
Telerik
 

Build cross-platform mobile apps using Visual Studio and .NET. Register for the online webinar on 03/27/2014, 11:00AM US ET.. Seats are limited.

 
Tags
ChartView
Asked by
Yonggu Kang
Top achievements
Rank 1
Iron
Answers by
Petar Marchev
Telerik team
Yonggu Kang
Top achievements
Rank 1
Iron
Share this question
or