Saving higher resolution charts without messing up

2019-02-07 04:19发布

you'll all have to excuse my ignorance as I have only recently started working with C#. I just have a question about the windows chart control, as I'm encountering a rather dumb problem.

I have a program which has a few reports that include nice looking windows Charts to represent some data. However, I have been saving these charts to files as well for various uses, by just using something like this:

chart2.SaveImage(savefilename, ChartImageFormat.Png);

My first problem lies in the fact that I am not sure how to save this as a higher resolution without first increasing the size of the chart control before saving. It would be nice to have an image of reasonable quality.

The second problem is when I do increase the size of the chart control, the available operations only seem to be able to increase the size of the actual chart, not the labels or the text. This wouldn't be a problem if I could change all of these manually, which is what I have done for a bar chart, but there is one line I can't figure out how to make thicker: the label lines on the pie chart. I have drawn an arrow to it in the following image:

http://www.bolinger.ca/chart.png

So when the chart is increased to a reasonable resolution this line is nearly invisible due to not increasing to an appropriate relative size. I feel like there should be a way to change it, but can't figure out what it would be.

Again, excuse my ignorance. If either one of these two problems could be solved then I could rest easy knowing that these pie charts look decent. Thanks!

3条回答
唯我独甜
2楼-- · 2019-02-07 04:34

Try setting chart2.RenderTransform = new ScaleTransform(10,10) and save it. This should also make your lines bigger.

查看更多
欢心
3楼-- · 2019-02-07 04:35

Create/Duplicate a hidden (Visible = false) chart object on the form. You can even set its Top and Left properties to be off of the form. Set this control to a very high Width and Height (i.e., 2100 x 1500)... Populate and format it to your specifications. Be sure to increase the font sizes, etc. Then call SaveImage() or DrawToBitmap() from the hidden chart...

When you save this file, it will essentially be high enough resolution for most word processing, desktop pubs, printing, etc. For example, 2100 x 1500 @ 300 dpi = 7" x 5" for printing...

In your application, you can also scale it down or print it: scaling down "adds" resolution, so the image becomes sharper. Scaling up makes an image blurry or fuzzy.

I have had to rely on this technique, as it is the most consistent way to get high-res charts from the .Net chart control for printing or saving... It is a classic cheat, but it works :)

For example:

private void cmdHidden_Click(object sender, EventArgs e) {
    System.Windows.Forms.DataVisualization.Charting.Title chtTitle =
        new System.Windows.Forms.DataVisualization.Charting.Title();
    System.Drawing.Font chtFont = new System.Drawing.Font("Arial", 42);
    string[] seriesArray = { "A", "B", "C" };
    int[] pointsArray = { 1, 7, 4 };

    chart1.Visible = false;
    chart1.Width = 2100;
    chart1.Height = 1500;
    chart1.Palette = System.Windows.Forms.DataVisualization.Charting.ChartColorPalette.Bright;

    chtTitle.Font = chtFont;
    chtTitle.Text = "Demographics Comparison";
    chart1.Titles.Add(chtTitle);

    chart1.Series.Clear();

    // populate chart    
    for (int i = 0; i < seriesArray.Length; i++) {
        Series series = chart1.Series.Add(seriesArray[i]);
        series.Label = seriesArray[i].ToString();
        series.Font = new System.Drawing.Font("Arial", 24);
        series.ShadowOffset = 5;
        series.Points.Add(pointsArray[i]);
    }

    // save from the chart object itself
    chart1.SaveImage(@"C:\Temp\HiddenChart.png", ChartImageFormat.Png);

    // save to a bitmap
    Bitmap bmp = new Bitmap(2100, 1500);
    chart1.DrawToBitmap(bmp, new Rectangle(0, 0, 2100, 1500));
    bmp.Save(@"C:\Temp\HiddenChart2.png");
}
查看更多
贼婆χ
4楼-- · 2019-02-07 04:46

Here's a class I made to make a larger graph, save it, then restore the graph. Works well for my my purposes.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OfficeOpenXml.Drawing;
using OfficeOpenXml.Drawing.Chart;
using System.Drawing.Imaging;
using System.Windows.Forms.DataVisualization.Charting;
using System.Windows.Forms;

namespace Simple_Grapher
{
    class saveQualityChartImage
    {
        Chart theChart;
        System.Drawing.Font oldFont1 = new System.Drawing.Font("Trebuchet MS", 35F, System.Drawing.FontStyle.Bold);
        System.Drawing.Font oldFont2 = new System.Drawing.Font("Trebuchet MS", 15F, System.Drawing.FontStyle.Bold);
        System.Drawing.Font oldFont3 = new System.Drawing.Font("Trebuchet MS", 35F, System.Drawing.FontStyle.Bold);
        System.Drawing.Font oldLegendFont = new System.Drawing.Font("Trebuchet MS", 35F, System.Drawing.FontStyle.Bold);

