保存更高分辨率的图表而不弄乱外观

问题描述 投票:0回答:4

请大家原谅我的无知,因为我最近才开始使用 C#。我只是有一个关于 Windows 图表控件的问题,因为我遇到了一个相当愚蠢的问题。

我有一个程序,其中有一些报告,其中包括漂亮的窗口图表来表示一些数据。但是,我一直将这些图表保存到文件中以供各种用途,只需使用类似这样的东西:

chart2.SaveImage(保存文件名, ChartImageFormat.Png);

我的第一个问题在于,我不确定如何将其保存为更高分辨率,而不在保存之前先增加图表控件的大小。如果能有一个质量合理的图像就好了。

第二个问题是当我确实增加图表控件的大小时,可用的操作似乎只能增加实际图表的大小,而不能增加标签或文本的大小。如果我可以手动更改所有这些,这将不是问题,这就是我对条形图所做的,但有一条线我无法弄清楚如何使其变粗:饼图上的标签线。我在下图中画了一个箭头:

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

因此,当图表增加到合理的分辨率时,由于没有增加到适当的相对大小,这条线几乎看不见。我觉得应该有办法改变它,但不知道会是什么。

再次请原谅我的无知。如果这两个问题中的任何一个都能得到解决,那么我就可以高枕无忧了,因为我知道这些饼图看起来不错。谢谢!

c# charts resize controls resolution
4个回答
11
投票

在表单上创建/复制hidden(可见 = false)图表对象。您甚至可以将其“顶部”和“左侧”属性设置为脱离表单。将此控件设置为非常高的宽度和高度(即 2100 x 1500)...根据您的规格填充并格式化它。请务必增加字体大小等。然后从隐藏图表中调用 SaveImage() 或 DrawToBitmap()...

当您保存此文件时,对于大多数文字处理、桌面酒吧、打印等来说,它基本上具有足够高的分辨率。例如,2100 x 1500 @ 300 dpi = 7" x 5" 用于打印...

在您的应用程序中,您还可以缩小或打印它:缩小“增加”分辨率,使图像变得更清晰。放大会使图像变得模糊或模糊。

我不得不依赖这种技术,因为它是从 .Net 图表控件获取高分辨率图表以进行打印或保存的最一致的方法...这是一个经典的作弊,但它有效:)

例如:

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");
}

3
投票

这是我制作的一个类,用于制作更大的图表,保存它,然后恢复图表。非常适合我的目的。

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;   
        }  
    }
}

1
投票

尝试设置

chart2.RenderTransform = new ScaleTransform(10,10)
并保存。这也会让你的线条变得更大。


0
投票

我将把它添加为一个类,以将图表保存为图像,因为我在这里找到的大多数示例都使用 System.Windows.Forms。这使用 System.Web.UI.DataVisualization.Charting。如果您尝试将此页面上的示例应用于 Web 服务器,则两者之间存在一些细微的差异,这些差异会引发错误。此外,许多其他 SO 问题/示例都没有使用 IEnumerable 数据源。

这里的数据源只是一个以 AsEnumerable() 返回的普通 DataTable(例如 return dt.AsEnumerable();)。

标题和图例也已添加到保存的图像中。

