KeywordsRegistry.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. //
  5. // Purpose: A registry that keeps track of all available
  6. // keywords and name of the objects and properties
  7. // where they can be used.
  8. // -----------------------------
  9. // Formatting Keywords Overview:
  10. // -----------------------------
  11. // A Formatting Keyword is a specially formatted character sequence
  12. // that gets replaced by an associated Chart Series value, or
  13. // calculated value. Keywords can be used with most string properties
  14. // of Series and DataPoint objects.
  15. // :
  16. // Here is an example of setting series labels so that the first
  17. // line will display the Y value and the second line displays
  18. // the X value.
  19. // :
  20. // Chart1.Series["Series1"].Label = "Y = #VALY\nX = #VALX";
  21. // :
  22. // Series label in this case will look like this:
  23. // :
  24. // Y = 45.78
  25. // X = 456
  26. // :
  27. // An optional format string can be added after the keyword.
  28. // For example, when you set the Format option to Percent for
  29. // the first Y value, the resulting keyword produced is "#VALY{P}".
  30. // You can also apply format strings in code-behind using the same
  31. // nomenclature; you do this by following the keyword with a format
  32. // specifier enclosed in braces. For information concerning the
  33. // types of formatting that can be used, see the Formatting Types
  34. // topic in the MSDN library.
  35. //
  36. using System;
  37. using System.Collections;
  38. using System.ComponentModel;
  39. namespace FastReport.DataVisualization.Charting.Utilities
  40. {
  41. /// <summary>
  42. /// KeywordName class contains constant strings defining
  43. /// names of all keywords used in the data point and series classes.
  44. /// </summary>
  45. internal static class KeywordName
  46. {
  47. #region Keyword Names
  48. internal const string Index = "#INDEX";
  49. internal const string ValX = "#VALX";
  50. internal const string ValY = "#VALY";
  51. internal const string Val = "#VAL";
  52. internal const string Total = "#TOTAL";
  53. internal const string Percent = "#PERCENT";
  54. internal const string Label = "#LABEL";
  55. internal const string AxisLabel = "#AXISLABEL";
  56. internal const string LegendText = "#LEGENDTEXT";
  57. internal const string SeriesName = "#SERIESNAME";
  58. internal const string Ser = "#SER";
  59. internal const string Avg = "#AVG";
  60. internal const string Max = "#MAX";
  61. internal const string Min = "#MIN";
  62. internal const string Last = "#LAST";
  63. internal const string First = "#FIRST";
  64. internal const string CustomProperty = "#CUSTOMPROPERTY";
  65. #endregion // Keyword Names
  66. }
  67. /// <summary>
  68. /// KeywordRegistry class stores information about all
  69. /// chart formatting keywords. It automatically registers
  70. /// all known keywords when object is constructed. This
  71. /// data is exposed as ArrayList through the ‘registeredKeywords’
  72. /// field. Each item in this ArrayList is a KeywordInfo
  73. /// object which describes a single formatting keyword.
  74. /// </summary>
  75. internal class KeywordsRegistry : IServiceProvider
  76. {
  77. #region Fields
  78. // List of registered keywords
  79. internal ArrayList registeredKeywords = new ArrayList();
  80. #endregion
  81. #region Constructor and Services
  82. /// <summary>
  83. /// Keywords registry public constructor.
  84. /// </summary>
  85. public KeywordsRegistry()
  86. {
  87. // Register Keywords used in the chart
  88. RegisterKeywords();
  89. }
  90. /// <summary>
  91. /// Returns Keywords registry service object.
  92. /// </summary>
  93. /// <param name="serviceType">Service type to get.</param>
  94. /// <returns>Custom properties registry service.</returns>
  95. [EditorBrowsableAttribute(EditorBrowsableState.Never)]
  96. object IServiceProvider.GetService(Type serviceType)
  97. {
  98. if(serviceType == typeof(KeywordsRegistry))
  99. {
  100. return this;
  101. }
  102. throw (new ArgumentException( SR.ExceptionKeywordsRegistryUnsupportedType(serviceType.ToString())));
  103. }
  104. #endregion
  105. #region Keywords Registering methods
  106. /// <summary>
  107. /// Registers all chart formatting keywords.
  108. /// </summary>
  109. private void RegisterKeywords()
  110. {
  111. string seriesPointSupportedProperties = "Text,Label,LabelMapAreaAttributes,ToolTip,Url,LabelToolTip,MapAreaAttributes,AxisLabel,LegendToolTip,LegendMapAreaAttributes,LegendUrl,LegendText";
  112. // #INDEX keyword
  113. this.Register(
  114. SR.DescriptionKeyWordNameIndexDataPoint,
  115. KeywordName.Index,
  116. string.Empty,
  117. SR.DescriptionKeyWordIndexDataPoint2,
  118. "DataPoint",
  119. seriesPointSupportedProperties,
  120. false,
  121. false);
  122. // #VALX keyword
  123. this.Register(
  124. SR.DescriptionKeyWordNameXValue,
  125. KeywordName.ValX,
  126. string.Empty,
  127. SR.DescriptionKeyWordXValue,
  128. "Series,DataPoint,Annotation,LegendCellColumn",
  129. seriesPointSupportedProperties,
  130. true,
  131. false);
  132. // #VALY keyword
  133. this.Register(
  134. SR.DescriptionKeyWordNameYValue,
  135. KeywordName.Val,
  136. string.Empty,
  137. SR.DescriptionKeyWordYValue,
  138. "Series,DataPoint,Annotation,LegendCellColumn,LegendCellColumn",
  139. seriesPointSupportedProperties,
  140. true,
  141. true);
  142. // #TOTAL keyword
  143. this.Register(
  144. SR.DescriptionKeyWordNameTotalYValues,
  145. KeywordName.Total,
  146. string.Empty,
  147. SR.DescriptionKeyWordTotalYValues,
  148. "Series,DataPoint,Annotation,LegendCellColumn",
  149. seriesPointSupportedProperties,
  150. true,
  151. false);
  152. // #PERCENT keyword
  153. this.Register(
  154. SR.DescriptionKeyWordNameYValuePercentTotal,
  155. KeywordName.Percent,
  156. string.Empty,
  157. SR.DescriptionKeyWordYValuePercentTotal,
  158. "Series,DataPoint,Annotation,LegendCellColumn",
  159. seriesPointSupportedProperties,
  160. true,
  161. true);
  162. // #INDEX keyword
  163. this.Register(
  164. SR.DescriptionKeyWordNameIndexTheDataPoint,
  165. KeywordName.Index,
  166. string.Empty,
  167. SR.DescriptionKeyWordIndexDataPoint,
  168. "Series,DataPoint,Annotation,LegendCellColumn",
  169. seriesPointSupportedProperties,
  170. false,
  171. false);
  172. // #LABEL keyword
  173. this.Register(
  174. SR.DescriptionKeyWordNameLabelDataPoint,
  175. KeywordName.Label,
  176. string.Empty,
  177. SR.DescriptionKeyWordLabelDataPoint,
  178. "Series,DataPoint,Annotation,LegendCellColumn",
  179. seriesPointSupportedProperties,
  180. false,
  181. false);
  182. // #AXISLABEL keyword
  183. this.Register(
  184. SR.DescriptionKeyWordNameAxisLabelDataPoint,
  185. KeywordName.AxisLabel,
  186. string.Empty,
  187. SR.DescriptionKeyWordAxisLabelDataPoint,
  188. "Series,DataPoint,Annotation,LegendCellColumn",
  189. seriesPointSupportedProperties,
  190. false,
  191. false);
  192. // #LEGENDTEXT keyword
  193. this.Register(
  194. SR.DescriptionKeyWordNameLegendText,
  195. KeywordName.LegendText,
  196. string.Empty,
  197. SR.DescriptionKeyWordLegendText,
  198. "Series,DataPoint,Annotation,LegendCellColumn",
  199. seriesPointSupportedProperties,
  200. false,
  201. false);
  202. // #SERIESNAME keyword
  203. this.Register(
  204. SR.DescriptionKeyWordNameSeriesName,
  205. KeywordName.SeriesName,
  206. KeywordName.Ser,
  207. SR.DescriptionKeyWordSeriesName,
  208. "Series,DataPoint,Annotation,LegendCellColumn",
  209. seriesPointSupportedProperties,
  210. false,
  211. false);
  212. // *************** NEW KEYWORDS in version 5.5 ***************
  213. // #AVG keyword
  214. this.Register(
  215. SR.DescriptionKeyWordNameAverageYValues,
  216. KeywordName.Avg,
  217. string.Empty,
  218. SR.DescriptionKeyWordAverageYValues,
  219. "Series,DataPoint,Annotation,LegendCellColumn",
  220. seriesPointSupportedProperties,
  221. true,
  222. true);
  223. // #MAX keyword
  224. this.Register(
  225. SR.DescriptionKeyWordNameMaximumYValues,
  226. KeywordName.Max,
  227. string.Empty,
  228. SR.DescriptionKeyWordMaximumYValues,
  229. "Series,DataPoint,Annotation,LegendCellColumn",
  230. seriesPointSupportedProperties,
  231. true,
  232. true);
  233. // #MIN keyword
  234. this.Register(
  235. SR.DescriptionKeyWordNameMinimumYValues,
  236. KeywordName.Min,
  237. string.Empty,
  238. SR.DescriptionKeyWordMinimumYValues,
  239. "Series,DataPoint,Annotation,LegendCellColumn",
  240. seriesPointSupportedProperties,
  241. true,
  242. true);
  243. // #LAST keyword
  244. this.Register(
  245. SR.DescriptionKeyWordNameLastPointYValue,
  246. KeywordName.Last,
  247. string.Empty,
  248. SR.DescriptionKeyWordLastPointYValue,
  249. "Series,DataPoint,Annotation,LegendCellColumn",
  250. seriesPointSupportedProperties,
  251. true,
  252. true);
  253. // #FIRST keyword
  254. this.Register(
  255. SR.DescriptionKeyWordNameFirstPointYValue,
  256. KeywordName.First,
  257. string.Empty,
  258. SR.DescriptionKeyWordFirstPointYValue,
  259. "Series,DataPoint,Annotation,LegendCellColumn",
  260. seriesPointSupportedProperties,
  261. true,
  262. true);
  263. }
  264. #endregion // Keywords Registering methods
  265. #region Registry methods
  266. /// <summary>
  267. /// Adds keyword information into the registry.
  268. /// </summary>
  269. /// <param name="name">Keyword full name.</param>
  270. /// <param name="keyword">Keyword text.</param>
  271. /// <param name="keywordAliases">Keyword alternative text.</param>
  272. /// <param name="description">Keyword description.</param>
  273. /// <param name="appliesToTypes">Comma separated list of applicable classes</param>
  274. /// <param name="appliesToProperties">Comma separated list of applicable properties.</param>
  275. /// <param name="supportsFormatting">True if formatting is supported.</param>
  276. /// <param name="supportsValueIndex">True if different point Y values are supported.</param>
  277. public void Register(
  278. string name,
  279. string keyword,
  280. string keywordAliases,
  281. string description,
  282. string appliesToTypes,
  283. string appliesToProperties,
  284. bool supportsFormatting,
  285. bool supportsValueIndex)
  286. {
  287. // Create new keyword information object
  288. KeywordInfo keywordInfo = new KeywordInfo(
  289. name,
  290. keyword,
  291. keywordAliases,
  292. description,
  293. appliesToTypes,
  294. appliesToProperties,
  295. supportsFormatting,
  296. supportsValueIndex);
  297. // Add keyword information to the hash table
  298. registeredKeywords.Add(keywordInfo);
  299. }
  300. #endregion
  301. }
  302. /// <summary>
  303. /// KeywordInfo class stores information about a single
  304. /// formatting keyword. This information includes Name,
  305. /// Description, list of data types and properties it
  306. /// applies to and other information.
  307. /// </summary>
  308. internal class KeywordInfo
  309. {
  310. #region Public Fields
  311. /// <summary>
  312. /// Keyword full name.
  313. /// </summary>
  314. public string Name = String.Empty;
  315. /// <summary>
  316. /// String that represent this keyword in the property (keyword).
  317. /// </summary>
  318. public string Keyword = String.Empty;
  319. /// <summary>
  320. /// Comma separated strings that may alternatively represent this
  321. /// keyword in the property.
  322. /// </summary>
  323. public string KeywordAliases = String.Empty;
  324. /// <summary>
  325. /// Keyword description.
  326. /// </summary>
  327. public string Description = String.Empty;
  328. /// <summary>
  329. /// Comma separated names of classes this keyword applies to.
  330. /// </summary>
  331. public string AppliesToTypes = String.Empty;
  332. /// <summary>
  333. /// Comma separated names of properties this keyword applies to.
  334. /// </summary>
  335. public string AppliesToProperties = String.Empty;
  336. /// <summary>
  337. /// True if keyword value can be formatted.
  338. /// </summary>
  339. public bool SupportsFormatting = false;
  340. /// <summary>
  341. /// True if keyword can be used with different point Y values.
  342. /// </summary>
  343. public bool SupportsValueIndex = false;
  344. #endregion // Public Fields
  345. #region Constructor
  346. /// <summary>
  347. /// Keyword information object constructor
  348. /// </summary>
  349. /// <param name="name">Keyword full name.</param>
  350. /// <param name="keyword">Keyword text.</param>
  351. /// <param name="keywordAliases">Keyword alternative text.</param>
  352. /// <param name="description">Keyword description.</param>
  353. /// <param name="appliesToTypes">Comma separated list of applicable classes</param>
  354. /// <param name="appliesToProperties">Comma separated list of applicable properties.</param>
  355. /// <param name="supportsFormatting">True if formatting is supported.</param>
  356. /// <param name="supportsValueIndex">True if different point Y values are supported.</param>
  357. public KeywordInfo(
  358. string name,
  359. string keyword,
  360. string keywordAliases,
  361. string description,
  362. string appliesToTypes,
  363. string appliesToProperties,
  364. bool supportsFormatting,
  365. bool supportsValueIndex)
  366. {
  367. this.Name = name;
  368. this.Keyword = keyword;
  369. this.KeywordAliases = keywordAliases;
  370. this.Description = description;
  371. this.AppliesToTypes = appliesToTypes;
  372. this.AppliesToProperties = appliesToProperties;
  373. this.SupportsFormatting = supportsFormatting;
  374. this.SupportsValueIndex = supportsValueIndex;
  375. }
  376. #endregion // Constructor
  377. #region Methods
  378. /// <summary>
  379. /// Returns a String that represents the current keyword Information.
  380. /// </summary>
  381. /// <returns>Returns keyword name.</returns>
  382. public override string ToString()
  383. {
  384. return this.Name;
  385. }
  386. /// <summary>
  387. /// Gets an array of keywords names including the aliases.
  388. /// </summary>
  389. /// <returns>A string array of keyword names that represent this keyword.</returns>
  390. public string[] GetKeywords()
  391. {
  392. // NOTE: Each keyword has a unique name. In addition the keyword may have an
  393. // alternative names (aliases).
  394. // Most common scenario for a keyword aliase is when keyword has a long and
  395. // short form. For example, KeywordName.Ser and "#SERIES".
  396. // Fill array of possible names for that keyword
  397. if(this.KeywordAliases.Length > 0)
  398. {
  399. string[] keywordAliases = this.KeywordAliases.Split(',');
  400. string[] keywordNames = new string[keywordAliases.Length + 1];
  401. keywordNames[0] = this.Keyword;
  402. keywordAliases.CopyTo(keywordNames, 1);
  403. return keywordNames;
  404. }
  405. else
  406. {
  407. return new string[] { this.Keyword };
  408. }
  409. }
  410. #endregion // Methods
  411. }
  412. }