2012-03-09 28 views
6

wszyscy musicie usprawiedliwić moją ignorancję, ponieważ dopiero niedawno zacząłem pracować z C#. Mam tylko pytanie dotyczące kontroli wykresów systemu Windows, ponieważ napotykam raczej głupi problem.Zapisywanie wykresów o wyższej rozdzielczości bez zniekształcania wyglądu

Mam program, który ma kilka raportów zawierających ładne wyglądające okna Wykresy przedstawiające niektóre dane. Jednak zapisywałem te wykresy do plików również dla różnych zastosowań, po prostu używając czegoś takiego:

chart2.SaveImage (savefilename, ChartImageFormat.Png);

Mój pierwszy problem polega na tym, że nie jestem pewien, jak zapisać to jako wyższą rozdzielczość bez wcześniejszego zwiększania rozmiaru kontrolki wykresu przed zapisaniem. Byłoby miło mieć obraz o rozsądnej jakości.

Drugi problem polega na tym, że zwiększam rozmiar kontrolki wykresu, dostępne operacje mogą jedynie zwiększać rozmiar rzeczywistego wykresu, a nie etykiety czy tekst. Nie stanowiłoby to problemu, gdybym mógł zmienić te wszystkie ręcznie, co zrobiłem dla wykresu słupkowego, ale jest jeden wiersz, w którym nie mogę rozgryźć: linie etykiet na wykresie kołowym . Mam wyciągnąć strzałę do niego w następujący obraz:

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

Więc gdy wykres jest zwiększona do rozsądnej rozdzielczości linia ta jest prawie niewidoczna ze względu na nie wzrasta do odpowiedniej wielkości względnej. Czuję, że powinien istnieć sposób, żeby to zmienić, ale nie wiem, co by to było.

Ponownie, przepraszam za moją niewiedzę. Gdyby któryś z tych dwóch problemów mógł zostać rozwiązany, mógłbym spać spokojnie, wiedząc, że te wykresy kołowe wyglądają przyzwoicie. Dzięki!

Odpowiedz

1

Spróbuj ustawić chart2.RenderTransform = new ScaleTransform(10,10) i zapisz. Powinno to również zwiększyć twoje linie.

8

Utwórz/zduplikuj ukryty obiekt formularza ukryty (Widoczny = fałszywy). Możesz nawet ustawić jego właściwości Górny i Lewy, aby wyłączyć formularz. Ustaw tę kontrolę na bardzo wysoką szerokość i wysokość (tj. 2100 x 1500) ... Wypełnij i sformatuj ją zgodnie ze swoimi specyfikacjami. Pamiętaj, aby zwiększyć rozmiary czcionek itp. Następnie wywołaj SaveImage() lub DrawToBitmap() z ukrytego wykresu ...

Po zapisaniu tego pliku, będzie to zasadniczo wystarczająco wysoka rozdzielczość dla większości edytorów tekstu, pubów na pulpicie , drukowanie itp. Na przykład 2100 x 1500 przy 300 dpi = 7 "x 5" do drukowania ...

W swojej aplikacji możesz również skalować go w dół lub wydrukować: zmniejszanie rozdzielczości "dodaje", więc obraz staje się ostrzejszy. Skalowanie powoduje rozmycie obrazu lub rozmycie obrazu.

Musiałem polegać na tej technice, ponieważ jest to najbardziej spójny sposób na uzyskanie wykresów wysokiej rozdzielczości z kontrolki wykresu .Net do drukowania lub zapisywania ... To klasyczny cheat, ale działa :)

na przykład:

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

Oto klasa I, aby uczynić większy wykres, zapisz go, a następnie przywrócić wykres. Działa dobrze dla moich celów.

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