这是从一个数据源生成两张图像。压力和温度图表。下面的压力图是此代码的实际输出。

  public static void ChartToImage(Certification.Chart chartData, string hashId, string orderId, string chartNo, string multiChart = "0")
    {
        string filepath = System.Web.Hosting.HostingEnvironment.MapPath("~/docs/");
        string fileNamePress = filepath + chartData.HashId + "p.png";
        string fileNameTemp = filepath + chartData.HashId + "t.png";

        System.Web.UI.DataVisualization.Charting.Chart chart1 = new System.Web.UI.DataVisualization.Charting.Chart();

        System.Web.UI.DataVisualization.Charting.Title cht1Title = new
        System.Web.UI.DataVisualization.Charting.Title();
        System.Drawing.Font cht1Font = new System.Drawing.Font("Arial", 18);


        System.Web.UI.DataVisualization.Charting.Legend cht1Legend = new
        System.Web.UI.DataVisualization.Charting.Legend();
        System.Drawing.Font cht1LegendFont = new System.Drawing.Font("Arial", 18);

        System.Collections.IEnumerable enumerableTable = ChartDAL.ChartIEList(hashId);

        System.DateTime x = new System.DateTime(2008, 11, 21);

        var chartArea1 = new System.Web.UI.DataVisualization.Charting.ChartArea();
        chart1.ChartAreas.Add(chartArea1);
        chart1.DataSource = enumerableTable;
        
        chart1.Series.Add("Series1");
        chart1.Series["Series1"].ChartType = SeriesChartType.Spline;
        chart1.Series["Series1"].XValueType = ChartValueType.Time;
        chart1.Series["Series1"].Points.AddXY(x.ToUniversalTime(), "tstamp");
        chart1.Series["Series1"].XValueMember = "tstamp";
        chart1.Series["Series1"].YValueMembers = "pressure";
        chart1.Series["Series1"].IsValueShownAsLabel = false;
        chart1.Series["Series1"].Name = "PSI"; // Normally PSI. In the future, pull pressure testing unit from enumerableTable;


        cht1Title.Font = cht1Font;
        cht1Title.Text = "Pressure Chart"; // In future, pull job number/chart number from database;
        chart1.Titles.Add(cht1Title);

        cht1Legend.Font = cht1Font;            
        chart1.Legends.Add(cht1Legend); // chart1.Series["Series1"].Name;

        chart1.Width = 900;
        chart1.Height = 400;
        chart1.DataBind();
        
        chart1.SaveImage(fileNamePress, ChartImageFormat.Png);

        System.Web.UI.DataVisualization.Charting.Chart chart2 = new System.Web.UI.DataVisualization.Charting.Chart();

        System.Web.UI.DataVisualization.Charting.Title cht2Title = new
        System.Web.UI.DataVisualization.Charting.Title();
        System.Drawing.Font cht2Font = new System.Drawing.Font("Arial", 18);

        System.Web.UI.DataVisualization.Charting.Legend cht2Legend = new
        System.Web.UI.DataVisualization.Charting.Legend();
        System.Drawing.Font cht2LegendFont = new System.Drawing.Font("Arial", 18);

        var chartArea2 = new System.Web.UI.DataVisualization.Charting.ChartArea();
        chart2.ChartAreas.Add(chartArea2);
        chart2.DataSource = enumerableTable;

        chart2.Series.Add("Series1");
        chart2.Series["Series1"].ChartType = SeriesChartType.Spline;
        chart2.Series["Series1"].XValueType = ChartValueType.Time;
        chart2.Series["Series1"].Points.AddXY(x.ToUniversalTime(), "tstamp");
        chart2.Series["Series1"].XValueMember = "tstamp";
        chart2.Series["Series1"].YValueMembers = "temperature";
        chart2.Series["Series1"].IsValueShownAsLabel = false;
        chart2.Series["Series1"].Name = "Celsius"; // Normally Celsius. In the future, pull temperature testing unit from enumerableTable;

        cht2Title.Font = cht2Font;
        cht2Title.Text = "Temperature Chart"; // In future, pull job number/chart number from database;
        chart2.Titles.Add(cht2Title);

        cht2Legend.Font = cht2Font;            
        chart2.Legends.Add(cht2Legend); // chart2.Series["Series1"].Name;

        chart2.Width = 900;
        chart2.Height = 400;
        chart2.DataBind();

        chart1.SaveImage(fileNamePress, ChartImageFormat.Png);
        chart2.SaveImage(fileNameTemp, ChartImageFormat.Png);


    }   

© www.soinside.com 2019 - 2024. All rights reserved.