        int oldLineWidth1;
        int oldLineWidth2;
        int oldLineWidth3;
        int oldLineWidth4;

        int oldWidth;
        int oldHeight;
        public saveQualityChartImage(Chart inputChart)
        {
            if (!(inputChart.Series.Count > 0))
            {
                return;
            }
            theChart = inputChart;
            if (inputChart.Titles.Count > 0)
            {
                oldFont1 = inputChart.Titles[0].Font;
            }
            oldFont2 = inputChart.ChartAreas[0].AxisX.LabelStyle.Font;
            oldFont3 = inputChart.ChartAreas[0].AxisX.TitleFont;
            if (theChart.Legends.Count > 0)
            {
                oldLegendFont = theChart.Legends["Legend"].Font;
            }
            oldLineWidth1 = theChart.ChartAreas[0].AxisX.LineWidth;
            oldLineWidth2 = theChart.ChartAreas[0].AxisX.MajorTickMark.LineWidth;
            oldLineWidth3 = theChart.Series[0].BorderWidth;
            oldLineWidth4 = theChart.ChartAreas[0].AxisY.MajorGrid.LineWidth;
            oldWidth = theChart.Width;
            oldHeight = theChart.Height;

            saveimage();
        }

        public void saveimage()
        {
            theChart.Visible = false;
            System.Drawing.Font chtFont = new System.Drawing.Font("Trebuchet MS", 35F, System.Drawing.FontStyle.Bold);
            System.Drawing.Font smallFont = new System.Drawing.Font("Trebuchet MS", 15F, System.Drawing.FontStyle.Bold);
            if (theChart.Titles.Count > 0)
            {
                theChart.Titles[0].Font = chtFont;
            }

            theChart.ChartAreas[0].AxisX.TitleFont = chtFont;
            theChart.ChartAreas[0].AxisX.LineWidth = 3;
            theChart.ChartAreas[0].AxisX.MajorGrid.LineWidth = 3;
            theChart.ChartAreas[0].AxisX.LabelStyle.Font = smallFont;
            theChart.ChartAreas[0].AxisX.MajorTickMark.LineWidth = 3;

            theChart.ChartAreas[0].AxisY.TitleFont = chtFont;
            theChart.ChartAreas[0].AxisY.LineWidth = 3;
            theChart.ChartAreas[0].AxisY.MajorGrid.LineWidth = 3;
            theChart.ChartAreas[0].AxisY.LabelStyle.Font = smallFont;
            theChart.ChartAreas[0].AxisY.MajorTickMark.LineWidth = 3;
            if (theChart.Legends.Count > 0)
            {
                theChart.Legends["Legend"].Font = smallFont;
            }


            foreach (Series series in theChart.Series)
            {
                series.BorderWidth = 3;

            }

            theChart.Width = 1800;
            theChart.Height = 1200;

            SaveFileDialog save = new SaveFileDialog();
            save.DefaultExt = ".png";
            if (save.ShowDialog() == DialogResult.OK)
            {
                theChart.SaveImage(save.FileName, ChartImageFormat.Png);
            }
            resetOldValues();

        }

        private void resetOldValues()
        {
            if (theChart.Titles.Count > 0)
            {
                theChart.Titles[0].Font = oldFont1;
            }

            theChart.ChartAreas[0].AxisX.TitleFont = oldFont3;
            theChart.ChartAreas[0].AxisX.LineWidth = oldLineWidth1;
            theChart.ChartAreas[0].AxisX.MajorGrid.LineWidth = oldLineWidth4;
            theChart.ChartAreas[0].AxisX.LabelStyle.Font = oldFont2;
            theChart.ChartAreas[0].AxisX.MajorTickMark.LineWidth = oldLineWidth2;

            theChart.ChartAreas[0].AxisY.TitleFont = oldFont3;
            theChart.ChartAreas[0].AxisY.LineWidth = oldLineWidth1;
            theChart.ChartAreas[0].AxisY.MajorGrid.LineWidth = oldLineWidth4;
            theChart.ChartAreas[0].AxisY.LabelStyle.Font = oldFont2;
            theChart.ChartAreas[0].AxisY.MajorTickMark.LineWidth = oldLineWidth2;
            if (theChart.Legends.Count > 0)
            {
                theChart.Legends["Legend"].Font = oldLegendFont;
            }



            foreach (Series series in theChart.Series)
            {
                series.BorderWidth = oldLineWidth3;

            }

            theChart.Width = oldWidth;
            theChart.Height = oldHeight;
            theChart.Visible = true;   
        }  
    }
}
查看更多
登录 后发表回答