Chart view image export doesn't work correctly

2 posts, 0 answers
  1. Chris
    Chris avatar
    4 posts
    Member since:
    Nov 2007

    Posted 25 Jul 2017 Link to this post

    I have noticed some strange behavior when I try to export chart as an image when using ShowGrid property. My Legend overlay by grid.
  2. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3532 posts

    Posted 26 Jul 2017 Link to this post

    Hello Chris, 

    Thank you for writing.  

    I have logged it in our feedback portal and I have added a vote for it on your behalf. You can track its progress, subscribe for status changes and add your comments on the following link - feedback item.

    I have also updated your Telerik points.

    Currently, the possible solution that I can suggest is to use the following way to export the chart to an image:

    CartesianRenderer renderer = null;
     
    public RadForm1()
    {
        InitializeComponent();
        this.radChartView1.CreateRenderer += new ChartViewCreateRendererEventHandler(radChartView1_CreateRenderer);
        LineSeries lineSeries = new LineSeries();
        lineSeries.LegendTitle = "Line 1";
        lineSeries.DataPoints.Add(new CategoricalDataPoint(20, "Jan"));
        lineSeries.DataPoints.Add(new CategoricalDataPoint(22, "Apr"));
        lineSeries.DataPoints.Add(new CategoricalDataPoint(12, "Jul"));
        lineSeries.DataPoints.Add(new CategoricalDataPoint(19, "Oct"));
        this.radChartView1.Series.Add(lineSeries);
        LineSeries lineSeries2 = new LineSeries();
        lineSeries2.LegendTitle = "Line 2";
        lineSeries2.DataPoints.Add(new CategoricalDataPoint(18, "Jan"));
        lineSeries2.DataPoints.Add(new CategoricalDataPoint(15, "Apr"));
        lineSeries2.DataPoints.Add(new CategoricalDataPoint(17, "Jul"));
        lineSeries2.DataPoints.Add(new CategoricalDataPoint(22, "Oct"));
        this.radChartView1.Series.Add(lineSeries2);
        this.radChartView1.ShowLegend = true;
        this.radChartView1.ChartElement.LegendPosition = LegendPosition.Float;
        this.radChartView1.ChartElement.LegendOffset = new Point(200, 95);
     
        CartesianArea area = this.radChartView1.GetArea<CartesianArea>();
        area.ShowGrid = true;
    }
     
    private void radChartView1_CreateRenderer(object sender, ChartViewCreateRendererEventArgs e)
    {
        renderer = new CartesianRenderer(e.Area as CartesianArea);
        e.Renderer = renderer;
    }
     
    private void radButton1_Click(object sender, EventArgs e)
    {
        string filePath = @"..\..\..\exportedChart" + DateTime.Now.ToLongTimeString().Replace(":", "_") + ".png";
        using (MemoryStream stream = new MemoryStream())
        {
            ExportToImage(this.radChartView1, stream, new Size(1000 ,500), ImageFormat.Png, filePath);
        }
        Process.Start(filePath);
    }
     
    public void ExportToImage(RadChartView chart, Stream stream, Size size, ImageFormat imageFormat, string filePath)
    {
        if (!this.IsLoaded)
        {
            this.LoadElementTree();
        }
     
        size = Telerik.WinControls.TelerikDpiHelper.ScaleSize(size, chart.ChartElement.DpiScaleFactor);
     
        Bitmap bmp = new Bitmap(size.Width, size.Height);
        Graphics graphics = Graphics.FromImage(bmp);
        graphics.Clear(Color.White);
     
        SizeF titleSize = graphics.MeasureString(chart.Title, chart.ChartElement.TitleElement.Font, this.Width);
     
        if (chart.ChartElement.TitleElement.TextOrientation == Orientation.Vertical)
        {
            float swap = titleSize.Height;
            titleSize.Height = titleSize.Width;
            titleSize.Width = swap;
        }
     
        RadRect titleRect = new RadRect(0, 0, titleSize.Width, titleSize.Height);
        RadRect legendRect = new RadRect(0, 0, size.Width, size.Height);
        RadRect chartRect = legendRect;
     
        switch (chart.ChartElement.TitlePosition)
        {
            case TitlePosition.Top:
            case TitlePosition.Bottom:
                titleRect.Width = size.Width;
                break;
            case TitlePosition.Right:
            case TitlePosition.Left:
                titleRect.Height = size.Height;
                break;
        }
     
        chartRect.X += chart.View.Margin.Left;
        chartRect.Y += chart.View.Margin.Top;
        chartRect.Width -= chart.View.Margin.Horizontal;
        chartRect.Height -= chart.View.Margin.Vertical;
     
        if (chart.ShowTitle)
        {
            switch (chart.ChartElement.TitlePosition)
            {
                case TitlePosition.Top:
                    legendRect.Y += titleRect.Height;
                    chartRect.Y += titleRect.Height;
                    legendRect.Height -= titleRect.Height;
                    chartRect.Height -= titleRect.Height;
                    break;
                case TitlePosition.Right:
                    titleRect.X = size.Width - chart.ChartElement.TitleElement.Size.Width;
                    titleRect.Height = size.Height;
                    legendRect.Width -= titleRect.Width;
                    chartRect.Width -= titleRect.Width;
                    break;
                case TitlePosition.Bottom:
                    titleRect.Y = size.Height - chart.ChartElement.TitleElement.Size.Height;
                    titleRect.Width = size.Width;
                    legendRect.Height -= titleRect.Height;
                    chartRect.Height -= titleRect.Height;
                    break;
                case TitlePosition.Left:
                    titleRect.Height = size.Height;
                    legendRect.X += titleRect.Width;
                    chartRect.X += titleRect.Width;
                    legendRect.Width -= titleRect.Width;
                    chartRect.Width -= titleRect.Width;
                    break;
            }
        }
        chart.View.Layout(chartRect);
        renderer.Draw(graphics);
        if (chart.ShowLegend)
        {
            switch (chart.ChartElement.LegendPosition)
            {
                case LegendPosition.Right:
                    if (chart.ChartElement.TitlePosition == TitlePosition.Right)
                    {
                        legendRect.X = titleRect.X - chart.ChartElement.LegendElement.Size.Width;
                    }
                    else
                    {
                        legendRect.X = size.Width - chart.ChartElement.LegendElement.Size.Width;
                    }
     
                    legendRect.Width = chart.ChartElement.LegendElement.Size.Width;
                    chartRect.Width -= legendRect.Width;
                    break;
                case LegendPosition.Bottom:
                    if (chart.ChartElement.TitlePosition == TitlePosition.Bottom)
                    {
                        legendRect.Y = titleRect.Y - chart.ChartElement.LegendElement.Size.Height;
                    }
                    else
                    {
                        legendRect.Y = size.Height - chart.ChartElement.LegendElement.Size.Height;
                    }
     
                    legendRect.Height = chart.ChartElement.LegendElement.Size.Height;
                    chartRect.Height -= legendRect.Height;
                    break;
                case LegendPosition.Left:
                    legendRect.Width = chart.ChartElement.LegendElement.Size.Width;
                    chartRect.X += legendRect.Width;
                    chartRect.Width -= legendRect.Width;
                    break;
                case LegendPosition.Top:
                    legendRect.Height = chart.ChartElement.LegendElement.Size.Height;
                    chartRect.Y += legendRect.Height;
                    chartRect.Height -= legendRect.Height;
                    break;
                case LegendPosition.Float:
                    legendRect.Width = chart.ChartElement.LegendElement.Size.Width;
                    legendRect.Height = chart.ChartElement.LegendElement.Size.Height;
                    double xRatio = size.Width / this.Size.Width;
                    double yRatio = size.Height / this.Size.Height;
                    legendRect.X = (chart.ChartElement.LegendOffset.X * xRatio) + ((chart.ChartElement.TitlePosition == TitlePosition.Left)
                                                                                   ? titleRect.Right : 0d);
                    legendRect.Y = (chart.ChartElement.LegendOffset.Y * yRatio) + ((chart.ChartElement.TitlePosition == TitlePosition.Top)
                                                                                   ? titleRect.Bottom : 0f);
                    break;
            }
        }
         
        if (chart.ShowLegend)
        {
            float xTransform = (float)legendRect.X - chart.ChartElement.LegendElement.ControlBoundingRectangle.X +
                               ((float)legendRect.Width - chart.ChartElement.LegendElement.ControlBoundingRectangle.Width) / 2f;
            float yTransform = (float)legendRect.Y - chart.ChartElement.LegendElement.ControlBoundingRectangle.Y +
                               ((float)legendRect.Height - chart.ChartElement.LegendElement.ControlBoundingRectangle.Height) / 2f;
            graphics.TranslateTransform(xTransform, yTransform);
            chart.ChartElement.LegendElement.Paint(new RadGdiGraphics(graphics), chart.ChartElement.LegendElement.ControlBoundingRectangle, 0f,
                new SizeF(1f, 1f), true);
            graphics.ResetTransform();
        }
      
        RadGdiGraphics radGraphics = new RadGdiGraphics(graphics);
     
        if (chart.ShowTitle)
        {
            radGraphics.DrawString(chart.Title, GetTitleDrawRectangle(ChartRenderer.ToRectangleF(titleRect), titleSize,
                chart.ChartElement.TitleElement.TextAlignment), chart.ChartElement.TitleElement.Font,
                chart.ChartElement.TitleElement.ForeColor, chart.ChartElement.TitleElement.TextParams.CreateStringFormat(),
                chart.ChartElement.TitleElement.TextOrientation, chart.ChartElement.TitleElement.FlipText);
        }
     
        if (imageFormat == ImageFormat.Emf ||
            imageFormat == ImageFormat.Wmf)
        {
            Metafile metafile = new Metafile(stream, graphics.GetHdc()); // file is created here
            using (Graphics g = Graphics.FromImage(metafile))
            {
                g.DrawImage(bmp, Point.Empty);
            }
     
            metafile.Dispose();
            graphics.ReleaseHdc();
        }
        else
        {
            bmp.Save(stream, imageFormat);
        }
     
        chart.View.Layout();
     
        Image img = Image.FromStream(stream);
        graphics.DrawImage(img, new Point(0, 0));
        img.Save(filePath);
    }
     
    private RectangleF GetTitleDrawRectangle(RectangleF drawArea, SizeF textRect, ContentAlignment textAlignment)
    {
        switch (textAlignment)
        {
            case ContentAlignment.BottomCenter:
                return new RectangleF(new PointF(drawArea.X + (drawArea.Width - textRect.Width) / 2f, drawArea.Bottom - textRect.Height), textRect);
            case ContentAlignment.BottomLeft:
                return new RectangleF(new PointF(drawArea.X, drawArea.Bottom - textRect.Height), textRect);
            case ContentAlignment.BottomRight:
                return new RectangleF(new PointF(drawArea.Right - textRect.Width, drawArea.Bottom - textRect.Height), textRect);
            case ContentAlignment.MiddleCenter:
                return new RectangleF(new PointF(drawArea.X + (drawArea.Width - textRect.Width) / 2f, drawArea.Y + (drawArea.Height - textRect.Height) / 2f),
                    textRect);
            case ContentAlignment.MiddleLeft:
                return new RectangleF(new PointF(drawArea.X, drawArea.Y + (drawArea.Height - textRect.Height) / 2f), textRect);
            case ContentAlignment.MiddleRight:
                return new RectangleF(new PointF(drawArea.Right - textRect.Width, drawArea.Y + (drawArea.Height - textRect.Height) / 2f), textRect);
            case ContentAlignment.TopCenter:
                return new RectangleF(new PointF(drawArea.X + (drawArea.Width - textRect.Width) / 2, drawArea.Y), textRect);
            case ContentAlignment.TopLeft:
                return new RectangleF(drawArea.Location, textRect);
            case ContentAlignment.TopRight:
                return new RectangleF(new PointF(drawArea.Right - textRect.Width, drawArea.Y), textRect);
            default:
                return new RectangleF(drawArea.Location, textRect);
        }
    }

    I hope this information helps. Should you have further questions I would be glad to help.

    Regards,
    Dess
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top