Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Visualization/HeuristicLab.Visualization/3.3/ChartControl.cs @ 9415

Last change on this file since 9415 was 9415, checked in by bburlacu, 11 years ago

#1265: Added save file functionality in emf and bitmap formats.

File size: 10.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Collections.Generic;
24using System.Drawing;
25using System.Drawing.Drawing2D;
26using System.Drawing.Imaging;
27using System.Windows.Forms;
28
29namespace HeuristicLab.Visualization {
30  public partial class ChartControl : UserControl {
31    private Bitmap bitmap;
32    public Bitmap Bitmap { get; private set; }
33    private bool renderingRequired;
34    private Point buttonDownPoint;
35    private Point mousePosition;
36    private int mouseClickCount;
37
38    private Chart myChart;
39    public Chart Chart {
40      get { return myChart; }
41      set {
42        if (myChart != null) myChart.Update -= new EventHandler(myChart_Update);
43        myChart = value;
44        if (myChart != null) {
45          myChart.Update += new EventHandler(myChart_Update);
46          SetMode(Chart.Mode);
47        }
48        GenerateImage();
49      }
50    }
51    private bool myScaleOnResize;
52    public bool ScaleOnResize {
53      get { return myScaleOnResize; }
54      set { myScaleOnResize = value; }
55    }
56
57    public ChartControl() {
58      InitializeComponent();
59      myScaleOnResize = true;
60      GenerateImage();
61    }
62
63    private void myChart_Update(object sender, EventArgs e) {
64      GenerateImage();
65    }
66    private void pictureBox_SizeChanged(object sender, EventArgs e) {
67      if (ScaleOnResize) {
68        if ((pictureBox.Width > 0) && (pictureBox.Height > 0) && (Chart != null)) {
69          PointD point = Chart.TransformPixelToWorld(new Point(pictureBox.Width, Chart.SizeInPixels.Height - pictureBox.Height));
70          Chart.SetPosition(Chart.LowerLeft, point);
71        }
72      }
73      GenerateImage();
74    }
75    private void pictureBox_VisibleChanged(object sender, EventArgs e) {
76      if (pictureBox.Visible && renderingRequired) {
77        GenerateImage();
78      }
79    }
80
81    private void pictureBox_MouseDown(object sender, MouseEventArgs e) {
82      buttonDownPoint = e.Location;
83      mouseClickCount = e.Clicks;
84    }
85    protected virtual void pictureBox_MouseUp(object sender, MouseEventArgs e) {
86      if (e.Button == MouseButtons.Left) {
87        if (Chart.Mode == ChartMode.Zoom) {
88          pictureBox.Refresh();
89          // some code to preserve the aspect ratio when zooming
90          //       +---------------------+ (Width,Height)
91          //       |  (x1,y1)            |
92          //       |      +-------+      |
93          //       |      |       |      |
94          //       |      |       |      |
95          //       |      +-------+      |
96          //       |             (x2,y2) |
97          // (0,0) +---------------------+
98          //
99          double aspectRatio = (double)Width / Height;
100          double x1 = Math.Min(e.X, buttonDownPoint.X);
101          double y1 = Math.Max(e.Y, buttonDownPoint.Y);
102          double x2 = Math.Max(e.X, buttonDownPoint.X);
103          double y2 = Math.Min(e.Y, buttonDownPoint.Y);
104          // consider the relative ratios between the X and Y dimensions of the selection
105          // area and the Width and Height, respectively. The "dominant" dimension is the
106          // one with a ratio closer to 1, and it stays fixed while the other is adjusted
107          // in order to preserve the aspect ratio
108          if ((x2 - x1) / Width > (y1 - y2) / Height) {
109            y1 = y2 + (x2 - x1) / aspectRatio;
110          } else {
111            x2 = aspectRatio * (y1 - y2) + x1;
112          }
113          var lowerLeft = new Point((int)x1, (int)y1);
114          var upperRight = new Point((int)x2, (int)y2);
115          if ((lowerLeft.X != upperRight.X) && (lowerLeft.Y != upperRight.Y)) {
116            Chart.ZoomIn(lowerLeft, upperRight);
117          }
118        }
119      } else if (e.Button == MouseButtons.Right) {
120        propertiesToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
121        oneLayerUpToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
122        oneLayerDownToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
123        intoForegroundToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
124        intoBackgroundToolStripMenuItem.Enabled = Chart.Group.SelectedPrimitives.Count == 1;
125      } else if (e.Button == MouseButtons.Middle) {
126        if (Chart.Mode == ChartMode.Zoom) {
127          if (mouseClickCount == 1) Chart.ZoomOut();
128          else if (mouseClickCount == 2) Chart.Unzoom();
129        }
130      }
131      if (buttonDownPoint == e.Location) {
132        if (mouseClickCount == 1)
133          Chart.MouseClick(e.Location, e.Button);
134        else if (mouseClickCount == 2)
135          Chart.MouseDoubleClick(e.Location, e.Button);
136      }
137    }
138
139    protected virtual void pictureBox_MouseMove(object sender, MouseEventArgs e) {
140      var text = Chart.GetToolTipText(e.Location);
141      if (toolTip.GetToolTip(pictureBox) != text)
142        toolTip.SetToolTip(pictureBox, text);
143      Cursor cursor = Chart.GetCursor(e.Location);
144      if (cursor != null) pictureBox.Cursor = cursor;
145      else pictureBox.Cursor = Cursors.Default;
146
147      if (e.Button != MouseButtons.None) {
148        if ((Chart.Mode == ChartMode.Zoom) && (e.Button == MouseButtons.Left)) {
149          pictureBox.Refresh();
150          Graphics graphics = pictureBox.CreateGraphics();
151          Pen pen = new Pen(Color.Gray);
152          pen.DashStyle = DashStyle.Dash;
153          graphics.DrawRectangle(pen,
154                                 Math.Min(e.X, buttonDownPoint.X),
155                                 Math.Min(e.Y, buttonDownPoint.Y),
156                                 Math.Abs(e.X - buttonDownPoint.X),
157                                 Math.Abs(e.Y - buttonDownPoint.Y));
158          pen.Dispose();
159          graphics.Dispose();
160        }
161        Chart.MouseDrag(mousePosition, e.Location, e.Button);
162      } else {
163        Chart.MouseMove(mousePosition, e.Location);
164      }
165      mousePosition = e.Location;
166    }
167
168    private void ChartControl_KeyDown(object sender, KeyEventArgs e) {
169      if (Chart.Mode == ChartMode.Select) {
170        if (e.KeyCode == Keys.Delete) {
171          IList<IPrimitive> selected = Chart.Group.SelectedPrimitives;
172          Chart.UpdateEnabled = false;
173          foreach (IPrimitive primitive in selected)
174            Chart.Group.Remove(primitive);
175          Chart.UpdateEnabled = true;
176          Chart.EnforceUpdate();
177        }
178      }
179    }
180
181    private void moveToolStripMenuItem_Click(object sender, EventArgs e) {
182      SetMode(ChartMode.Move);
183    }
184    private void zoomToolStripMenuItem_Click(object sender, EventArgs e) {
185      SetMode(ChartMode.Zoom);
186    }
187    private void selectToolStripMenuItem_Click(object sender, EventArgs e) {
188      SetMode(ChartMode.Select);
189    }
190    private void oneLayerUpToolStripMenuItem_Click(object sender, EventArgs e) {
191      if (Chart.Group.SelectedPrimitives.Count == 1) {
192        Chart.Group.SelectedPrimitives[0].OneLayerUp();
193      }
194    }
195    private void oneLayerDownToolStripMenuItem_Click(object sender, EventArgs e) {
196      if (Chart.Group.SelectedPrimitives.Count == 1) {
197        Chart.Group.SelectedPrimitives[0].OneLayerDown();
198      }
199    }
200    private void intoForegroundToolStripMenuItem_Click(object sender, EventArgs e) {
201      if (Chart.Group.SelectedPrimitives.Count == 1) {
202        Chart.Group.SelectedPrimitives[0].IntoForeground();
203      }
204    }
205    private void intoBackgroundToolStripMenuItem_Click(object sender, EventArgs e) {
206      if (Chart.Group.SelectedPrimitives.Count == 1) {
207        Chart.Group.SelectedPrimitives[0].IntoBackground();
208      }
209    }
210    private void propertiesToolStripMenuItem_Click(object sender, EventArgs e) {
211      if (Chart.Group.SelectedPrimitives.Count == 1) {
212        PropertiesDialog dialog = new PropertiesDialog(Chart.Group.SelectedPrimitives[0]);
213        dialog.ShowDialog(this);
214        dialog.Dispose();
215      }
216    }
217
218    private void GenerateImage() {
219      if (!Visible) {
220        renderingRequired = true;
221      } else {
222        if ((pictureBox.Width == 0) || (pictureBox.Height == 0)) {
223          bitmap = null;
224        } else {
225          bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
226          if (Chart != null) {
227            Graphics graphics = Graphics.FromImage(bitmap);
228            graphics.SetClip(new System.Drawing.Rectangle(0, 0, pictureBox.Width, pictureBox.Height));
229            Chart.Render(graphics, pictureBox.Width, pictureBox.Height);
230            graphics.Dispose();
231          }
232        }
233        if (pictureBox.Image != null) pictureBox.Image.Dispose();
234        pictureBox.Image = bitmap;
235        renderingRequired = false;
236      }
237    }
238
239    private void SetMode(ChartMode mode) {
240      moveToolStripMenuItem.Checked = false;
241      zoomToolStripMenuItem.Checked = false;
242      selectToolStripMenuItem.Checked = false;
243      if (mode == ChartMode.Move) moveToolStripMenuItem.Checked = true;
244      else if (mode == ChartMode.Zoom) zoomToolStripMenuItem.Checked = true;
245      else if (mode == ChartMode.Select) selectToolStripMenuItem.Checked = true;
246      Chart.Mode = mode;
247    }
248
249    private void SaveImageAsBitmap(string filename) {
250      if (bitmap == null) throw new Exception("Bitmap is null.");
251      bitmap.Save(filename);
252    }
253
254    private void SaveImageAsEmf(string filename) {
255      using (Graphics g = CreateGraphics()) {
256        using (Metafile file = new Metafile(filename, g.GetHdc())) {
257          using (Graphics emfFile = Graphics.FromImage(file)) {
258            Chart.Render(emfFile, pictureBox.Width, pictureBox.Height);
259          }
260        }
261        g.ReleaseHdc();
262      }
263    }
264
265    private void saveImageToolStripMenuItem_Click(object sender, EventArgs e) {
266      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
267        string filename = saveFileDialog.FileName.ToLower();
268        if (filename.EndsWith("bmp")) SaveImageAsBitmap(filename);
269        else if (filename.EndsWith("emf")) SaveImageAsEmf(filename);
270        else SaveImageAsBitmap(filename);
271      }
272    }
273  }
274}
Note: See TracBrowser for help on using the repository browser.