**Chart** Simple and flexible charting component for data visualization, which supports eight chart types: bar, line, area, pie, bubble, radar, polar, and scatter. **Bar Chart**: Randomize Data Add Dataset Remove Dataset Add Data Remove Data private const int INITAL_COUNT = 5; private BitChart _chart = default!; private BitChartBarConfig _config = default!; protected override void OnInitialized() { _config = new BitChartBarConfig { Options = new BitChartBarOptions { Responsive = true, Title = new BitChartOptionsTitle { Display = true, Text = "BitChart bar Chart" }, Scales = new BitChartBarScales { XAxes = [ new BitChartBarCategoryAxis { GridLines = new BitChartGridLines { Color = "gray" } } ], YAxes = [ new BitChartLinearCartesianAxis { GridLines = new BitChartGridLines { Color = "gray" } } ] } } }; System.Drawing.Color color = BitChartDemoColors.All[new Random().Next(0, BitChartDemoColors.All.Count - 1)]; var dataset = new BitChartBarDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { Label = "Dataset 1", BackgroundColor = BitChartColorUtil.FromDrawingColor(System.Drawing.Color.FromArgb(128, color)), }; _config.Data.Labels.AddRange(BitChartDemoUtils.Months.Take(INITAL_COUNT)); _config.Data.Datasets.Add(dataset); } private void RandomizeBarData() { foreach (IDataset dataset in _config.Data.Datasets) { int count = dataset.Count; dataset.Clear(); for (int i = 0; i < count; i++) { if (BitChartDemoUtils._rng.NextDouble() < 0.2) { dataset.Add(0); } else { dataset.Add(BitChartDemoUtils.RandomScalingFactor()); } } } _chart.Update(); } private void AddBarDataset() { System.Drawing.Color color = BitChartDemoColors.All[_config.Data.Datasets.Count % BitChartDemoColors.All.Count]; IDataset dataset = new BitChartBarDataset(BitChartDemoUtils.RandomScalingFactor(_config.Data.Labels.Count)) { Label = $"Dataset {_config.Data.Datasets.Count + 1}", BackgroundColor = BitChartColorUtil.FromDrawingColor(System.Drawing.Color.FromArgb(128, color)), BorderColor = BitChartColorUtil.FromDrawingColor(color), BorderWidth = 1 }; _config.Data.Datasets.Add(dataset); _chart.Update(); } private void RemoveBarDataset() { IList datasets = _config.Data.Datasets; if (datasets.Count == 0) return; datasets.RemoveAt(datasets.Count - 1); _chart.Update(); } private void AddBarData() { if (_config.Data.Datasets.Count == 0) return; string month = BitChartDemoUtils.Months[_config.Data.Labels.Count % BitChartDemoUtils.Months.Count]; _config.Data.Labels.Add(month); foreach (IDataset dataset in _config.Data.Datasets) { dataset.Add(BitChartDemoUtils.RandomScalingFactor()); } _chart.Update(); } private void RemoveBarData() { if (_config.Data.Datasets.Count == 0 || _config.Data.Labels.Count == 0) { return; } _config.Data.Labels.RemoveAt(_config.Data.Labels.Count - 1); foreach (IDataset dataset in _config.Data.Datasets) { dataset.RemoveAt(dataset.Count - 1); } _chart.Update(); } public static class BitChartDemoColors { private static readonly Lazy> _all = new(() => [ Red, Orange, Yellow, Green, Blue, Purple, Grey ]); public static IReadOnlyList All => _all.Value; public static readonly System.Drawing.Color Red = System.Drawing.Color.FromArgb(255, 99, 132); public static readonly System.Drawing.Color Orange = System.Drawing.Color.FromArgb(255, 159, 64); public static readonly System.Drawing.Color Yellow = System.Drawing.Color.FromArgb(255, 205, 86); public static readonly System.Drawing.Color Green = System.Drawing.Color.FromArgb(75, 192, 192); public static readonly System.Drawing.Color Blue = System.Drawing.Color.FromArgb(54, 162, 235); public static readonly System.Drawing.Color Purple = System.Drawing.Color.FromArgb(153, 102, 255); public static readonly System.Drawing.Color Grey = System.Drawing.Color.FromArgb(201, 203, 207); } public static class BitChartDemoUtils { public static readonly Random _rng = new(); public static IReadOnlyList Months { get; } = new ReadOnlyCollection( [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]); private static int RandomScalingFactorThreadUnsafe(int min, int max) => _rng.Next(min, max); public static int RandomScalingFactor() { lock (_rng) { return RandomScalingFactorThreadUnsafe(0, 100); } } public static IEnumerable RandomScalingFactor(int count, int min = 0, int max = 100) { int[] factors = new int[count]; lock (_rng) { for (int i = 0; i < count; i++) { factors[i] = RandomScalingFactorThreadUnsafe(min, max); } } return factors; } public static IEnumerable GetNextDays(int count) { DateTime now = DateTime.Now; DateTime[] factors = new DateTime[count]; for (int i = 0; i < factors.Length; i++) { factors[i] = now.AddDays(i); } return factors; } } public static class IListExtensions { public static void AddRange(this IList list, IEnumerable items) { if (list == null) throw new ArgumentNullException(nameof(list)); if (items == null) throw new ArgumentNullException(nameof(items)); if (list is List asList) { asList.AddRange(items); } else { foreach (T item in items) { list.Add(item); } } } } **Horizontal Bar Chart**: private const int INITAL_COUNT = 5; private BitChart _chart = default!; private BitChartBarConfig _config = default!; protected override void OnInitialized() { _config = new BitChartBarConfig(horizontal: true) { Options = new BitChartBarOptions { Responsive = true, Legend = new BitChartLegend { Position = BitChartPosition.Right }, Title = new BitChartOptionsTitle { Display = true, Text = "BitChart Horizontal Bar Chart" }, Scales = new BitChartBarScales { XAxes = [ new BitChartLinearCartesianAxis { GridLines = new BitChartGridLines { Color = "gray" } } ], YAxes = [ new BitChartBarCategoryAxis { GridLines = new BitChartGridLines { Color = "gray" } } ] } } }; IDataset dataset1 = new BitChartBarDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT, -100), horizontal: true) { Label = "My first dataset", BackgroundColor = BitChartColorUtil.FromDrawingColor(System.Drawing.Color.FromArgb(128, BitChartDemoColors.Red)), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Red), BorderWidth = 1 }; IDataset dataset2 = new BitChartBarDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT, -100), horizontal: true) { Label = "My second dataset", BackgroundColor = BitChartColorUtil.FromDrawingColor(System.Drawing.Color.FromArgb(128, BitChartDemoColors.Blue)), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Blue), BorderWidth = 1 }; _config.Data.Labels.AddRange(BitChartDemoUtils.Months.Take(INITAL_COUNT)); _config.Data.Datasets.Add(dataset1); _config.Data.Datasets.Add(dataset2); } public static class BitChartDemoColors { private static readonly Lazy> _all = new(() => [ Red, Orange, Yellow, Green, Blue, Purple, Grey ]); public static IReadOnlyList All => _all.Value; public static readonly System.Drawing.Color Red = System.Drawing.Color.FromArgb(255, 99, 132); public static readonly System.Drawing.Color Orange = System.Drawing.Color.FromArgb(255, 159, 64); public static readonly System.Drawing.Color Yellow = System.Drawing.Color.FromArgb(255, 205, 86); public static readonly System.Drawing.Color Green = System.Drawing.Color.FromArgb(75, 192, 192); public static readonly System.Drawing.Color Blue = System.Drawing.Color.FromArgb(54, 162, 235); public static readonly System.Drawing.Color Purple = System.Drawing.Color.FromArgb(153, 102, 255); public static readonly System.Drawing.Color Grey = System.Drawing.Color.FromArgb(201, 203, 207); } public static class BitChartDemoUtils { public static readonly Random _rng = new(); public static IReadOnlyList Months { get; } = new ReadOnlyCollection( [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]); private static int RandomScalingFactorThreadUnsafe(int min, int max) => _rng.Next(min, max); public static int RandomScalingFactor() { lock (_rng) { return RandomScalingFactorThreadUnsafe(0, 100); } } public static IEnumerable RandomScalingFactor(int count, int min = 0, int max = 100) { int[] factors = new int[count]; lock (_rng) { for (int i = 0; i < count; i++) { factors[i] = RandomScalingFactorThreadUnsafe(min, max); } } return factors; } public static IEnumerable GetNextDays(int count) { DateTime now = DateTime.Now; DateTime[] factors = new DateTime[count]; for (int i = 0; i < factors.Length; i++) { factors[i] = now.AddDays(i); } return factors; } } public static class IListExtensions { public static void AddRange(this IList list, IEnumerable items) { if (list == null) throw new ArgumentNullException(nameof(list)); if (items == null) throw new ArgumentNullException(nameof(items)); if (list is List asList) { asList.AddRange(items); } else { foreach (T item in items) { list.Add(item); } } } } **Stacked Bar Chart**: private const int INITAL_COUNT = 5; private BitChart _chart = default!; private BitChartBarConfig _config = default!; protected override void OnInitialized() { _config = new BitChartBarConfig { Options = new BitChartBarOptions() { Responsive = true, Title = new BitChartOptionsTitle { Display = true, Text = "BitChart stacked bar Chart" }, Tooltips = new BitChartTooltips { Mode = BitChartInteractionMode.Index, Intersect = false }, Scales = new BitChartBarScales { XAxes = [ new BitChartBarCategoryAxis { Stacked = true, GridLines = new BitChartGridLines { Color = "gray" } } ], YAxes = [ new BitChartBarLinearCartesianAxis { Stacked = true, GridLines = new BitChartGridLines { Color = "gray" } } ] } } }; IDataset dataset1 = new BitChartBarDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { Label = "Dataset 1", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Red) }; IDataset dataset2 = new BitChartBarDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { Label = "Dataset 2", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Blue) }; IDataset dataset3 = new BitChartBarDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { Label = "Dataset 3", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Green) }; _config.Data.Datasets.Add(dataset1); _config.Data.Datasets.Add(dataset2); _config.Data.Datasets.Add(dataset3); _config.Data.Labels.AddRange(BitChartDemoUtils.Months.Take(INITAL_COUNT)); } public static class BitChartDemoColors { private static readonly Lazy> _all = new(() => [ Red, Orange, Yellow, Green, Blue, Purple, Grey ]); public static IReadOnlyList All => _all.Value; public static readonly System.Drawing.Color Red = System.Drawing.Color.FromArgb(255, 99, 132); public static readonly System.Drawing.Color Orange = System.Drawing.Color.FromArgb(255, 159, 64); public static readonly System.Drawing.Color Yellow = System.Drawing.Color.FromArgb(255, 205, 86); public static readonly System.Drawing.Color Green = System.Drawing.Color.FromArgb(75, 192, 192); public static readonly System.Drawing.Color Blue = System.Drawing.Color.FromArgb(54, 162, 235); public static readonly System.Drawing.Color Purple = System.Drawing.Color.FromArgb(153, 102, 255); public static readonly System.Drawing.Color Grey = System.Drawing.Color.FromArgb(201, 203, 207); } public static class BitChartDemoUtils { public static readonly Random _rng = new(); public static IReadOnlyList Months { get; } = new ReadOnlyCollection( [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]); private static int RandomScalingFactorThreadUnsafe(int min, int max) => _rng.Next(min, max); public static int RandomScalingFactor() { lock (_rng) { return RandomScalingFactorThreadUnsafe(0, 100); } } public static IEnumerable RandomScalingFactor(int count, int min = 0, int max = 100) { int[] factors = new int[count]; lock (_rng) { for (int i = 0; i < count; i++) { factors[i] = RandomScalingFactorThreadUnsafe(min, max); } } return factors; } public static IEnumerable GetNextDays(int count) { DateTime now = DateTime.Now; DateTime[] factors = new DateTime[count]; for (int i = 0; i < factors.Length; i++) { factors[i] = now.AddDays(i); } return factors; } } public static class IListExtensions { public static void AddRange(this IList list, IEnumerable items) { if (list == null) throw new ArgumentNullException(nameof(list)); if (items == null) throw new ArgumentNullException(nameof(items)); if (list is List asList) { asList.AddRange(items); } else { foreach (T item in items) { list.Add(item); } } } } **Linear Line Chart**: private const int INITAL_COUNT = 5; private BitChart _chart = default!; private BitChartLineConfig _config = default!; protected override void OnInitialized() { _config = new BitChartLineConfig { Options = new BitChartLineOptions { Responsive = true, Title = new BitChartOptionsTitle { Display = true, Text = "BitChart Line Chart" }, Tooltips = new BitChartTooltips { Mode = BitChartInteractionMode.Nearest, Intersect = true }, Hover = new BitChartHover { Mode = BitChartInteractionMode.Nearest, Intersect = true }, Scales = new BitChartScales { XAxes = [ new BitChartCategoryAxis { ScaleLabel = new BitChartScaleLabel { LabelString = "Month" }, GridLines = new BitChartGridLines { Color = "gray" } } ], YAxes = [ new BitChartLinearCartesianAxis { ScaleLabel = new BitChartScaleLabel { LabelString = "Value" }, GridLines = new BitChartGridLines { Color = "gray" } } ] } } }; IDataset dataset1 = new BitChartLineDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { Label = "My first dataset", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Red), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Red), Fill = BitChartFillingMode.Disabled }; IDataset dataset2 = new BitChartLineDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { Label = "My second dataset", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Blue), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Blue), Fill = BitChartFillingMode.Disabled }; _config.Data.Labels.AddRange(BitChartDemoUtils.Months.Take(INITAL_COUNT)); _config.Data.Datasets.Add(dataset1); _config.Data.Datasets.Add(dataset2); } public static class BitChartDemoColors { private static readonly Lazy> _all = new(() => [ Red, Orange, Yellow, Green, Blue, Purple, Grey ]); public static IReadOnlyList All => _all.Value; public static readonly System.Drawing.Color Red = System.Drawing.Color.FromArgb(255, 99, 132); public static readonly System.Drawing.Color Orange = System.Drawing.Color.FromArgb(255, 159, 64); public static readonly System.Drawing.Color Yellow = System.Drawing.Color.FromArgb(255, 205, 86); public static readonly System.Drawing.Color Green = System.Drawing.Color.FromArgb(75, 192, 192); public static readonly System.Drawing.Color Blue = System.Drawing.Color.FromArgb(54, 162, 235); public static readonly System.Drawing.Color Purple = System.Drawing.Color.FromArgb(153, 102, 255); public static readonly System.Drawing.Color Grey = System.Drawing.Color.FromArgb(201, 203, 207); } public static class BitChartDemoUtils { public static readonly Random _rng = new(); public static IReadOnlyList Months { get; } = new ReadOnlyCollection( [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]); private static int RandomScalingFactorThreadUnsafe(int min, int max) => _rng.Next(min, max); public static int RandomScalingFactor() { lock (_rng) { return RandomScalingFactorThreadUnsafe(0, 100); } } public static IEnumerable RandomScalingFactor(int count, int min = 0, int max = 100) { int[] factors = new int[count]; lock (_rng) { for (int i = 0; i < count; i++) { factors[i] = RandomScalingFactorThreadUnsafe(min, max); } } return factors; } public static IEnumerable GetNextDays(int count) { DateTime now = DateTime.Now; DateTime[] factors = new DateTime[count]; for (int i = 0; i < factors.Length; i++) { factors[i] = now.AddDays(i); } return factors; } } public static class IListExtensions { public static void AddRange(this IList list, IEnumerable items) { if (list == null) throw new ArgumentNullException(nameof(list)); if (items == null) throw new ArgumentNullException(nameof(items)); if (list is List asList) { asList.AddRange(items); } else { foreach (T item in items) { list.Add(item); } } } } **Pie Chart**: Randomize Data Add Dataset Remove Dataset private const int INITAL_COUNT = 5; private BitChart _chart = default!; private BitChartPieConfig _config = default!; protected override void OnInitialized() { _config = new BitChartPieConfig { Options = new BitChartPieOptions { Responsive = true, Title = new BitChartOptionsTitle { Display = true, Text = "BitChart Pie Chart" } } }; var dataset = new BitChartPieDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { BackgroundColor = BitChartDemoColors.All.Take(INITAL_COUNT).Select(color => BitChartColorUtil.FromDrawingColor(color)).ToArray() }; _config.Data.Labels.AddRange(BitChartDemoUtils.Months.Take(INITAL_COUNT)); _config.Data.Datasets.Add(dataset); } private void RandomizePieData() { foreach (IDataset dataset in _config.Data.Datasets) { int count = dataset.Count; dataset.Clear(); for (int i = 0; i < count; i++) { if (BitChartDemoUtils._rng.NextDouble() < 0.2) { dataset.Add(0); } else { dataset.Add(BitChartDemoUtils.RandomScalingFactor()); } } } _chart.Update(); } private void AddPieDataset() { int count = _config.Data.Labels.Count; var dataset = new BitChartPieDataset(BitChartDemoUtils.RandomScalingFactor(count, -100, 100)) { BackgroundColor = BitChartDemoColors.All.Take(count).Select(color => BitChartColorUtil.FromDrawingColor(color)).ToArray() }; _config.Data.Datasets.Add(dataset); _chart.Update(); } private void RemovePieDataset() { IList datasets = _config.Data.Datasets; if (datasets.Count == 0) return; datasets.RemoveAt(0); _chart.Update(); } public static class BitChartDemoColors { private static readonly Lazy> _all = new(() => [ Red, Orange, Yellow, Green, Blue, Purple, Grey ]); public static IReadOnlyList All => _all.Value; public static readonly System.Drawing.Color Red = System.Drawing.Color.FromArgb(255, 99, 132); public static readonly System.Drawing.Color Orange = System.Drawing.Color.FromArgb(255, 159, 64); public static readonly System.Drawing.Color Yellow = System.Drawing.Color.FromArgb(255, 205, 86); public static readonly System.Drawing.Color Green = System.Drawing.Color.FromArgb(75, 192, 192); public static readonly System.Drawing.Color Blue = System.Drawing.Color.FromArgb(54, 162, 235); public static readonly System.Drawing.Color Purple = System.Drawing.Color.FromArgb(153, 102, 255); public static readonly System.Drawing.Color Grey = System.Drawing.Color.FromArgb(201, 203, 207); } public static class BitChartDemoUtils { public static readonly Random _rng = new(); public static IReadOnlyList Months { get; } = new ReadOnlyCollection( [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]); private static int RandomScalingFactorThreadUnsafe(int min, int max) => _rng.Next(min, max); public static int RandomScalingFactor() { lock (_rng) { return RandomScalingFactorThreadUnsafe(0, 100); } } public static IEnumerable RandomScalingFactor(int count, int min = 0, int max = 100) { int[] factors = new int[count]; lock (_rng) { for (int i = 0; i < count; i++) { factors[i] = RandomScalingFactorThreadUnsafe(min, max); } } return factors; } public static IEnumerable GetNextDays(int count) { DateTime now = DateTime.Now; DateTime[] factors = new DateTime[count]; for (int i = 0; i < factors.Length; i++) { factors[i] = now.AddDays(i); } return factors; } } public static class IListExtensions { public static void AddRange(this IList list, IEnumerable items) { if (list == null) throw new ArgumentNullException(nameof(list)); if (items == null) throw new ArgumentNullException(nameof(items)); if (list is List asList) { asList.AddRange(items); } else { foreach (T item in items) { list.Add(item); } } } } **Doughnut Chart**: private const int INITAL_COUNT = 5; private BitChart _chart = default!; private BitChartPieConfig _config = default!; protected override void OnInitialized() { _config = new BitChartPieConfig(useDoughnutType: true) { Options = new BitChartPieOptions { Responsive = true, Title = new BitChartOptionsTitle { Display = true, Text = "BitChart Doughnut Chart" } } }; BitChartPieDataset dataset = new BitChartPieDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { BackgroundColor = BitChartDemoColors.All.Take(INITAL_COUNT).Select(c => BitChartColorUtil.FromDrawingColor(System.Drawing.Color.FromArgb(220, c))).ToArray() }; _config.Data.Labels.AddRange(BitChartDemoUtils.Months.Take(INITAL_COUNT)); _config.Data.Datasets.Add(dataset); } public static class BitChartDemoColors { private static readonly Lazy> _all = new(() => [ Red, Orange, Yellow, Green, Blue, Purple, Grey ]); public static IReadOnlyList All => _all.Value; public static readonly System.Drawing.Color Red = System.Drawing.Color.FromArgb(255, 99, 132); public static readonly System.Drawing.Color Orange = System.Drawing.Color.FromArgb(255, 159, 64); public static readonly System.Drawing.Color Yellow = System.Drawing.Color.FromArgb(255, 205, 86); public static readonly System.Drawing.Color Green = System.Drawing.Color.FromArgb(75, 192, 192); public static readonly System.Drawing.Color Blue = System.Drawing.Color.FromArgb(54, 162, 235); public static readonly System.Drawing.Color Purple = System.Drawing.Color.FromArgb(153, 102, 255); public static readonly System.Drawing.Color Grey = System.Drawing.Color.FromArgb(201, 203, 207); } public static class BitChartDemoUtils { public static readonly Random _rng = new(); public static IReadOnlyList Months { get; } = new ReadOnlyCollection( [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]); private static int RandomScalingFactorThreadUnsafe(int min, int max) => _rng.Next(min, max); public static int RandomScalingFactor() { lock (_rng) { return RandomScalingFactorThreadUnsafe(0, 100); } } public static IEnumerable RandomScalingFactor(int count, int min = 0, int max = 100) { int[] factors = new int[count]; lock (_rng) { for (int i = 0; i < count; i++) { factors[i] = RandomScalingFactorThreadUnsafe(min, max); } } return factors; } public static IEnumerable GetNextDays(int count) { DateTime now = DateTime.Now; DateTime[] factors = new DateTime[count]; for (int i = 0; i < factors.Length; i++) { factors[i] = now.AddDays(i); } return factors; } } public static class IListExtensions { public static void AddRange(this IList list, IEnumerable items) { if (list == null) throw new ArgumentNullException(nameof(list)); if (items == null) throw new ArgumentNullException(nameof(items)); if (list is List asList) { asList.AddRange(items); } else { foreach (T item in items) { list.Add(item); } } } } **PolarArea Chart**: Randomize Data Add Dataset Remove Dataset private const int INITAL_COUNT = 5; private BitChart _chart = default!; private BitChartPolarAreaConfig _config = default!; protected override void OnInitialized() { _config = new BitChartPolarAreaConfig { Options = new BitChartPolarAreaOptions { Responsive = true, Title = new BitChartOptionsTitle { Display = true, Text = "BitChart PolarArea Chart" }, Scale = new BitChartLinearRadialAxis { GridLines = new BitChartGridLines { Color = "gray" } } } }; var dataset = new BitChartPolarAreaDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { BackgroundColor = BitChartDemoColors.All.Take(INITAL_COUNT).Select(color => BitChartColorUtil.FromDrawingColor(color)).ToArray() }; _config.Data.Labels.AddRange(BitChartDemoUtils.Months.Take(INITAL_COUNT)); _config.Data.Datasets.Add(dataset); } private void RandomizePolarAreaData() { foreach (IDataset dataset in _config.Data.Datasets) { int count = dataset.Count; dataset.Clear(); for (int i = 0; i < count; i++) { if (BitChartDemoUtils._rng.NextDouble() < 0.2) { dataset.Add(0); } else { dataset.Add(BitChartDemoUtils.RandomScalingFactor()); } } } _chart.Update(); } private void AddPolarAreaDataset() { int count = _config.Data.Labels.Count; BitChartPolarAreaDataset dataset = new BitChartPolarAreaDataset(BitChartDemoUtils.RandomScalingFactor(count, -100, 100)) { BackgroundColor = BitChartDemoColors.All.Take(count).Select(color => BitChartColorUtil.FromDrawingColor(color)).ToArray() }; _config.Data.Datasets.Add(dataset); _chart.Update(); } private void RemovePolarAreaDataset() { IList datasets = _config.Data.Datasets; if (datasets.Count == 0) return; datasets.RemoveAt(datasets.Count - 1); _chart.Update(); } public static class BitChartDemoColors { private static readonly Lazy> _all = new(() => [ Red, Orange, Yellow, Green, Blue, Purple, Grey ]); public static IReadOnlyList All => _all.Value; public static readonly System.Drawing.Color Red = System.Drawing.Color.FromArgb(255, 99, 132); public static readonly System.Drawing.Color Orange = System.Drawing.Color.FromArgb(255, 159, 64); public static readonly System.Drawing.Color Yellow = System.Drawing.Color.FromArgb(255, 205, 86); public static readonly System.Drawing.Color Green = System.Drawing.Color.FromArgb(75, 192, 192); public static readonly System.Drawing.Color Blue = System.Drawing.Color.FromArgb(54, 162, 235); public static readonly System.Drawing.Color Purple = System.Drawing.Color.FromArgb(153, 102, 255); public static readonly System.Drawing.Color Grey = System.Drawing.Color.FromArgb(201, 203, 207); } public static class BitChartDemoUtils { public static readonly Random _rng = new(); public static IReadOnlyList Months { get; } = new ReadOnlyCollection( [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]); private static int RandomScalingFactorThreadUnsafe(int min, int max) => _rng.Next(min, max); public static int RandomScalingFactor() { lock (_rng) { return RandomScalingFactorThreadUnsafe(0, 100); } } public static IEnumerable RandomScalingFactor(int count, int min = 0, int max = 100) { int[] factors = new int[count]; lock (_rng) { for (int i = 0; i < count; i++) { factors[i] = RandomScalingFactorThreadUnsafe(min, max); } } return factors; } public static IEnumerable GetNextDays(int count) { DateTime now = DateTime.Now; DateTime[] factors = new DateTime[count]; for (int i = 0; i < factors.Length; i++) { factors[i] = now.AddDays(i); } return factors; } } public static class IListExtensions { public static void AddRange(this IList list, IEnumerable items) { if (list == null) throw new ArgumentNullException(nameof(list)); if (items == null) throw new ArgumentNullException(nameof(items)); if (list is List asList) { asList.AddRange(items); } else { foreach (T item in items) { list.Add(item); } } } } **Time Cartesian Axis**: Randomize Data Add Dataset Remove Dataset Add Data Remove Data private const int INITAL_COUNT = 5; private BitChart _chart = default!; private BitChartLineConfig _config = default!; protected override void OnInitialized() { _config = new BitChartLineConfig { Options = new BitChartLineOptions { Responsive = true, Title = new BitChartOptionsTitle { Display = true, Text = "BitChart Time Scale Chart" }, Tooltips = new BitChartTooltips { Mode = BitChartInteractionMode.Nearest, Intersect = true }, Hover = new BitChartHover { Mode = BitChartInteractionMode.Nearest, Intersect = true }, Scales = new BitChartScales { XAxes = [ new BitChartTimeAxis { ScaleLabel = new BitChartScaleLabel { LabelString = "Date" }, Time = new BitChartTimeOptions { TooltipFormat = "dd MMM HH:mm" }, GridLines = new BitChartGridLines { Color = "gray" } } ], YAxes = [ new BitChartLinearCartesianAxis { ScaleLabel = new BitChartScaleLabel { LabelString = "Value" }, GridLines = new BitChartGridLines { Color = "gray" } } ] } } }; _config.Data.Labels.AddRange(BitChartDemoUtils.GetNextDays(INITAL_COUNT).Select(d => d.ToString("o"))); IDataset dataset1 = new BitChartLineDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { Label = "My first dataset", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Red), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Red), Fill = BitChartFillingMode.Disabled }; IDataset dataset2 = new BitChartLineDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { Label = "My second dataset", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Blue), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Blue), Fill = BitChartFillingMode.Disabled }; IDataset dataset3 = new BitChartLineDataset() { Label = "Dataset with point data", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Green), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Green), Fill = BitChartFillingMode.Disabled }; DateTime now = DateTime.Now; dataset3.Add(new BitChartTimePoint(now, BitChartDemoUtils.RandomScalingFactor())); dataset3.Add(new BitChartTimePoint(now.AddDays(2), BitChartDemoUtils.RandomScalingFactor())); dataset3.Add(new BitChartTimePoint(now.AddDays(3), BitChartDemoUtils.RandomScalingFactor())); dataset3.Add(new BitChartTimePoint(now.AddDays(4), BitChartDemoUtils.RandomScalingFactor())); _config.Data.Datasets.Add(dataset1); _config.Data.Datasets.Add(dataset2); _config.Data.Datasets.Add(dataset3); } private void RandomizeData() { foreach (IBitChartDataset dataset in _config.Data.Datasets) { if (dataset is IDataset pointDataset) { for (int i = 0; i < pointDataset.Count; i++) { pointDataset[i] = new BitChartTimePoint(pointDataset[i].Time, BitChartDemoUtils.RandomScalingFactor()); } } else if (dataset is IDataset intDataset) { int count = intDataset.Count; intDataset.Clear(); foreach (var factor in BitChartDemoUtils.RandomScalingFactor(count)) { intDataset.Add(factor); } } } _chart.Update(); } private void AddDataset() { string color = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.All[_config.Data.Datasets.Count % BitChartDemoColors.All.Count]); IDataset dataset = new BitChartLineDataset(BitChartDemoUtils.RandomScalingFactor(_config.Data.Labels.Count)) { Label = $"Dataset {_config.Data.Datasets.Count}", BackgroundColor = color, BorderColor = color, Fill = BitChartFillingMode.Disabled }; _config.Data.Datasets.Add(dataset); _chart.Update(); } private void RemoveDataset() { IList datasets = _config.Data.Datasets; if (datasets.Count == 0) return; datasets.RemoveAt(datasets.Count - 1); _chart.Update(); } private void AddData() { if (_config.Data.Datasets.Count == 0) return; DateTime now = DateTime.Now; _config.Data.Labels.Add(now.AddDays(_config.Data.Labels.Count).ToString("o")); foreach (IBitChartDataset dataset in _config.Data.Datasets) { if (dataset is IDataset pointDataset) { pointDataset.Add(new BitChartTimePoint(now.AddDays(pointDataset.Count), BitChartDemoUtils.RandomScalingFactor())); } else if (dataset is IDataset intDataset) { intDataset.Add(BitChartDemoUtils.RandomScalingFactor()); } } _chart.Update(); } private void RemoveData() { if (_config.Data.Datasets.Count == 0) return; IList labels = _config.Data.Labels; if (labels.Count > 0) labels.RemoveAt(labels.Count - 1); foreach (IBitChartDataset dataset in _config.Data.Datasets) { if (dataset is IDataset pointDataset && pointDataset.Count > 0) { pointDataset.RemoveAt(pointDataset.Count - 1); } else if (dataset is IDataset intDataset && intDataset.Count > 0) { intDataset.RemoveAt(intDataset.Count - 1); } } _chart.Update(); } public static class BitChartDemoColors { private static readonly Lazy> _all = new(() => [ Red, Orange, Yellow, Green, Blue, Purple, Grey ]); public static IReadOnlyList All => _all.Value; public static readonly System.Drawing.Color Red = System.Drawing.Color.FromArgb(255, 99, 132); public static readonly System.Drawing.Color Orange = System.Drawing.Color.FromArgb(255, 159, 64); public static readonly System.Drawing.Color Yellow = System.Drawing.Color.FromArgb(255, 205, 86); public static readonly System.Drawing.Color Green = System.Drawing.Color.FromArgb(75, 192, 192); public static readonly System.Drawing.Color Blue = System.Drawing.Color.FromArgb(54, 162, 235); public static readonly System.Drawing.Color Purple = System.Drawing.Color.FromArgb(153, 102, 255); public static readonly System.Drawing.Color Grey = System.Drawing.Color.FromArgb(201, 203, 207); } public static class BitChartDemoUtils { public static readonly Random _rng = new(); public static IReadOnlyList Months { get; } = new ReadOnlyCollection( [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]); private static int RandomScalingFactorThreadUnsafe(int min, int max) => _rng.Next(min, max); public static int RandomScalingFactor() { lock (_rng) { return RandomScalingFactorThreadUnsafe(0, 100); } } public static IEnumerable RandomScalingFactor(int count, int min = 0, int max = 100) { int[] factors = new int[count]; lock (_rng) { for (int i = 0; i < count; i++) { factors[i] = RandomScalingFactorThreadUnsafe(min, max); } } return factors; } public static IEnumerable GetNextDays(int count) { DateTime now = DateTime.Now; DateTime[] factors = new DateTime[count]; for (int i = 0; i < factors.Length; i++) { factors[i] = now.AddDays(i); } return factors; } } public static class IListExtensions { public static void AddRange(this IList list, IEnumerable items) { if (list == null) throw new ArgumentNullException(nameof(list)); if (items == null) throw new ArgumentNullException(nameof(items)); if (list is List asList) { asList.AddRange(items); } else { foreach (T item in items) { list.Add(item); } } } } **Scatter**: Randomize Data Add Dataset Remove Dataset private const int INITAL_COUNT = 5; private BitChart _chart = default!; private BitChartScatterConfig _config = default!; protected override void OnInitialized() { _config = new BitChartScatterConfig() { Options = new BitChartLineOptions { Scales = new BitChartScales { XAxes = [ new BitChartLinearCartesianAxis { ScaleLabel = new BitChartScaleLabel { LabelString = "Value" }, GridLines = new BitChartGridLines { Color = "gray" } } ], YAxes = [ new BitChartLinearCartesianAxis { ScaleLabel = new BitChartScaleLabel { LabelString = "Value" }, GridLines = new BitChartGridLines { Color = "gray" } } ] } } }; _config.Data.Labels.AddRange(BitChartDemoUtils.GetNextDays(INITAL_COUNT).Select(d => d.ToString("o"))); var dataset1 = new BitChartScatterDataset(BitChartDemoUtils.CreateRandomPoints(10)) { Label = "My first dataset", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Red), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Red), }; var dataset2 = new BitChartScatterDataset(BitChartDemoUtils.CreateRandomPoints(10)) { Label = "My second dataset", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Blue), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Blue), }; var dataset3 = new BitChartScatterDataset(BitChartDemoUtils.CreateRandomPoints(10)) { Label = "Dataset with point data", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Green), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Green), }; _config.Data.Datasets.Add(dataset1); _config.Data.Datasets.Add(dataset2); _config.Data.Datasets.Add(dataset3); } private void RandomizeData() { foreach (IBitChartDataset dataset in _config.Data.Datasets) { if (dataset is BitChartScatterDataset scatterDataset) { int count = scatterDataset.Count; scatterDataset.Clear(); scatterDataset.AddRange(BitChartDemoUtils.CreateRandomPoints(count)); } } _chart.Update(); } private void AddDataset() { string color = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.All[_config.Data.Datasets.Count % BitChartDemoColors.All.Count]); var newDataset = new BitChartScatterDataset(BitChartDemoUtils.CreateRandomPoints(_config.Data.Labels.Count)) { Label = $"Dataset {_config.Data.Datasets.Count + 1}", BackgroundColor = color, BorderColor = color, }; _config.Data.Datasets.Add(newDataset); _chart.Update(); } private void RemoveDataset() { IList datasets = _config.Data.Datasets; if (datasets.Count == 0) return; datasets.RemoveAt(datasets.Count - 1); _chart.Update(); } public static class BitChartDemoColors { private static readonly Lazy> _all = new(() => [ Red, Orange, Yellow, Green, Blue, Purple, Grey ]); public static IReadOnlyList All => _all.Value; public static readonly System.Drawing.Color Red = System.Drawing.Color.FromArgb(255, 99, 132); public static readonly System.Drawing.Color Orange = System.Drawing.Color.FromArgb(255, 159, 64); public static readonly System.Drawing.Color Yellow = System.Drawing.Color.FromArgb(255, 205, 86); public static readonly System.Drawing.Color Green = System.Drawing.Color.FromArgb(75, 192, 192); public static readonly System.Drawing.Color Blue = System.Drawing.Color.FromArgb(54, 162, 235); public static readonly System.Drawing.Color Purple = System.Drawing.Color.FromArgb(153, 102, 255); public static readonly System.Drawing.Color Grey = System.Drawing.Color.FromArgb(201, 203, 207); } public static class BitChartDemoUtils { public static readonly Random _rng = new(); public static IReadOnlyList Months { get; } = new ReadOnlyCollection( [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]); private static int RandomScalingFactorThreadUnsafe(int min, int max) => _rng.Next(min, max); public static int RandomScalingFactor() { lock (_rng) { return RandomScalingFactorThreadUnsafe(0, 100); } } public static IEnumerable RandomScalingFactor(int count, int min = 0, int max = 100) { int[] factors = new int[count]; lock (_rng) { for (int i = 0; i < count; i++) { factors[i] = RandomScalingFactorThreadUnsafe(min, max); } } return factors; } public static IEnumerable GetNextDays(int count) { DateTime now = DateTime.Now; DateTime[] factors = new DateTime[count]; for (int i = 0; i < factors.Length; i++) { factors[i] = now.AddDays(i); } return factors; } public static List CreateRandomPoints(int count) { List points = new(); for (int i = 0; i < count; i++) { double x = RandomScalingFactor(); double y = RandomScalingFactor(); points.Add(new BitChartPoint(x, y)); } return points; } } public static class IListExtensions { public static void AddRange(this IList list, IEnumerable items) { if (list == null) throw new ArgumentNullException(nameof(list)); if (items == null) throw new ArgumentNullException(nameof(items)); if (list is List asList) { asList.AddRange(items); } else { foreach (T item in items) { list.Add(item); } } } } **Bubble**: Randomize Data Add Dataset Remove Dataset private const int INITAL_COUNT = 5; private BitChart _chart = default!; private BitChartBubbleConfig _config = default!; protected override void OnInitialized() { _config = new BitChartBubbleConfig { Options = new BitChartLineOptions { Responsive = true, Title = new BitChartOptionsTitle { Display = true, Text = "BitChart Bubble Chart" }, Tooltips = new BitChartTooltips { Mode = BitChartInteractionMode.Nearest, Intersect = true }, Hover = new BitChartHover { Mode = BitChartInteractionMode.Nearest, Intersect = true }, Scales = new BitChartScales { XAxes = [ new BitChartLinearCartesianAxis { ScaleLabel = new BitChartScaleLabel { LabelString = "Value" }, GridLines = new BitChartGridLines { Color = "gray" } } ], YAxes = [ new BitChartLinearCartesianAxis { ScaleLabel = new BitChartScaleLabel { LabelString = "Value" }, GridLines = new BitChartGridLines { Color = "gray" } } ] } } }; _config.Data.Labels.AddRange(BitChartDemoUtils.GetNextDays(INITAL_COUNT).Select(d => d.ToString("o"))); var dataset1 = new BitChartBubbleDataset(BitChartDemoUtils.CreateRandomBubblePoints(10)) { Label = "My first dataset", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Red), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Red), }; var dataset2 = new BitChartBubbleDataset(BitChartDemoUtils.CreateRandomBubblePoints(10)) { Label = "My second dataset", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Blue), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Blue), }; var dataset3 = new BitChartBubbleDataset(BitChartDemoUtils.CreateRandomBubblePoints(10)) { Label = "Dataset with point data", BackgroundColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Green), BorderColor = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.Green), }; _config.Data.Datasets.Add(dataset1); _config.Data.Datasets.Add(dataset2); _config.Data.Datasets.Add(dataset3); } private void RandomizeData() { foreach (IBitChartDataset dataset in _config.Data.Datasets) { if (dataset is BitChartBubbleDataset bubbleDataset) { int count = bubbleDataset.Count; bubbleDataset.Clear(); bubbleDataset.AddRange(BitChartDemoUtils.CreateRandomBubblePoints(count)); } } _chart.Update(); } private void AddDataset() { string color = BitChartColorUtil.FromDrawingColor(BitChartDemoColors.All[_config.Data.Datasets.Count % BitChartDemoColors.All.Count]); var newDataset = new BitChartBubbleDataset(BitChartDemoUtils.CreateRandomBubblePoints(_config.Data.Labels.Count)) { Label = $"Dataset {_config.Data.Datasets.Count + 1}", BackgroundColor = color, BorderColor = color, }; _config.Data.Datasets.Add(newDataset); _chart.Update(); } private void RemoveDataset() { IList datasets = _config.Data.Datasets; if (datasets.Count == 0) return; datasets.RemoveAt(datasets.Count - 1); _chart.Update(); } public static class BitChartDemoColors { private static readonly Lazy> _all = new(() => [ Red, Orange, Yellow, Green, Blue, Purple, Grey ]); public static IReadOnlyList All => _all.Value; public static readonly System.Drawing.Color Red = System.Drawing.Color.FromArgb(255, 99, 132); public static readonly System.Drawing.Color Orange = System.Drawing.Color.FromArgb(255, 159, 64); public static readonly System.Drawing.Color Yellow = System.Drawing.Color.FromArgb(255, 205, 86); public static readonly System.Drawing.Color Green = System.Drawing.Color.FromArgb(75, 192, 192); public static readonly System.Drawing.Color Blue = System.Drawing.Color.FromArgb(54, 162, 235); public static readonly System.Drawing.Color Purple = System.Drawing.Color.FromArgb(153, 102, 255); public static readonly System.Drawing.Color Grey = System.Drawing.Color.FromArgb(201, 203, 207); } public static class BitChartDemoUtils { public static readonly Random _rng = new(); public static IReadOnlyList Months { get; } = new ReadOnlyCollection( [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]); private static int RandomScalingFactorThreadUnsafe(int min, int max) => _rng.Next(min, max); public static int RandomScalingFactor() { lock (_rng) { return RandomScalingFactorThreadUnsafe(0, 100); } } public static IEnumerable RandomScalingFactor(int count, int min = 0, int max = 100) { int[] factors = new int[count]; lock (_rng) { for (int i = 0; i < count; i++) { factors[i] = RandomScalingFactorThreadUnsafe(min, max); } } return factors; } public static IEnumerable GetNextDays(int count) { DateTime now = DateTime.Now; DateTime[] factors = new DateTime[count]; for (int i = 0; i < factors.Length; i++) { factors[i] = now.AddDays(i); } return factors; } public static List CreateRandomBubblePoints(int count) { List points = new(); for (int i = 0; i < count; i++) { double x = RandomScalingFactor(); double y = RandomScalingFactor(); double radius = RandomScalingFactor() % 20 + 5; points.Add(new BitChartBubblePoint(x, y, radius)); } return points; } } public static class IListExtensions { public static void AddRange(this IList list, IEnumerable items) { if (list == null) throw new ArgumentNullException(nameof(list)); if (items == null) throw new ArgumentNullException(nameof(items)); if (list is List asList) { asList.AddRange(items); } else { foreach (T item in items) { list.Add(item); } } } } **Radar Chart**: Randomize Data Add Dataset Remove Dataset Add Data Remove Data private const int INITAL_COUNT = 8; private BitChart _chart = default!; private BitChartRadarConfig _config = default!; protected override void OnInitialized() { _config = new BitChartRadarConfig { Options = new BitChartRadarOptions() { Responsive = true, Title = new BitChartOptionsTitle { Display = true, Text = "BitChart Radar Chart" }, Scale = new BitChartLinearRadialAxis { GridLines = new BitChartGridLines { Color = "gray" } } } }; IDataset dataset1 = new BitChartRadarDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { Label = "Dataset 1", BackgroundColor = BitChartColorUtil.FromDrawingColor(System.Drawing.Color.FromArgb(128, BitChartDemoColors.Red)) }; IDataset dataset2 = new BitChartRadarDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { Label = "Dataset 2", BackgroundColor = BitChartColorUtil.FromDrawingColor(System.Drawing.Color.FromArgb(128, BitChartDemoColors.Blue)) }; IDataset dataset3 = new BitChartRadarDataset(BitChartDemoUtils.RandomScalingFactor(INITAL_COUNT)) { Label = "Dataset 3", BackgroundColor = BitChartColorUtil.FromDrawingColor(System.Drawing.Color.FromArgb(128, BitChartDemoColors.Orange)) }; _config.Data.Datasets.Add(dataset1); _config.Data.Datasets.Add(dataset2); _config.Data.Datasets.Add(dataset3); } private void RandomizeRadarData() { foreach (IDataset dataset in _config.Data.Datasets) { int count = dataset.Count; dataset.Clear(); for (int i = 0; i < count; i++) { if (BitChartDemoUtils._rng.NextDouble() < 0.2) { dataset.Add(0); } else { dataset.Add(BitChartDemoUtils.RandomScalingFactor()); } } } _chart.Update(); } private void AddRadarDataset() { System.Drawing.Color color = BitChartDemoColors.All[_config.Data.Datasets.Count % BitChartDemoColors.All.Count]; IDataset dataset = new BitChartRadarDataset(BitChartDemoUtils.RandomScalingFactor(_config.Data.Labels.Count)) { Label = $"Dataset {_config.Data.Datasets.Count + 1}", BackgroundColor = BitChartColorUtil.FromDrawingColor(System.Drawing.Color.FromArgb(128, color)), BorderColor = BitChartColorUtil.FromDrawingColor(color), BorderWidth = 1 }; _config.Data.Datasets.Add(dataset); _chart.Update(); } private void RemoveRadarDataset() { IList datasets = _config.Data.Datasets; if (datasets.Count == 0) return; datasets.RemoveAt(datasets.Count - 1); _chart.Update(); } private void AddRadarData() { if (_config.Data.Datasets.Count == 0) return; string month = BitChartDemoUtils.Months[_config.Data.Labels.Count % BitChartDemoUtils.Months.Count]; _config.Data.Labels.Add(month); foreach (IDataset dataset in _config.Data.Datasets) { dataset.Add(BitChartDemoUtils.RandomScalingFactor()); } _chart.Update(); } private void RemoveRadarData() { if (_config.Data.Datasets.Count == 0 || _config.Data.Labels.Count == 0) { return; } _config.Data.Labels.RemoveAt(_config.Data.Labels.Count - 1); foreach (IDataset dataset in _config.Data.Datasets) { dataset.RemoveAt(dataset.Count - 1); } _chart.Update(); } public static class BitChartDemoColors { private static readonly Lazy> _all = new(() => [ Red, Orange, Yellow, Green, Blue, Purple, Grey ]); public static IReadOnlyList All => _all.Value; public static readonly System.Drawing.Color Red = System.Drawing.Color.FromArgb(255, 99, 132); public static readonly System.Drawing.Color Orange = System.Drawing.Color.FromArgb(255, 159, 64); public static readonly System.Drawing.Color Yellow = System.Drawing.Color.FromArgb(255, 205, 86); public static readonly System.Drawing.Color Green = System.Drawing.Color.FromArgb(75, 192, 192); public static readonly System.Drawing.Color Blue = System.Drawing.Color.FromArgb(54, 162, 235); public static readonly System.Drawing.Color Purple = System.Drawing.Color.FromArgb(153, 102, 255); public static readonly System.Drawing.Color Grey = System.Drawing.Color.FromArgb(201, 203, 207); } public static class BitChartDemoUtils { public static readonly Random _rng = new(); public static IReadOnlyList Months { get; } = new ReadOnlyCollection( [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]); private static int RandomScalingFactorThreadUnsafe(int min, int max) => _rng.Next(min, max); public static int RandomScalingFactor() { lock (_rng) { return RandomScalingFactorThreadUnsafe(0, 100); } } public static IEnumerable RandomScalingFactor(int count, int min = 0, int max = 100) { int[] factors = new int[count]; lock (_rng) { for (int i = 0; i < count; i++) { factors[i] = RandomScalingFactorThreadUnsafe(min, max); } } return factors; } public static IEnumerable GetNextDays(int count) { DateTime now = DateTime.Now; DateTime[] factors = new DateTime[count]; for (int i = 0; i < factors.Length; i++) { factors[i] = now.AddDays(i); } return factors; } } public static class IListExtensions { public static void AddRange(this IList list, IEnumerable items) { if (list == null) throw new ArgumentNullException(nameof(list)); if (items == null) throw new ArgumentNullException(nameof(items)); if (list is List asList) { asList.AddRange(items); } else { foreach (T item in items) { list.Add(item); } } } }