Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Visualization.ChartControlsExtensions/3.3/ImageExportDialog.cs @ 6641

Last change on this file since 6641 was 6641, checked in by abeham, 13 years ago

#1611

  • allow to specify font size of legend items
  • cleaned up code a little (dpi/dpcm, cm/inch)
  • added detection for region settings to select either cm or inch
  • improved preview view (now doesn't scale images beyond 100%)
File size: 13.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.ComponentModel;
24using System.Drawing;
25using System.Drawing.Imaging;
26using System.IO;
27using System.Windows.Forms;
28using System.Windows.Forms.DataVisualization.Charting;
29
30namespace HeuristicLab.Visualization.ChartControlsExtensions {
31  public sealed partial class ImageExportDialog : Form {
32    private const float CMPERINCH = 2.54f;
33    private static readonly string DPI = "dpi", DPCM = "dpcm", INCH = "inch", CM = "cm";
34    private Chart originalChart, workingChart;
35    private bool SuppressEvents { get; set; }
36
37    /// <summary>
38    /// Initializes a new ImageExportDialog.
39    /// </summary>
40    /// <remarks>
41    /// Throws an ArgumentNullException if <paramref name="chart"/> is null.
42    /// </remarks>
43    /// <param name="chart">The chart for which the export should be generated.</param>
44    public ImageExportDialog(Chart chart) {
45      if (chart == null) throw new ArgumentNullException("chart");
46      this.originalChart = chart;
47      InitializeComponent();
48      #region Custom Initialization
49      SuppressEvents = true;
50      try {
51        resolutionUnitComboBox.Items.Add(DPI);
52        resolutionUnitComboBox.Items.Add(DPCM);
53        lengthUnitComboBox.Items.Add(INCH);
54        lengthUnitComboBox.Items.Add(CM);
55        resolutionUnitComboBox.SelectedIndex = 0;
56        if (System.Globalization.RegionInfo.CurrentRegion.IsMetric)
57          lengthUnitComboBox.SelectedIndex = 1;
58        else lengthUnitComboBox.SelectedIndex = 0;
59
60        titleFontSizeComboBox.Text = "12";
61        axisFontSizeComboBox.Text = "8";
62        scalesFontSizeComboBox.Text = "6";
63        legendFontSizeComboBox.Text = "6";
64        resolutionComboBox.Text = "300";
65        SuppressEvents = false;
66        splitContainer.Panel2Collapsed = true;
67        Width = 305;
68        Height = 550;
69      } finally { SuppressEvents = false; }
70      #endregion
71    }
72
73    private void UpdateFields() {
74      ChartArea area = GetCurrentChartArea();
75
76      try {
77        SuppressEvents = true;
78
79        if (workingChart.Titles.Count == 0) titleFontSizeComboBox.Text = "12";
80        else {
81          titleTextBox.Text = workingChart.Titles[0].Text;
82          titleFontSizeComboBox.Text = workingChart.Titles[0].Font.SizeInPoints.ToString();
83        }
84
85        primaryXTextBox.Text = area.AxisX.Title;
86        primaryYTextBox.Text = area.AxisY.Title;
87        secondaryXTextBox.Text = area.AxisX2.Title;
88        secondaryYTextBox.Text = area.AxisY2.Title;
89
90        axisFontSizeComboBox.Text = area.AxisX.TitleFont.SizeInPoints.ToString();
91        scalesFontSizeComboBox.Text = area.AxisX.LabelStyle.Font.SizeInPoints.ToString();
92        if (workingChart.Legends.Count == 0) legendFontSizeComboBox.Text = "8";
93        else legendFontSizeComboBox.Text = workingChart.Legends[0].Font.SizeInPoints.ToString();
94      } finally {
95        SuppressEvents = false;
96      }
97    }
98
99    private ChartArea GetCurrentChartArea() {
100      return workingChart.ChartAreas[chartAreaComboBox.Text];
101    }
102
103    private void UpdatePreview() {
104      float dpi;
105      float width;
106      float height;
107      GetImageParameters(out dpi, out width, out height);
108
109      if (previewPictureBox.Image != null) {
110        previewPictureBox.Image.Dispose();
111        previewPictureBox.Image = null;
112      }
113
114      int previewWidth, previewHeight;
115      if (width / height >= 1.0) {
116        previewWidth = previewPictureBox.Width;
117        previewHeight = (int)Math.Round(height / width * previewWidth);
118      } else {
119        previewHeight = previewPictureBox.Height;
120        previewWidth = (int)Math.Round(width / height * previewHeight);
121      }
122
123      float scaleFactor = (float)Math.Min(previewWidth / width, previewHeight / height);
124      if (scaleFactor >= 1) {
125        previewZoomLabel.Text = "100%";
126        previewWidth = (int)Math.Round(width);
127        previewHeight = (int)Math.Round(height);
128      } else previewZoomLabel.Text = (scaleFactor * 100).ToString("0") + "%";
129
130      Bitmap image = new Bitmap(previewWidth, previewHeight);
131      image.SetResolution(dpi, dpi);
132      using (Graphics graphics = Graphics.FromImage(image)) {
133        if (scaleFactor < 1) graphics.ScaleTransform(scaleFactor, scaleFactor);
134        workingChart.Printing.PrintPaint(graphics, new Rectangle(0, 0, (int)Math.Round(width), (int)Math.Round(height)));
135      }
136      previewPictureBox.Image = image;
137    }
138
139    private void GetImageParameters(out float dpi, out float width, out float height) {
140      dpi = float.Parse(resolutionComboBox.Text);
141      if (resolutionUnitComboBox.Text == DPCM) dpi *= CMPERINCH;
142      width = (float)widthNumericUD.Value;
143      height = (float)heightNumericUD.Value;
144      if (lengthUnitComboBox.Text == CM) {
145        width /= CMPERINCH; height /= CMPERINCH;
146      }
147      width *= dpi; height *= dpi;
148    }
149
150    protected override void OnShown(EventArgs e) {
151      #region Create copy of chart
152      var prevContent = originalChart.Serializer.Content;
153      var prevFormat = originalChart.Serializer.Format;
154      originalChart.Serializer.Content = SerializationContents.Default;
155      originalChart.Serializer.Format = SerializationFormat.Binary;
156      MemoryStream ms = new MemoryStream();
157      originalChart.Serializer.Save(ms);
158      originalChart.Serializer.Content = prevContent;
159      originalChart.Serializer.Format = prevFormat;
160
161      ms.Seek(0, SeekOrigin.Begin);
162      workingChart = new EnhancedChart();
163      workingChart.Serializer.Load(ms);
164      ms.Close();
165      #endregion
166
167      chartAreaComboBox.Items.Clear();
168      foreach (ChartArea area in originalChart.ChartAreas) {
169        chartAreaComboBox.Items.Add(area.Name);
170      }
171      chartAreaComboBox.SelectedIndex = 0;
172      base.OnShown(e);
173
174      if (togglePreviewCheckBox.Checked) UpdatePreview();
175    }
176
177    private void togglePreviewCheckBox_CheckedChanged(object sender, EventArgs e) {
178      splitContainer.Panel2Collapsed = !togglePreviewCheckBox.Checked;
179      togglePreviewCheckBox.Text = togglePreviewCheckBox.Checked ? "<" : ">";
180      if (splitContainer.Panel2Collapsed)
181        Width = cancelButton.Right + cancelButton.Margin.Right + Margin.Right + 10;
182      else
183        Width = splitContainer.Right + splitContainer.Margin.Right + Margin.Right;
184      if (togglePreviewCheckBox.Checked) UpdatePreview();
185    }
186
187    private void chartAreaComboBox_SelectedIndexChanged(object sender, EventArgs e) {
188      if (chartAreaComboBox.SelectedIndex >= 0)
189        UpdateFields();
190    }
191
192    private void titleTextBox_TextChanged(object sender, EventArgs e) {
193      if (!SuppressEvents) {
194        if (workingChart.Titles.Count > 0) {
195          workingChart.Titles[0].Text = titleTextBox.Text;
196        } else {
197          Title t = new Title(titleTextBox.Text);
198          t.Font = ChangeFontSizePt(t.Font, float.Parse(titleFontSizeComboBox.Text));
199          workingChart.Titles.Add(t);
200        }
201        if (togglePreviewCheckBox.Checked) UpdatePreview();
202      }
203    }
204
205    private void primaryXTextBox_TextChanged(object sender, EventArgs e) {
206      if (!SuppressEvents) {
207        ChartArea area = GetCurrentChartArea();
208        area.AxisX.Title = primaryXTextBox.Text;
209        if (togglePreviewCheckBox.Checked) UpdatePreview();
210      }
211    }
212
213    private void primaryYTextBox_TextChanged(object sender, EventArgs e) {
214      if (!SuppressEvents) {
215        ChartArea area = GetCurrentChartArea();
216        area.AxisY.Title = primaryYTextBox.Text;
217        if (togglePreviewCheckBox.Checked) UpdatePreview();
218      }
219    }
220
221    private void secondaryXTextBox_TextChanged(object sender, EventArgs e) {
222      if (!SuppressEvents) {
223        ChartArea area = GetCurrentChartArea();
224        area.AxisX2.Title = secondaryXTextBox.Text;
225        if (togglePreviewCheckBox.Checked) UpdatePreview();
226      }
227    }
228
229    private void secondaryYTextBox_TextChanged(object sender, EventArgs e) {
230      if (!SuppressEvents) {
231        ChartArea area = GetCurrentChartArea();
232        area.AxisY2.Title = secondaryYTextBox.Text;
233        if (togglePreviewCheckBox.Checked) UpdatePreview();
234      }
235    }
236
237    private void widthNumericUD_ValueChanged(object sender, EventArgs e) {
238      if (togglePreviewCheckBox.Checked) UpdatePreview();
239    }
240
241    private void heightNumericUD_ValueChanged(object sender, EventArgs e) {
242      if (togglePreviewCheckBox.Checked) UpdatePreview();
243    }
244
245    private void titleFontSizeComboBox_TextChanged(object sender, EventArgs e) {
246      if (!SuppressEvents) {
247        float fontSize;
248        if (float.TryParse(titleFontSizeComboBox.Text, out fontSize)) {
249          if (workingChart.Titles.Count > 0) {
250            workingChart.Titles[0].Font = ChangeFontSizePt(workingChart.Titles[0].Font, fontSize);
251            if (togglePreviewCheckBox.Checked) UpdatePreview();
252          }
253        }
254      }
255    }
256
257    private void axisFontSizeComboBox_TextChanged(object sender, EventArgs e) {
258      if (!SuppressEvents) {
259        float fontSize;
260        if (float.TryParse(axisFontSizeComboBox.Text, out fontSize)) {
261          ChartArea area = GetCurrentChartArea();
262          foreach (Axis a in area.Axes) {
263            a.TitleFont = ChangeFontSizePt(a.TitleFont, fontSize);
264          }
265        }
266        if (togglePreviewCheckBox.Checked) UpdatePreview();
267      }
268    }
269
270    private void scalesFontSizeComboBox_TextChanged(object sender, EventArgs e) {
271      if (!SuppressEvents) {
272        float fontSize;
273        if (float.TryParse(scalesFontSizeComboBox.Text, out fontSize)) {
274          ChartArea area = GetCurrentChartArea();
275          foreach (Axis a in area.Axes) {
276            a.LabelStyle.Font = ChangeFontSizePt(a.LabelStyle.Font, fontSize);
277          }
278        }
279        if (togglePreviewCheckBox.Checked) UpdatePreview();
280      }
281    }
282
283    private void legendFontSizeComboBox_TextChanged(object sender, EventArgs e) {
284      if (!SuppressEvents) {
285        float fontSize;
286        if (float.TryParse(legendFontSizeComboBox.Text, out fontSize)) {
287          foreach (Legend l in workingChart.Legends) {
288            l.Font = ChangeFontSizePt(l.Font, fontSize);
289          }
290        }
291        if (togglePreviewCheckBox.Checked) UpdatePreview();
292      }
293    }
294
295    private void numericComboBox_Validating(object sender, CancelEventArgs e) {
296      if (!(sender is ComboBox)) return;
297      float number;
298      e.Cancel = !float.TryParse((sender as ComboBox).Text, out number);
299    }
300
301    private void resolutionComboBox_TextChanged(object sender, EventArgs e) {
302      float resolution;
303      if (float.TryParse(resolutionComboBox.Text, out resolution)) {
304        if (togglePreviewCheckBox.Checked) UpdatePreview();
305      }
306    }
307
308    private void resolutionComboBox_Validating(object sender, CancelEventArgs e) {
309      float resolution;
310      e.Cancel = !float.TryParse(resolutionComboBox.Text, out resolution);
311    }
312
313    private void resolutionUnitComboBox_SelectedIndexChanged(object sender, EventArgs e) {
314      if (togglePreviewCheckBox.Checked) UpdatePreview();
315    }
316
317    private void lengthUnitComboBox_SelectedIndexChanged(object sender, EventArgs e) {
318      if (togglePreviewCheckBox.Checked) UpdatePreview();
319    }
320
321    private void okButton_Click(object sender, EventArgs e) {
322      float dpi;
323      float width;
324      float height;
325      GetImageParameters(out dpi, out width, out height);
326
327      Bitmap image = new Bitmap((int)Math.Round(width), (int)Math.Round(height));
328      image.SetResolution(dpi, dpi);
329      using (Graphics graphics = Graphics.FromImage(image)) {
330        workingChart.Printing.PrintPaint(graphics, new Rectangle(0, 0, image.Width, image.Height));
331      }
332
333      if (titleTextBox.Text.Trim() != String.Empty) saveFileDialog.FileName = titleTextBox.Text.Trim();
334      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
335        ImageFormat format = ImageFormat.Bmp;
336        string filename = saveFileDialog.FileName.ToLower();
337        if (filename.EndsWith("jpg")) {
338          format = ImageFormat.Jpeg;
339        } else if (filename.EndsWith("emf")) {
340          format = ImageFormat.Emf;
341        } else if (filename.EndsWith("gif")) {
342          format = ImageFormat.Gif;
343        } else if (filename.EndsWith("png")) {
344          format = ImageFormat.Png;
345        } else if (filename.EndsWith("tif")) {
346          format = ImageFormat.Tiff;
347        }
348        image.Save(saveFileDialog.FileName, format);
349      }
350
351      image.Dispose();
352
353      Cleanup();
354    }
355
356    private void cancelButton_Click(object sender, EventArgs e) {
357      Cleanup();
358    }
359
360    private void Cleanup() {
361      if (previewPictureBox.Image != null) previewPictureBox.Image.Dispose();
362      previewPictureBox.Image = null;
363      workingChart = null;
364    }
365
366    private static Font ChangeFontSizePt(Font font, float fontSize) {
367      if (font != null) {
368        float currentSize = font.Size;
369        if (currentSize != fontSize) {
370          font = new Font(font.Name, fontSize, font.Style, GraphicsUnit.Point, font.GdiCharSet, font.GdiVerticalFont);
371        }
372      }
373      return font;
374    }
375
376  }
377}
Note: See TracBrowser for help on using the repository browser.