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