source: stable/HeuristicLab.Visualization.ChartControlsExtensions/3.3/EnhancedChart.cs @ 15039

Last change on this file since 15039 was 15039, checked in by pfleck, 4 years ago

#2694: merged r14369 from trunk to stable

File size: 6.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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.Windows.Forms;
26using System.Windows.Forms.DataVisualization.Charting;
27
28namespace HeuristicLab.Visualization.ChartControlsExtensions {
29  public partial class EnhancedChart : Chart {
30
31    private ImageExportDialog exportDialog;
32
33    private ImageExportDialog ExportDialog {
34      get { return exportDialog ?? (exportDialog = new ImageExportDialog(this)); }
35    }
36
37    public EnhancedChart()
38      : base() {
39      InitializeComponent();
40      EnableDoubleClickResetsZoom = true;
41      EnableMiddleClickPanning = true;
42      CustomizeAllChartAreas();
43    }
44
45    [DefaultValue(true)]
46    public bool EnableDoubleClickResetsZoom { get; set; }
47    [DefaultValue(true)]
48    public bool EnableMiddleClickPanning { get; set; }
49
50    public static void CustomizeChartArea(ChartArea chartArea) {
51      foreach (Axis axis in chartArea.Axes) {
52        axis.MajorGrid.LineColor = SystemColors.GradientInactiveCaption;
53        axis.MajorTickMark.TickMarkStyle = TickMarkStyle.AcrossAxis;
54        axis.ScrollBar.BackColor = Color.Transparent;
55        axis.ScrollBar.LineColor = Color.Gray;
56        axis.ScrollBar.ButtonColor = SystemColors.GradientInactiveCaption;
57        axis.ScrollBar.ButtonStyle = ScrollBarButtonStyles.All;
58        axis.ScrollBar.Size = 12;
59        axis.TitleFont = new Font(axis.TitleFont.FontFamily, 10);
60      }
61      chartArea.CursorX.IsUserSelectionEnabled = true;
62      chartArea.CursorY.IsUserSelectionEnabled = true;
63      chartArea.CursorX.IsUserEnabled = false;
64      chartArea.CursorY.IsUserEnabled = false;
65      chartArea.CursorX.SelectionColor = Color.Gray;
66      chartArea.CursorY.SelectionColor = Color.Gray;
67    }
68
69    public void CustomizeAllChartAreas() {
70      foreach (ChartArea chartArea in ChartAreas) {
71        CustomizeChartArea(chartArea);
72      }
73    }
74
75    #region Mouse Event Ehancements
76    protected override void OnMouseDoubleClick(MouseEventArgs e) {
77      if (EnableDoubleClickResetsZoom) {
78        HitTestResult result = HitTest(e.X, e.Y);
79        if (result.ChartArea != null && (result.ChartElementType == ChartElementType.PlottingArea || result.ChartElementType == ChartElementType.Gridlines)) {
80          foreach (var axis in result.ChartArea.Axes)
81            axis.ScaleView.ZoomReset(0);
82        }
83      }
84      base.OnMouseDoubleClick(e);
85    }
86
87    #region Panning
88    private class PanningSupport {
89      public ChartArea ChartArea { get; private set; }
90
91      private Point PixelStartPosition;
92      private PointF ChartStartPosition;
93
94      public PanningSupport(Point pixelStartPos, ChartArea chartArea, Size size) {
95        PixelStartPosition = pixelStartPos;
96        ChartArea = chartArea;
97        ChartStartPosition = new PointF(
98          (float)chartArea.AxisX.ScaleView.Position,
99          (float)chartArea.AxisY.ScaleView.Position);
100      }
101
102      public double ChartX(double pixelX, int width) {
103        return ChartStartPosition.X - (pixelX - PixelStartPosition.X) *
104          (ChartArea.AxisX.ScaleView.ViewMaximum - ChartArea.AxisX.ScaleView.ViewMinimum) /
105            (width * ChartArea.Position.Width * ChartArea.InnerPlotPosition.Width / 100 / 100);
106      }
107      public double ChartY(double pixelY, int height) {
108        return ChartStartPosition.Y + (pixelY - PixelStartPosition.Y) *
109          (ChartArea.AxisY.ScaleView.ViewMaximum - ChartArea.AxisY.ScaleView.ViewMinimum) /
110            (height * ChartArea.Position.Height * ChartArea.InnerPlotPosition.Height / 100 / 100);
111      }
112    }
113
114    private PanningSupport panning = null;
115
116    protected override void OnMouseDown(MouseEventArgs e) {
117      if (EnableMiddleClickPanning && e.Button == MouseButtons.Middle) {
118        HitTestResult result = HitTest(e.X, e.Y);
119        if (result.ChartArea != null)
120          panning = new PanningSupport(e.Location, result.ChartArea, Size);
121      }
122      base.OnMouseDown(e);
123    }
124
125    protected override void OnMouseUp(MouseEventArgs e) {
126      if (e.Button == MouseButtons.Middle && panning != null)
127        panning = null;
128      base.OnMouseUp(e);
129    }
130
131    protected override void OnMouseMove(MouseEventArgs e) {
132      if (panning != null) {
133        double x = panning.ChartX(e.Location.X, Width);
134        double y = panning.ChartY(e.Location.Y, Height);
135        if (panning.ChartArea.CursorX.Interval > 0) {
136          x = Math.Round(x / panning.ChartArea.CursorX.Interval) * panning.ChartArea.CursorX.Interval;
137          y = Math.Round(y / panning.ChartArea.CursorY.Interval) * panning.ChartArea.CursorY.Interval;
138        }
139        panning.ChartArea.AxisX.ScaleView.Scroll(x);
140        panning.ChartArea.AxisY.ScaleView.Scroll(y);
141      }
142      base.OnMouseMove(e);
143    }
144    #endregion
145    #endregion
146
147    private void exportChartToolStripMenuItem_Click(object sender, EventArgs e) {
148      // Set image file format
149      if (saveFileDialog.ShowDialog() == DialogResult.OK) {
150        ChartImageFormat format = ChartImageFormat.Bmp;
151        string filename = saveFileDialog.FileName.ToLower();
152        if (filename.EndsWith("bmp")) {
153          format = ChartImageFormat.Bmp;
154        } else if (filename.EndsWith("jpg")) {
155          format = ChartImageFormat.Jpeg;
156        } else if (filename.EndsWith("emf")) {
157          format = ChartImageFormat.EmfDual;
158        } else if (filename.EndsWith("gif")) {
159          format = ChartImageFormat.Gif;
160        } else if (filename.EndsWith("png")) {
161          format = ChartImageFormat.Png;
162        } else if (filename.EndsWith("tif")) {
163          format = ChartImageFormat.Tiff;
164        }
165
166        // Save image
167        SaveImage(saveFileDialog.FileName, format);
168      }
169    }
170
171    private void exportToolStripMenuItem_Click(object sender, EventArgs e) {
172      ExportDialog.ShowDialog();
173    }
174
175    private void copyImageToClipboardBitmapToolStripMenuItem_Click(object sender, EventArgs e) {
176      System.IO.MemoryStream stream = new System.IO.MemoryStream();
177      SaveImage(stream, System.Drawing.Imaging.ImageFormat.Bmp);
178      Bitmap bmp = new Bitmap(stream);
179      Clipboard.SetDataObject(bmp);
180    }
181  }
182}
Note: See TracBrowser for help on using the repository browser.