1 //-------------------------------------------------------------
2 // <copyright company=�Microsoft Corporation�>
3 //   Copyright � Microsoft Corporation. All Rights Reserved.
4 // </copyright>
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 //  File:		ChartTypeRegistry.cs
9 //
10 //  Namespace:	DataVisualization.Charting.ChartTypes
11 //
12 //	Classes:	ChartTypeRegistry, IChartType
13 //
14 //  Purpose:	ChartTypeRegistry is a repository for all standard
15 //              and custom chart types. Each chart type has unique
16 //              name and IChartType derived class which provides
17 //              behaviour information about the chart type and
18 //              also contains drwaing functionality.
19 //
20 //              ChartTypeRegistry can be used by user for custom
21 //              chart type registering and can be retrieved using
22 //              Chart.GetService(typeof(ChartTypeRegistry)) method.
23 //
24 //	Reviewed:	AG - Aug 6, 2002
25 //              AG - Microsoft 6, 2007
26 //
27 //===================================================================
28 
29 #region Used namespaces
30 
31 using System;
32 using System.Resources;
33 using System.Collections;
34 using System.ComponentModel;
35 using System.ComponentModel.Design;
36 using System.Reflection;
37 using System.Drawing;
38 
39 #if Microsoft_CONTROL
40 	using System.Windows.Forms.DataVisualization.Charting;
41 	using System.Windows.Forms.DataVisualization.Charting.Data;
42 	using System.Windows.Forms.DataVisualization.Charting.ChartTypes;
43 	using System.Windows.Forms.DataVisualization.Charting.Utilities;
44 	using System.Windows.Forms.DataVisualization.Charting.Borders3D;
45 
46 #else
47 using System.Web.UI.DataVisualization.Charting;
48 
49 	using System.Web.UI.DataVisualization.Charting.Data;
50 	using System.Web.UI.DataVisualization.Charting.ChartTypes;
51 	using System.Web.UI.DataVisualization.Charting.Utilities;
52 #endif
53 
54 #endregion
55 
56 #if Microsoft_CONTROL
57 	namespace System.Windows.Forms.DataVisualization.Charting.ChartTypes
58 #else
59 	namespace System.Web.UI.DataVisualization.Charting.ChartTypes
60 #endif
61 {
62     /// <summary>
63     /// ChartTypeName class contains constant strings defining
64     /// names of all ChartTypes used in the Chart.
65     /// </summary>
66     internal static class ChartTypeNames
67     {
68         #region Chart type names
69 
70         internal const string Area = "Area";
71         internal const string RangeBar = "RangeBar";
72         internal const string Bar = "Bar";
73         internal const string SplineArea = "SplineArea";
74         internal const string BoxPlot = "BoxPlot";
75         internal const string Bubble = "Bubble";
76         internal const string Column = "Column";
77         internal const string RangeColumn = "RangeColumn";
78         internal const string Doughnut = "Doughnut";
79         internal const string ErrorBar = "ErrorBar";
80         internal const string FastLine = "FastLine";
81         internal const string FastPoint = "FastPoint";
82         internal const string Funnel = "Funnel";
83         internal const string Pyramid = "Pyramid";
84         internal const string Kagi = "Kagi";
85         internal const string Spline = "Spline";
86         internal const string Line = "Line";
87         internal const string PointAndFigure = "PointAndFigure";
88         internal const string Pie = "Pie";
89         internal const string Point = "Point";
90         internal const string Polar = "Polar";
91         internal const string Radar = "Radar";
92         internal const string SplineRange = "SplineRange";
93         internal const string Range = "Range";
94         internal const string Renko = "Renko";
95         internal const string OneHundredPercentStackedArea = "100%StackedArea";
96         internal const string StackedArea = "StackedArea";
97         internal const string OneHundredPercentStackedBar = "100%StackedBar";
98         internal const string StackedBar = "StackedBar";
99         internal const string OneHundredPercentStackedColumn = "100%StackedColumn";
100         internal const string StackedColumn = "StackedColumn";
101         internal const string StepLine = "StepLine";
102         internal const string Candlestick = "Candlestick";
103         internal const string Stock = "Stock";
104         internal const string ThreeLineBreak = "ThreeLineBreak";
105 
106         #endregion // Keyword Names
107     }
108 
109 	/// <summary>
110 	/// ChartTypeRegistry class is a repository for all standard and custom
111     /// chart types. In order for the chart control to display the chart
112     /// type, it first must be registered using unique name and IChartType
113     /// derived class which provides the description of the chart type and
114     /// also responsible for all drawing and hit testing.
115     ///
116     /// ChartTypeRegistry can be used by user for custom chart type registering
117     /// and can be retrieved using Chart.GetService(typeof(ChartTypeRegistry))
118     /// method.
119 	/// </summary>
120     internal class ChartTypeRegistry : IServiceProvider, IDisposable
121 	{
122 		#region Fields
123 
124 		// Chart types image resource manager
125 		private		ResourceManager		_resourceManager = null;
126 
127 		// Storage for registered/created chart types
128         internal    Hashtable           registeredChartTypes = new Hashtable(StringComparer.OrdinalIgnoreCase);
129         private     Hashtable           _createdChartTypes = new Hashtable(StringComparer.OrdinalIgnoreCase);
130 
131 		#endregion
132 
133 		#region Constructor and Services
134 
135 		/// <summary>
136 		/// Chart types registry public constructor.
137 		/// </summary>
ChartTypeRegistry()138 		public ChartTypeRegistry()
139 		{
140 		}
141 
142 		/// <summary>
143 		/// Returns chart type registry service object.
144 		/// </summary>
145 		/// <param name="serviceType">Service type to get.</param>
146 		/// <returns>Chart type registry service.</returns>
147 		[EditorBrowsableAttribute(EditorBrowsableState.Never)]
IServiceProvider.GetService(Type serviceType)148 		object IServiceProvider.GetService(Type serviceType)
149 		{
150 			if(serviceType == typeof(ChartTypeRegistry))
151 			{
152 				return this;
153 			}
154             throw (new ArgumentException(SR.ExceptionChartTypeRegistryUnsupportedType( serviceType.ToString() ) ) );
155 		}
156 
157 		#endregion
158 
159 		#region Registry methods
160 
161 		/// <summary>
162 		/// Adds chart type into the registry.
163 		/// </summary>
164 		/// <param name="name">Chart type name.</param>
165 		/// <param name="chartType">Chart class type.</param>
Register(string name, Type chartType)166 		public void Register(string name, Type chartType)
167 		{
168 			// First check if chart type with specified name already registered
169 			if(registeredChartTypes.Contains(name))
170 			{
171 				// If same type provided - ignore
172 				if(registeredChartTypes[name].GetType() == chartType)
173 				{
174 					return;
175 				}
176 
177 				// Error - throw exception
178 				throw( new ArgumentException( SR.ExceptionChartTypeNameIsNotUnique( name ) ) );
179 			}
180 
181 			// Make sure that specified class support IChartType interface
182 			bool	found = false;
183 			Type[]	interfaces = chartType.GetInterfaces();
184 			foreach(Type type in interfaces)
185 			{
186 				if(type == typeof(IChartType))
187 				{
188 					found = true;
189 					break;
190 				}
191 			}
192 			if(!found)
193 			{
194                 throw (new ArgumentException(SR.ExceptionChartTypeHasNoInterface ));
195 			}
196 
197 			// Add chart type to the hash table
198 			registeredChartTypes[name] = chartType;
199 		}
200 
201 		/// <summary>
202 		/// Returns chart type object by name.
203 		/// </summary>
204 		/// <param name="chartType">Chart type.</param>
205 		/// <returns>Chart type object derived from IChartType.</returns>
GetChartType(SeriesChartType chartType)206 		public IChartType GetChartType(SeriesChartType chartType)
207 		{
208 			return this.GetChartType(Series.GetChartTypeName(chartType));
209 		}
210 
211 		/// <summary>
212 		/// Returns chart type object by name.
213 		/// </summary>
214 		/// <param name="name">Chart type name.</param>
215 		/// <returns>Chart type object derived from IChartType.</returns>
GetChartType(string name)216 		public IChartType GetChartType(string name)
217 		{
218 			// First check if chart type with specified name registered
219 			if(!registeredChartTypes.Contains(name))
220 			{
221 				throw( new ArgumentException( SR.ExceptionChartTypeUnknown( name ) ) );
222 			}
223 
224 			// Check if the chart type object is already created
225 			if(!_createdChartTypes.Contains(name))
226 			{
227 				// Create chart type object
228 				_createdChartTypes[name] =
229 					((Type)registeredChartTypes[name]).Assembly.
230 					CreateInstance(((Type)registeredChartTypes[name]).ToString());
231 			}
232 
233 			return (IChartType)_createdChartTypes[name];
234 		}
235 
236 		/// <summary>
237 		/// Chart images resource manager.
238 		/// </summary>
239 		public ResourceManager	ResourceManager
240 		{
241 			get
242 			{
243 				// Create chart images resource manager
244 				if(_resourceManager == null)
245 				{
246                     _resourceManager = new ResourceManager(typeof(Chart).Namespace + ".Design", Assembly.GetExecutingAssembly());
247 				}
248 				return _resourceManager;
249 			}
250 		}
251 
252 		#endregion
253 
254         #region IDisposable Members
255 
256         /// <summary>
257         /// Releases unmanaged and - optionally - managed resources
258         /// </summary>
259         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
Dispose(bool disposing)260         protected virtual void Dispose(bool disposing)
261         {
262             if (disposing)
263             {
264                 // Dispose managed resource
265                 foreach (string name in this._createdChartTypes.Keys)
266                 {
267                     IChartType chartType = (IChartType)_createdChartTypes[name];
268                     chartType.Dispose();
269                 }
270                 this._createdChartTypes.Clear();
271             }
272         }
273 
274         /// <summary>
275         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
276         /// </summary>
Dispose()277         public void Dispose()
278         {
279             Dispose(true);
280             GC.SuppressFinalize(this);
281         }
282 
283         #endregion
284     }
285 
286 	/// <summary>
287 	/// IChartType interface must be implemented for any standard or custom
288     /// chart type displayed in the chart control. This interface defines
289     /// properties which provide information on chart type behaviour including
290     /// how many Y values supported, is it a stacked chart type, how it
291     /// interacts with axes and much more.
292     ///
293     /// IChartType interface methods define how to draw series data point,
294     /// calculate Y values and process SmartLabelStyle.
295 	/// </summary>
296     internal interface IChartType : IDisposable
297 	{
298 		#region Properties
299 
300 		/// <summary>
301 		/// Chart type name
302 		/// </summary>
303 		string Name			{ get; }
304 
305 		/// <summary>
306 		/// Gets chart type image
307 		/// </summary>
308 		/// <param name="registry">Chart types registry object.</param>
309 		/// <returns>Chart type image.</returns>
GetImage(ChartTypeRegistry registry)310         System.Drawing.Image GetImage(ChartTypeRegistry registry);
311 
312 		/// <summary>
313 		/// True if chart type is stacked
314 		/// </summary>
315 		bool Stacked		{ get; }
316 
317 
318 		/// <summary>
319 		/// True if stacked chart type supports groups
320 		/// </summary>
321 		bool SupportStackedGroups	{ get; }
322 
323 
324 		/// <summary>
325 		/// True if stacked chart type should draw separately positive and
326 		/// negative data points ( Bar and column Stacked types ).
327 		/// </summary>
328 		bool StackSign		{ get; }
329 
330 		/// <summary>
331 		/// True if chart type supports axeses
332 		/// </summary>
333 		bool RequireAxes	{ get; }
334 
335 		/// <summary>
336 		/// True if chart type requires circular chart area.
337 		/// </summary>
338 		bool CircularChartArea	{ get; }
339 
340 		/// <summary>
341 		/// True if chart type supports logarithmic axes
342 		/// </summary>
343 		bool SupportLogarithmicAxes	{ get; }
344 
345 		/// <summary>
346 		/// True if chart type requires to switch the value (Y) axes position
347 		/// </summary>
348 		bool SwitchValueAxes	{ get; }
349 
350 		/// <summary>
351 		/// True if chart series can be placed side-by-side.
352 		/// </summary>
353 		bool SideBySideSeries	{ get; }
354 
355 		/// <summary>
356 		/// True if each data point of a chart must be represented in the legend
357 		/// </summary>
358 		bool DataPointsInLegend	{ get; }
359 
360 		/// <summary>
361 		/// True if palette colors should be applied for each data paoint.
362 		/// Otherwise the color is applied to the series.
363 		/// </summary>
364 		bool ApplyPaletteColorsToPoints	{ get; }
365 
366 		/// <summary>
367 		/// Indicates that extra Y values are connected to the scale of the Y axis
368 		/// </summary>
369 		bool ExtraYValuesConnectedToYAxis{ get; }
370 
371 		/// <summary>
372 		/// If the crossing value is auto Crossing value should be
373 		/// automatically set to zero for some chart
374 		/// types (Bar, column, area etc.)
375 		/// </summary>
376 		bool ZeroCrossing { get; }
377 
378 		/// <summary>
379 		/// Number of supported Y value(s) per point
380 		/// </summary>
381 		int YValuesPerPoint{ get; }
382 
383 		/// <summary>
384 		/// Chart type with two y values used for scale ( bubble chart type )
385 		/// </summary>
386 		bool SecondYScale{ get; }
387 
388 		/// <summary>
389 		/// Indicates that it's a hundredred percent chart.
390 		/// Axis scale from 0 to 100 percent should be used.
391 		/// </summary>
392 		bool HundredPercent{ get; }
393 
394 		/// <summary>
395 		/// Indicates that negative 100% stacked values are shown on
396 		/// the other side of the X axis
397 		/// </summary>
398 		bool HundredPercentSupportNegative{ get; }
399 
400 		/// <summary>
401 		/// How to draw series/points in legend:
402 		/// Filled rectangle, Line or Marker
403 		/// </summary>
404 		/// <param name="series">Legend item series.</param>
405 		/// <returns>Legend item style.</returns>
GetLegendImageStyle(Series series)406 		LegendImageStyle GetLegendImageStyle(Series series);
407 
408 		#endregion
409 
410 		#region Painting and Selection methods
411 
412 		/// <summary>
413 		/// Draw chart on specified chart graphics.
414 		/// </summary>
415 		/// <param name="graph">Chart grahhics object.</param>
416 		/// <param name="common">Common elements.</param>
417 		/// <param name="area">Chart area to draw on.</param>
418 		/// <param name="seriesToDraw">Chart series to draw.</param>
Paint(ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw)419         void Paint(ChartGraphics graph, CommonElements common, ChartArea area, Series seriesToDraw);
420 
421 		#endregion
422 
423 		#region Y values methods
424 
425 		/// <summary>
426 		/// Helper function, which returns the Y value of the data point.
427 		/// </summary>
428 		/// <param name="common">Chart common elements.</param>
429 		/// <param name="area">Chart area the series belongs to.</param>
430 		/// <param name="series">Sereis of the point.</param>
431 		/// <param name="point">Point object.</param>
432 		/// <param name="pointIndex">Index of the point.</param>
433 		/// <param name="yValueIndex">Index of the Y value to get.</param>
434 		/// <returns>Y value of the point.</returns>
435         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "5#y")]
GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex)436 		double GetYValue(CommonElements common, ChartArea area, Series series, DataPoint point, int pointIndex, int yValueIndex);
437 
438 		#endregion
439 
440 		#region SmartLabelStyle methods
441 
442 		/// <summary>
443 		/// Adds markers position to the list. Used to check SmartLabelStyle overlapping.
444 		/// </summary>
445 		/// <param name="common">Common chart elements.</param>
446 		/// <param name="area">Chart area.</param>
447 		/// <param name="series">Series values to be used.</param>
448 		/// <param name="list">List to add to.</param>
AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list)449 		void AddSmartLabelMarkerPositions(CommonElements common, ChartArea area, Series series, ArrayList list);
450 
451 		#endregion
452 	}
453 }
454