Index: trunk/sources/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.cs
===================================================================
--- trunk/sources/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.cs	(revision 4616)
+++ trunk/sources/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.cs	(revision 4621)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.ComponentModel;
 using System.Drawing;
 using System.Windows.Forms;
@@ -25,7 +26,121 @@
 namespace HeuristicLab.Visualization.ChartControlsExtensions {
   public partial class EnhancedChart : Chart {
+
+
     public EnhancedChart()
       : base() {
+      EnableDoubleClickResetsZoom = true;
+      EnableMiddleClickPanning = true;
     }
+
+    [DefaultValue(true)]
+    public bool EnableDoubleClickResetsZoom { get; set; }
+
+    [DefaultValue(true)]
+    public bool EnableMiddleClickPanning { get; set; }
+
+    public void InitializeChartAreas() {
+      ChartAreas.Clear();
+      ChartAreas.Add(GetDefaultChartArea("ChartArea"));
+    }
+
+    public static ChartArea GetDefaultChartArea(string name) {
+      ChartArea chartArea = new ChartArea(name);
+      chartArea.AxisX.MajorGrid.LineColor = SystemColors.GradientInactiveCaption;
+      chartArea.AxisY.MajorGrid.LineColor = SystemColors.GradientInactiveCaption;
+      chartArea.AxisX.MajorTickMark.TickMarkStyle = TickMarkStyle.AcrossAxis;
+      chartArea.AxisY.MajorTickMark.TickMarkStyle = TickMarkStyle.AcrossAxis;
+      chartArea.AxisX.ScrollBar.BackColor = Color.Transparent;
+      chartArea.AxisY.ScrollBar.BackColor = Color.Transparent;
+      chartArea.AxisX.ScrollBar.LineColor = Color.Transparent;
+      chartArea.AxisY.ScrollBar.LineColor = Color.Transparent;
+      chartArea.AxisX.ScrollBar.ButtonColor = SystemColors.GradientInactiveCaption;
+      chartArea.AxisY.ScrollBar.ButtonColor = SystemColors.GradientInactiveCaption;
+      chartArea.AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
+      chartArea.AxisY.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
+      chartArea.AxisX.ScrollBar.Size = 12;
+      chartArea.AxisY.ScrollBar.Size = 12;
+      chartArea.CursorX.Interval = 0;
+      chartArea.CursorY.Interval = 0;
+      chartArea.CursorX.IsUserSelectionEnabled = true;
+      chartArea.CursorY.IsUserSelectionEnabled = true;
+      chartArea.CursorX.SelectionColor = SystemColors.GradientActiveCaption;
+      chartArea.CursorY.SelectionColor = SystemColors.GradientActiveCaption;
+      return chartArea;
+    }
+
+    #region Mouse event ehancements
+
+    protected override void OnMouseDoubleClick(MouseEventArgs e) {
+      if (EnableDoubleClickResetsZoom) {
+        HitTestResult result = HitTest(e.X, e.Y);
+        if (result.ChartArea != null && result.ChartElementType == ChartElementType.PlottingArea) {
+          foreach (var axis in result.ChartArea.Axes)
+            axis.ScaleView.ZoomReset();
+        }
+      }
+      base.OnMouseDoubleClick(e);
+    }
+
+    #region panning
+
+    private class PanningSupport {
+
+      public ChartArea ChartArea { get; private set; }
+
+      private Point PixelStartPosition;
+      private PointF ChartStartPosition;
+      private SizeF Pixel2ChartScale;
+
+      public PanningSupport(Point pixelStartPos, ChartArea chartArea, Size size) {
+        PixelStartPosition = pixelStartPos;
+        ChartArea = chartArea;
+        ChartStartPosition = new PointF(
+          (float)chartArea.AxisX.ScaleView.Position,
+          (float)chartArea.AxisY.ScaleView.Position);
+        Pixel2ChartScale = new SizeF(
+          (float)chartArea.AxisX.ScaleView.Size /
+            (size.Width * chartArea.Position.Width * chartArea.InnerPlotPosition.Width / 100 / 100),
+          (float)chartArea.AxisY.ScaleView.Size /
+            (size.Height * chartArea.Position.Height * chartArea.InnerPlotPosition.Height / 100 / 100));
+      }
+
+      public double ChartX(double pixelX) {
+        return ChartStartPosition.X - (pixelX - PixelStartPosition.X) * Pixel2ChartScale.Width;
+      }
+
+      public double ChartY(double pixelY) {
+        return ChartStartPosition.Y + (pixelY - PixelStartPosition.Y) * Pixel2ChartScale.Height;
+      }
+    }
+
+    private PanningSupport panning = null;
+
+    protected override void OnMouseDown(MouseEventArgs e) {
+      if (EnableMiddleClickPanning && e.Button == MouseButtons.Middle) {
+        HitTestResult result = HitTest(e.X, e.Y);
+        if (result.ChartArea != null)
+          panning = new PanningSupport(e.Location, result.ChartArea, Size);
+      }
+      base.OnMouseDown(e);
+    }
+
+    protected override void OnMouseUp(MouseEventArgs e) {
+      if (e.Button == MouseButtons.Middle && panning != null)
+        panning = null;
+      base.OnMouseUp(e);
+    }
+
+    protected override void OnMouseMove(MouseEventArgs e) {
+      if (panning != null) {
+        panning.ChartArea.AxisX.ScaleView.Scroll(panning.ChartX(e.Location.X));
+        panning.ChartArea.AxisY.ScaleView.Scroll(panning.ChartY(e.Location.Y));
+      }
+      base.OnMouseMove(e);
+    }
+
+    #endregion
+
+    #endregion
 
     private void saveImageToolStripMenuItem_Click(object sender, System.EventArgs e) {
@@ -42,16 +157,16 @@
       if (saveFileDialog.ShowDialog() == DialogResult.OK) {
         ChartImageFormat format = ChartImageFormat.Bmp;
-
-        if (saveFileDialog.FileName.EndsWith("bmp")) {
+        string filename = saveFileDialog.FileName.ToLower();
+        if (filename.EndsWith("bmp")) {
           format = ChartImageFormat.Bmp;
-        } else if (saveFileDialog.FileName.EndsWith("jpg")) {
+        } else if (filename.EndsWith("jpg")) {
           format = ChartImageFormat.Jpeg;
-        } else if (saveFileDialog.FileName.EndsWith("emf")) {
+        } else if (filename.EndsWith("emf")) {
           format = ChartImageFormat.EmfDual;
-        } else if (saveFileDialog.FileName.EndsWith("gif")) {
+        } else if (filename.EndsWith("gif")) {
           format = ChartImageFormat.Gif;
-        } else if (saveFileDialog.FileName.EndsWith("png")) {
+        } else if (filename.EndsWith("png")) {
           format = ChartImageFormat.Png;
-        } else if (saveFileDialog.FileName.EndsWith("tif")) {
+        } else if (filename.EndsWith("tif")) {
           format = ChartImageFormat.Tiff;
         }
