/Release/Silverlight3/SampleSource/Controls.Samples/Charting/SampleGenerators.cs

# · C# · 293 lines · 179 code · 23 blank · 91 comment · 5 complexity · cc4bf7a1b12c3d12c83276051d0c9315 MD5 · raw file

  1. // (c) Copyright Microsoft Corporation.
  2. // This source is subject to the Microsoft Public License (Ms-PL).
  3. // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
  4. // All other rights reserved.
  5. using System;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.Diagnostics.CodeAnalysis;
  10. using System.Linq;
  11. using System.Windows;
  12. using System.Windows.Controls;
  13. using System.Windows.Data;
  14. using System.Windows.Threading;
  15. using System.Windows.Controls.DataVisualization.Charting;
  16. namespace System.Windows.Controls.Samples
  17. {
  18. /// <summary>
  19. /// Contains methods that generate sample Charts for any Series type.
  20. /// </summary>
  21. public static class SampleGenerators
  22. {
  23. /// <summary>
  24. /// Stores a shared ObservableCollection for use by the dynamic collection scenario.
  25. /// </summary>
  26. private static ObservableCollection<int> _dynamicCollectionItemsSource = new ObservableCollection<int>();
  27. /// <summary>
  28. /// Stores a shared List for use by the dynamic data items scenario.
  29. /// </summary>
  30. private static List<Pet> _dynamicDataItemsSource = new List<Pet>
  31. {
  32. new Pet { Species = "Dogs" },
  33. new Pet { Species = "Cats" },
  34. new Pet { Species = "Birds" },
  35. new Pet { Species = "Fish" },
  36. };
  37. /// <summary>
  38. /// Stores a shared List for use by the dynamic date items scenario.
  39. /// </summary>
  40. private static List<Pair> _dynamicDateItemsSource = new List<Pair>
  41. {
  42. new Pair { First = new DateTime(2008, 10, 11), Second = 0.0 },
  43. new Pair { First = new DateTime(2008, 10, 12), Second = 0.0 },
  44. new Pair { First = new DateTime(2008, 10, 13), Second = 0.0 },
  45. new Pair { First = new DateTime(2008, 10, 14), Second = 0.0 },
  46. new Pair { First = new DateTime(2008, 10, 15), Second = 0.0 },
  47. new Pair { First = new DateTime(2008, 10, 16), Second = 0.0 },
  48. };
  49. /// <summary>
  50. /// Stores a shared random number generator.
  51. /// </summary>
  52. private static Random _random = new Random();
  53. /// <summary>
  54. /// Initializes static members of the SampleGenerators class.
  55. /// </summary>
  56. [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", Justification = "Need to do additional initialization.")]
  57. static SampleGenerators()
  58. {
  59. // Create a timer to update the dynamic data regularly
  60. DispatcherTimer dispatcherTimer = new DispatcherTimer();
  61. dispatcherTimer.Interval = TimeSpan.FromSeconds(2);
  62. dispatcherTimer.Tick += delegate
  63. {
  64. // Update _dynamicCollectionItemsSource
  65. _dynamicCollectionItemsSource.Add(_random.Next(1, 11));
  66. if (10 < _dynamicCollectionItemsSource.Count)
  67. {
  68. _dynamicCollectionItemsSource.RemoveAt(0);
  69. }
  70. // Update _dynamicDataItemsSource
  71. foreach (Pet pet in _dynamicDataItemsSource)
  72. {
  73. pet.Count = _random.Next(1, 20);
  74. }
  75. // Update _dynamicDateItemsSource
  76. foreach (Pair pair in _dynamicDateItemsSource)
  77. {
  78. pair.Second = _random.NextDouble() * 20;
  79. }
  80. };
  81. dispatcherTimer.Start();
  82. }
  83. /// <summary>
  84. /// Generates numeric Series samples.
  85. /// </summary>
  86. /// <param name="panel">Panel to add the generated Charts to.</param>
  87. /// <param name="seriesConstructor">Function that returns a Series instance for each sample.</param>
  88. /// <param name="includeIndependentValueBinding">True if an IndependentValueBinding should be created.</param>
  89. public static void GenerateNumericSeriesSamples(Panel panel, Func<Series> seriesConstructor, bool includeIndependentValueBinding)
  90. {
  91. Binding independentValueBinding = includeIndependentValueBinding ? new Binding() : null;
  92. Scenario[] scenarios = new Scenario[]
  93. {
  94. new Scenario { Title = "One Int", ItemsSource = new int[] { 3 }, IndependentValueBinding = independentValueBinding },
  95. new Scenario { Title = "Three Ints", ItemsSource = new int[] { 4, 2, 7 }, IndependentValueBinding = independentValueBinding },
  96. new Scenario { Title = "Seven Doubles", ItemsSource = new double[] { 4.4, 6.2, 9.7, 7.0, 2.1, 8.3, 5.5 }, IndependentValueBinding = independentValueBinding },
  97. new Scenario { Title = "No Points", ItemsSource = new int[0], IndependentValueBinding = independentValueBinding },
  98. new Scenario { Title = "Some Points with Value 0", ItemsSource = new int[] { 0, 1, 0, 2, 0 }, IndependentValueBinding = independentValueBinding },
  99. new Scenario { Title = "Some Negative-Value Points", ItemsSource = new double[] { 2.1, 3.7, -2.5, -4.6, 1.0 }, IndependentValueBinding = independentValueBinding },
  100. new Scenario { Title = "High-Value Points", ItemsSource = new int[] { 2000000000, 1200000000, 2100000000, 1000000000, 2000000000 }, IndependentValueBinding = independentValueBinding },
  101. // new Scenario { Title = "100 Points", ItemsSource = Enumerable.Range(1, 100), IndependentValueBinding = independentValueBinding },
  102. new Scenario { Title = "Dynamic Collection", ItemsSource = _dynamicCollectionItemsSource, IndependentValueBinding = independentValueBinding },
  103. };
  104. GenerateSeriesSamples(panel, seriesConstructor, scenarios, null);
  105. }
  106. /// <summary>
  107. /// Generates value Series samples.
  108. /// </summary>
  109. /// <param name="panel">Panel to add the generated Charts to.</param>
  110. /// <param name="seriesConstructor">Function that returns a Series instance for each sample.</param>
  111. public static void GenerateValueSeriesSamples(Panel panel, Func<Series> seriesConstructor)
  112. {
  113. Scenario[] scenarios = new Scenario[]
  114. {
  115. new Scenario { Title = "Pet Counts (No Names)", ItemsSource = pets, DependentValueBinding = new Binding("Count") },
  116. new Scenario { Title = "Dynamic Data Items (No Names)", ItemsSource = _dynamicDataItemsSource, DependentValueBinding = new Binding("Count") },
  117. };
  118. GenerateSeriesSamples(panel, seriesConstructor, scenarios, null);
  119. }
  120. /// <summary>
  121. /// Generates category/value Series samples.
  122. /// </summary>
  123. /// <param name="panel">Panel to add the generated Charts to.</param>
  124. /// <param name="seriesConstructor">Function that returns a Series instance for each sample.</param>
  125. public static void GenerateCategoryValueSeriesSamples(Panel panel, Func<Series> seriesConstructor)
  126. {
  127. Scenario[] scenarios = new Scenario[]
  128. {
  129. new Scenario { Title = "Pet Counts (Names)", ItemsSource = pets, DependentValueBinding = new Binding("Count"), IndependentValueBinding = new Binding("Species") },
  130. new Scenario { Title = "Dynamic Data Items (Names)", ItemsSource = _dynamicDataItemsSource, DependentValueBinding = new Binding("Count"), IndependentValueBinding = new Binding("Species") },
  131. };
  132. GenerateSeriesSamples(panel, seriesConstructor, scenarios, null);
  133. }
  134. /// <summary>
  135. /// Generates value/value Series samples.
  136. /// </summary>
  137. /// <param name="panel">Panel to add the generated Charts to.</param>
  138. /// <param name="seriesConstructor">Function that returns a Series instance for each sample.</param>
  139. public static void GenerateValueValueSeriesSamples(Panel panel, Func<Series> seriesConstructor)
  140. {
  141. List<Point> circle = new List<Point>();
  142. for (double i = 0; i < 2 * Math.PI; i += 0.1)
  143. {
  144. circle.Add(new Point(Math.Sin(i), Math.Cos(i)));
  145. }
  146. Scenario[] scenarios = new Scenario[]
  147. {
  148. new Scenario { Title = "Circle", ItemsSource = circle, DependentValueBinding = new Binding("X"), IndependentValueBinding = new Binding("Y") },
  149. };
  150. GenerateSeriesSamples(panel, seriesConstructor, scenarios, null);
  151. }
  152. /// <summary>
  153. /// Generates value/value Series samples.
  154. /// </summary>
  155. /// <param name="panel">Panel to add the generated Charts to.</param>
  156. /// <param name="seriesConstructor">Function that returns a Series instance for each sample.</param>
  157. public static void GenerateDateTimeValueSeriesSamples(Panel panel, Func<Series> seriesConstructor)
  158. {
  159. Scenario[] scenarios = new Scenario[]
  160. {
  161. new Scenario { Title = "Value by Date", ItemsSource = _dynamicDateItemsSource, DependentValueBinding = new Binding("Second"), IndependentValueBinding = new Binding("First") },
  162. };
  163. Action<Chart> chartModifier = (chart) =>
  164. {
  165. IAxis dateAxis = new DateTimeAxis { Orientation = AxisOrientation.X };
  166. chart.Axes.Add(dateAxis);
  167. IAxis valueAxis = new LinearAxis { Orientation = AxisOrientation.Y, Minimum = 0, Maximum = 20, ShowGridLines = true };
  168. chart.Axes.Add(valueAxis);
  169. };
  170. GenerateSeriesSamples(panel, seriesConstructor, scenarios, chartModifier);
  171. }
  172. /// <summary>
  173. /// Generates multiple value Series samples.
  174. /// </summary>
  175. /// <param name="panel">Panel to add the generated Charts to.</param>
  176. /// <param name="seriesConstructor">Function that returns a Series instance for each sample.</param>
  177. /// <param name="includeIndependentValueBinding">True if an IndependentValueBinding should be created.</param>
  178. public static void GenerateMultipleValueSeriesSamples(Panel panel, Func<Series> seriesConstructor, bool includeIndependentValueBinding)
  179. {
  180. Binding independentValueBinding = includeIndependentValueBinding ? new Binding() : null;
  181. double[] items = new double[] { 3.1, 1.6, 4.9, 0.8, 2.2 };
  182. List<IEnumerable> itemsRepeated = new List<IEnumerable>();
  183. for (int i = 0; i < 30; i++)
  184. {
  185. itemsRepeated.Add(items);
  186. }
  187. Scenario[] scenarios = new Scenario[]
  188. {
  189. new Scenario { Title = "Three Series", ItemsSources = new IEnumerable[] { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 }, new int[] { 7, 8, 9 } }, IndependentValueBinding = independentValueBinding },
  190. // new Scenario { Title = "Thirty Series", ItemsSources = itemsRepeated, IndependentValueBinding = independentValueBinding },
  191. };
  192. GenerateSeriesSamples(panel, seriesConstructor, scenarios, null);
  193. }
  194. /// <summary>
  195. /// Generates various Series samples.
  196. /// </summary>
  197. /// <param name="panel">Panel to add the generated Charts to.</param>
  198. /// <param name="seriesConstructor">Function that returns a Series instance for each sample.</param>
  199. /// <param name="scenarios">Collection of scenarios to generate.</param>
  200. /// <param name="chartModifier">Function that applies any necessary modifications to the Chart.</param>
  201. private static void GenerateSeriesSamples(Panel panel, Func<Series> seriesConstructor, IEnumerable<Scenario> scenarios, Action<Chart> chartModifier)
  202. {
  203. Style wrapperStyle = Application.Current.Resources["WrapperStyle"] as Style;
  204. // For each scenario...
  205. foreach (Scenario scenario in scenarios)
  206. {
  207. // Create the sample Chart
  208. Chart chart = new Chart { Title = scenario.Title, MaxWidth = 500, MaxHeight = 270 };
  209. foreach (IEnumerable itemsSource in scenario.ItemsSources)
  210. {
  211. DataPointSeries series = seriesConstructor() as DataPointSeries;
  212. series.ItemsSource = itemsSource;
  213. series.DependentValueBinding = scenario.DependentValueBinding;
  214. series.IndependentValueBinding = scenario.IndependentValueBinding;
  215. chart.Series.Add(series);
  216. }
  217. if (null != chartModifier)
  218. {
  219. chartModifier(chart);
  220. }
  221. // Wrap the Chart in a suitably formatted Grid
  222. Grid grid = new Grid { Style = wrapperStyle };
  223. grid.Children.Add(chart);
  224. panel.Children.Add(grid);
  225. }
  226. }
  227. /// <summary>
  228. /// Collection of Pet objects for use by Chart samples.
  229. /// </summary>
  230. private static Pet[] pets = new Pet[]
  231. {
  232. new Pet { Species = "Dogs", Count = 5 },
  233. new Pet { Species = "Cats", Count = 4 },
  234. new Pet { Species = "Birds", Count = 6 },
  235. new Pet { Species = "Fish", Count = 9 }
  236. };
  237. /// <summary>
  238. /// Class representing an automatically generated Chart sample.
  239. /// </summary>
  240. private class Scenario
  241. {
  242. /// <summary>
  243. /// Gets or sets the title of the scenario.
  244. /// </summary>
  245. public string Title { get; set; }
  246. /// <summary>
  247. /// Sets the ItemsSource for the Chart's Series.
  248. /// </summary>
  249. public IEnumerable ItemsSource
  250. {
  251. set
  252. {
  253. ItemsSources = new IEnumerable[] { value };
  254. }
  255. }
  256. /// <summary>
  257. /// Gets or sets the ItemsSources for the Chart's Series.
  258. /// </summary>
  259. public IEnumerable<IEnumerable> ItemsSources { get; set; }
  260. /// <summary>
  261. /// Gets or sets the DependentValueBinding for the Chart's Series.
  262. /// </summary>
  263. public Binding DependentValueBinding { get; set; }
  264. /// <summary>
  265. /// Gets or sets the IndependentValueBinding for the Chart's Series.
  266. /// </summary>
  267. public Binding IndependentValueBinding { get; set; }
  268. }
  269. }
  270. }