issue when creating image on background

4 posts, 1 answers
  1. YongKoo Kang
    YongKoo Kang avatar
    101 posts
    Member since:
    Jan 2010

    Posted 23 Mar 2014 Link to this post

    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
  2. Answer
    Petar Marchev
    Admin
    Petar Marchev avatar
    968 posts

    Posted 25 Mar 2014 Link to this post

    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.

     
  3. DevCraft banner
  4. YongKoo Kang
    YongKoo Kang avatar
    101 posts
    Member since:
    Jan 2010

    Posted 29 Mar 2014 in reply to Petar Marchev Link to this post

    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





  5. Petar Marchev
    Admin
    Petar Marchev avatar
    968 posts

    Posted 31 Mar 2014 Link to this post

    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.

     
Back to Top