MSChart Extension - Zoom and Pan Controls
NEW: MSChart Extension 2.0 Released - Find out more
Introduction - About MSChart Extension
MSChart Extension is an extension package created to provide additional features and functions to Microsoft Chart (MSChart) control. This control is released under MIT license.Get latest source code and package from NuGet or GitHub.
GitHub: https://github.com/Code-Artist/MSChartExtension
NuGet: http://nuget.org/packages/MSChartExtension
Background
Microsoft Chart (MSChart) in Visual Studio is a great Windows Forms (WinForms) controls to create chart for standalone application. However, there are several features that could be added and improved to make this controls more user friendly.Zooming and panning are two common feature for chart when dealing with large amount of data. Unfortunately, there are no easy way to have these two features enabled with MSChart. Although there is a built in Zoom controls, it is not very user friendly which described below. On the other hand, panning is not available. Search around web but didn't find any reliable solutions.
I tried to implement these two features in MSChart by writing custom codes and YES it is possible. Instead of copy and paste the same piece of code over and over again to every single project that I need, I created this MSChart Extension class which put all these additional features in a separated assembly which can be simply add as reference when needed.
Features List
- Fast Clear Data
- Windowed Zoom in and Zoom Out
- Pan
- Show / hide series
- Annotations (Version 1.2.0)
Fast Clear Data
MSChart has a known problem which impact most of
the users which is the speed of clearing data points. This become worst
when dealing with large amount of data. Workaround for this solution had
been published by Microsoft and users to fix this problem. See previous
post: Speedup MSChart for more details. //Clear Data Points
myChart.Series[0].ClearPoints();
Windowed Zoom
This is a improvement version of zoom control with
zoom out (full view) instead of using built in zoom control in MSChart.
The main reason for recreate this feature is because zooming out is
really a pain where need to zoom out each axis
separately by clicking a button on the axis by number of time that I
zoomed in. Moreover, the built in controls does not seems to works well
with annotations.Notes: Zoom out function is available in pop up menu when chart is zoomed.
Pan
Panning allowed user to move zoomed window using mouse. This is much better than moving the horizontal and vertical scroll bar.
Show / Hide Series
Sometimes, it is necessary to plot chart with
multiple series for data comparison. However, it would not be easy to
visualize the data for each individual series when we have multiple
series overlapping each other. Show and hide series function provide a
flexibility to hide each series as you wish. MSChart extension will
automatically detect number of series used in chart, no setup is
required to use this feature. Each series can be hide / show from
context menu.
Annotations (Version 1.2.0)
Extensions methods to create chart annotations are added in Version 1.2.0 as below.- DrawHorizontalLine
- DrawVerticalLine
- DrawLine
- DrawRectangle
- DrawText
With the extension methods provided above, adding annotation can be easily done in single function call. Colors, line weight, line style and position are exposed as input parameters.
Functions listed above are just few of the commonly used annotation type. You may create similar function for other types of annotation using the similar methods.
NOTE: Please note that these functions are created to add annotation to first chart area with primary axis.
Codes below shows an example of adding horizontal line to chart. ClipToChartArea, AxisXName, YAxisName, and IsInfinite are properties that we need to overwrite its default values. AxisXName and YAxisName are hidden properties which is not visible in IntelliSense.
Custom annotation name should only be assigned after annotation was added to annotation list. This is because the Name property will be overwrite with auto generated value when adding the object to annotation list.
public static void DrawHorizontalLine(this Chart sender, double y, Drawing.Color lineColor, string name = "", int lineWidth = 1, ChartDashStyle lineStyle = ChartDashStyle.Solid) { HorizontalLineAnnotation horzLine = new HorizontalLineAnnotation(); string chartAreaName = sender.ChartAreas[0].Name; horzLine.ClipToChartArea = chartAreaName; horzLine.AxisXName = chartAreaName + "\\rX"; horzLine.YAxisName = chartAreaName + "\\rY"; horzLine.IsInfinitive = true; horzLine.IsSizeAlwaysRelative = false; horzLine.Y = y; horzLine.LineColor = lineColor; horzLine.LineWidth = lineWidth; horzLine.LineDashStyle = lineStyle; sender.Annotations.Add(horzLine); if (!string.IsNullOrEmpty(name)) horzLine.Name = name; }
Using MSChart Extension
To use this extension package, simply add MSChart assembly to reference of the project.Additional features and dedicated context menu can be enabled by the following function call.
private void AttachChartControl() { //Enable Extension Functions and Context Menu myChart.EnableZoomAndPanControls(ChartCursorSelected, ChartCursorMoved); } private void ChartCursorSelected(double x, double y) { txtChartSelect.Text = x.ToString("F4") + ", " + y.ToString("F4"); } private void ChartCursorMoved(double x, double y) { txtChartValue.Text = x.ToString("F4") + ", " + y.ToString("F4"); }
ChartCursorSelected and ChartCursorMoved are two optional callback to notify parent when chart coordinate changed. ChartCursorSelected will be called when a point in chart area is selected whereas ChartCursorMoved will trigger when mouse is move in chart area. x and y values in these two call backs are values for X-Axis and Y-Axis. It is hard coded to use primary axis at this moment.
This operation is reversible by calling the following function.
//Disable Extension Functions and restore chart settings myChart.DisableZoomAndPanControls();
MSChart Extension come with a built in pop up menu which allow user to use features such as zoom and pan controls during run-time. All functions such as zoom, pan, select and series hide / show can be access from context menu. This context menu is shown when right click mouse in chart with Zoom and Pan controls enabled as show above.
Updates
Merged Context Menu (Version 1.1.1)
MSChart Extension's context menu will automatically merge with user assigned context menu when Zoom and Pan controls is enabled. Disabling the control will restore the context menu to original state.Cloning context menu is implemented using Menu_Cloner by jmertus.
Speedup Zoom Out (ZoomReset) (Version 1.1.2)
Time need to zoom out chart is proportional to number of times chart is zoomed.A work around is implemented to speed up this process to stop chart repaint until zoom out process is complete. SuspendDrawing is called before ZoomReset to stop painting whereas ResumeDrawing is called after ZoomReset to resume chart painting.
using System.Runtime.InteropServices; static class WindowMessagesNativeMethods { [DllImport("user32.dll")] private static extern long SendMessage(IntPtr hWnd, Int32 wMsg, [MarshalAs(UnmanagedType.Bool)] bool wParam, Int32 lParam); private const int WM_SETREDRAW = 11; public static void SuspendDrawing(Control parent) { SendMessage(parent.Handle, WM_SETREDRAW, false, 0); } public static void ResumeDrawing(Control parent) { SendMessage(parent.Handle, WM_SETREDRAW, true, 0); parent.Refresh(); } }
Future Improvement
- Add option to select between primary / secondary axis for Select tool and callback functions.
Append MSChart Extension's context menu to user defined context menu if exists.- Implement 2 cursor to calculate different between 2 points.
Version History
02/04/2012 Original document.03/04/2012 Reformat.
04/04/2012 Added description to call back functions and future improvement list.
24/04/2012 Published as NuGet Package
29/05/2012 Added Version 1.1.1 and Version 1.1.2 updates.
18/07/2012 Version 1.2.0: Added annotations functions.
03/07/2013 Version 1.3.0: Improved zoom function, refactoring...
30/08/2014 Version 1.4.0: Support secondary axis zoom and pan functions.
08/10/2015 Version 1.4.1: Added license file.