diff --git a/BlazorExpress.ChartJS.Demo.RCL/BlazorExpress.ChartJS.Demo.RCL.csproj b/BlazorExpress.ChartJS.Demo.RCL/BlazorExpress.ChartJS.Demo.RCL.csproj index d3d9ab7d..788476be 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/BlazorExpress.ChartJS.Demo.RCL.csproj +++ b/BlazorExpress.ChartJS.Demo.RCL/BlazorExpress.ChartJS.Demo.RCL.csproj @@ -6,13 +6,23 @@ enable + + + + + + + + + - - + + + @@ -23,8 +33,9 @@ - - + + + diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/EmptyLayout.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/EmptyLayout.razor deleted file mode 100644 index 19a08dfd..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/EmptyLayout.razor +++ /dev/null @@ -1,119 +0,0 @@ -@namespace BlazroExpress.ChartJS.Demo.RCL -@inherits LayoutComponentBase - - - - If you like BlazorExpress.ChartJS, give it a star on GitHub! - - - - - -
- @Body -
- - - diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/EmptyLayout.razor.css b/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/EmptyLayout.razor.css deleted file mode 100644 index d890e56d..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/EmptyLayout.razor.css +++ /dev/null @@ -1,3 +0,0 @@ -main, .main { - height: auto !important; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayout.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayout.razor deleted file mode 100644 index dcb36482..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayout.razor +++ /dev/null @@ -1,42 +0,0 @@ -@using BlazorBootstrap -@namespace BlazorExpress.ChartJS.Demo.RCL -@inherits MainLayoutBase - -
- - - -
- - - - -
-
- - \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayout.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayout.razor.cs deleted file mode 100644 index 108bc737..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayout.razor.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -public partial class MainLayout : MainLayoutBase -{ - internal override IEnumerable GetNavItems() - { - navItems ??= new List - { - new (){ Id = "1", Text = "Overview", Href = "/charts/overview", IconName = IconName.HouseDoorFill }, - - new (){ Id = "2", Text = "Getting Started", IconName = IconName.Rulers }, - new (){ Id = "201", Text = "Blazor WebAssembly (.NET 8)", Href = "/charts/getting-started/blazor-webassembly-net-8", IconName = IconName.BrowserEdge, ParentId = "2" }, - new (){ Id = "202", Text = "Blazor WebApp Server (.NET 8)", Href = "/charts/getting-started/blazor-webapp-server-global-net-8", IconName = IconName.Pc, ParentId = "2", }, - new (){ Id = "202", Text = "Blazor WebApp Auto (.NET 8)", Href = "/charts/getting-started/blazor-webapp-auto-global-net-8", IconName = IconName.BrowserSafari, ParentId = "2" }, - - new (){ Id = "3", Text = "Bar Chart", IconName = IconName.BarChartLineFill }, - new (){ Id = "300", Text = "API Documentation", Href = "/charts/bar-chart/api-documentation", IconName = IconName.FileText, ParentId = "3", }, - new (){ Id = "301", Text = "Bar", Href = "/charts/bar-chart", IconName = IconName.BarChartLine, ParentId = "3", Match = NavLinkMatch.All }, - new (){ Id = "302", Text = "Horizontal", Href = "/charts/bar-chart/horizontal", IconName = IconName.BarChartSteps, ParentId = "3", }, - new (){ Id = "303", Text = "Stacked", Href = "/charts/bar-chart/stacked", IconName = IconName.ViewStacked, ParentId = "3", }, - new (){ Id = "304", Text = "Data labels", Href = "/charts/bar-chart/data-labels", IconName = IconName.Bookmarks, ParentId = "3", }, - new (){ Id = "305", Text = "Locale", Href = "/charts/bar-chart/locale", IconName = IconName.Translate, ParentId = "3", }, - - new (){ Id = "4", Text = "Doughnut Chart", IconName = IconName.CircleFill, }, - new (){ Id = "400", Text = "API Documentation", Href = "/charts/doughnut-chart/api-documentation", IconName = IconName.FileText, ParentId = "4", }, - new (){ Id = "401", Text = "Doughnut", Href = "/charts/doughnut-chart", IconName = IconName.Circle, ParentId = "4", Match = NavLinkMatch.All }, - new (){ Id = "402", Text = "Data labels", Href = "/charts/doughnut-chart/doughnut-labels", IconName = IconName.Bookmarks, ParentId = "4", Match = NavLinkMatch.All }, - - new (){ Id = "5", Text = "Line Chart", IconName = IconName.GraphUpArrow }, - new (){ Id = "500", Text = "API Documentation", Href = "/charts/line-chart/api-documentation", IconName = IconName.FileText, ParentId = "5", }, - new (){ Id = "501", Text = "Line", Href = "/charts/line-chart", IconName = IconName.GraphUp, ParentId = "5", Match = NavLinkMatch.All }, - new (){ Id = "502", Text = "Data labels", Href = "/charts/line-chart/data-labels", IconName = IconName.Bookmarks, ParentId = "5", Match = NavLinkMatch.All }, - new (){ Id = "503", Text = "Tick configuration", Href = "/charts/line-chart/tick-configuration", IconName = IconName.GearWideConnected, ParentId = "5", Match = NavLinkMatch.All }, - new (){ Id = "504", Text = "Locale", Href = "/charts/line-chart/locale", IconName = IconName.Translate, ParentId = "5", Match = NavLinkMatch.All }, - - new (){ Id = "6", Text = "Pie Chart", IconName = IconName.PieChartFill }, - new (){ Id = "600", Text = "API Documentation", Href = "/charts/pie-chart/api-documentation", IconName = IconName.FileText, ParentId = "6", }, - new (){ Id = "601", Text = "Pie", Href = "/charts/pie-chart", IconName = IconName.PieChart, ParentId = "6", Match = NavLinkMatch.All }, - new (){ Id = "602", Text = "Data labels", Href = "/charts/pie-chart/data-labels", IconName = IconName.Bookmarks, ParentId = "6", Match = NavLinkMatch.All }, - new (){ Id = "603", Text = "Legend position", Href = "/charts/pie-chart/legend", IconName = IconName.Signpost, ParentId = "6", Match = NavLinkMatch.All }, - }; - - return navItems; - } -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayout.razor.css b/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayout.razor.css deleted file mode 100644 index e69de29b..00000000 diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBase.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBase.cs deleted file mode 100644 index 5f3c6859..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBase.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -public class MainLayoutBase : LayoutComponentBase -{ - private string version = default!; - private string homeUrl = default!; - private string docsUrl = default!; - private string blogUrl = default!; - private string githubUrl = default!; - private string twitterUrl = default!; - private string linkedInUrl = default!; - private string openCollectiveUrl = default!; - private string githubIssuesUrl = default!; - private string githubDiscussionsUrl = default!; - private string stackoverflowUrl = default!; - - internal Sidebar sidebar = default!; - internal IEnumerable navItems = default!; - - [Inject] public IConfiguration _configuration { get; set; } = default!; - - protected override void OnInitialized() - { - version = $"v{_configuration["version"]}"; // example: v0.6.1 - homeUrl = $"{_configuration["urls:homeUrl"]}"; - docsUrl = $"{_configuration["urls:docs"]}"; - blogUrl = $"{_configuration["urls:blog"]}"; - githubUrl = $"{_configuration["urls:github"]}"; - twitterUrl = $"{_configuration["urls:twitter"]}"; - linkedInUrl = $"{_configuration["urls:linkedin"]}"; - openCollectiveUrl = $"{_configuration["urls:opencollective"]}"; - githubIssuesUrl = $"{_configuration["urls:github_issues"]}"; - githubDiscussionsUrl = $"{_configuration["urls:github_discussions"]}"; - stackoverflowUrl = $"{_configuration["urls:stackoverflow"]}"; - base.OnInitialized(); - } - - internal virtual async Task SidebarDataProvider(SidebarDataProviderRequest request) - { - if (navItems is null) - navItems = GetNavItems(); - - return await Task.FromResult(request.ApplyTo(navItems)); - } - - internal virtual IEnumerable GetNavItems() => new List(); - - public string Version => version; - public string HomeUrl => homeUrl; - public string DocsUrl => docsUrl; - public string BlogUrl => blogUrl; - public string GithubUrl => githubUrl; - public string TwitterUrl => twitterUrl; - public string LinkedInUrl => linkedInUrl; - public string OpenCollectiveUrl => openCollectiveUrl; - public string GithubIssuesUrl => githubIssuesUrl; - public string GithubDiscussionsUrl => githubDiscussionsUrl; - public string StackoverflowUrl => stackoverflowUrl; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBase.css b/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBase.css deleted file mode 100644 index 710ea05e..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBase.css +++ /dev/null @@ -1,73 +0,0 @@ -.page { - position: relative; - display: flex; - flex-direction: column; -} - -.main { - flex: 1; - overflow-x: hidden; - /*width: 100%;*/ -} - -.sidebar { - background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); -} - -.top-row { - background-color: #f7f7f7; - border-bottom: 1px solid #d6d5d5; - justify-content: flex-end; - height: 3.5rem; - display: flex; - align-items: center; -} - - .top-row ::deep a, .top-row .btn-link { - white-space: nowrap; - margin-left: 1.5rem; - } - - .top-row a:first-child { - overflow: hidden; - text-overflow: ellipsis; - } - -@media (max-width: 640.98px) { - .top-row:not(.auth) { - display: none; - } - - .top-row.auth { - justify-content: space-between; - } - - .top-row a, .top-row .btn-link { - margin-left: 0; - } -} - -@media (min-width: 641px) { - .page { - flex-direction: row; - } - - .sidebar { - width: 260px !important; - height: 100vh !important; - overflow-y: auto !important; - position: sticky !important; - top: 0 !important; - } - - .top-row { - position: sticky; - top: 0; - z-index: 1; - } - - .main > div { - padding-left: 2rem !important; - padding-right: 1.5rem !important; - } -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBaseFooter.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBaseFooter.razor deleted file mode 100644 index dc46502c..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBaseFooter.razor +++ /dev/null @@ -1,46 +0,0 @@ -@namespace BlazorExpress.ChartJS.Demo.RCL -@inherits ComponentBase - - diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBaseServices.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBaseServices.razor deleted file mode 100644 index 854acff2..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBaseServices.razor +++ /dev/null @@ -1,2 +0,0 @@ -@namespace BlazorExpress.ChartJS.Demo.RCL -@inherits ComponentBase diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_00_API_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_00_API_Documentation.razor deleted file mode 100644 index 35a326da..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_00_API_Documentation.razor +++ /dev/null @@ -1,85 +0,0 @@ -@attribute [Route(pageUrl)] - - - -Blazor Bar Chart - API Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - BarChartDataset implements IChartDataset. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BarChartOptions implements ChartOptions. - - - - - - - - - - - -@code { - private const string pageUrl = "/charts/bar-chart/api-documentation"; - private const string title = "Blazor Bar Chart - API Documentation"; - private const string heading = "Blazor Bar Chart - API Documentation"; - private const string description = "This documentation provides a comprehensive reference for the Blazor Bar Chart component, guiding you through its functionalities and configuration options."; - private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_01.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_01.razor deleted file mode 100644 index f6ad97b7..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_01.razor +++ /dev/null @@ -1,27 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - - -
- In the following example, a categorical 12-color palette is used. -
- - For data visualization, you can use the predefined palettes ColorUtility.CategoricalTwelveColors for a 12-color palette and ColorUtility.CategoricalSixColors for a 6-color palette. - These palettes offer a range of distinct and visually appealing colors that can be applied to represent different categories or data elements in your visualizations. - - - -@code { - private const string pageUrl = "/charts/bar-chart"; - private const string title = "Blazor Bar Chart"; - private const string heading = "Blazor Bar Chart"; - private const string description = "A Blazor bar chart component is used to represent data values as vertical bars. It is sometimes used to show trend data and to compare multiple data sets side by side."; - private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; // TODO: update -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_02.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_02.razor deleted file mode 100644 index c8bf6606..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_02.razor +++ /dev/null @@ -1,17 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - -@code { - private const string pageUrl = "/charts/bar-chart/horizontal"; - private const string title = "Blazor Bar Chart - Horizontal"; - private const string heading = "Blazor Bar Chart - Horizontal"; - private const string description = "A Blazor bar chart component is used to represent data values as vertical bars. It is sometimes used to show trend data and to compare multiple data sets side by side."; - private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_03.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_03.razor deleted file mode 100644 index 895e8d14..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_03.razor +++ /dev/null @@ -1,17 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - -@code { - private const string pageUrl = "/charts/bar-chart/stacked"; - private const string title = "Blazor Bar Chart - Stacked"; - private const string heading = "Blazor Bar Chart - Stacked"; - private const string description = "A Blazor bar chart component is used to represent data values as vertical bars. It is sometimes used to show trend data and to compare multiple data sets side by side."; - private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_04.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_04.razor deleted file mode 100644 index 3f76c21f..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_04.razor +++ /dev/null @@ -1,17 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - -@code { - private const string pageUrl = "/charts/bar-chart/data-labels"; - private const string title = "Blazor Bar Chart - Data labels"; - private const string heading = "Blazor Bar Chart - Data labels"; - private const string description = "A Blazor bar chart component is used to represent data values as vertical bars. It is sometimes used to show trend data and to compare multiple data sets side by side."; - private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_05.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_05.razor deleted file mode 100644 index fb66eff3..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChartDocumentation_05.razor +++ /dev/null @@ -1,17 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - -@code { - private const string pageUrl = "/charts/bar-chart/locale"; - private const string title = "Blazor Bar Chart - Locale"; - private const string heading = "Blazor Bar Chart - Locale"; - private const string description = "By default, the chart is using the default locale of the platform on which it is running. In the following example, you will see the chart in the German locale (de_DE)."; - private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChartDocumentation_00_API_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChartDocumentation_00_API_Documentation.razor deleted file mode 100644 index 37d01f66..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChartDocumentation_00_API_Documentation.razor +++ /dev/null @@ -1,76 +0,0 @@ -@attribute [Route(pageUrl)] - - - -Blazor Doughnut Chart - API Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - DoughnutChartDataset implements IChartDataset. - - - - - - - - - - - - - - - - - - - - - - - - - DoughnutChartOptions implements ChartOptions. - - - - - - - -@code { - private const string pageUrl = "/charts/doughnut-chart/api-documentation"; - private const string title = "Blazor Doughnut Chart - API Documentation"; - private const string heading = "Blazor Doughnut Chart - API Documentation"; - private const string description = "This documentation provides a comprehensive reference for the Blazor Doughnut Chart component, guiding you through its functionalities and configuration options."; - private const string imageUrl = "https://i.imgur.com/8b7jH0D.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChartDocumentation_01.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChartDocumentation_01.razor deleted file mode 100644 index 187f7dbc..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChartDocumentation_01.razor +++ /dev/null @@ -1,27 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - - -
- In the following example, a categorical 12-color palette is used. -
- - For data visualization, you can use the predefined palettes ColorUtility.CategoricalTwelveColors for a 12-color palette and ColorUtility.CategoricalSixColors for a 6-color palette. - These palettes offer a range of distinct and visually appealing colors that can be applied to represent different categories or data elements in your visualizations. - - - -@code { - private const string pageUrl = "/charts/doughnut-chart"; - private const string title = "Blazor Doughnut Chart"; - private const string heading = "Blazor Doughnut Chart"; - private const string description = "A Blazor donut chart component is a circular chart that shows the proportional values of different categories. It is similar to a pie chart, but the center of the donut chart is hollow. This makes it easier to see the individual values of each category."; - private const string imageUrl = "https://i.imgur.com/xEPhAsW.png"; -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChartDocumentation_02.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChartDocumentation_02.razor deleted file mode 100644 index fd69b6e4..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChartDocumentation_02.razor +++ /dev/null @@ -1,18 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - - -@code { - private const string pageUrl = "/charts/doughnut-chart/doughnut-labels"; - private const string title = "Blazor Doughnut Chart"; - private const string heading = "Blazor Doughnut Chart"; - private const string description = "A Blazor donut chart component is a circular chart that shows the proportional values of different categories. It is similar to a pie chart, but the center of the donut chart is hollow. This makes it easier to see the individual values of each category."; - private const string imageUrl = "https://i.imgur.com/xEPhAsW.png"; -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_01_WebAssembly/GettingStarted.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_01_WebAssembly/GettingStarted.razor deleted file mode 100644 index bd9bf2ef..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_01_WebAssembly/GettingStarted.razor +++ /dev/null @@ -1,59 +0,0 @@ -@attribute [Route(pageUrl)] -@attribute [Route(pageUrl2)] - - - - -
- Looking to quickly add BlazorExpress.ChartJS to your project? Use NuGet package manager. -
-
- Install-Package BlazorExpress.ChartJS -Version @version -
- - -
- Insert the following references into the body section of the wwwroot/index.html file, immediately after the _framework/blazor.webassembly.js reference: -
- - - -
- Register tag helpers in _Imports.razor. -
- - -@code { - private const string pageUrl = "/charts/getting-started"; - private const string pageUrl2 = "/charts/getting-started/blazor-webassembly-net-8"; - private const string title = "Getting started - Blazor WebAssembly (.NET 8)"; - private const string heading = "Getting started - Blazor WebAssembly (.NET 8)"; - private const string description = "Get started with the Enterprise-class Component library built on the Blazor and Chart.js JavaScript library."; - private const string imageUrl = "https://i.imgur.com/xEPhAsW.png"; - private string version = default!; - - [Inject] - private NavigationManager _navigationManager { get; set; } = default!; - - [Inject] - private IConfiguration _configuration { get; set; } = default!; - - protected override void OnInitialized() - { - try - { - version = _configuration["version"]!; - - if (_navigationManager.Uri.Replace(_navigationManager.BaseUri, "").Contains("charts/getting-started")) - _navigationManager.NavigateTo(pageUrl2); - } - catch - { - // do nothing - } - } -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_01_WebAssembly/Getting_Started_Snippet_02_Register.txt b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_01_WebAssembly/Getting_Started_Snippet_02_Register.txt deleted file mode 100644 index 6b2af1d4..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_01_WebAssembly/Getting_Started_Snippet_02_Register.txt +++ /dev/null @@ -1 +0,0 @@ -@using BlazorExpress.ChartJS \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_02_WebApp_Server_Global/GettingStarted.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_02_WebApp_Server_Global/GettingStarted.razor deleted file mode 100644 index ffb49ad6..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_02_WebApp_Server_Global/GettingStarted.razor +++ /dev/null @@ -1,51 +0,0 @@ -@attribute [Route(pageUrl)] - - - - -
- Looking to quickly add BlazorExpress.ChartJS to your project? Use NuGet package manager. -
-
- Install-Package BlazorExpress.ChartJS -Version @version -
- - -
- Insert the following references into the body section of the Components/App.razor file, immediately after the _framework/blazor.web.js reference: -
- - - -
- Register tag helpers in Components/_Imports.razor. -
- - -@code { - private const string pageUrl = "/charts/getting-started/blazor-webapp-server-global-net-8"; - private const string title = "Getting started - Blazor WebApp (.NET 8) - Interactive render mode Server - Global location"; - private const string heading = "Getting started - Blazor WebApp (.NET 8) - Interactive render mode Server - Global location"; - private const string description = "Get started with the Enterprise-class Component library built on the Blazor and Chart.js JavaScript library."; - private const string imageUrl = "https://i.imgur.com/C5ObC3A.png"; - private string version = default!; - - [Inject] - private IConfiguration _configuration { get; set; } = default!; - - protected override void OnInitialized() - { - try - { - version = _configuration["version"]!; - } - catch - { - // do nothing - } - } -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_02_WebApp_Server_Global/Getting_Started_Snippet_02_Register.txt b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_02_WebApp_Server_Global/Getting_Started_Snippet_02_Register.txt deleted file mode 100644 index 6b2af1d4..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_02_WebApp_Server_Global/Getting_Started_Snippet_02_Register.txt +++ /dev/null @@ -1 +0,0 @@ -@using BlazorExpress.ChartJS \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_03_WebApp_Auto/GettingStarted.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_03_WebApp_Auto/GettingStarted.razor deleted file mode 100644 index d15cfa78..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_03_WebApp_Auto/GettingStarted.razor +++ /dev/null @@ -1,55 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - - -
- Looking to quickly add BlazorExpress.ChartJS to your project? Use NuGet package manager. -
-
- Install-Package BlazorExpress.ChartJS -Version @version -
- - -
- Register tag helpers in _Imports.razor. -
- - - - - -
- Insert the following references into the body section of the Components/App.razor file, immediately after the _framework/blazor.web.js reference: -
- - -@code { - private const string pageUrl = "/charts/getting-started/blazor-webapp-auto-global-net-8"; - private const string title = "Getting started - Blazor WebApp (.NET 8) - Interactive render mode Auto - Global location"; - private const string heading = "Getting started - Blazor WebApp (.NET 8) - Interactive render mode Auto - Global location"; - private const string description = "Get started with the Enterprise-class Component library built on the Blazor and Chart.js JavaScript library."; - private const string imageUrl = "https://i.imgur.com/C5ObC3A.png"; - private string version = default!; - - [Inject] - private IConfiguration _configuration { get; set; } = default!; - - protected override void OnInitialized() - { - try - { - version = _configuration["version"]!; - } - catch - { - // do nothing - } - } -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_03_WebApp_Auto/Getting_Started_Snippet_01_Scripts.html b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_03_WebApp_Auto/Getting_Started_Snippet_01_Scripts.html deleted file mode 100644 index 9105166d..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_03_WebApp_Auto/Getting_Started_Snippet_01_Scripts.html +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_03_WebApp_Auto/Getting_Started_Snippet_02_Register.txt b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_03_WebApp_Auto/Getting_Started_Snippet_02_Register.txt deleted file mode 100644 index 6b2af1d4..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_03_WebApp_Auto/Getting_Started_Snippet_02_Register.txt +++ /dev/null @@ -1 +0,0 @@ -@using BlazorExpress.ChartJS \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_01_BarChart.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_01_BarChart.razor deleted file mode 100644 index 2edbfd72..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_01_BarChart.razor +++ /dev/null @@ -1,87 +0,0 @@ - - -@code { - private BarChart barChart = default!; - private BarChartOptions barChartOptions = default!; - private ChartData chartData = default!; - - private int datasetsCount = 0; - private int labelsCount = 0; - private string[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; - private Random random = new(); - - protected override void OnInitialized() - { - chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; - barChartOptions = new BarChartOptions { Responsive = true, Interaction = new Interaction { Mode = InteractionMode.Index } }; - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await barChart.InitializeAsync(chartData, barChartOptions); - } - await base.OnAfterRenderAsync(firstRender); - } - - #region Data Preparation - - private List GetDefaultDataSets(int numberOfDatasets) - { - var datasets = new List(); - - for (var index = 0; index < numberOfDatasets; index++) - { - datasets.Add(GetRandomBarChartDataset()); - } - - return datasets; - } - - private BarChartDataset GetRandomBarChartDataset() - { - var c = ColorUtility.CategoricalTwelveColors[datasetsCount].ToColor(); - - datasetsCount += 1; - - return new BarChartDataset() - { - Label = $"Product {datasetsCount}", - Data = GetRandomData(), - BackgroundColor = new List { c.ToRgbString() }, - BorderColor = new List { c.ToRgbString() }, - BorderWidth = new List { 0 }, - }; - } - - private List GetRandomData() - { - var data = new List(); - for (var index = 0; index < labelsCount; index++) - { - data.Add(random.Next(200)); - } - - return data; - } - - private List GetDefaultDataLabels(int numberOfLabels) - { - var labels = new List(); - for (var index = 0; index < numberOfLabels; index++) - { - labels.Add(GetNextDataLabel()); - } - - return labels; - } - - private string GetNextDataLabel() - { - labelsCount += 1; - return months[labelsCount - 1]; - } - - #endregion Data Preparation -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_02_DoughnutChart.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_02_DoughnutChart.razor deleted file mode 100644 index 9795f1e0..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_02_DoughnutChart.razor +++ /dev/null @@ -1,93 +0,0 @@ - - -@code { - private DoughnutChart doughnutChart = default!; - private DoughnutChartOptions doughnutChartOptions = default!; - private ChartData chartData = default!; - private string[]? backgroundColors; - - private int datasetsCount = 0; - private int dataLabelsCount = 0; - - private Random random = new(); - - protected override void OnInitialized() - { - backgroundColors = ColorUtility.CategoricalTwelveColors; - chartData = new ChartData { Labels = GetDefaultDataLabels(4), Datasets = GetDefaultDataSets(1) }; - - doughnutChartOptions = new(); - doughnutChartOptions.Responsive = true; - doughnutChartOptions.Plugins.Title!.Text = "2022 - Sales"; - doughnutChartOptions.Plugins.Title.Display = true; - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await doughnutChart.InitializeAsync(chartData, doughnutChartOptions); - } - await base.OnAfterRenderAsync(firstRender); - } - - #region Data Preparation - - private List GetDefaultDataSets(int numberOfDatasets) - { - var datasets = new List(); - - for (var index = 0; index < numberOfDatasets; index++) - { - datasets.Add(GetRandomDoughnutChartDataset()); - } - - return datasets; - } - - private DoughnutChartDataset GetRandomDoughnutChartDataset() - { - datasetsCount += 1; - return new() { Label = $"Team {datasetsCount}", Data = GetRandomData(), BackgroundColor = GetRandomBackgroundColors() }; - } - - private List GetRandomData() - { - var data = new List(); - for (var index = 0; index < dataLabelsCount; index++) - { - data.Add(random.Next(0, 100)); - } - - return data; - } - - private List GetRandomBackgroundColors() - { - var colors = new List(); - for (var index = 0; index < dataLabelsCount; index++) - { - colors.Add(backgroundColors![index]); - } - - return colors; - } - - private List GetDefaultDataLabels(int numberOfLabels) - { - var labels = new List(); - for (var index = 0; index < numberOfLabels; index++) - { - labels.Add(GetNextDataLabel()); - dataLabelsCount += 1; - } - - return labels; - } - - private string GetNextDataLabel() => $"Product {dataLabelsCount + 1}"; - - private string GetNextDataBackgrounfColor() => backgroundColors![dataLabelsCount]; - - #endregion Data Preparation -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_03_LineChart.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_03_LineChart.razor deleted file mode 100644 index da00931b..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_03_LineChart.razor +++ /dev/null @@ -1,92 +0,0 @@ - - -@code { - private LineChart lineChart = default!; - private LineChartOptions lineChartOptions = default!; - private ChartData chartData = default!; - - private int datasetsCount; - private int labelsCount; - - private Random random = new(); - - protected override void OnInitialized() - { - chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; - lineChartOptions = new() { Responsive = true, Interaction = new Interaction { Mode = InteractionMode.Index } }; - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await lineChart.InitializeAsync(chartData, lineChartOptions); - } - await base.OnAfterRenderAsync(firstRender); - } - - #region Data Preparation - - private List GetDefaultDataSets(int numberOfDatasets) - { - var datasets = new List(); - - for (var index = 0; index < numberOfDatasets; index++) - { - datasets.Add(GetRandomLineChartDataset()); - } - - return datasets; - } - - private LineChartDataset GetRandomLineChartDataset() - { - var c = ColorUtility.CategoricalTwelveColors[datasetsCount].ToColor(); - - datasetsCount += 1; - - return new LineChartDataset - { - Label = $"Team {datasetsCount}", - Data = GetRandomData(), - BackgroundColor = new List { c.ToRgbString() }, - BorderColor = new List { c.ToRgbString() }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { c.ToRgbString() }, - PointRadius = new List { 0 }, // hide points - PointHoverRadius = new List { 4 } - }; - } - - private List GetRandomData() - { - var data = new List(); - for (var index = 0; index < labelsCount; index++) - { - data.Add(random.Next(200)); - } - - return data; - } - - private List GetDefaultDataLabels(int numberOfLabels) - { - var labels = new List(); - for (var index = 0; index < numberOfLabels; index++) - { - labels.Add(GetNextDataLabel()); - } - - return labels; - } - - private string GetNextDataLabel() - { - labelsCount += 1; - return $"Day {labelsCount}"; - } - - #endregion Data Preparation - -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_04_PieChart.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_04_PieChart.razor deleted file mode 100644 index 7ab35e80..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_04_PieChart.razor +++ /dev/null @@ -1,93 +0,0 @@ - - -@code { - private PieChart pieChart = default!; - private PieChartOptions pieChartOptions = default!; - private ChartData chartData = default!; - private string[]? backgroundColors; - - private int datasetsCount = 0; - private int dataLabelsCount = 0; - - private Random random = new(); - - protected override void OnInitialized() - { - backgroundColors = ColorUtility.CategoricalTwelveColors; - chartData = new ChartData { Labels = GetDefaultDataLabels(4), Datasets = GetDefaultDataSets(1) }; - - pieChartOptions = new(); - pieChartOptions.Responsive = true; - pieChartOptions.Plugins.Title!.Text = "2022 - Sales"; - pieChartOptions.Plugins.Title.Display = true; - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await pieChart.InitializeAsync(chartData, pieChartOptions); - } - await base.OnAfterRenderAsync(firstRender); - } - - #region Data Preparation - - private List GetDefaultDataSets(int numberOfDatasets) - { - var datasets = new List(); - - for (var index = 0; index < numberOfDatasets; index++) - { - datasets.Add(GetRandomPieChartDataset()); - } - - return datasets; - } - - private PieChartDataset GetRandomPieChartDataset() - { - datasetsCount += 1; - return new() { Label = $"Team {datasetsCount}", Data = GetRandomData(), BackgroundColor = GetRandomBackgroundColors() }; - } - - private List GetRandomData() - { - var data = new List(); - for (var index = 0; index < dataLabelsCount; index++) - { - data.Add(random.Next(0, 100)); - } - - return data; - } - - private List GetRandomBackgroundColors() - { - var colors = new List(); - for (var index = 0; index < dataLabelsCount; index++) - { - colors.Add(backgroundColors![index]); - } - - return colors; - } - - private List GetDefaultDataLabels(int numberOfLabels) - { - var labels = new List(); - for (var index = 0; index < numberOfLabels; index++) - { - labels.Add(GetNextDataLabel()); - dataLabelsCount += 1; - } - - return labels; - } - - private string GetNextDataLabel() => $"Product {dataLabelsCount + 1}"; - - private string GetNextDataBackgrounfColor() => backgroundColors![dataLabelsCount]; - - #endregion Data Preparation -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_99_Example.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_99_Example.razor deleted file mode 100644 index 0f69a26e..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Charts_Demo_99_Example.razor +++ /dev/null @@ -1,112 +0,0 @@ - - - -@code { - private BarChart barChart = default!; - private LineChart lineChart = default!; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await RenderManhattanAsync(); - await RenderWormAsync(); - } - - await base.OnAfterRenderAsync(firstRender); - } - - private async Task RenderManhattanAsync() - { - var data = new ChartData - { - Labels = new List { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" }, - Datasets = new List() - { - new BarChartDataset() - { - Label = "India", - Data = new List{ 9, 11, 9, 4, 17, 16, 9, 11, 5, 14, 15, 6, 15, 9, 6, 8, 13, 3, 4, 11 }, - BackgroundColor = new List{ "rgb(88, 80, 141)" }, - CategoryPercentage = 0.8, - BarPercentage = 1, - }, - new BarChartDataset() - { - Label = "England", - Data = new List{ 1, 0, 7, 11, 5, 2, 13, 8, 9, 10, 7, 13, 7, 5, 9, 5, 10, 5, 11, 2 }, - BackgroundColor = new List { "rgb(255, 166, 0)" }, - CategoryPercentage = 0.8, - BarPercentage = 1, - } - } - }; - - var options = new BarChartOptions(); - - options.Interaction.Mode = InteractionMode.Index; - - options.Plugins.Title!.Text = "MANHATTAN"; - options.Plugins.Title.Display = true; - options.Plugins.Title.Font = new ChartFont { Size = 20 }; - - options.Responsive = true; - - options.Scales.X!.Title = new ChartAxesTitle { Text = "Overs", Display = true }; - options.Scales.Y!.Title = new ChartAxesTitle { Text = "Runs", Display = true }; - - await barChart.InitializeAsync(data, options); - } - - private async Task RenderWormAsync() - { - var data = new ChartData - { - Labels = new List { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20" }, - Datasets = new List() - { - new LineChartDataset() - { - Label = "India", - Data = new List{ 9, 20, 29, 33, 50, 66, 75, 86, 91, 105, 120, 126, 141, 150, 156, 164, 177, 180, 184, 195 }, - BackgroundColor = new List{ "rgb(88, 80, 141)" }, - BorderColor = new List{ "rgb(88, 80, 141)" }, - BorderWidth = new List{2}, - HoverBorderWidth = new List{4}, - PointBackgroundColor = new List{ "rgb(88, 80, 141)" }, - PointBorderColor = new List{ "rgb(88, 80, 141)" }, - PointRadius = new List{0}, // hide points - PointHoverRadius = new List{4}, - }, - new LineChartDataset() - { - Label = "England", - Data = new List{ 1, 1, 8, 19, 24, 26, 39, 47, 56, 66, 75, 88, 95, 100, 109, 114, 124, 129, 140, 142 }, - BackgroundColor = new List{ "rgb(255, 166, 0)" }, - BorderColor = new List{ "rgb(255, 166, 0)" }, - BorderWidth = new List{2}, - HoverBorderWidth = new List{4}, - PointBackgroundColor = new List{ "rgb(255, 166, 0)" }, - PointBorderColor = new List{ "rgb(255, 166, 0)" }, - PointRadius = new List{0}, // hide points - PointHoverRadius = new List{4}, - } - } - }; - - var options = new LineChartOptions(); - - options.Interaction.Mode = InteractionMode.Index; - - options.Plugins.Title!.Text = "WORM"; - options.Plugins.Title.Display = true; - options.Plugins.Title.Font = new ChartFont { Size = 20 }; - - options.Responsive = true; - - options.Scales.X!.Title = new ChartAxesTitle { Text = "Overs", Display = true }; - options.Scales.Y!.Title = new ChartAxesTitle { Text = "Runs", Display = true }; - - await lineChart.InitializeAsync(data, options); - } -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Index.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Index.razor deleted file mode 100644 index 57fe0fb8..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/Home/Index.razor +++ /dev/null @@ -1,73 +0,0 @@ -@attribute [Route(pageUrl)] -@attribute [Route(pageUrl2)] - -@title | BlazorExpress.ChartJS Components - - - -

Blazor Charts

-
- Blazor Express charts are well-designed chart components on top of Chart.js to visualize data. It contains a rich UI gallery of charts that cater to all charting scenarios. Its high performance helps render large amounts of data quickly. -
- -@* *@ - -
-
- -
-
- -
-
- -
-
- -
-
-
- -
- - -
At this moment we are supporting four blazor chart types.
-
    -
  1. Bar Chart
  2. -
  3. Doughnut Chart
  4. -
  5. Line Chart
  6. -
  7. Pie Chart
  8. -
- - - We will add Bubble Chart, Polar Area Chart, Radar Chart, Scatter Chart, and Mixed Chart support in the subsequent versions. - - - -
- Refer to the getting started guide for setting up charts. -
- -@code { - private const string pageUrl = "/"; - private const string pageUrl2 = "/charts/overview"; - private const string title = "Blazor Chart Components"; - private const string heading = "Blazor Charts"; - private const string description = "Blazor Express charts are well-designed chart components on top of Chart.js to visualize data. It contains a rich UI gallery of charts that cater to all charting scenarios. Its high performance helps render large amounts of data quickly."; - private const string imageUrl = "https://i.imgur.com/C5ObC3A.png"; - - [Inject] private NavigationManager _navigationManager { get; set; } = default!; - - protected override void OnInitialized() - { - try - { - if (_navigationManager.Uri.Replace(_navigationManager.BaseUri, "").Equals("")) - _navigationManager.NavigateTo(pageUrl2); - } - catch - { - // do nothing - } - } -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_00_API_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_00_API_Documentation.razor deleted file mode 100644 index fb7d873f..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_00_API_Documentation.razor +++ /dev/null @@ -1,105 +0,0 @@ -@attribute [Route(pageUrl)] - - - -Blazor Line Chart - API Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - LineChartDataset implements IChartDataset. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LineChartOptions implements ChartOptions. - - - - - - - - - - - -@code { - private const string pageUrl = "/charts/line-chart/api-documentation"; - private const string title = "Blazor Line Chart - API Documentation"; - private const string heading = "Blazor Line Chart - API Documentation"; - private const string description = "This documentation provides a comprehensive reference for the Blazor Line Chart component, guiding you through its functionalities and configuration options."; - private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_01.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_01.razor deleted file mode 100644 index 42098bcb..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_01.razor +++ /dev/null @@ -1,29 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - - -
- In the following example, a categorical 12-color palette is used. -
- - For data visualization, you can use the predefined palettes ColorUtility.CategoricalTwelveColors for a 12-color palette and ColorUtility.CategoricalSixColors for a 6-color palette. - These palettes offer a range of distinct and visually appealing colors that can be applied to represent different categories or data elements in your visualizations. - - -
- - -@code { - private const string pageUrl = "/charts/line-chart"; - private const string title = "Blazor Line Chart"; - private const string heading = "Blazor Line Chart"; - private const string description = "A Blazor line chart component is a graphical representation of data that uses a series of connected points to show how the data changes over time. It is a type of x-y chart, where the x-axis represents the independent variable, such as time, and the y-axis represents the dependent variable, such as the value."; - private const string imageUrl = "https://i.imgur.com/8b7jH0D.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_02.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_02.razor deleted file mode 100644 index bb82f9dc..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_02.razor +++ /dev/null @@ -1,18 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - - -@code { - private const string pageUrl = "/charts/line-chart/data-labels"; - private const string title = "Blazor Line Chart"; - private const string heading = "Blazor Line Chart"; - private const string description = "A Blazor line chart component is a graphical representation of data that uses a series of connected points to show how the data changes over time. It is a type of x-y chart, where the x-axis represents the independent variable, such as time, and the y-axis represents the dependent variable, such as the value."; - private const string imageUrl = "https://i.imgur.com/8b7jH0D.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_03.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_03.razor deleted file mode 100644 index 312de48c..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_03.razor +++ /dev/null @@ -1,18 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - - -@code { - private const string pageUrl = "/charts/line-chart/tick-configuration"; - private const string title = "Blazor Line Chart"; - private const string heading = "Blazor Line Chart"; - private const string description = "A Blazor line chart component is a graphical representation of data that uses a series of connected points to show how the data changes over time. It is a type of x-y chart, where the x-axis represents the independent variable, such as time, and the y-axis represents the dependent variable, such as the value."; - private const string imageUrl = "https://i.imgur.com/8b7jH0D.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_04.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_04.razor deleted file mode 100644 index 91dbc03d..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChartDocumentation_04.razor +++ /dev/null @@ -1,22 +0,0 @@ -@attribute [Route(pageUrl)] - - - - -
- By default, the chart is using the default locale of the platform on which it is running. - In the following example, you will see the chart in the German locale (de_DE). -
- - -@code { - private const string pageUrl = "/charts/line-chart/locale"; - private const string title = "Blazor Line Chart"; - private const string heading = "Blazor Line Chart"; - private const string description = "A Blazor line chart component is a graphical representation of data that uses a series of connected points to show how the data changes over time. It is a type of x-y chart, where the x-axis represents the independent variable, such as time, and the y-axis represents the dependent variable, such as the value."; - private const string imageUrl = "https://i.imgur.com/8b7jH0D.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_01_B_Examples.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_01_B_Examples.razor deleted file mode 100644 index 2787412e..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_01_B_Examples.razor +++ /dev/null @@ -1,79 +0,0 @@ - - -@code { - private LineChart lineChart = default!; - private LineChartOptions lineChartOptions = default!; - private ChartData chartData = default!; - - protected override void OnInitialized() - { - var colors = ColorUtility.CategoricalTwelveColors; - - var labels = new List { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; - var datasets = new List(); - - var dataset1 = new LineChartDataset - { - Label = "Windows", - Data = new List { 7265791, 5899643, 6317759, 6315641, 5338211, 8496306, 7568556, 8538933, 8274297, 8657298, 7548388, 7764845 }, - BackgroundColor = new List { colors[0] }, - BorderColor = new List { colors[0] }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { colors[0] }, - PointRadius = new List { 0 }, // hide points - PointHoverRadius = new List { 4 } - }; - datasets.Add(dataset1); - - var dataset2 = new LineChartDataset - { - Label = "macOS", - Data = new List { 1809499, 1816642, 2122410, 1809499, 1850793, 1846743, 1954797, 2391313, 1983430, 2469918, 2633303, 2821149 }, - BackgroundColor = new List { colors[1] }, - BorderColor = new List { colors[1] }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { colors[1] }, - PointRadius = new List { 0 }, // hide points - PointHoverRadius = new List { 4 } - }; - datasets.Add(dataset2); - - var dataset3 = new LineChartDataset - { - Label = "Other", - Data = new List { 1081241, 1100363, 1118136, 1073255, 1120315, 1395736, 1488788, 1489466, 1489947, 1414739, 1735811, 1820171 }, - BackgroundColor = new List { colors[2] }, - BorderColor = new List { colors[2] }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { colors[2] }, - PointRadius = new List { 0 }, // hide points - PointHoverRadius = new List { 4 } - }; - datasets.Add(dataset3); - - chartData = new ChartData { Labels = labels, Datasets = datasets }; - - lineChartOptions = new(); - lineChartOptions.Responsive = true; - lineChartOptions.Interaction = new Interaction { Mode = InteractionMode.Index }; - - lineChartOptions.Scales.X!.Title = new ChartAxesTitle { Text = "2019", Display = true }; - lineChartOptions.Scales.Y!.Title = new ChartAxesTitle { Text = "Visitors", Display = true }; - - lineChartOptions.Plugins.Title!.Text = "Operating system"; - lineChartOptions.Plugins.Title.Display = true; - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await lineChart.InitializeAsync(chartData, lineChartOptions); - } - await base.OnAfterRenderAsync(firstRender); - } - -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_02_Datalabels.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_02_Datalabels.razor deleted file mode 100644 index 9350a1d0..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_02_Datalabels.razor +++ /dev/null @@ -1,97 +0,0 @@ -@using BlazorExpress.ChartJS.Enums - - -@code { - private LineChart lineChart = default!; - private LineChartOptions lineChartOptions = default!; - private ChartData chartData = default!; - - protected override void OnInitialized() - { - var colors = ColorUtility.CategoricalTwelveColors; - - var labels = new List { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; - var datasets = new List(); - - var dataset1 = new LineChartDataset - { - Label = "Windows", - Data = new List { 7265791, 5899643, 6317759, 6315641, 5338211, 8496306, 7568556, 8538933, 8274297, 8657298, 7548388, 7764845 }, - BackgroundColor = new List { colors[0] }, - BorderColor = new List { colors[0] }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { colors[0] }, - PointRadius = new List { 3 }, // show points - PointHoverRadius = new List { 4 }, - - // datalabels - Datalabels = new() { Alignment = Alignment.End, Anchor = Anchor.End } - }; - datasets.Add(dataset1); - - var dataset2 = new LineChartDataset - { - Label = "macOS", - Data = new List { 1809499, 1816642, 2122410, 1809499, 1850793, 1846743, 1954797, 2391313, 1983430, 2469918, 2633303, 2821149 }, - BackgroundColor = new List { colors[1] }, - BorderColor = new List { colors[1] }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { colors[1] }, - PointRadius = new List { 3 }, // show points - PointHoverRadius = new List { 4 }, - - // datalabels - Datalabels = new() { Alignment = Alignment.End, Anchor = Anchor.End } - }; - datasets.Add(dataset2); - - var dataset3 = new LineChartDataset - { - Label = "Other", - Data = new List { 1081241, 1100363, 1118136, 1073255, 1120315, 1395736, 1488788, 1489466, 1489947, 1414739, 1735811, 1820171 }, - BackgroundColor = new List { colors[2] }, - BorderColor = new List { colors[2] }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { colors[2] }, - PointRadius = new List { 3 }, // show points - PointHoverRadius = new List { 4 }, - - // datalabels - Datalabels = new() { Alignment = Alignment.Start, Anchor = Anchor.Start } - }; - datasets.Add(dataset3); - - chartData = new ChartData - { - Labels = labels, - Datasets = datasets - }; - - lineChartOptions = new(); - lineChartOptions.Responsive = true; - lineChartOptions.Interaction = new Interaction { Mode = InteractionMode.Index }; - - lineChartOptions.Scales.X!.Title = new ChartAxesTitle { Text = "2019", Display = true }; - lineChartOptions.Scales.Y!.Title = new ChartAxesTitle { Text = "Visitors", Display = true }; - - lineChartOptions.Plugins.Title!.Text = "Operating system"; - lineChartOptions.Plugins.Title.Display = true; - - // datalabels - lineChartOptions.Plugins.Datalabels.Color = "white"; - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - // pass the plugin name to enable the data labels - await lineChart.InitializeAsync(chartData: chartData, chartOptions: lineChartOptions, plugins: new string[] { "ChartDataLabels" }); - } - await base.OnAfterRenderAsync(firstRender); - } - -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_04_Locale.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_04_Locale.razor deleted file mode 100644 index ddc83610..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_04_Locale.razor +++ /dev/null @@ -1,80 +0,0 @@ - - -@code { - private LineChart lineChart = default!; - private LineChartOptions lineChartOptions = default!; - private ChartData chartData = default!; - - protected override void OnInitialized() - { - var colors = ColorUtility.CategoricalTwelveColors; - - var labels = new List { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; - var datasets = new List(); - - var dataset1 = new LineChartDataset - { - Label = "Windows", - Data = new List { 7265791, 5899643, 6317759, 6315641, 5338211, 8496306, 7568556, 8538933, 8274297, 8657298, 7548388, 7764845 }, - BackgroundColor = new List { colors[0] }, - BorderColor = new List { colors[0] }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { colors[0] }, - PointRadius = new List { 0 }, // hide points - PointHoverRadius = new List { 4 } - }; - datasets.Add(dataset1); - - var dataset2 = new LineChartDataset - { - Label = "macOS", - Data = new List { 1809499, 1816642, 2122410, 1809499, 1850793, 1846743, 1954797, 2391313, 1983430, 2469918, 2633303, 2821149 }, - BackgroundColor = new List { colors[1] }, - BorderColor = new List { colors[1] }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { colors[1] }, - PointRadius = new List { 0 }, // hide points - PointHoverRadius = new List { 4 } - }; - datasets.Add(dataset2); - - var dataset3 = new LineChartDataset - { - Label = "Other", - Data = new List { 1081241, 1100363, 1118136, 1073255, 1120315, 1395736, 1488788, 1489466, 1489947, 1414739, 1735811, 1820171 }, - BackgroundColor = new List { colors[2] }, - BorderColor = new List { colors[2] }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { colors[2] }, - PointRadius = new List { 0 }, // hide points - PointHoverRadius = new List { 4 } - }; - datasets.Add(dataset3); - - chartData = new ChartData { Labels = labels, Datasets = datasets }; - - lineChartOptions = new(); - lineChartOptions.Locale = "de-DE"; - lineChartOptions.Responsive = true; - lineChartOptions.Interaction = new Interaction { Mode = InteractionMode.Index }; - - lineChartOptions.Scales.X!.Title = new ChartAxesTitle { Text = "2019", Display = true }; - lineChartOptions.Scales.Y!.Title = new ChartAxesTitle { Text = "Visitors", Display = true }; - - lineChartOptions.Plugins.Title!.Text = "Operating system"; - lineChartOptions.Plugins.Title.Display = true; - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await lineChart.InitializeAsync(chartData, lineChartOptions); - } - await base.OnAfterRenderAsync(firstRender); - } - -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_00_API_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_00_API_Documentation.razor deleted file mode 100644 index edd4fbfd..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_00_API_Documentation.razor +++ /dev/null @@ -1,76 +0,0 @@ -@attribute [Route(pageUrl)] - - - -Blazor Pie Chart - API Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - PieChartDataset implements IChartDataset. - - - - - - - - - - - - - - - - - - - - - - - - - PieChartOptions implements ChartOptions. - - - - - - - -@code { - private const string pageUrl = "/charts/pie-chart/api-documentation"; - private const string title = "Blazor Pie Chart - API Documentation"; - private const string heading = "Blazor Pie Chart - API Documentation"; - private const string description = "This documentation provides a comprehensive reference for the Blazor Pie Chart component, guiding you through its functionalities and configuration options."; - private const string imageUrl = "https://i.imgur.com/dDpIuzk.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_01.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_01.razor deleted file mode 100644 index 5bfd1b9b..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_01.razor +++ /dev/null @@ -1,27 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - - -
- In the following example, a categorical 12-color palette is used. -
- - For data visualization, you can use the predefined palettes ColorUtility.CategoricalTwelveColors for a 12-color palette and ColorUtility.CategoricalSixColors for a 6-color palette. - These palettes offer a range of distinct and visually appealing colors that can be applied to represent different categories or data elements in your visualizations. - - - -@code { - private const string pageUrl = "/charts/pie-chart"; - private const string title = "Blazor Pie Chart"; - private const string heading = "Blazor Pie Chart"; - private const string description = "A Blazor pie chart component is a circular chart that shows the proportional values of different categories."; - private const string imageUrl = "https://i.imgur.com/ieBupT2.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_02.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_02.razor deleted file mode 100644 index 29c109ec..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_02.razor +++ /dev/null @@ -1,18 +0,0 @@ -@attribute [Route(pageUrl)] - - - - - - -@code { - private const string pageUrl = "/charts/pie-chart/data-labels"; - private const string title = "Blazor Pie Chart"; - private const string heading = "Blazor Pie Chart"; - private const string description = "A Blazor pie chart component is a circular chart that shows the proportional values of different categories."; - private const string imageUrl = "https://i.imgur.com/ieBupT2.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_03.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_03.razor deleted file mode 100644 index eb2379c5..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChartDocumentation_03.razor +++ /dev/null @@ -1,21 +0,0 @@ -@attribute [Route(pageUrl)] - - - - -
- This sample demonstrates how to change the position of the chart legend. -
- - -@code { - private const string pageUrl = "/charts/pie-chart/legend"; - private const string title = "Blazor Pie Chart"; - private const string heading = "Blazor Pie Chart"; - private const string description = "A Blazor pie chart component is a circular chart that shows the proportional values of different categories."; - private const string imageUrl = "https://i.imgur.com/ieBupT2.png"; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Demo.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Demo.razor deleted file mode 100644 index f1085ccc..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Demo.razor +++ /dev/null @@ -1,90 +0,0 @@ -@using BlazorBootstrap -@namespace BlazorExpress.ChartJS.Demo.RCL -@inherits ComponentBase - -@if (ShowCodeOnly) -{ -
-
- razor -
- - - -
-
-
-
-                
-                    @if (snippet is not null)
-                    {
-                        @snippet.Trim()
-                    }
-                
-            
-
-
-} -else if (!Tabs) -{ -
-
- -
-
- razor -
- - - -
-
-
-
-                
-                    @if (snippet is not null)
-                    {
-                        @snippet.Trim()
-                    }
-                
-            
-
-
-} -else // Tabs = true -{ - - - - Example - - -
- -
-
-
- - - View Source - - -
- - - -
-
-
-                        
-                            @if (snippet is not null)
-                            {
-                                @snippet.Trim()
-                            }
-                        
-                    
-
-
-
-
-} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Demo.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Demo.razor.cs deleted file mode 100644 index 88aa6850..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Demo.razor.cs +++ /dev/null @@ -1,117 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -public partial class Demo : ComponentBase -{ - #region Fields and Constants - - private IconColor clipboardTooltipIconColor = IconColor.Dark; - - private IconName clipboardTooltipIconName = IconName.Clipboard; - - private string? clipboardTooltipTitle = "Copy to clipboard"; - - private string? snippet; - - /// - /// A reference to this component instance for use in JavaScript calls. - /// - private DotNetObjectReference objRef = default!; - - #endregion - - #region Methods - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - await JS.InvokeVoidAsync("highlightCode"); - - await base.OnAfterRenderAsync(firstRender); - } - - protected override async Task OnInitializedAsync() - { - objRef ??= DotNetObjectReference.Create(this); - await base.OnInitializedAsync(); - } - - protected override async Task OnParametersSetAsync() - { - if (snippet is null) - { - var resourceFullName = Type.FullName + ".razor"; - - using (var stream = Type.Assembly.GetManifestResourceStream(resourceFullName)!) - { - try - { - if (stream is null) - return; - - using (var reader = new StreamReader(stream)) - { - snippet = await reader.ReadToEndAsync(); - } - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - } - } - } - - /// - /// Handles a copy error event from JavaScript. - /// - /// The error message. - [JSInvokable] - public void OnCopyFailJS(string errorMessage) - { - // TODO: show message - } - - /// - /// Handles a copy success event from JavaScript. - /// - [JSInvokable] - public void OnCopySuccessJS() - { - clipboardTooltipTitle = "Copied!"; - clipboardTooltipIconName = IconName.Check2; - clipboardTooltipIconColor = IconColor.Success; - - StateHasChanged(); - } - - /// - /// Handles a copy status reset event from JavaScript. - /// - [JSInvokable] - public void ResetCopyStatusJS() - { - clipboardTooltipTitle = "Copy to clipboard"; - clipboardTooltipIconName = IconName.Clipboard; - clipboardTooltipIconColor = IconColor.Dark; - - StateHasChanged(); - } - - private async Task CopyToClipboardAsync() => await JS.InvokeVoidAsync("copyToClipboard", snippet, objRef); - - #endregion - - #region Properties, Indexers - - [Inject] protected IJSRuntime JS { get; set; } = default!; - - [Parameter] public LanguageCode LanguageCode { get; set; } = LanguageCode.Razor; - - [Parameter] public bool ShowCodeOnly { get; set; } - - [Parameter] public bool Tabs { get; set; } = false; - - [Parameter] public Type Type { get; set; } = default!; - - #endregion -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Demo.razor.css b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Demo.razor.css deleted file mode 100644 index 6d21ea99..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Demo.razor.css +++ /dev/null @@ -1,4 +0,0 @@ -.highlight-toolbar { - color: #212529; - background-color: #f8f9fa; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTRow.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTRow.razor deleted file mode 100644 index 2521fc24..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTRow.razor +++ /dev/null @@ -1,36 +0,0 @@ -@namespace BlazorExpress.ChartJS.Demo.RCL -@inherits ComponentBase -@typeparam TItem - -@if (DocType is DocType.Parameters or DocType.Properties) -{ - - @PropertyName - @if (string.IsNullOrWhiteSpace(PropertyType)) - { - @typeof(TItem).GetPropertyTypeName(PropertyName!) - } - else - { - @PropertyType - } - @DefaultValue - - @if (Required) - { - - } - - @((MarkupString)Description!) - @AddedVersion - -} -else if (DocType == DocType.Methods) -{ - - @MethodName - @ReturnType - @Description - @AddedVersion - -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTRow.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTRow.razor.cs deleted file mode 100644 index 96048dc6..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTRow.razor.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -public partial class DocxTRow : ComponentBase -{ - [Parameter] - public string? PropertyName { get; set; } - - [Parameter] - public string? PropertyType { get; set; } - - [Parameter] - public string? DefaultValue { get; set; } - - [Parameter] - public bool Required { get; set; } - - [Parameter] - public string? Description { get; set; } - - [Parameter] - public string? AddedVersion { get; set; } - - [CascadingParameter(Name = "DocType")] - public DocType DocType { get; set; } = DocType.Parameters; - - [Parameter] - public string? MethodName { get; set; } - - [Parameter] - public string? ReturnType { get; set; } - - -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTable.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTable.razor deleted file mode 100644 index 5e084950..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTable.razor +++ /dev/null @@ -1,61 +0,0 @@ -@namespace BlazorExpress.ChartJS.Demo.RCL -@inherits ComponentBase -@typeparam TItem - - - @if (DocType is DocType.Parameters or DocType.Properties) - { -
- - - - - - - - - - - - - @ChildContent - -
NameTypeDefaultRequiredDescriptionAdded Version
-
- } - else if (DocType == DocType.Methods) - { -
- - - - - - - - - - - @ChildContent - -
NameReturn typeDescriptionAdded Version
-
- } - else if (DocType == DocType.Events) - { -
- - - - - - - - - - @ChildContent - -
NameDescriptionAdded Version
-
- } -
diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTable.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTable.razor.cs deleted file mode 100644 index 3526ab9b..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTable.razor.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -public partial class DocxTable : ComponentBase -{ - [Parameter] - public RenderFragment? ChildContent { get; set; } - - [Parameter] - public DocType DocType { get; set; } = DocType.Parameters; -} - - diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTable.razor.css b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/DocxTable/DocxTable.razor.css deleted file mode 100644 index e69de29b..00000000 diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Enums/DocType.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Enums/DocType.cs deleted file mode 100644 index b9a77b12..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Enums/DocType.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -public enum DocType -{ - Enum, - Events, - Methods, - Parameters, - Properties -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Enums/LanguageCode.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Enums/LanguageCode.cs deleted file mode 100644 index 1aff779c..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Enums/LanguageCode.cs +++ /dev/null @@ -1,68 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -/// -/// -/// -public enum LanguageCode -{ - /// - /// ASP.NET (C#) - aspnet - /// - AspNet, - - /// - /// C# - csharp, cs, dotnet - /// - CSharp, - - /// - /// CSS - css - /// - Css, - - /// - /// HTML - html - /// - HTML, - - /// - /// JavaScript - javascript, js - /// - JavaScript, - - /// - /// JSON - json - /// - JSON, - - /// - /// JSONP - jsonp - /// - JSONP, - - /// - /// Markdown - md - /// - Markdown, - - /// - /// PowerShell - powershell - /// - PowerShell, - - /// - /// Razor C# - cshtml, razor - /// - Razor, - - /// - /// Text - none - /// - Text, - - /// - /// YAML - yaml, yml - /// - YAML -} - diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Extensions/EnumExtensions.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Extensions/EnumExtensions.cs deleted file mode 100644 index 7776f873..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Extensions/EnumExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -public static class EnumExtensions -{ - public static string? ToLanguageCssClass(this LanguageCode languageCode) => - languageCode switch - { - LanguageCode.AspNet => "language-aspnet", - LanguageCode.CSharp => "language-csharp", - LanguageCode.JavaScript => "language-js", - LanguageCode.JSON => "language-json", - LanguageCode.JSONP => "language-jsonp", - LanguageCode.Markdown => "language-md", - LanguageCode.PowerShell => "language-powershell", - LanguageCode.Razor => "language-razor", - LanguageCode.Text => "language-none", - LanguageCode.YAML => "language-yaml", - _ => null - }; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Extensions/TypeExtensions.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Extensions/TypeExtensions.cs deleted file mode 100644 index 75812d0f..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Extensions/TypeExtensions.cs +++ /dev/null @@ -1,86 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -/// -/// Various extension methods for . -/// -public static class TypeExtensions -{ - #region Methods - - /// - /// Get property type name. - /// - /// - /// - /// string - public static string GetPropertyTypeName(this Type type, string propertyName) - { - if (type is null || string.IsNullOrWhiteSpace(propertyName)) - return string.Empty; - - var propertyType = type.GetProperty(propertyName)?.PropertyType; - if (propertyType is null) - return string.Empty; - - var propertyTypeName = propertyType?.ToString(); - if (string.IsNullOrWhiteSpace(propertyTypeName)) - return string.Empty; - - if (propertyTypeName.Contains(StringConstants.PropertyTypeNameInt16, StringComparison.InvariantCulture)) - propertyTypeName = StringConstants.PropertyTypeNameInt16CSharpTypeKeyword; - - else if (propertyTypeName.Contains(StringConstants.PropertyTypeNameInt32, StringComparison.InvariantCulture)) - propertyTypeName = StringConstants.PropertyTypeNameInt32CSharpTypeKeyword; - - else if (propertyTypeName.Contains(StringConstants.PropertyTypeNameInt64, StringComparison.InvariantCulture)) - propertyTypeName = StringConstants.PropertyTypeNameInt64CSharpTypeKeyword; - - else if (propertyTypeName.Contains(StringConstants.PropertyTypeNameChar, StringComparison.InvariantCulture)) - propertyTypeName = StringConstants.PropertyTypeNameCharCSharpTypeKeyword; - - else if (propertyTypeName.Contains(StringConstants.PropertyTypeNameString, StringComparison.InvariantCulture)) - propertyTypeName = StringConstants.PropertyTypeNameStringCSharpTypeKeyword; - - else if (propertyTypeName.Contains(StringConstants.PropertyTypeNameSingle, StringComparison.InvariantCulture)) // float - propertyTypeName = StringConstants.PropertyTypeNameSingleCSharpTypeKeyword; - - else if (propertyTypeName.Contains(StringConstants.PropertyTypeNameDecimal, StringComparison.InvariantCulture)) - propertyTypeName = StringConstants.PropertyTypeNameDecimalCSharpTypeKeyword; - - else if (propertyTypeName.Contains(StringConstants.PropertyTypeNameDouble, StringComparison.InvariantCulture)) - propertyTypeName = StringConstants.PropertyTypeNameDoubleCSharpTypeKeyword; - - else if (propertyTypeName.Contains(StringConstants.PropertyTypeNameDateOnly, StringComparison.InvariantCulture)) - propertyTypeName = StringConstants.PropertyTypeNameDateOnlyCSharpTypeKeyword; - - else if (propertyTypeName.Contains(StringConstants.PropertyTypeNameDateTime, StringComparison.InvariantCulture)) - propertyTypeName = StringConstants.PropertyTypeNameDateTimeCSharpTypeKeyword; - - else if (propertyTypeName.Contains(StringConstants.PropertyTypeNameBoolean, StringComparison.InvariantCulture)) - propertyTypeName = StringConstants.PropertyTypeNameBooleanCSharpTypeKeyword; - - else if (propertyType!.IsEnum) - propertyTypeName = StringConstants.PropertyTypeNameEnumCSharpTypeKeyword; - - else if (propertyTypeName.Contains(StringConstants.PropertyTypeNameGuid, StringComparison.InvariantCulture)) - propertyTypeName = StringConstants.PropertyTypeNameGuidCSharpTypeKeyword; - - return propertyType!.IsNullableType() ? $"{propertyTypeName}?" : propertyTypeName; - } - - /// - /// Get property type. - /// - /// - /// - /// Type? - public static Type? GetPropertyType(this Type type, string propertyName) - { - if (type is null || string.IsNullOrWhiteSpace(propertyName)) - return null; - - return type.GetProperty(propertyName)?.PropertyType; - } - - #endregion -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/MetaTags.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/MetaTags.razor deleted file mode 100644 index 7c7872e8..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/MetaTags.razor +++ /dev/null @@ -1,26 +0,0 @@ -@namespace BlazorExpress.ChartJS.Demo.RCL -@inherits ComponentBase - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/MetaTags.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/MetaTags.razor.cs deleted file mode 100644 index 0ee53682..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/MetaTags.razor.cs +++ /dev/null @@ -1,52 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -public partial class MetaTags : ComponentBase -{ - private string homeUrl = default!; - - #region Members - - private string siteName => "Blazor Express - ChartJS"; - - private string title => $"{Title} | {siteName}"; - - private string url => $"{homeUrl}{PageUrl}"; - - #endregion - - #region Methods - - protected override void OnInitialized() - { - homeUrl = $"{Configuration["urls:homeUrl"]}"; - } - - #endregion - - #region Properties - - [Inject] public IConfiguration Configuration { get; set; } = default!; - - /// - /// Meta Url. - /// Example: /alerts, /modal - /// - [Parameter] public string PageUrl { get; set; } = null!; - - /// - /// Page Title / Meta Title. - /// - [Parameter] public string Title { get; set; } = null!; - - /// - /// Meta Description. - /// - [Parameter] public string Description { get; set; } = null!; - - /// - /// Meta Image Url. - /// - [Parameter] public string ImageUrl { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/PageHeroSection.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/PageHeroSection.razor deleted file mode 100644 index 03c17157..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/PageHeroSection.razor +++ /dev/null @@ -1,12 +0,0 @@ -@namespace BlazorExpress.ChartJS.Demo.RCL -@inherits ComponentBase - -@Title | BlazorExpress.ChartJS Components - - - -

@((MarkupString)Heading!)

- -
@((MarkupString)Description!)
- -@* *@ \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/PageHeroSection.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/PageHeroSection.razor.cs deleted file mode 100644 index a336c990..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/PageHeroSection.razor.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -public partial class PageHeroSection : ComponentBase -{ - /// - /// Meta Url. - /// Example: /alerts, /modal - /// - [Parameter] public string? PageUrl { get; set; } - - /// - /// Page Title / Meta Title. - /// - [Parameter] public string? Title { get; set; } - - /// - /// Page Heading. - /// - [Parameter] public string? Heading { get; set; } - - /// - /// Meta Description. - /// - [Parameter] public string? Description { get; set; } - - /// - /// Meta Image Url. - /// - [Parameter] public string? ImageUrl { get; set; } -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Prerequisites.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Prerequisites.razor deleted file mode 100644 index 66cc235f..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Prerequisites.razor +++ /dev/null @@ -1,7 +0,0 @@ -@namespace BlazorExpress.ChartJS.Demo.RCL -@inherits ComponentBase - - -
- Refer to the getting started guide for setting up charts. -
diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Prerequisites.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Prerequisites.razor.cs deleted file mode 100644 index b7943238..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Prerequisites.razor.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -public partial class Prerequisites : ComponentBase -{ - [Parameter] - public string? PageUrl { get; set; } -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/SectionHeading.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/SectionHeading.razor deleted file mode 100644 index b34111e6..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/SectionHeading.razor +++ /dev/null @@ -1,33 +0,0 @@ -@namespace BlazroExpress.ChartJS.Demo.RCL -@inherits ComponentBase - -@if (Size == HeadingSize.H2) -{ -

- @Text# -

-} -else if (Size == HeadingSize.H3) -{ -

- @Text# -

-} -else if (Size == HeadingSize.H4) -{ -

- @Text# -

-} -else if (Size == HeadingSize.H5) -{ -
- @Text# -
-} -else if (Size == HeadingSize.H6) -{ -
- @Text# -
-} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/SectionHeading.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/SectionHeading.razor.cs deleted file mode 100644 index bab1f20c..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/SectionHeading.razor.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace BlazroExpress.ChartJS.Demo.RCL; - -public partial class SectionHeading : ComponentBase -{ - #region Members - - private string link => $"{PageUrl}#{HashTagName}".Trim().ToLower(); - - #endregion - - #region Methods - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await Task.Delay(200); - await JS.InvokeVoidAsync("navigateToHeading"); - - await base.OnAfterRenderAsync(firstRender); - } - - private async Task OnClick() - { - await JS.InvokeVoidAsync("navigateToHeading"); - } - - #endregion - - #region Properties - - [Parameter] public HeadingSize Size { get; set; } - - [Parameter] public string Text { get; set; } = null!; - - [Parameter] public string PageUrl { get; set; } = null!; - - [Parameter] public string HashTagName { get; set; } = null!; - - [Inject] protected IJSRuntime JS { get; set; } = null!; - - #endregion -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Skippy.razor b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Skippy.razor deleted file mode 100644 index 9f4314a6..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Skippy.razor +++ /dev/null @@ -1,10 +0,0 @@ -@namespace BlazroExpress.ChartJS.Demo.RCL -@inherits ComponentBase - - \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Skippy.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Skippy.razor.cs deleted file mode 100644 index e4a59a04..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Skippy.razor.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace BlazroExpress.ChartJS.Demo.RCL; - -public partial class Skippy : ComponentBase -{ - [Parameter] - public string Url { get; set; } = default!; - - [Parameter] - public RenderFragment ChildContent { get; set; } = default!; -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Skippy.razor.css b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Skippy.razor.css deleted file mode 100644 index e69de29b..00000000 diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Snippet.cs b/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Snippet.cs deleted file mode 100644 index 76c20057..00000000 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Snippet.cs +++ /dev/null @@ -1,79 +0,0 @@ -namespace BlazorExpress.ChartJS.Demo.RCL; - -public class Snippet : ComponentBase -{ - #region Members - - private string? snippet; - - #endregion - - #region Methods - - protected override void BuildRenderTree(RenderTreeBuilder builder) - { - builder.OpenElement(300, "div"); - builder.AddAttribute(301, "class", "highlight show-code-only"); - - builder.OpenElement(400, "pre"); - - builder.OpenElement(500, "code"); - builder.AddAttribute(501, "class", LanguageCode.ToLanguageCssClass()); - - if (snippet != null) - builder.AddContent(600, snippet.Trim()); - - builder.CloseElement(); // end: code - builder.CloseElement(); // end: pre - builder.CloseElement(); // end: div - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - await JS.InvokeVoidAsync("highlightCode"); - - await base.OnAfterRenderAsync(firstRender); - } - - protected override async Task OnParametersSetAsync() - { - if (snippet is null) - { - if (!string.IsNullOrWhiteSpace(FilePath)) - { - var resourceName = FilePath.Replace("~", typeof(Snippet).Assembly.GetName().Name).Replace("/", ".").Replace("\\", "."); - - using (var stream = typeof(Snippet).Assembly.GetManifestResourceStream(resourceName)!) - { - try - { - if (stream is null) - return; - - using (var reader = new StreamReader(stream)) - { - snippet = await reader.ReadToEndAsync(); - } - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - } - } - } - } - - #endregion - - #region Properties - - [Inject] protected IJSRuntime JS { get; set; } = null!; - - [Parameter] public LanguageCode LanguageCode { get; set; } = LanguageCode.Razor; - - [Parameter] public string? FilePath { get; set; } - - #endregion -} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Constants/DemoAppConstants.cs b/BlazorExpress.ChartJS.Demo.RCL/Constants/DemoAppConstants.cs new file mode 100644 index 00000000..8913c91e --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Constants/DemoAppConstants.cs @@ -0,0 +1,6 @@ +namespace BlazorExpress.ChartJS.Demo.RCL; + +public static class DemoAppConstants +{ + public static Type ProjectRootClassType => typeof(App); +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Constants/DemoImageSrcConstants.cs b/BlazorExpress.ChartJS.Demo.RCL/Constants/DemoImageSrcConstants.cs new file mode 100644 index 00000000..530da88c --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Constants/DemoImageSrcConstants.cs @@ -0,0 +1,16 @@ +namespace BlazorExpress.ChartJS.Demo.RCL; + +public static class DemoImageSrcConstants +{ + #region Fields and Constants + + public const string BarChart = "https://i.imgur.com/FGgEMp6.jpg"; + public const string DoughnutChart = "https://i.imgur.com/FGgEMp6.jpg"; + public const string LineChart = "https://i.imgur.com/FGgEMp6.jpg"; + public const string PieChart = "https://i.imgur.com/FGgEMp6.jpg"; + public const string PolarAreaChart = "https://i.imgur.com/FGgEMp6.jpg"; + public const string RadarChart = "https://i.imgur.com/FGgEMp6.jpg"; + public const string ScatterChart = "https://i.imgur.com/FGgEMp6.jpg"; + + #endregion +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Constants/DemoRouteConstants.cs b/BlazorExpress.ChartJS.Demo.RCL/Constants/DemoRouteConstants.cs new file mode 100644 index 00000000..efecaf3f --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Constants/DemoRouteConstants.cs @@ -0,0 +1,60 @@ +namespace BlazorExpress.ChartJS.Demo.RCL; + +public static class DemoRouteConstants +{ + public const string Home_Prefix = "/"; + + public const string Blog_Prefix = "/blog"; + public const string Demos_Prefix = "/demos"; + public const string Docs_Prefix = "/docs"; + + #region Blog + + public const string Blog_Home = Blog_Prefix + "/home"; + + #endregion + + #region Demos + + // Charts + public const string Demos_BarChart = Demos_Prefix + "/bar-chart"; + public const string Demos_BubbleChart = Demos_Prefix + "/bubble-chart"; + public const string Demos_DoughnutChart = Demos_Prefix + "/doughnut-chart"; + public const string Demos_LineChart = Demos_Prefix + "/line-chart"; + public const string Demos_PieChart = Demos_Prefix + "/pie-chart"; + public const string Demos_PolarAreaChart = Demos_Prefix + "/polar-area-chart"; + public const string Demos_RadarChart = Demos_Prefix + "/radar-chart"; + public const string Demos_ScatterChart = Demos_Prefix + "/scatter-chart"; + + // Utils + public const string Demos_Utils_Prefix = Demos_Prefix + "/utils"; + public const string Demos_ColorUtils = Demos_Utils_Prefix + "/color-utility"; + + #endregion + + #region Docs + + // Getting Started + public const string Docs_Getting_Started_Prefix = Docs_Prefix + "/getting-started"; + public const string Docs_Getting_Started_Introduction = Docs_Getting_Started_Prefix + "/introduction"; + public const string Docs_Getting_Started_Blazor_WebAssembly_NET8 = Docs_Getting_Started_Prefix + "/blazor-webassembly-net-8"; + public const string Docs_Getting_Started_Blazor_WebApp_NET_8_Interactive_Render_Mode_Server_Global_Location = Docs_Getting_Started_Prefix + "/blazor-webapp-server-global-net-8"; + public const string Docs_Getting_Started_Blazor_WebApp_NET_8_Interactive_Render_Mode_Auto_Global_Location = Docs_Getting_Started_Prefix + "/blazor-webapp-auto-global-net-8"; + public const string Docs_Getting_Started_MAUI_NET_8 = Docs_Getting_Started_Prefix + "/maui-blazor-net-8"; + + // Charts + public const string Docs_BarChart = Docs_Prefix + "/bar-chart"; + public const string Docs_BubbleChart = Docs_Prefix + "/bubble-chart"; + public const string Docs_DoughnutChart = Docs_Prefix + "/doughnut-chart"; + public const string Docs_LineChart = Docs_Prefix + "/line-chart"; + public const string Docs_PieChart = Docs_Prefix + "/pie-chart"; + public const string Docs_PolarAreaChart = Docs_Prefix + "/polar-area-chart"; + public const string Docs_RadarChart = Docs_Prefix + "/radar-chart"; + public const string Docs_ScatterChart = Docs_Prefix + "/scatter-chart"; + + // Utils + public const string Docs_Utils_Prefix = Docs_Prefix + "/utils"; + public const string Docs_ColorUtils = Docs_Utils_Prefix + "/color-utility"; + + #endregion +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Constants/StringConstants.cs b/BlazorExpress.ChartJS.Demo.RCL/Constants/DemoStringConstants.cs similarity index 70% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Constants/StringConstants.cs rename to BlazorExpress.ChartJS.Demo.RCL/Constants/DemoStringConstants.cs index 0fc7176f..dabd9e70 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Shared/Constants/StringConstants.cs +++ b/BlazorExpress.ChartJS.Demo.RCL/Constants/DemoStringConstants.cs @@ -1,14 +1,20 @@ namespace BlazorExpress.ChartJS.Demo.RCL; -internal static class StringConstants +public static class DemoStringConstants { #region Fields and Constants + public const string NugetPackageName = "BlazorExpress.ChartJS"; + public const string NugetPackageDisplayName = "BlazorExpress ChartJS"; + + public const string PageTitle_Suffix = " | BlazorExpress ChartJS: An enterprise-grade open-source component library from the Blazor Express team."; + public const string Nullable = "Nullable"; public const string PropertyTypeNameInt16 = "Int16"; public const string PropertyTypeNameInt32 = "Int32"; public const string PropertyTypeNameInt64 = "Int64"; public const string PropertyTypeNameChar = "Char"; + public const string PropertyTypeNameStringComparison = "StringComparison"; public const string PropertyTypeNameString = "String"; public const string PropertyTypeNameSingle = "Single"; // float public const string PropertyTypeNameDecimal = "Decimal"; @@ -23,6 +29,7 @@ internal static class StringConstants public const string PropertyTypeNameInt32CSharpTypeKeyword = "int"; public const string PropertyTypeNameInt64CSharpTypeKeyword = "long"; public const string PropertyTypeNameCharCSharpTypeKeyword = "char"; + public const string PropertyTypeNameStringComparisonCSharpTypeKeyword = "StringComparison"; public const string PropertyTypeNameStringCSharpTypeKeyword = "string"; public const string PropertyTypeNameSingleCSharpTypeKeyword = "float"; public const string PropertyTypeNameDecimalCSharpTypeKeyword = "decimal"; @@ -33,5 +40,9 @@ internal static class StringConstants public const string PropertyTypeNameEnumCSharpTypeKeyword = "enum"; public const string PropertyTypeNameGuidCSharpTypeKeyword = "Guid"; + public const string StaticAssets_RootPath = "_content/BlazorExpress.ChartJS.Demo.RCL"; + public const string StaticAssets_Icons_Path = StaticAssets_RootPath + "/icons"; + public const string StaticAssets_Icons_Logo_png = StaticAssets_Icons_Path + "/logo.png"; + #endregion } diff --git a/BlazorExpress.ChartJS.Demo.RCL/Enums/DemoPageLinkCategory.cs b/BlazorExpress.ChartJS.Demo.RCL/Enums/DemoPageLinkCategory.cs new file mode 100644 index 00000000..495531cb --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Enums/DemoPageLinkCategory.cs @@ -0,0 +1,18 @@ +using System.ComponentModel; + +namespace BlazorExpress.ChartJS.Demo.RCL; + +public enum DemoPageLinkCategory +{ + [Description("All")] + All, + + [Description("Getting Started")] + GettingStarted, + + [Description("Charts")] + Charts, + + [Description("Utils")] + Utils +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Layout/BlogMainLayout.razor b/BlazorExpress.ChartJS.Demo.RCL/Layout/BlogMainLayout.razor new file mode 100644 index 00000000..cd3289b3 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/BlogMainLayout.razor @@ -0,0 +1,70 @@ +@namespace BlazorExpress.ChartJS.Demo.RCL +@inherits MainLayoutBase + + + + + + + + + + @foreach (var group in linkGroups) + { + @group.Name + if (group.Links?.Any() ?? false) + { + + @foreach (var link in group.Links) + { + + @if (link.Links?.Any() ?? false) // level 2 links + { + @link.Text + + @foreach (var cLink in link.Links) + { + @cLink.Text + } + + } + else + { + @link.Text + } + + } + + } + } + + + + +
+
+
+ + +
+
+
+
diff --git a/BlazorExpress.ChartJS.Demo.RCL/Layout/BlogMainLayout.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Layout/BlogMainLayout.razor.cs new file mode 100644 index 00000000..1b74c009 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/BlogMainLayout.razor.cs @@ -0,0 +1,88 @@ +namespace BlazorExpress.ChartJS.Demo.RCL; + +public partial class BlogMainLayout : MainLayoutBase +{ + #region Fields and Constants + + private bool isSidebarVisible = false; + private HashSet linkGroups = new(); + private Menu menuRef = default!; + + #endregion + + #region Methods + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + await JS.InvokeVoidAsync("initializeTheme"); + + await base.OnAfterRenderAsync(firstRender); + } + + protected override void OnInitialized() + { + if (!linkGroups.Any()) + linkGroups = GetLinkGroups(); + + base.OnInitialized(); + } + + private HashSet GetLinkGroups() + { + var groups = new HashSet(); + + // GETTING STARTED + groups.Add(new LinkGroup + { + Name = "Getting Started", + CssClass = "is-size-7 has-text-weight-bold has-text-danger", + Links = [ + new Link { Href = DemoRouteConstants.Docs_Getting_Started_Prefix, Text = "Getting started" } + ] + }); + + // CHARTS + groups.Add(new LinkGroup + { + Name = "Charts", + CssClass = "is-size-7 has-text-weight-bold has-text-warning", + Links = [ + new Link { Href = DemoRouteConstants.Docs_BarChart, Text = "Bar chart" }, + new Link { Href = DemoRouteConstants.Docs_DoughnutChart, Text = "Doughnut chart" }, + new Link { Href = DemoRouteConstants.Docs_LineChart, Text = "Line chart" }, + new Link { Href = DemoRouteConstants.Docs_PieChart, Text = "Pie chart" }, + new Link { Href = DemoRouteConstants.Docs_PolarAreaChart, Text = "PolarArea chart" }, + new Link { Href = DemoRouteConstants.Docs_RadarChart, Text = "Radar chart" }, + new Link { Href = DemoRouteConstants.Docs_ScatterChart, Text = "Scatter chart" } + ] + }); + + // UTILS + groups.Add(new LinkGroup + { + Name = "UTILS", + CssClass = "is-size-7 has-text-weight-bold has-text-info", + Links = [ + new Link { Href = DemoRouteConstants.Demos_ColorUtils, Text = "Color Utils" }, + ] + }); + + return groups; + } + + private Task SetAutoTheme() => SetTheme("system"); + + private Task SetDarkTheme() => SetTheme("dark"); + + private Task SetLightTheme() => SetTheme("light"); + + private async Task SetTheme(string themeName) => await JS.InvokeVoidAsync("setTheme", themeName); + + private void ToggleSidebarSection() + { + @menuRef.Toggle(); + } + + #endregion +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Layout/DemosMainLayout.razor b/BlazorExpress.ChartJS.Demo.RCL/Layout/DemosMainLayout.razor new file mode 100644 index 00000000..ff70a162 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/DemosMainLayout.razor @@ -0,0 +1,67 @@ +@namespace BlazorExpress.ChartJS.Demo.RCL +@inherits MainLayoutBase + + + + + + + + @foreach (var group in linkGroups) + { + @group.Name + if (group.Links?.Any() ?? false) + { + + @foreach (var link in group.Links) + { + + @if (link.Links?.Any() ?? false) // level 2 links + { + @link.Text + + @foreach (var cLink in link.Links) + { + @cLink.Text + } + + } + else + { + @link.Text + } + + } + + } + } + + + +
+
+
+ + +
+
+
+
diff --git a/BlazorExpress.ChartJS.Demo.RCL/Layout/DemosMainLayout.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Layout/DemosMainLayout.razor.cs new file mode 100644 index 00000000..511f36cf --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/DemosMainLayout.razor.cs @@ -0,0 +1,79 @@ +namespace BlazorExpress.ChartJS.Demo.RCL; + +public partial class DemosMainLayout : MainLayoutBase +{ + #region Fields and Constants + + private bool isSidebarVisible = false; + private HashSet linkGroups = new(); + private Menu menuRef = default!; + + #endregion + + #region Methods + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + await JS.InvokeVoidAsync("initializeTheme"); + + await base.OnAfterRenderAsync(firstRender); + } + + protected override void OnInitialized() + { + if (!linkGroups.Any()) + linkGroups = GetLinkGroups(); + + base.OnInitialized(); + } + + private HashSet GetLinkGroups() + { + var groups = new HashSet(); + + // CHARTS + groups.Add(new LinkGroup + { + Name = "Charts", + CssClass = "is-size-7 has-text-weight-bold has-text-warning", + Links = [ + new Link { Href = DemoRouteConstants.Demos_BarChart, Text = "Bar chart" }, + new Link { Href = DemoRouteConstants.Demos_BubbleChart, Text = "Bubble chart" }, + new Link { Href = DemoRouteConstants.Demos_DoughnutChart, Text = "Doughnut chart" }, + new Link { Href = DemoRouteConstants.Demos_LineChart, Text = "Line chart" }, + new Link { Href = DemoRouteConstants.Demos_PieChart, Text = "Pie chart" }, + new Link { Href = DemoRouteConstants.Demos_PolarAreaChart, Text = "PolarArea chart" }, + new Link { Href = DemoRouteConstants.Demos_RadarChart, Text = "Radar chart" }, + new Link { Href = DemoRouteConstants.Demos_ScatterChart, Text = "Scatter chart" } + ] + }); + + // UTILS + groups.Add(new LinkGroup + { + Name = "UTILS", + CssClass = "is-size-7 has-text-weight-bold has-text-info", + Links = [ + new Link { Href = DemoRouteConstants.Demos_ColorUtils, Text = "Color Utils" }, + ] + }); + + return groups; + } + + private Task SetAutoTheme() => SetTheme("system"); + + private Task SetDarkTheme() => SetTheme("dark"); + + private Task SetLightTheme() => SetTheme("light"); + + private async Task SetTheme(string themeName) => await JS.InvokeVoidAsync("setTheme", themeName); + + private void ToggleSidebarSection() + { + @menuRef.Toggle(); + } + + #endregion +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Layout/DocsMainLayout.razor b/BlazorExpress.ChartJS.Demo.RCL/Layout/DocsMainLayout.razor new file mode 100644 index 00000000..cd3289b3 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/DocsMainLayout.razor @@ -0,0 +1,70 @@ +@namespace BlazorExpress.ChartJS.Demo.RCL +@inherits MainLayoutBase + + + + + + + + + + @foreach (var group in linkGroups) + { + @group.Name + if (group.Links?.Any() ?? false) + { + + @foreach (var link in group.Links) + { + + @if (link.Links?.Any() ?? false) // level 2 links + { + @link.Text + + @foreach (var cLink in link.Links) + { + @cLink.Text + } + + } + else + { + @link.Text + } + + } + + } + } + + + + +
+
+
+ + +
+
+
+
diff --git a/BlazorExpress.ChartJS.Demo.RCL/Layout/DocsMainLayout.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Layout/DocsMainLayout.razor.cs new file mode 100644 index 00000000..a65b6f39 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/DocsMainLayout.razor.cs @@ -0,0 +1,93 @@ +namespace BlazorExpress.ChartJS.Demo.RCL; + +public partial class DocsMainLayout : MainLayoutBase +{ + #region Fields and Constants + + private bool isSidebarVisible = false; + private HashSet linkGroups = new(); + private Menu menuRef = default!; + + #endregion + + #region Methods + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + await JS.InvokeVoidAsync("initializeTheme"); + + await base.OnAfterRenderAsync(firstRender); + } + + protected override void OnInitialized() + { + if (!linkGroups.Any()) + linkGroups = GetLinkGroups(); + + base.OnInitialized(); + } + + private HashSet GetLinkGroups() + { + var groups = new HashSet(); + + // GETTING STARTED + groups.Add(new LinkGroup + { + Name = "GETTING STARTED", + CssClass = "is-size-7 has-text-weight-bold has-text-danger", + Links = [ + new Link { Href = DemoRouteConstants.Docs_Getting_Started_Introduction, Text = "Introduction" }, + new Link { Href = DemoRouteConstants.Docs_Getting_Started_Blazor_WebAssembly_NET8, Text = "Blazor WebAssembly (.NET 8)" }, + new Link { Href = DemoRouteConstants.Docs_Getting_Started_Blazor_WebApp_NET_8_Interactive_Render_Mode_Server_Global_Location, Text = "Blazor WebApp (.NET 8) Server" }, + //new Link { Href = RouteConstants.Docs_Getting_Started_WebApp_Auto_NET_8, Text = "Blazor WebApp (.NET 8) Auto" }, + //new Link { Href = RouteConstants.Docs_Getting_Started_MAUI_NET_8, Text = "MAUI Blazor Hybrid App (.NET 8)" }, + ] + }); + + // CHARTS + groups.Add(new LinkGroup + { + Name = "Charts", + CssClass = "is-size-7 has-text-weight-bold has-text-warning", + Links = [ + new Link { Href = DemoRouteConstants.Docs_BarChart, Text = "Bar chart" }, + new Link { Href = DemoRouteConstants.Docs_BubbleChart, Text = "Bubble chart" }, + new Link { Href = DemoRouteConstants.Docs_DoughnutChart, Text = "Doughnut chart" }, + new Link { Href = DemoRouteConstants.Docs_LineChart, Text = "Line chart" }, + new Link { Href = DemoRouteConstants.Docs_PieChart, Text = "Pie chart" }, + new Link { Href = DemoRouteConstants.Docs_PolarAreaChart, Text = "PolarArea chart" }, + new Link { Href = DemoRouteConstants.Docs_RadarChart, Text = "Radar chart" }, + new Link { Href = DemoRouteConstants.Docs_ScatterChart, Text = "Scatter chart" } + ] + }); + + // UTILS + groups.Add(new LinkGroup + { + Name = "UTILS", + CssClass = "is-size-7 has-text-weight-bold has-text-info", + Links = [ + new Link { Href = DemoRouteConstants.Demos_ColorUtils, Text = "Color Utils" }, + ] + }); + + return groups; + } + + private Task SetAutoTheme() => SetTheme("system"); + + private Task SetDarkTheme() => SetTheme("dark"); + + private Task SetLightTheme() => SetTheme("light"); + + private async Task SetTheme(string themeName) => await JS.InvokeVoidAsync("setTheme", themeName); + + private void ToggleSidebarSection() + { + @menuRef.Toggle(); + } + + #endregion +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Layout/EmptyLayout.razor b/BlazorExpress.ChartJS.Demo.RCL/Layout/EmptyLayout.razor new file mode 100644 index 00000000..d75560f5 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/EmptyLayout.razor @@ -0,0 +1,2 @@ +@namespace BlazroExpress.ChartJS.Demo.RCL +@inherits MainLayoutBase diff --git a/BlazorExpress.ChartJS.Demo.RCL/Layout/EmptyLayout.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Layout/EmptyLayout.razor.cs new file mode 100644 index 00000000..6e6867c1 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/EmptyLayout.razor.cs @@ -0,0 +1,5 @@ +namespace BlazroExpress.ChartJS.Demo.RCL; + +public partial class EmptyLayout : MainLayoutBase +{ +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayout.razor b/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayout.razor new file mode 100644 index 00000000..90bb5d74 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayout.razor @@ -0,0 +1,33 @@ +@namespace BlazorExpress.ChartJS.Demo.RCL +@inherits MainLayoutBase + + + + + + +
+ @Body +
+ +
+
+
+ +
+
+
+
diff --git a/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayout.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayout.razor.cs new file mode 100644 index 00000000..fc8bd82d --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayout.razor.cs @@ -0,0 +1,24 @@ +namespace BlazorExpress.ChartJS.Demo.RCL; + +public partial class MainLayout : MainLayoutBase +{ + #region Fields and Constants + + private bool isSidebarVisible = false; + //private HashSet linkGroups = new(); + private Menu menuRef = default!; + + #endregion + + #region Methods + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + await JS.InvokeVoidAsync("initializeTheme"); + + await base.OnAfterRenderAsync(firstRender); + } + + #endregion +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/EmptyLayout.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayoutBase.cs similarity index 55% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Layout/EmptyLayout.razor.cs rename to BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayoutBase.cs index 228bb3ff..c3a44451 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/EmptyLayout.razor.cs +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayoutBase.cs @@ -1,12 +1,13 @@ -namespace BlazroExpress.ChartJS.Demo.RCL; +namespace BlazorExpress.ChartJS.Demo.RCL; -public partial class EmptyLayout : LayoutComponentBase +public class MainLayoutBase : LayoutComponentBase { private string version = default!; - private string homeUrl = default!; + private string dotNetVersion = default!; private string docsUrl = default!; private string blogUrl = default!; private string githubUrl = default!; + private string nugetUrl = default!; private string twitterUrl = default!; private string linkedInUrl = default!; private string openCollectiveUrl = default!; @@ -16,20 +17,34 @@ public partial class EmptyLayout : LayoutComponentBase [Inject] public IConfiguration Configuration { get; set; } = default!; + [Inject] protected IJSRuntime JS { get; set; } = default!; + protected override void OnInitialized() { version = $"v{Configuration["version"]}"; // example: v0.6.1 - homeUrl = $"{Configuration["urls:homeUrl"]}"; + dotNetVersion = $".NET {Configuration["dotNetVersion"]}"; // example: 9.0.0 docsUrl = $"{Configuration["urls:docs"]}"; blogUrl = $"{Configuration["urls:blog"]}"; githubUrl = $"{Configuration["urls:github"]}"; + nugetUrl = $"{Configuration["urls:nuget"]}"; twitterUrl = $"{Configuration["urls:twitter"]}"; linkedInUrl = $"{Configuration["urls:linkedin"]}"; openCollectiveUrl = $"{Configuration["urls:opencollective"]}"; githubIssuesUrl = $"{Configuration["urls:github_issues"]}"; githubDiscussionsUrl = $"{Configuration["urls:github_discussions"]}"; stackoverflowUrl = $"{Configuration["urls:stackoverflow"]}"; - - base.OnInitialized(); } + + public string Version => version; + public string DotNetVersion => dotNetVersion; + public string DocsUrl => docsUrl; + public string BlogUrl => blogUrl; + public string GithubUrl => githubUrl; + public string NuGetUrl => nugetUrl; + public string TwitterUrl => twitterUrl; + public string LinkedInUrl => linkedInUrl; + public string OpenCollectiveUrl => openCollectiveUrl; + public string GithubIssuesUrl => githubIssuesUrl; + public string GithubDiscussionsUrl => githubDiscussionsUrl; + public string StackoverflowUrl => stackoverflowUrl; } diff --git a/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayoutBaseFooter.razor b/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayoutBaseFooter.razor new file mode 100644 index 00000000..d706ada0 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayoutBaseFooter.razor @@ -0,0 +1,57 @@ +@namespace BlazorExpress.ChartJS.Demo.RCL +@inherits ComponentBase + + \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBaseFooter.razor.cs b/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayoutBaseFooter.razor.cs similarity index 85% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBaseFooter.razor.cs rename to BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayoutBaseFooter.razor.cs index aaa22b08..c76c13d7 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Layout/MainLayoutBaseFooter.razor.cs +++ b/BlazorExpress.ChartJS.Demo.RCL/Layout/MainLayoutBaseFooter.razor.cs @@ -3,10 +3,11 @@ public partial class MainLayoutBaseFooter : ComponentBase { [Parameter] public string? Version { get; set; } - [Parameter] public string? HomeUrl { get; set; } + [Parameter] public string? DotNetVersion { get; set; } [Parameter] public string? DocsUrl { get; set; } [Parameter] public string? BlogUrl { get; set; } [Parameter] public string? GithubUrl { get; set; } + [Parameter] public string? NugetUrl { get; set; } [Parameter] public string? TwitterUrl { get; set; } [Parameter] public string? LinkedInUrl { get; set; } [Parameter] public string? OpenCollectiveUrl { get; set; } diff --git a/BlazorExpress.ChartJS.Demo.RCL/Models/PageLink.cs b/BlazorExpress.ChartJS.Demo.RCL/Models/PageLink.cs new file mode 100644 index 00000000..cfabc651 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Models/PageLink.cs @@ -0,0 +1,16 @@ +using BlazorExpress.Bulma.Docx; + +namespace BlazorExpress.ChartJS.Demo.RCL; + +public class PageLink +{ + public int Id { get; set; } + public BootstrapIconName IconName { get; set; } = default!; + public string Href { get; set; } = default!; + public string Text { get; set; } = default!; + public int SortOrder { get; set; } + public HashSet Categories { get; set; } = new(); + public PageLinkStatus Status { get; set; } + public bool IsActive { get; set; } + public bool ExcludedFromHomePage { get; set; } = false; +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChartDocumentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChartDocumentation.razor new file mode 100644 index 00000000..203605bd --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChartDocumentation.razor @@ -0,0 +1,102 @@ +@attribute [Route(pageUrl)] +@attribute [Route(pageUrl2)] +@layout DemosMainLayout + + + + + + @((MarkupString)pageDescription) + + + + + + + +
+ + The Bar Chart component visualizes data as vertical bars, making it easy to compare values across categories or track changes over time. +

+ How to use: +
    +
  • Add the BarChart component to your page.
  • +
  • Provide Labels for the X-axis categories and one or more Datasets for the Y-axis values.
  • +
  • Customize appearance and behavior using the Options property (e.g., colors, tooltips, axis settings).
  • +
  • Refer to the demo code for examples of basic and advanced usage, including multiple datasets and custom styling.
  • +
+ This demo showcases the essential setup for a bar chart and demonstrates how to bind your data for quick visualization. +
+ +
+ +
+ + The Horizontal Bar Chart displays data values as horizontal bars, making it ideal for comparing categories with long labels or when you want to emphasize comparison between values. +

+ How to use: +
    +
  • Use the BarChart component and set the IndexAxis option to 'y' to render bars horizontally.
  • +
  • Provide your data and labels as you would for a standard bar chart.
  • +
  • Customize colors and appearance using the available palette utilities or your own color set.
  • +
+ Refer to the demo code below for a working example and configuration options. +
+ +
+ +
+ + The Stacked Bar Chart allows you to display multiple data series stacked on top of each other, making it easy to compare the total and individual contributions of each series for every category. +

+ How to use: +
    +
  • Use the BarChart component and configure the Options.Scales.X.Stacked and Options.Scales.Y.Stacked properties to true to enable stacking.
  • +
  • Provide multiple datasets in your chart data, each representing a different series to be stacked.
  • +
  • Customize colors for each dataset using palette utilities or your own color set for better distinction.
  • +
  • Refer to the demo code below for a working example and further configuration options.
  • +
+
+ +
+ +
+ + The Stacked Bar Chart with Data Labels enhances the standard stacked bar chart by displaying value labels directly on each bar segment. This makes it easier to read and compare the values of each dataset within a category. +

+ How to use: +
    +
  • Use the BarChart component and enable stacking by setting Options.Scales.X.Stacked and Options.Scales.Y.Stacked to true.
  • +
  • Add multiple datasets to your chart data to represent different series.
  • +
  • Enable data labels by configuring the chart's plugins, such as Options.Plugins.Datalabels.Display = true.
  • +
  • Customize the appearance and formatting of data labels as needed for your scenario.
  • +
+ Refer to the demo code below for a working example and further configuration options. +
+ +
+ +
+ + The Locale demo shows how to localize number and date formatting in your bar chart. +

+ How to use: +
    +
  • Set the Locale property on the BarChart component to your desired culture code (e.g., "fr-FR" for French).
  • +
  • Number and date labels in the chart will automatically format according to the specified locale.
  • +
  • This is useful for displaying charts to users in different regions with appropriate formatting.
  • +
+ Refer to the demo code below for a working example and configuration options. +
+ +
+ +@code { + private const string pageUrl = DemoRouteConstants.Demos_BarChart; + private const string pageUrl2 = DemoRouteConstants.Demos_Prefix; + private const string pageTitle = "Bar Chart"; + private const string pageDescription = "The Blazor Bar Chart component displays data values as vertical bars, making it easy to compare multiple data sets or visualize trends over time."; + private const string metaTitle = "Blazor Bar Chart"; + private const string metaDescription = "The Blazor Bar Chart component displays data values as vertical bars, making it easy to compare multiple data sets or visualize trends over time."; + private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; // TODO: update with the actual image URL for the Bar Chart demo +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_01_Examples.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_01_Examples.razor similarity index 80% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_01_Examples.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_01_Examples.razor index 0a462d75..c66b5d30 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_01_Examples.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_01_Examples.razor @@ -1,11 +1,11 @@
- - - - - + + + + +
@code { @@ -47,7 +47,7 @@ { var count = barChartDataset.Data.Count; - var newData = new List(); + var newData = new List(); for (var i = 0; i < count; i++) { newData.Add(random.Next(200)); @@ -125,18 +125,18 @@ datasetsCount += 1; return new BarChartDataset() - { - Label = $"Product {datasetsCount}", - Data = GetRandomData(), - BackgroundColor = new List { c.ToRgbString() }, - BorderColor = new List { c.ToRgbString() }, - BorderWidth = new List { 0 }, - }; + { + Label = $"Product {datasetsCount}", + Data = GetRandomData(), + BackgroundColor = new List { c.ToRgbString() }, + BorderColor = new List { c.ToRgbString() }, + BorderWidth = new List { 0 }, + }; } - private List GetRandomData() + private List GetRandomData() { - var data = new List(); + var data = new List(); for (var index = 0; index < labelsCount; index++) { data.Add(random.Next(200)); diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_02_Horizontal_BarChart.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_02_Horizontal_BarChart.razor similarity index 80% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_02_Horizontal_BarChart.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_02_Horizontal_BarChart.razor index 213700cc..6ec4123f 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_02_Horizontal_BarChart.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_02_Horizontal_BarChart.razor @@ -11,12 +11,12 @@ var datasets = new List(); var dataset1 = new BarChartDataset() - { - Data = new List { 55000, 15000, 18000, 21000 }, - BackgroundColor = new List { ColorUtility.CategoricalTwelveColors[0] }, - BorderColor = new List { ColorUtility.CategoricalTwelveColors[0] }, - BorderWidth = new List { 0 }, - }; + { + Data = new List { 55000, 15000, 18000, 21000 }, + BackgroundColor = new List { ColorUtility.CategoricalTwelveColors[0] }, + BorderColor = new List { ColorUtility.CategoricalTwelveColors[0] }, + BorderWidth = new List { 0 }, + }; datasets.Add(dataset1); chartData = new ChartData { Labels = labels, Datasets = datasets }; diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_03_Stacked_BarChart.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_03_Stacked_BarChart.razor similarity index 63% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_03_Stacked_BarChart.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_03_Stacked_BarChart.razor index 1b1b5515..0b98e51b 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_03_Stacked_BarChart.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_03_Stacked_BarChart.razor @@ -13,33 +13,33 @@ var datasets = new List(); var dataset1 = new BarChartDataset() - { - Label = "Windows", - Data = new List { 28000, 8000, 2000, 17000 }, - BackgroundColor = new List { colors[0] }, - BorderColor = new List { colors[0] }, - BorderWidth = new List { 0 }, - }; + { + Label = "Windows", + Data = new List { 28000, 8000, 2000, 17000 }, + BackgroundColor = new List { colors[0] }, + BorderColor = new List { colors[0] }, + BorderWidth = new List { 0 }, + }; datasets.Add(dataset1); var dataset2 = new BarChartDataset() - { - Label = "macOS", - Data = new List { 8000, 10000, 14000, 8000 }, - BackgroundColor = new List { colors[1] }, - BorderColor = new List { colors[1] }, - BorderWidth = new List { 0 }, - }; + { + Label = "macOS", + Data = new List { 8000, 10000, 14000, 8000 }, + BackgroundColor = new List { colors[1] }, + BorderColor = new List { colors[1] }, + BorderWidth = new List { 0 }, + }; datasets.Add(dataset2); var dataset3 = new BarChartDataset() - { - Label = "Other", - Data = new List { 28000, 10000, 14000, 8000 }, - BackgroundColor = new List { colors[2] }, - BorderColor = new List { colors[2] }, - BorderWidth = new List { 0 }, - }; + { + Label = "Other", + Data = new List { 28000, 10000, 14000, 8000 }, + BackgroundColor = new List { colors[2] }, + BorderColor = new List { colors[2] }, + BorderWidth = new List { 0 }, + }; datasets.Add(dataset3); chartData = new ChartData { Labels = labels, Datasets = datasets }; diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_04_Stacked_BarChart_with_Datalabels.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_04_Stacked_BarChart_with_Datalabels.razor similarity index 62% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_04_Stacked_BarChart_with_Datalabels.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_04_Stacked_BarChart_with_Datalabels.razor index 06746562..60e6fdce 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_04_Stacked_BarChart_with_Datalabels.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_04_Stacked_BarChart_with_Datalabels.razor @@ -13,40 +13,40 @@ var datasets = new List(); var dataset1 = new BarChartDataset() - { - Label = "Windows", - Data = new List { 28000, 8000, 2000, 17000 }, - BackgroundColor = new List { colors[0] }, - BorderColor = new List { colors[0] }, - BorderWidth = new List { 0 }, - }; + { + Label = "Windows", + Data = new List { 28000, 8000, 2000, 17000 }, + BackgroundColor = new List { colors[0] }, + BorderColor = new List { colors[0] }, + BorderWidth = new List { 0 }, + }; datasets.Add(dataset1); var dataset2 = new BarChartDataset() - { - Label = "macOS", - Data = new List { 8000, 10000, 14000, 8000 }, - BackgroundColor = new List { colors[1] }, - BorderColor = new List { colors[1] }, - BorderWidth = new List { 0 }, - }; + { + Label = "macOS", + Data = new List { 8000, 10000, 14000, 8000 }, + BackgroundColor = new List { colors[1] }, + BorderColor = new List { colors[1] }, + BorderWidth = new List { 0 }, + }; datasets.Add(dataset2); var dataset3 = new BarChartDataset() - { - Label = "Other", - Data = new List { 28000, 10000, 14000, 8000 }, - BackgroundColor = new List { colors[2] }, - BorderColor = new List { colors[2] }, - BorderWidth = new List { 0 }, - }; + { + Label = "Other", + Data = new List { 28000, 10000, 14000, 8000 }, + BackgroundColor = new List { colors[2] }, + BorderColor = new List { colors[2] }, + BorderWidth = new List { 0 }, + }; datasets.Add(dataset3); chartData = new ChartData - { - Labels = labels, - Datasets = datasets - }; + { + Labels = labels, + Datasets = datasets + }; barChartOptions = new(); barChartOptions.Responsive = true; diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_05_Locale.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_05_Locale.razor similarity index 63% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_05_Locale.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_05_Locale.razor index 28b1c2c7..5f9a8d4f 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/BarCharts/BarChart_Demo_05_Locale.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BarChart/BarChart_Demo_05_Locale.razor @@ -13,33 +13,33 @@ var datasets = new List(); var dataset1 = new BarChartDataset() - { - Label = "Windows", - Data = new List { 28000, 8000, 2000, 17000 }, - BackgroundColor = new List { colors[0] }, - BorderColor = new List { colors[0] }, - BorderWidth = new List { 0 }, - }; + { + Label = "Windows", + Data = new List { 28000, 8000, 2000, 17000 }, + BackgroundColor = new List { colors[0] }, + BorderColor = new List { colors[0] }, + BorderWidth = new List { 0 }, + }; datasets.Add(dataset1); var dataset2 = new BarChartDataset() - { - Label = "macOS", - Data = new List { 8000, 10000, 14000, 8000 }, - BackgroundColor = new List { colors[1] }, - BorderColor = new List { colors[1] }, - BorderWidth = new List { 0 }, - }; + { + Label = "macOS", + Data = new List { 8000, 10000, 14000, 8000 }, + BackgroundColor = new List { colors[1] }, + BorderColor = new List { colors[1] }, + BorderWidth = new List { 0 }, + }; datasets.Add(dataset2); var dataset3 = new BarChartDataset() - { - Label = "Other", - Data = new List { 28000, 10000, 14000, 8000 }, - BackgroundColor = new List { colors[2] }, - BorderColor = new List { colors[2] }, - BorderWidth = new List { 0 }, - }; + { + Label = "Other", + Data = new List { 28000, 10000, 14000, 8000 }, + BackgroundColor = new List { colors[2] }, + BorderColor = new List { colors[2] }, + BorderWidth = new List { 0 }, + }; datasets.Add(dataset3); chartData = new ChartData { Labels = labels, Datasets = datasets }; diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BubbleChart/BubbleChartDocumentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BubbleChart/BubbleChartDocumentation.razor new file mode 100644 index 00000000..bceda2a1 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BubbleChart/BubbleChartDocumentation.razor @@ -0,0 +1,42 @@ +@attribute [Route(pageUrl)] +@layout DemosMainLayout + + + + + + @((MarkupString)pageDescription) + + + + + + + +
+ + The Bubble Chart component visualizes three dimensions of data by displaying each data point as a bubble, where the X and Y coordinates determine the position and the bubble size represents a third value. This makes it ideal for comparing and analyzing relationships between multiple variables. + +

+ How to use: +
    +
  • Add the BubbleChart component to your page and set its desired Width (e.g., Width="600").
  • +
  • Prepare your ChartData with Labels for the X-axis and one or more BubbleChartDataset objects, each containing a list of BubbleChartDataPoint (with X, Y, and R values).
  • +
  • Configure chart appearance and behavior using BubbleChartOptions (e.g., responsiveness, tooltips, axis settings).
  • +
  • Initialize the chart by calling InitializeAsync with your data and options.
  • +
  • Use built-in methods such as AddDatasetAsync, AddDataAsync, and UpdateAsync to dynamically update the chart as shown in the demo.
  • +
  • Refer to the demo code below for practical examples, including adding datasets, randomizing data, and customizing chart styles.
  • +
+ This demo provides a hands-on example of setting up a Bubble Chart in Blazor, demonstrating how to bind and update your data for interactive visualizations. +
+ +
+ +@code { + private const string pageUrl = DemoRouteConstants.Demos_BubbleChart; + private const string pageTitle = "Bubble Chart"; + private const string pageDescription = "The Blazor Bubble Chart component is used to display three dimensions of data at the same time. The location of the bubble is determined by the first two dimensions and the corresponding horizontal and vertical axes. The third dimension is represented by the size of the individual bubbles."; + private const string metaTitle = "Blazor Bubble Chart"; + private const string metaDescription = "The Blazor Bubble Chart component is used to display three dimensions of data at the same time. The location of the bubble is determined by the first two dimensions and the corresponding horizontal and vertical axes. The third dimension is represented by the size of the individual bubbles."; + private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; // TODO: update with the actual image URL for the Bar Chart demo +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BubbleChart/BubbleChart_Demo_01_Examples.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BubbleChart/BubbleChart_Demo_01_Examples.razor new file mode 100644 index 00000000..b4e76221 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/BubbleChart/BubbleChart_Demo_01_Examples.razor @@ -0,0 +1,153 @@ + + +
+ + + +
+ +@code { + private BubbleChart bubbleChart = default!; + private BubbleChartOptions bubbleChartOptions = default!; + private ChartData chartData = default!; + + private int datasetsCount = 0; + private int labelsCount = 0; + private string[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + private Random random = new(); + + protected override void OnInitialized() + { + chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; + bubbleChartOptions = new BubbleChartOptions { Responsive = true }; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await bubbleChart.InitializeAsync(chartData, bubbleChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } + + private async Task RandomizeAsync() + { + if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return; + + var newDatasets = new List(); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is BubbleChartDataset bubbleChartDataset + && bubbleChartDataset is not null + && bubbleChartDataset.Data is not null) + { + var count = bubbleChartDataset.Data.Count; + + var newData = new List(); + for (var i = 0; i < count; i++) + { + newData.Add(NewBubbleChartDataPoint); + } + + bubbleChartDataset.Data = newData; + newDatasets.Add(bubbleChartDataset); + } + } + + chartData.Datasets = newDatasets; + + await bubbleChart.UpdateAsync(chartData, bubbleChartOptions); + } + + private async Task AddDatasetAsync() + { + if (chartData is null || chartData.Datasets is null) return; + + if (datasetsCount >= 12) + return; + + var chartDataset = GetRandomBarChartDataset(); + chartData = await bubbleChart.AddDatasetAsync(chartData, chartDataset, bubbleChartOptions); + } + + private async Task AddDataAsync() + { + if (chartData is null || chartData.Datasets is null) + return; + + if (labelsCount >= 12) + return; + + var data = new List(); + foreach (var dataset in chartData.Datasets) + { + if (dataset is BubbleChartDataset barChartDataset) + data.Add(new BubbleChartDatasetData(barChartDataset.Label, NewBubbleChartDataPoint)); + } + + chartData = await bubbleChart.AddDataAsync(chartData, GetNextDataLabel(), data); + } + + #region Data Preparation + + private List GetDefaultDataSets(int numberOfDatasets) + { + var datasets = new List(); + + for (var index = 0; index < numberOfDatasets; index++) + { + datasets.Add(GetRandomBarChartDataset()); + } + + return datasets; + } + + private BubbleChartDataset GetRandomBarChartDataset() + { + var c = ColorUtility.CategoricalTwelveColors[datasetsCount].ToColor(); + + datasetsCount += 1; + + return new BubbleChartDataset() + { + Label = $"Product {datasetsCount}", + Data = GetRandomData(), + BackgroundColor = new List { c.ToRgbString() }, + BorderColor = new List { c.ToRgbString() }, + BorderWidth = 3, + }; + } + + private List GetRandomData() + { + var data = new List(labelsCount); + for (var i = 0; i < labelsCount; i++) + { + data.Add(NewBubbleChartDataPoint); + } + return data; + } + + private List GetDefaultDataLabels(int numberOfLabels) + { + var labels = new List(); + for (var index = 0; index < numberOfLabels; index++) + { + labels.Add(GetNextDataLabel()); + } + + return labels; + } + + private string GetNextDataLabel() + { + labelsCount += 1; + return months[labelsCount - 1]; + } + + private BubbleChartDataPoint NewBubbleChartDataPoint => new(X: random.Next(40), Y: random.Next(40), R: random.Next(10)); + + #endregion Data Preparation +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/DoughnutChart/DoughnutChartDocumentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/DoughnutChart/DoughnutChartDocumentation.razor new file mode 100644 index 00000000..74140307 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/DoughnutChart/DoughnutChartDocumentation.razor @@ -0,0 +1,56 @@ +@attribute [Route(pageUrl)] +@layout DemosMainLayout + + + + + + @((MarkupString)pageDescription) + + + + + + + +
+ + The Doughnut Chart component provides a simple way to visualize categorical data as proportional segments of a circle. +

+ How to use: +
    +
  • Add the DoughnutChart component to your page.
  • +
  • Define your data and labels using the chart's data model.
  • +
  • Customize appearance and behavior using the Options property (e.g., colors, legend, tooltips).
  • +
  • Bind your data and options to the component.
  • +
  • Refer to the demo code below for a working example and further customization options.
  • +
+ This demo shows how to configure a basic doughnut chart, assign data, and adjust chart options for your scenario. +
+ +
+ +
+ + The Doughnut Chart component supports data labels, allowing you to display values or category names directly on each segment of the chart. +

+ How to use: +
    +
  • Enable data labels by configuring the chart's plugin options, such as Options.Plugins.Datalabels.Display = true.
  • +
  • You can customize the label content, formatting, and position using the available plugin settings.
  • +
  • Assign your data and labels as usual to the chart's data model.
  • +
  • Refer to the demo code below for a working example and further configuration options.
  • +
+ Data labels make it easier for users to interpret the chart by showing relevant information directly on each doughnut segment. +
+ +
+ +@code { + private const string pageUrl = DemoRouteConstants.Demos_DoughnutChart; + private const string pageTitle = "Doughnut Chart"; + private const string pageDescription = "Explore interactive Blazor Doughnut Chart demos with real-world examples. Learn how to visualize data, customize chart options, and implement data labels using the Blazor Doughnut Chart component."; + private const string metaTitle = "Blazor Doughnut Chart Demo & Examples"; + private const string metaDescription = "Explore interactive Blazor Doughnut Chart demos with real-world examples. Learn how to visualize data, customize chart options, and implement data labels using the Blazor Doughnut Chart component."; + private const string imageUrl = "https://i.imgur.com/xEPhAsW.png"; // TODO: Update with the actual image URL for the Doughnut Chart demo +} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChart_Demo_01_Examples.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/DoughnutChart/DoughnutChart_Demo_01_Examples.razor similarity index 90% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChart_Demo_01_Examples.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/DoughnutChart/DoughnutChart_Demo_01_Examples.razor index 041cfd43..5f1bbd5b 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChart_Demo_01_Examples.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/DoughnutChart/DoughnutChart_Demo_01_Examples.razor @@ -1,9 +1,9 @@
- - - + + +
@code { @@ -51,7 +51,7 @@ { var count = doughnutChartDataset.Data.Count; - var newData = new List(); + var newData = new List(); for (var i = 0; i < count; i++) { newData.Add(random.Next(0, 100)); @@ -117,9 +117,9 @@ return new() { Label = $"Team {datasetsCount}", Data = GetRandomData(), BackgroundColor = GetRandomBackgroundColors() }; } - private List GetRandomData() + private List GetRandomData() { - var data = new List(); + var data = new List(); for (var index = 0; index < dataLabelsCount; index++) { data.Add(random.Next(0, 100)); diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChart_Demo_02_Datalabels.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/DoughnutChart/DoughnutChart_Demo_02_Datalabels.razor similarity index 59% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChart_Demo_02_Datalabels.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/DoughnutChart/DoughnutChart_Demo_02_Datalabels.razor index c4a6741a..07a6ff48 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/DoughnutCharts/DoughnutChart_Demo_02_Datalabels.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/DoughnutChart/DoughnutChart_Demo_02_Datalabels.razor @@ -1,4 +1,3 @@ -@using BlazorExpress.ChartJS.Enums @code { @@ -33,6 +32,58 @@ await base.OnAfterRenderAsync(firstRender); } + private async Task RandomizeAsync() + { + if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return; + + var newDatasets = new List(); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is DoughnutChartDataset doughnutChartDataset + && doughnutChartDataset is not null + && doughnutChartDataset.Data is not null) + { + var count = doughnutChartDataset.Data.Count; + + var newData = new List(); + for (var i = 0; i < count; i++) + { + newData.Add(random.Next(0, 100)); + } + + doughnutChartDataset.Data = newData; + newDatasets.Add(doughnutChartDataset); + } + } + + chartData.Datasets = newDatasets; + + await doughnutChart.UpdateAsync(chartData: chartData, chartOptions: doughnutChartOptions); + } + + private async Task AddDataAsync() + { + if (dataLabelsCount >= 12) + return; + + if (chartData is null || chartData.Datasets is null) + return; + + var data = new List(); + foreach (var dataset in chartData.Datasets) + { + if (dataset is DoughnutChartDataset doughnutChartDataset) + { + data.Add(new DoughnutChartDatasetData(doughnutChartDataset.Label, random.Next(0, 100), backgroundColors![dataLabelsCount])); + } + } + + chartData = await doughnutChart.AddDataAsync(chartData, GetNextDataLabel(), data); + + dataLabelsCount += 1; + } + #region Data Preparation private List GetDefaultDataSets(int numberOfDatasets) @@ -44,11 +95,11 @@ var dataset = GetRandomDoughnutChartDataset(); if (index == 0) - dataset.Datalabels.Anchor = Anchor.End; + dataset.Datalabels.Anchor = DataLabelAnchor.End; else if (index == numberOfDatasets - 1) - dataset.Datalabels.Anchor = Anchor.Start; + dataset.Datalabels.Anchor = DataLabelAnchor.Start; else - dataset.Datalabels.Anchor = Anchor.Center; + dataset.Datalabels.Anchor = DataLabelAnchor.Center; datasets.Add(dataset); } @@ -62,9 +113,9 @@ return new() { Label = $"Team {datasetsCount}", Data = GetRandomData(), BackgroundColor = GetRandomBackgroundColors() }; } - private List GetRandomData() + private List GetRandomData() { - var data = new List(); + var data = new List(); for (var index = 0; index < dataLabelsCount; index++) { data.Add(random.Next(0, 100)); diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChartDocumentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChartDocumentation.razor new file mode 100644 index 00000000..19ef67cc --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChartDocumentation.razor @@ -0,0 +1,93 @@ +@attribute [Route(pageUrl)] +@layout DemosMainLayout + + + + + + @((MarkupString)pageDescription) + + + + + + + +
+ + The Line Chart component visualizes data trends using connected data points, making it ideal for tracking changes over time or comparing multiple series. +

+ How to use: +
    +
  • Define your chart data by specifying Labels for the X-axis and one or more Datasets for the Y-axis values.
  • +
  • Customize the chart appearance and behavior using the Options property (e.g., colors, line styles, tooltips, axis settings).
  • +
  • Add the LineChart component to your page and bind your data and options.
  • +
  • Refer to the demo code below for examples of basic usage, advanced customization, and dynamic updates.
  • +
+ These demos demonstrate how to set up a line chart, configure its appearance, and update the data or options to fit your application's needs. +
+ + +

+ You can further enhance your charts by updating datasets, changing styles, or handling chart events. Review the demo code for practical scenarios and copy the relevant parts into your own project to get started quickly. +

+
+ +
+ +
+ + The Line Chart component supports data labels, allowing you to display values directly on each data point in the chart. +

+ How to use: +
    +
  • Enable data labels by setting Options.Plugins.Datalabels.Display = true in your chart options.
  • +
  • Customize the label content, formatting, and position using the available plugin settings.
  • +
  • Bind your data and labels to the chart as usual.
  • +
  • Refer to the demo code below for a working example and further configuration options.
  • +
+ Data labels make it easier for users to interpret the chart by showing the exact value of each point directly on the line. +
+ +
+ +
+ + The Tick Configuration demo shows how to customize the appearance and behavior of axis ticks in the Line Chart component. +

+ How to use: +
    +
  • Use the Options.Scales.X.Ticks and Options.Scales.Y.Ticks properties to control tick display, such as step size, min/max values, and formatting.
  • +
  • You can format tick labels, hide or show specific ticks, and adjust their appearance to improve chart readability.
  • +
  • Apply custom logic for tick callbacks to display values in a specific format (e.g., currency, percentage).
  • +
  • Refer to the demo code below for practical examples of configuring axis ticks for your data visualization needs.
  • +
+ Customizing tick configuration helps ensure your chart is clear and tailored to your application's requirements. +
+ +
+ +
+ + The Locale demo illustrates how to localize number and date formatting in the Line Chart component to match your users' regional preferences. +

+ How to use: +
    +
  • Set the Locale property on the LineChart component to your desired culture code (e.g., "de-DE" for German).
  • +
  • All number and date labels in the chart will automatically format according to the specified locale, ensuring correct separators, symbols, and date formats.
  • +
  • This is especially useful for applications targeting users in different regions, providing a familiar and accessible data presentation.
  • +
  • Refer to the demo code below for a working example and additional configuration options.
  • +
+ Adapting the chart's locale improves usability and ensures your data is presented in a way that aligns with your audience's expectations. +
+ +
+ +@code { + private const string pageUrl = DemoRouteConstants.Demos_LineChart; + private const string pageTitle = "Line Chart"; + private const string pageDescription = "Explore interactive Blazor Line Chart examples with source code. Learn how to visualize time-series data, customize chart appearance, and enhance your Blazor applications. Try live demos and discover practical usage scenarios for the Line Chart component."; + private const string metaTitle = "Blazor Line Chart Examples & Interactive Demos"; + private const string metaDescription = "Explore interactive Blazor Line Chart examples with source code. Learn how to visualize time-series data, customize chart appearance, and enhance your Blazor applications. Try live demos and discover practical usage scenarios for the Line Chart component."; + private const string imageUrl = "https://i.imgur.com/8b7jH0D.png"; // TODO: Update with the actual image URL for the Line Chart demo +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_01_A_Examples.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_01_A_Examples.razor similarity index 84% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_01_A_Examples.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_01_A_Examples.razor index e79839f6..f56da685 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_01_A_Examples.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_01_A_Examples.razor @@ -21,7 +21,12 @@ protected override void OnInitialized() { chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; - lineChartOptions = new() { Responsive = true, Interaction = new Interaction { Mode = InteractionMode.Index } }; + lineChartOptions = new() + { + IndexAxis = "x", + Interaction = new Interaction { Mode = InteractionMode.Index, Intersect = false }, + Responsive = true, + }; } protected override async Task OnAfterRenderAsync(bool firstRender) @@ -47,7 +52,7 @@ { var count = lineChartDataset.Data.Count; - var newData = new List(); + var newData = new List(); for (var i = 0; i < count; i++) { newData.Add(random.Next(200)); @@ -119,22 +124,19 @@ datasetsCount += 1; return new LineChartDataset - { - Label = $"Team {datasetsCount}", - Data = GetRandomData(), - BackgroundColor = new List { c.ToRgbString() }, - BorderColor = new List { c.ToRgbString() }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { c.ToRgbString() }, - PointRadius = new List { 0 }, // hide points - PointHoverRadius = new List { 4 } - }; + { + Label = $"Team {datasetsCount}", + Data = GetRandomData(), + BackgroundColor = c.ToRgbaString(), + BorderColor = c.ToRgbString(), + PointRadius = new List { 5 }, + PointHoverRadius = new List { 8 }, + }; } - private List GetRandomData() + private List GetRandomData() { - var data = new List(); + var data = new List(); for (var index = 0; index < labelsCount; index++) { data.Add(random.Next(200)); @@ -161,5 +163,4 @@ } #endregion Data Preparation - } \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_01_B_Examples.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_01_B_Examples.razor new file mode 100644 index 00000000..c0491ad3 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_01_B_Examples.razor @@ -0,0 +1,78 @@ + + +@code { + private LineChart lineChart = default!; + private LineChartOptions lineChartOptions = default!; + private ChartData chartData = default!; + + protected override void OnInitialized() + { + var colors = ColorUtility.CategoricalTwelveColors; + + var labels = new List { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + var datasets = new List(); + + var dataset1 = new LineChartDataset + { + Label = "Windows", + Data = new List { 7265791, 5899643, 6317759, 6315641, 5338211, 8496306, 7568556, 8538933, 8274297, 8657298, 7548388, 7764845 }, + BackgroundColor = colors[0], + BorderColor = colors[0], + BorderWidth = 2, + HoverBorderWidth = 4, + // PointBackgroundColor = colors[0], + // PointRadius = 0, // hide points + // PointHoverRadius = 4, + }; + datasets.Add(dataset1); + + var dataset2 = new LineChartDataset + { + Label = "macOS", + Data = new List { 1809499, 1816642, 2122410, 1809499, 1850793, 1846743, 1954797, 2391313, 1983430, 2469918, 2633303, 2821149 }, + BackgroundColor = colors[1], + BorderColor = colors[1], + BorderWidth = 2, + HoverBorderWidth = 4, + // PointBackgroundColor = colors[1], + // PointRadius = 0, // hide points + // PointHoverRadius = 4, + }; + datasets.Add(dataset2); + + var dataset3 = new LineChartDataset + { + Label = "Other", + Data = new List { 1081241, 1100363, 1118136, 1073255, 1120315, 1395736, 1488788, 1489466, 1489947, 1414739, 1735811, 1820171 }, + BackgroundColor = colors[2], + BorderColor = colors[2], + BorderWidth = 2, + HoverBorderWidth = 4, + // PointBackgroundColor = colors[2], + // PointRadius = 0, // hide points + // PointHoverRadius = 4, + }; + datasets.Add(dataset3); + + chartData = new ChartData { Labels = labels, Datasets = datasets }; + + lineChartOptions = new(); + lineChartOptions.Responsive = true; + lineChartOptions.Interaction = new Interaction { Mode = InteractionMode.Index }; + + lineChartOptions.Scales.X!.Title = new ChartAxesTitle { Text = "2019", Display = true }; + lineChartOptions.Scales.Y!.Title = new ChartAxesTitle { Text = "Visitors", Display = true }; + + lineChartOptions.Plugins.Title!.Text = "Operating system"; + lineChartOptions.Plugins.Title.Display = true; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await lineChart.InitializeAsync(chartData, lineChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } +} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_02_Datalabels.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_02_Datalabels.razor new file mode 100644 index 00000000..3083481b --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_02_Datalabels.razor @@ -0,0 +1,95 @@ + + +@code { + private LineChart lineChart = default!; + private LineChartOptions lineChartOptions = default!; + private ChartData chartData = default!; + + protected override void OnInitialized() + { + var colors = ColorUtility.CategoricalTwelveColors; + + var labels = new List { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + var datasets = new List(); + + var dataset1 = new LineChartDataset + { + Label = "Windows", + Data = new List { 7265791, 5899643, 6317759, 6315641, 5338211, 8496306, 7568556, 8538933, 8274297, 8657298, 7548388, 7764845 }, + BackgroundColor = colors[0], + BorderColor = colors[0], + BorderWidth = 2, + HoverBorderWidth = 4, + // PointBackgroundColor = colors[0], + // PointRadius = 3, // show points + // PointHoverRadius = 4, + + // datalabels + Datalabels = new() { Alignment = DataLabelAlignment.End, Anchor = DataLabelAnchor.End, BackgroundColor = colors[0] } + }; + datasets.Add(dataset1); + + var dataset2 = new LineChartDataset + { + Label = "macOS", + Data = new List { 1809499, 1816642, 2122410, 1809499, 1850793, 1846743, 1954797, 2391313, 1983430, 2469918, 2633303, 2821149 }, + BackgroundColor = colors[1], + BorderColor = colors[1], + BorderWidth = 2, + HoverBorderWidth = 4, + // PointBackgroundColor = colors[1], + // PointRadius = 3, // show points + // PointHoverRadius = 4, + + // datalabels + Datalabels = new() { Alignment = DataLabelAlignment.End, Anchor = DataLabelAnchor.End, BackgroundColor = colors[1] } + }; + datasets.Add(dataset2); + + var dataset3 = new LineChartDataset + { + Label = "Other", + Data = new List { 1081241, 1100363, 1118136, 1073255, 1120315, 1395736, 1488788, 1489466, 1489947, 1414739, 1735811, 1820171 }, + BackgroundColor = colors[2], + BorderColor = colors[2], + BorderWidth = 2, + HoverBorderWidth = 4, + // PointBackgroundColor = colors[2], + // PointRadius = 3, // show points + // PointHoverRadius = 4, + + // datalabels + Datalabels = new() { Alignment = DataLabelAlignment.Start, Anchor = DataLabelAnchor.Start, BackgroundColor = colors[2] } + }; + datasets.Add(dataset3); + + chartData = new ChartData + { + Labels = labels, + Datasets = datasets + }; + + lineChartOptions = new(); + lineChartOptions.Responsive = true; + lineChartOptions.Interaction = new Interaction { Mode = InteractionMode.Index }; + + lineChartOptions.Scales.X!.Title = new ChartAxesTitle { Text = "2019", Display = true }; + lineChartOptions.Scales.Y!.Title = new ChartAxesTitle { Text = "Visitors", Display = true }; + + lineChartOptions.Plugins.Title!.Text = "Operating system"; + lineChartOptions.Plugins.Title.Display = true; + + // datalabels + lineChartOptions.Plugins.Datalabels.Color = "white"; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + // pass the plugin name to enable the data labels + await lineChart.InitializeAsync(chartData: chartData, chartOptions: lineChartOptions, plugins: new string[] { "ChartDataLabels" }); + } + await base.OnAfterRenderAsync(firstRender); + } +} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_03_Tick_Configuration.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_03_Tick_Configuration.razor similarity index 77% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_03_Tick_Configuration.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_03_Tick_Configuration.razor index aa918c83..27bcd3ba 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/LineCharts/LineChart_Demo_03_Tick_Configuration.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_03_Tick_Configuration.razor @@ -37,19 +37,19 @@ private async Task ChangeTicksAlignmentToStart() { - lineChartOptions.Scales.X!.Ticks!.Alignment = Alignment.Start; + lineChartOptions.Scales.X!.Ticks!.TicksAlignment = TicksAlignment.Start; await lineChart.UpdateAsync(chartData, lineChartOptions); } private async Task ChangeTicksAlignmentToCenter() { - lineChartOptions.Scales.X!.Ticks!.Alignment = Alignment.Center; + lineChartOptions.Scales.X!.Ticks!.TicksAlignment = TicksAlignment.Center; await lineChart.UpdateAsync(chartData, lineChartOptions); } private async Task ChangeTicksAlignmentToEnd() { - lineChartOptions.Scales.X!.Ticks!.Alignment = Alignment.End; + lineChartOptions.Scales.X!.Ticks!.TicksAlignment = TicksAlignment.End; await lineChart.UpdateAsync(chartData, lineChartOptions); } @@ -74,22 +74,22 @@ datasetsCount += 1; return new LineChartDataset - { - Label = $"Team {datasetsCount}", - Data = GetRandomData(), - BackgroundColor = new List { c.ToRgbString() }, - BorderColor = new List { c.ToRgbString() }, - BorderWidth = new List { 2 }, - HoverBorderWidth = new List { 4 }, - PointBackgroundColor = new List { c.ToRgbString() }, - PointRadius = new List { 0 }, // hide points - PointHoverRadius = new List { 4 } - }; + { + Label = $"Team {datasetsCount}", + Data = GetRandomData(), + BackgroundColor = c.ToRgbString(), + BorderColor = c.ToRgbString(), + BorderWidth = 2, + HoverBorderWidth = 4, + // PointBackgroundColor = c.ToRgbString(), + // PointRadius = 0, // hide points + // PointHoverRadius = 4, + }; } - private List GetRandomData() + private List GetRandomData() { - var data = new List(); + var data = new List(); for (var index = 0; index < labelsCount; index++) { data.Add(random.Next(200)); @@ -116,5 +116,4 @@ } #endregion Data Preparation - } \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_04_Locale.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_04_Locale.razor new file mode 100644 index 00000000..47981248 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/LineChart/LineChart_Demo_04_Locale.razor @@ -0,0 +1,79 @@ + + +@code { + private LineChart lineChart = default!; + private LineChartOptions lineChartOptions = default!; + private ChartData chartData = default!; + + protected override void OnInitialized() + { + var colors = ColorUtility.CategoricalTwelveColors; + + var labels = new List { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; + var datasets = new List(); + + var dataset1 = new LineChartDataset + { + Label = "Windows", + Data = new List { 7265791, 5899643, 6317759, 6315641, 5338211, 8496306, 7568556, 8538933, 8274297, 8657298, 7548388, 7764845 }, + BackgroundColor = colors[0], + BorderColor = colors[0], + BorderWidth = 2, + HoverBorderWidth = 4, + // PointBackgroundColor = colors[0], + // PointRadius = 0, // hide points + // PointHoverRadius = 4, + }; + datasets.Add(dataset1); + + var dataset2 = new LineChartDataset + { + Label = "macOS", + Data = new List { 1809499, 1816642, 2122410, 1809499, 1850793, 1846743, 1954797, 2391313, 1983430, 2469918, 2633303, 2821149 }, + BackgroundColor = colors[1], + BorderColor = colors[1], + BorderWidth = 2, + HoverBorderWidth = 4, + // PointBackgroundColor = colors[1], + // PointRadius = 0, // hide points + // PointHoverRadius = 4, + }; + datasets.Add(dataset2); + + var dataset3 = new LineChartDataset + { + Label = "Other", + Data = new List { 1081241, 1100363, 1118136, 1073255, 1120315, 1395736, 1488788, 1489466, 1489947, 1414739, 1735811, 1820171 }, + BackgroundColor = colors[2], + BorderColor = colors[2], + BorderWidth = 2, + HoverBorderWidth = 4, + // PointBackgroundColor = colors[2], + // PointRadius = 0, // hide points + // PointHoverRadius = 4, + }; + datasets.Add(dataset3); + + chartData = new ChartData { Labels = labels, Datasets = datasets }; + + lineChartOptions = new(); + lineChartOptions.Locale = "de-DE"; + lineChartOptions.Responsive = true; + lineChartOptions.Interaction = new Interaction { Mode = InteractionMode.Index }; + + lineChartOptions.Scales.X!.Title = new ChartAxesTitle { Text = "2019", Display = true }; + lineChartOptions.Scales.Y!.Title = new ChartAxesTitle { Text = "Visitors", Display = true }; + + lineChartOptions.Plugins.Title!.Text = "Operating system"; + lineChartOptions.Plugins.Title.Display = true; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await lineChart.InitializeAsync(chartData, lineChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } +} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChartDocumentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChartDocumentation.razor new file mode 100644 index 00000000..9ee42bbd --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChartDocumentation.razor @@ -0,0 +1,74 @@ +@attribute [Route(pageUrl)] +@layout DemosMainLayout + + + + + + @((MarkupString)pageDescription) + + + + + + + +
+ + The Pie Chart component visualizes categorical data as proportional slices of a circle, making it ideal for showing parts of a whole. +

+ How to use: +
    +
  • Add the PieChart component to your page and set its dimensions (e.g., Width="600").
  • +
  • Prepare your chart data by specifying Labels for each category and one or more Datasets with values and background colors.
  • +
  • Configure chart options such as Responsive and Title using the PieChartOptions object.
  • +
  • Initialize the chart in OnAfterRenderAsync by calling pieChart.InitializeAsync(chartData, pieChartOptions).
  • +
  • Use the demo's interactive buttons to randomize data, add datasets, or add new data points dynamically.
  • +
  • Refer to the demo code below for practical examples of data preparation, dynamic updates, and chart customization.
  • +
+ This demo demonstrates how to set up a pie chart, bind your data, and interactively update the chart to fit your application's needs. +
+ +
+ +
+ + The Pie Chart component supports data labels, allowing you to display values or category names directly on each slice of the chart. +

+ How to use: +
    +
  • Enable data labels by passing the ChartDataLabels plugin when initializing the chart: plugins: new[] { "ChartDataLabels" }.
  • +
  • Customize the position of data labels for each dataset using the Datalabels.Anchor property (e.g., Anchor.End or Anchor.Center).
  • +
  • Prepare your chart data and datasets as usual, and bind them to the PieChart component.
  • +
  • Use the provided buttons to randomize data or add new data points dynamically, and observe how data labels update automatically.
  • +
  • Refer to the demo code below for practical examples of enabling and customizing data labels in your pie charts.
  • +
+ Data labels make it easier for users to interpret the chart by showing relevant information directly on each pie slice. +
+ +
+ +
+ + The Pie Chart component allows you to easily change the position of the chart legend to improve readability or match your application's layout. +

+ How to use: +
    +
  • Set the legend position using pieChartOptions.Plugins.Legend.Position (e.g., "top", "right", "bottom", or "left").
  • +
  • Update the legend position dynamically by changing this property and calling pieChart.UpdateAsync(chartData, pieChartOptions).
  • +
  • Use the demo's buttons to switch the legend position interactively and see the effect in real time.
  • +
  • Refer to the demo code below for practical examples of configuring and updating the legend position in your pie charts.
  • +
+ Adjusting the legend position helps ensure your chart is clear and fits well within your application's design. +
+ +
+ +@code { + private const string pageUrl = DemoRouteConstants.Demos_PieChart; + private const string pageTitle = "Pie Chart"; + private const string pageDescription = "Explore interactive Blazor Pie Chart examples with source code. Learn how to visualize categorical data, customize chart appearance, and enhance your Blazor applications. Try live demos and discover practical usage scenarios for the Pie Chart component."; + private const string metaTitle = "Blazor Pie Chart Examples & Interactive Demos"; + private const string metaDescription = "Explore interactive Blazor Pie Chart examples with source code. Learn how to visualize categorical data, customize chart appearance, and enhance your Blazor applications. Try live demos and discover practical usage scenarios for the Pie Chart component."; + private const string imageUrl = "https://i.imgur.com/8b7jH0D.png"; // TODO: Update with the actual image URL for the Line Chart demo +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChart_Demo_01_Examples.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChart_Demo_01_Examples.razor similarity index 97% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChart_Demo_01_Examples.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChart_Demo_01_Examples.razor index ac6a6d69..d9ee2660 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChart_Demo_01_Examples.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChart_Demo_01_Examples.razor @@ -51,7 +51,7 @@ { var count = pieChartDataset.Data.Count; - var newData = new List(); + var newData = new List(); for (var i = 0; i < count; i++) { newData.Add(random.Next(0, 100)); @@ -115,9 +115,9 @@ return new() { Label = $"Team {datasetsCount}", Data = GetRandomData(), BackgroundColor = GetRandomBackgroundColors() }; } - private List GetRandomData() + private List GetRandomData() { - var data = new List(); + var data = new List(); for (var index = 0; index < dataLabelsCount; index++) { data.Add(random.Next(0, 100)); diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChart_Demo_02_Datalabels.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChart_Demo_02_Datalabels.razor similarity index 92% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChart_Demo_02_Datalabels.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChart_Demo_02_Datalabels.razor index c2fb6e9f..9d63948e 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChart_Demo_02_Datalabels.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChart_Demo_02_Datalabels.razor @@ -1,5 +1,4 @@ -@using BlazorExpress.ChartJS.Enums - +
@@ -52,7 +51,7 @@ { var count = pieChartDataset.Data.Count; - var newData = new List(); + var newData = new List(); for (var i = 0; i < count; i++) { newData.Add(random.Next(0, 100)); @@ -99,11 +98,11 @@ var dataset = GetRandomPieChartDataset(); if (index == 0) - dataset.Datalabels.Anchor = Anchor.End; + dataset.Datalabels.Anchor = DataLabelAnchor.End; else if (index == numberOfDatasets - 1) - dataset.Datalabels.Anchor = Anchor.End; + dataset.Datalabels.Anchor = DataLabelAnchor.End; else - dataset.Datalabels.Anchor = Anchor.Center; + dataset.Datalabels.Anchor = DataLabelAnchor.Center; datasets.Add(dataset); } @@ -117,9 +116,9 @@ return new() { Label = $"Team {datasetsCount}", Data = GetRandomData(), BackgroundColor = GetRandomBackgroundColors() }; } - private List GetRandomData() + private List GetRandomData() { - var data = new List(); + var data = new List(); for (var index = 0; index < dataLabelsCount; index++) { data.Add(random.Next(0, 100)); diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChart_Demo_03_Change_Legend_Position.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChart_Demo_03_Change_Legend_Position.razor similarity index 97% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChart_Demo_03_Change_Legend_Position.razor rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChart_Demo_03_Change_Legend_Position.razor index f475cdf2..c9feb03b 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/PieCharts/PieChart_Demo_03_Change_Legend_Position.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PieChart/PieChart_Demo_03_Change_Legend_Position.razor @@ -71,9 +71,9 @@ return new() { Label = $"Team {datasetsCount}", Data = GetRandomData(), BackgroundColor = GetRandomBackgroundColors() }; } - private List GetRandomData() + private List GetRandomData() { - var data = new List(); + var data = new List(); for (var index = 0; index < dataLabelsCount; index++) { data.Add(random.Next(0, 100)); diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PolarAreaChart/PolarAreaChartDocumentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PolarAreaChart/PolarAreaChartDocumentation.razor new file mode 100644 index 00000000..4bbadd7e --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PolarAreaChart/PolarAreaChartDocumentation.razor @@ -0,0 +1,41 @@ +@attribute [Route(pageUrl)] +@layout DemosMainLayout + + + + + + @((MarkupString)pageDescription) + + + + + + + +
+ + The Polar Area Chart component visualizes each data value as a segment with equal angles but varying radius, making it ideal for comparing values across categories in a circular layout. +

+ How to use: +
    +
  • Add the PolarAreaChart component to your page and set its dimensions (e.g., Width="600").
  • +
  • Prepare your chart data by specifying Labels for each category and one or more Datasets with values and background colors.
  • +
  • Configure chart options such as Responsive and Title using the PolarAreaChartOptions object.
  • +
  • Initialize the chart in OnAfterRenderAsync by calling polarAreaChart.InitializeAsync(chartData, polarAreaChartOptions).
  • +
  • Use the demo's interactive buttons to randomize data, add datasets, or add new data points dynamically and see the chart update in real time.
  • +
  • Refer to the demo code below for practical examples of data preparation, dynamic updates, and chart customization.
  • +
+ This demo demonstrates how to set up a Polar Area Chart, bind your data, and interactively update the chart to fit your application's needs. +
+ +
+ +@code { + private const string pageUrl = DemoRouteConstants.Demos_PolarAreaChart; + private const string pageTitle = "PolarArea Chart"; + private const string pageDescription = "Explore interactive Blazor Polar Area Chart examples with source code. Learn how to visualize categorical data, customize chart appearance, and enhance your Blazor applications. Try live demos and discover practical usage scenarios for the Polar Area Chart component."; + private const string metaTitle = "Blazor Polar Area Chart Examples & Interactive Demos"; + private const string metaDescription = "Explore interactive Blazor Polar Area Chart examples with source code. Learn how to visualize categorical data, customize chart appearance, and enhance your Blazor applications. Try live demos and discover practical usage scenarios for the Polar Area Chart component."; + private const string imageUrl = "https://i.imgur.com/8b7jH0D.png"; // TODO: Update with the actual image URL for the Line Chart demo +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PolarAreaChart/PolarAreaChart_Demo_01_Examples.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PolarAreaChart/PolarAreaChart_Demo_01_Examples.razor new file mode 100644 index 00000000..2afd68bc --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/PolarAreaChart/PolarAreaChart_Demo_01_Examples.razor @@ -0,0 +1,177 @@ + + +
+ + + +
+ +@code { + private PolarAreaChart polarAreaChart = default!; + private PolarAreaChartOptions polarAreaChartOptions = default!; + private ChartData chartData = default!; + private string[]? chartColors; + + private int datasetsCount = 0; + private int dataLabelsCount = 0; + + private Random random = new(); + + protected override void OnInitialized() + { + chartColors = ColorUtility.CategoricalTwelveColors; + chartData = new ChartData { Labels = GetDefaultDataLabels(5), Datasets = GetDefaultDataSets(1) }; + polarAreaChartOptions = new(); + polarAreaChartOptions.Responsive = true; + polarAreaChartOptions.Plugins.Title!.Text = "2022 - Sales"; + polarAreaChartOptions.Plugins.Title.Display = true; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await polarAreaChart.InitializeAsync(chartData, polarAreaChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } + + private async Task RandomizeAsync() + { + if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return; + + var newDatasets = new List(); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is PolarAreaChartDataset polarAreaChartDataset + && polarAreaChartDataset is not null + && polarAreaChartDataset.Data is not null) + { + var count = polarAreaChartDataset.Data.Count; + + var newData = new List(); + for (var i = 0; i < count; i++) + { + newData.Add(random.Next(0, 100)); + } + + var backgroundColors = new List(); + for (var index = 0; index < count; index++) + { + backgroundColors.Add(chartColors![index].ToColor().ToRgbaString(0.5)); // RGBA + } + + polarAreaChartDataset.Data = newData; + polarAreaChartDataset.BackgroundColor = backgroundColors; + newDatasets.Add(polarAreaChartDataset); + } + } + + chartData.Datasets = newDatasets; + + await polarAreaChart.UpdateAsync(chartData, polarAreaChartOptions); + } + + private async Task AddDatasetAsync() + { + if (chartData is null || chartData.Datasets is null) return; + + var chartDataset = GetRandomPolarAreaChartDataset(); + chartData = await polarAreaChart.AddDatasetAsync(chartData, chartDataset, polarAreaChartOptions); + } + + private async Task AddDataAsync() + { + if (dataLabelsCount >= 12) + return; + + if (chartData is null || chartData.Datasets is null) + return; + + dataLabelsCount += 1; + + var data = new List(); + foreach (var dataset in chartData.Datasets) + { + if (dataset is PolarAreaChartDataset polarAreaChartDataset) + data.Add(new PolarAreaChartDatasetData(polarAreaChartDataset.Label, random.Next(0, 100), chartColors![dataLabelsCount - 1].ToColor().ToRgbaString(0.5), null)); + } + + chartData = await polarAreaChart.AddDataAsync(chartData, GetNextDataLabel(), data); + } + + #region Data Preparation + + private List GetDefaultDataLabels(int numberOfLabels) + { + var labels = new List(); + for (var index = 0; index < numberOfLabels; index++) + { + dataLabelsCount += 1; + labels.Add(GetNextDataLabel()); + } + + return labels; + } + + private string GetNextDataLabel() => $"Product {dataLabelsCount}"; + + private List GetDefaultDataSets(int numberOfDatasets) + { + var datasets = new List(); + + for (var index = 0; index < numberOfDatasets; index++) + { + datasets.Add(GetRandomPolarAreaChartDataset()); + } + + return datasets; + } + + private PolarAreaChartDataset GetRandomPolarAreaChartDataset() + { + datasetsCount += 1; + return new() + { + Label = $"Team {datasetsCount}", + Data = GetRandomData(), + BackgroundColor = GetRandomBackgroundColors() + }; + } + + private List GetRandomData() + { + var data = new List(); + for (var index = 0; index < dataLabelsCount; index++) + { + data.Add(random.Next(0, 100)); + } + + return data; + } + + private List GetRandomBackgroundColors() + { + var colors = new List(); + for (var index = 0; index < dataLabelsCount; index++) + { + colors.Add(chartColors![index].ToColor().ToRgbaString(0.5)); // RGBA + } + + return colors; + } + + private List GetRandomBorderColors() + { + var colors = new List(); + for (var index = 0; index < dataLabelsCount; index++) + { + colors.Add(chartColors![index].ToColor().ToRgbString()); // RGB + } + + return colors; + } + + #endregion Data Preparation +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/RadarChart/RadarChartDocumentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/RadarChart/RadarChartDocumentation.razor new file mode 100644 index 00000000..948952b8 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/RadarChart/RadarChartDocumentation.razor @@ -0,0 +1,41 @@ +@attribute [Route(pageUrl)] +@layout DemosMainLayout + + + + + + @((MarkupString)pageDescription) + + + + + + + +
+ + The Radar Chart component visualizes multivariate data with each variable represented on axes starting from the same point, making it ideal for comparing multiple groups across several categories. +

+ How to use: +
    +
  • Add the RadarChart component to your page and set its dimensions (e.g., Width="600").
  • +
  • Prepare your chart data by specifying Labels for each axis and one or more Datasets with values and styling options.
  • +
  • Configure chart options such as Responsive using the RadarChartOptions object.
  • +
  • Initialize the chart in OnAfterRenderAsync by calling radarChart.InitializeAsync(chartData, radarChartOptions).
  • +
  • Use the demo's interactive buttons to randomize data, add datasets, or add new data points dynamically and see the chart update in real time.
  • +
  • Refer to the demo code below for practical examples of data preparation, dynamic updates, and chart customization.
  • +
+ This demo demonstrates how to set up a Radar Chart, bind your data, and interactively update the chart to fit your application's needs. +
+ +
+ +@code { + private const string pageUrl = DemoRouteConstants.Demos_RadarChart; + private const string pageTitle = "Radar Chart"; + private const string pageDescription = "Explore interactive Blazor Radar Chart examples with source code. Learn how to visualize categorical data, customize chart appearance, and enhance your Blazor applications using the Radar Chart component. Try live demos and discover practical usage scenarios."; + private const string metaTitle = "Blazor Radar Chart Examples & Interactive Demos"; + private const string metaDescription = "Explore interactive Blazor Radar Chart examples with source code. Learn how to visualize categorical data, customize chart appearance, and enhance your Blazor applications using the Radar Chart component. Try live demos and discover practical usage scenarios."; + private const string imageUrl = "https://i.imgur.com/8b7jH0D.png"; // TODO: Update with the actual image URL for the Line Chart demo +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/RadarChart/RadarChart_Demo_01_Examples.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/RadarChart/RadarChart_Demo_01_Examples.razor new file mode 100644 index 00000000..7570b0bf --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/RadarChart/RadarChart_Demo_01_Examples.razor @@ -0,0 +1,155 @@ + + +
+ + + +
+ +@code { + private RadarChart radarChart = default!; + private RadarChartOptions radarChartOptions = default!; + private ChartData chartData = default!; + private string[]? chartColors; + + private int datasetsCount; + private int dataLabelsCount; + + private Random random = new(); + + protected override void OnInitialized() + { + chartColors = ColorUtility.CategoricalTwelveColors; + chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; + radarChartOptions = new() { Responsive = true }; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await radarChart.InitializeAsync(chartData, radarChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } + + private async Task RandomizeAsync() + { + if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return; + + var newDatasets = new List(); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is RadarChartDataset radarChartDataset + && radarChartDataset is not null + && radarChartDataset.Data is not null) + { + var count = radarChartDataset.Data.Count; + + var newData = new List(); + for (var i = 0; i < count; i++) + { + newData.Add(random.Next(200)); + } + + radarChartDataset.Data = newData; + newDatasets.Add(radarChartDataset); + } + } + + chartData.Datasets = newDatasets; + + await radarChart.UpdateAsync(chartData, radarChartOptions); + } + + private async Task AddDatasetAsync() + { + if (datasetsCount >= 12) + return; + + if (chartData is null || chartData.Datasets is null) return; + + var chartDataset = GetRandomRadarChartDataset(); + chartData = await radarChart.AddDatasetAsync(chartData, chartDataset, radarChartOptions); + } + + private async Task AddDataAsync() + { + if (dataLabelsCount >= 12) + return; + + if (chartData is null || chartData.Datasets is null) + return; + + dataLabelsCount += 1; + + var data = new List(); + foreach (var dataset in chartData.Datasets) + { + if (dataset is RadarChartDataset radarChartDataset) + data.Add(new RadarChartDatasetData(radarChartDataset.Label, random.Next(200))); + } + + chartData = await radarChart.AddDataAsync(chartData, GetNextDataLabel(), data); + } + + #region Data Preparation + + private List GetDefaultDataLabels(int numberOfLabels) + { + var labels = new List(); + for (var index = 0; index < numberOfLabels; index++) + { + dataLabelsCount += 1; + labels.Add(GetNextDataLabel()); + } + + return labels; + } + + private string GetNextDataLabel() => $"Day {dataLabelsCount}"; + + private List GetDefaultDataSets(int numberOfDatasets) + { + var datasets = new List(); + + for (var index = 0; index < numberOfDatasets; index++) + { + datasets.Add(GetRandomRadarChartDataset()); + } + + return datasets; + } + + private RadarChartDataset GetRandomRadarChartDataset() + { + var c = chartColors![datasetsCount].ToColor(); + + datasetsCount += 1; + + return new RadarChartDataset + { + Label = $"Team {datasetsCount}", + Data = GetRandomData(), + BackgroundColor = c.ToRgbaString(), + BorderColor = c.ToRgbaString(0.8), + BorderWidth = 2, + Fill = true, + HoverBorderWidth = 4, + }; + } + + private List GetRandomData() + { + var data = new List(); + for (var index = 0; index < dataLabelsCount; index++) + { + data.Add(random.Next(200)); + } + + return data; + } + + #endregion Data Preparation +} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/ScatterChart/ScatterChartDocumentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/ScatterChart/ScatterChartDocumentation.razor new file mode 100644 index 00000000..f63ee5ed --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/ScatterChart/ScatterChartDocumentation.razor @@ -0,0 +1,58 @@ +@attribute [Route(pageUrl)] +@layout DemosMainLayout + + + + + + @((MarkupString)pageDescription) + + + + + + + +
+ + The Scatter Chart component visualizes individual data points as (X, Y) coordinates, making it ideal for displaying relationships or distributions between two numeric variables. +

+ How to use: +
    +
  • Add the ScatterChart component to your page and set its dimensions (e.g., Width="560", Height="480").
  • +
  • Prepare your chart data by creating one or more ScatterChartDataset objects, each containing a list of ScatterChartDataPoint instances with X and Y values.
  • +
  • Customize the appearance of each dataset using properties like BackgroundColor, BorderColor, and BorderWidth.
  • +
  • Configure chart options using the ScatterChartOptions object as needed.
  • +
  • Initialize the chart in OnAfterRenderAsync by calling scatterChart.InitializeAsync(chartData, scatterChartOptions).
  • +
  • Refer to the demo code below for practical examples of data preparation, dataset customization, and chart initialization.
  • +
+ This demo shows how to set up a scatter chart, bind your data, and customize the chart's appearance to fit your application's needs. +
+ +
+ +
+ + The Scatter Chart component supports dynamic data updates, allowing you to add, remove, or modify data points and datasets at runtime. This is useful for visualizing real-time data or enabling interactive data exploration. +

+ How to use: +
    +
  • Add the ScatterChart component to your page and set its Width and Height as needed.
  • +
  • Prepare your chart data using one or more ScatterChartDataset objects, each containing a list of ScatterChartDataPoint (with X and Y values).
  • +
  • Implement methods to update your data dynamically, such as adding new points, randomizing values, or modifying existing datasets.
  • +
  • After updating the data, call scatterChart.UpdateAsync(chartData, scatterChartOptions) to refresh the chart and reflect the changes.
  • +
  • Refer to the demo code below for practical examples of dynamic data manipulation and chart updates in a Blazor application.
  • +
+ This demo demonstrates how to work with dynamic data in a scatter chart, enabling interactive and real-time data visualizations in your Blazor projects. +
+ +
+ +@code { + private const string pageUrl = DemoRouteConstants.Demos_ScatterChart; + private const string pageTitle = "Scatter Chart"; + private const string pageDescription = "The Blazor Scatter Chart component displays data values as vertical bars, making it easy to compare multiple data sets or visualize trends over time."; + private const string metaTitle = "Blazor Scatter Chart"; + private const string metaDescription = "The Blazor Scatter Chart component displays data values as vertical bars, making it easy to compare multiple data sets or visualize trends over time."; + private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; // TODO: update with the actual image URL for the Bar Chart demo +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/ScatterChart/ScatterChart_Demo_01_Examples.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/ScatterChart/ScatterChart_Demo_01_Examples.razor new file mode 100644 index 00000000..44d731ae --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/ScatterChart/ScatterChart_Demo_01_Examples.razor @@ -0,0 +1,65 @@ +
+ +
+ +@code { + private ScatterChart scatterChart = default!; + private ScatterChartOptions scatterChartOptions = default!; + private ChartData chartData = default!; + + private Random random = new(); + + protected override void OnInitialized() + { + chartData = new ChartData + { + Datasets = new() + { + GetRandomRadarChartDataset(0), + GetRandomRadarChartDataset(1), + GetRandomRadarChartDataset(2) + } + }; + + scatterChartOptions = new() { }; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await scatterChart.InitializeAsync(chartData, scatterChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } + + #region Data Preparation + + private ScatterChartDataset GetRandomRadarChartDataset(int recordIndex) + { + var c = ColorUtility.CategoricalTwelveColors[recordIndex].ToColor(); + + return new ScatterChartDataset + { + Label = $"Team {recordIndex + 1}", + Data = GetRandomData(), + BackgroundColor = c.ToRgbaString(), // RGBA + BorderColor = c.ToRgbString(), // RGB + BorderWidth = 2, + HoverBorderWidth = 4, + }; + } + + private List GetRandomData() + { + var data = new List(); + for (var index = 0; index < 10; index++) + { + data.Add(new(random.Next(200), random.Next(200))); + } + + return data; + } + + #endregion Data Preparation +} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/ScatterChart/ScatterChart_Demo_02_Dynamic_Data.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/ScatterChart/ScatterChart_Demo_02_Dynamic_Data.razor new file mode 100644 index 00000000..33b50416 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/ScatterChart/ScatterChart_Demo_02_Dynamic_Data.razor @@ -0,0 +1,172 @@ + + + +
+ + + + + +
+ +@code { + private ScatterChart scatterChart = default!; + private ScatterChartOptions scatterChartOptions = default!; + private ChartData chartData = default!; + + private int datasetsCount; + private int dataLabelsCount; + + private Random random = new(); + + protected override void OnInitialized() + { + chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) }; + scatterChartOptions = new() + { + Responsive = true, + Interaction = new Interaction { Mode = InteractionMode.Index }, + }; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await scatterChart.InitializeAsync(chartData, scatterChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } + + private async Task RandomizeAsync() + { + if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) return; + + var newDatasets = new List(); + + foreach (var dataset in chartData.Datasets) + { + if (dataset is ScatterChartDataset scatterChartDataset + && scatterChartDataset is not null + && scatterChartDataset.Data is not null) + { + var count = scatterChartDataset.Data.Count; + + var newData = new List(); + for (var i = 0; i < count; i++) + { + newData.Add(new(random.Next(200), random.Next(200))); + } + + scatterChartDataset.Data = newData; + newDatasets.Add(scatterChartDataset); + } + } + + chartData.Datasets = newDatasets; + + await scatterChart.UpdateAsync(chartData, scatterChartOptions); + } + + private async Task AddDatasetAsync() + { + if (datasetsCount >= 12) + return; + + if (chartData is null || chartData.Datasets is null) return; + + var chartDataset = GetRandomScatterChartDataset(); + chartData = await scatterChart.AddDatasetAsync(chartData, chartDataset, scatterChartOptions); + } + + private async Task AddDataAsync() + { + if (chartData is null || chartData.Datasets is null) + return; + + var data = new List(); + foreach (var dataset in chartData.Datasets) + { + if (dataset is ScatterChartDataset scatterChartDataset) + data.Add(new ScatterChartDatasetData(scatterChartDataset.Label, new ScatterChartDataPoint(random.Next(200), random.Next(200)))); + } + + chartData = await scatterChart.AddDataAsync(chartData, GetNextDataLabel(), data); + } + + private async Task ShowHorizontalLineChartAsync() + { + scatterChartOptions.IndexAxis = "y"; + await scatterChart.UpdateAsync(chartData, scatterChartOptions); + } + + private async Task ShowVerticalLineChartAsync() + { + scatterChartOptions.IndexAxis = "x"; + await scatterChart.UpdateAsync(chartData, scatterChartOptions); + } + + #region Data Preparation + + private List GetDefaultDataSets(int numberOfDatasets) + { + var datasets = new List(); + + for (var index = 0; index < numberOfDatasets; index++) + { + datasets.Add(GetRandomScatterChartDataset()); + } + + return datasets; + } + + private ScatterChartDataset GetRandomScatterChartDataset() + { + var c = ColorUtility.CategoricalTwelveColors[datasetsCount].ToColor(); + + datasetsCount += 1; + + return new ScatterChartDataset + { + Label = $"Team {datasetsCount}", + Data = GetRandomData(), + BackgroundColor = c.ToRgbaString(), // RGBA + BorderColor = c.ToRgbString(), // RGB + BorderWidth = 2, + Fill = true, + HoverBorderWidth = 4, + PointHoverRadius = new List { 6 }, + }; + } + + private List GetRandomData() + { + var data = new List(); + for (var index = 0; index < dataLabelsCount; index++) + { + data.Add(new ScatterChartDataPoint(random.Next(200), random.Next(200))); + } + + return data; + } + + private List GetDefaultDataLabels(int numberOfLabels) + { + var labels = new List(); + for (var index = 0; index < numberOfLabels; index++) + { + labels.Add(GetNextDataLabel()); + } + + return labels; + } + + private string GetNextDataLabel() + { + dataLabelsCount += 1; + return $"Day {dataLabelsCount}"; + } + + #endregion Data Preparation + +} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/Utils/ColorUtil/ColorUtilDocumentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/Utils/ColorUtil/ColorUtilDocumentation.razor new file mode 100644 index 00000000..52f14ac2 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/Utils/ColorUtil/ColorUtilDocumentation.razor @@ -0,0 +1,31 @@ +@attribute [Route(pageUrl)] +@layout DemosMainLayout + + + + + + @((MarkupString)pageDescription) + + + +
+ + + +
+ +
+ + + +
+ +@code { + private const string pageUrl = DemoRouteConstants.Demos_ColorUtils; + private const string pageTitle = "Color Utils"; + private const string pageDescription = "For data visualization, you can use the predefined palettes ColorBuilder.CategoricalTwelveColors for a 12-color palette and ColorBuilder.CategoricalSixColors for a 6-color palette. These palettes offer a range of distinct and visually appealing colors that can be applied to represent different categories or data elements in your visualizations."; + private const string metaTitle = "Color Utils"; + private const string metaDescription = "For data visualization, you can use the predefined palettes ColorBuilder.CategoricalTwelveColors for a 12-color palette and ColorBuilder.CategoricalSixColors for a 6-color palette. These palettes offer a range of distinct and visually appealing colors that can be applied to represent different categories or data elements in your visualizations."; + private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; // TODO: update with the actual image URL for the Bar Chart demo +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/Utils/ColorUtil/ColorUtil_Demo_01_CategoricalSixColor.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/Utils/ColorUtil/ColorUtil_Demo_01_CategoricalSixColor.razor new file mode 100644 index 00000000..1b8e108b --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/Utils/ColorUtil/ColorUtil_Demo_01_CategoricalSixColor.razor @@ -0,0 +1,17 @@ +
+ + + @foreach (var c in ColorUtility.CategoricalSixColors.Select((c, i) => new { Color = c, Index = i })) + { + + + + + + + + + } + +
@c.Color
+
\ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/Utils/ColorUtil/ColorUtil_Demo_02_CategoricalTwelveColor.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/Utils/ColorUtil/ColorUtil_Demo_02_CategoricalTwelveColor.razor new file mode 100644 index 00000000..ca7162e3 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Demos/Utils/ColorUtil/ColorUtil_Demo_02_CategoricalTwelveColor.razor @@ -0,0 +1,17 @@ +
+ + + @foreach (var c in ColorUtility.CategoricalTwelveColors.Select((c, i) => new { Color = c, Index = i })) + { + + + + + + + + + } + +
@c.Color
+
\ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/BarChart/BarChart_Doc_01_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/BarChart/BarChart_Doc_01_Documentation.razor new file mode 100644 index 00000000..423947d2 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/BarChart/BarChart_Doc_01_Documentation.razor @@ -0,0 +1,52 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +Blazor Bar Chart - API Documentation + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +@code { + private const string componentName = nameof(BarChart); + private const string pageUrl = DemoRouteConstants.Docs_BarChart; + private const string pageTitle = $"Blazor {componentName} component"; + private const string pageDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string metaTitle = $"Blazor {componentName} component API Reference & Configuration Guide"; + private const string metaDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string imageUrl = @DemoImageSrcConstants.BarChart; +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/BubbleChart/BubbleChart_Doc_01_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/BubbleChart/BubbleChart_Doc_01_Documentation.razor new file mode 100644 index 00000000..b2f76549 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/BubbleChart/BubbleChart_Doc_01_Documentation.razor @@ -0,0 +1,52 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +Blazor Bar Chart - API Documentation + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +@code { + private const string componentName = nameof(BubbleChart); + private const string pageUrl = DemoRouteConstants.Docs_BubbleChart; + private const string pageTitle = $"Blazor {componentName} component"; + private const string pageDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string metaTitle = $"Blazor {componentName} component API Reference & Configuration Guide"; + private const string metaDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string imageUrl = @DemoImageSrcConstants.BarChart; +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/DoughnutChart/DoughnutChart_Doc_01_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/DoughnutChart/DoughnutChart_Doc_01_Documentation.razor new file mode 100644 index 00000000..defa2ab4 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/DoughnutChart/DoughnutChart_Doc_01_Documentation.razor @@ -0,0 +1,52 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +Blazor Doughnut Chart - API Documentation + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +@code { + private const string componentName = nameof(DoughnutChart); + private const string pageUrl = DemoRouteConstants.Docs_DoughnutChart; + private const string pageTitle = $"Blazor {componentName} component"; + private const string pageDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string metaTitle = $"Blazor {componentName} component API Reference & Configuration Guide"; + private const string metaDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string imageUrl = @DemoImageSrcConstants.DoughnutChart; +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/GettingStartedDocumentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/GettingStartedDocumentation.razor new file mode 100644 index 00000000..6383259e --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/GettingStartedDocumentation.razor @@ -0,0 +1,60 @@ +@attribute [Route(pageUrl)] +@attribute [Route(pageUrl2)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#.NET VersionProject TypeDocumentation Link
1.NET 8Blazor WebAssembly (.NET 8)
2.NET 8Blazor WebApp (.NET 8) - Interactive render mode Server - Global location
3.NET 8Blazor WebApp (.NET 8) - Interactive render mode Auto - Global locationTODO: Pending
4.NET 8MAUI Blazor Hybrid App (.NET 8)TODO: Pending
+
+ +@code { + private const string pageUrl = DemoRouteConstants.Docs_Getting_Started_Introduction; + private const string pageUrl2 = DemoRouteConstants.Docs_Prefix; + private const string pageTitle = "Getting started with BlazorExpress.ChartJS"; + private const string pageDescription = "Explore practical Blazor ChartJS demos with step-by-step examples. Learn how to create interactive charts in your Blazor projects."; + private const string metaTitle = "Blazor ChartJS Demo – Getting Started with Interactive Chart Examples"; + private const string metaDescription = "Explore practical Blazor ChartJS demos with step-by-step examples. Learn how to create interactive charts in your Blazor projects."; + private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; // TODO: update with the actual image URL for the Bar Chart demo +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_01_Snippet.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_01_Snippet.razor new file mode 100644 index 00000000..a4a03020 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_01_Snippet.razor @@ -0,0 +1 @@ +dotnet add package BlazorExpress.ChartJS \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_01_WebAssembly/Getting_Started_Snippet_01_Scripts.html b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_03_Snippet.html similarity index 50% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_01_WebAssembly/Getting_Started_Snippet_01_Scripts.html rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_03_Snippet.html index 9105166d..e6a019dd 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_01_WebAssembly/Getting_Started_Snippet_01_Scripts.html +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_03_Snippet.html @@ -1,4 +1,6 @@ - - + + + + \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_04_Snippet.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_04_Snippet.razor new file mode 100644 index 00000000..59222951 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_04_Snippet.razor @@ -0,0 +1 @@ +@using BlazorExpress.ChartJS \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_06_Snippet.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_06_Snippet.razor new file mode 100644 index 00000000..7fb558af --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/01_A_Manual_Install_06_Snippet.razor @@ -0,0 +1,43 @@ + + +@code { + private BarChart barChart = default!; + private BarChartOptions barChartOptions = default!; + private ChartData chartData = default!; + + protected override void OnInitialized() + { + var labels = new List { "Chrome", "Firefox", "Safari", "Edge" }; + var datasets = new List(); + + var dataset1 = new BarChartDataset() + { + Data = new List { 55000, 15000, 18000, 21000 }, + BackgroundColor = new List { ColorUtility.CategoricalTwelveColors[0] }, + BorderColor = new List { ColorUtility.CategoricalTwelveColors[0] }, + BorderWidth = new List { 0 }, + }; + datasets.Add(dataset1); + + chartData = new ChartData { Labels = labels, Datasets = datasets }; + + barChartOptions = new BarChartOptions(); + barChartOptions.Responsive = true; + barChartOptions.Interaction = new Interaction { Mode = InteractionMode.Y }; + barChartOptions.IndexAxis = "y"; + + barChartOptions.Scales.X!.Title = new ChartAxesTitle { Text = "Visitors", Display = true }; + barChartOptions.Scales.Y!.Title = new ChartAxesTitle { Text = "Browser", Display = true }; + + barChartOptions.Plugins.Legend.Display = false; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await barChart.InitializeAsync(chartData, barChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } +} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_01_Snippet.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_01_Snippet.razor new file mode 100644 index 00000000..a4a03020 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_01_Snippet.razor @@ -0,0 +1 @@ +dotnet add package BlazorExpress.ChartJS \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_02_WebApp_Server_Global/Getting_Started_Snippet_01_Scripts.html b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_03_Snippet.html similarity index 50% rename from BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_02_WebApp_Server_Global/Getting_Started_Snippet_01_Scripts.html rename to BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_03_Snippet.html index 9105166d..e6a019dd 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Components/Pages/GettingStarted/NET8_02_WebApp_Server_Global/Getting_Started_Snippet_01_Scripts.html +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_03_Snippet.html @@ -1,4 +1,6 @@ - - + + + + \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_04_Snippet.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_04_Snippet.razor new file mode 100644 index 00000000..59222951 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_04_Snippet.razor @@ -0,0 +1 @@ +@using BlazorExpress.ChartJS \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_06_Snippet.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_06_Snippet.razor new file mode 100644 index 00000000..7fb558af --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/02_A_Manual_Install_06_Snippet.razor @@ -0,0 +1,43 @@ + + +@code { + private BarChart barChart = default!; + private BarChartOptions barChartOptions = default!; + private ChartData chartData = default!; + + protected override void OnInitialized() + { + var labels = new List { "Chrome", "Firefox", "Safari", "Edge" }; + var datasets = new List(); + + var dataset1 = new BarChartDataset() + { + Data = new List { 55000, 15000, 18000, 21000 }, + BackgroundColor = new List { ColorUtility.CategoricalTwelveColors[0] }, + BorderColor = new List { ColorUtility.CategoricalTwelveColors[0] }, + BorderWidth = new List { 0 }, + }; + datasets.Add(dataset1); + + chartData = new ChartData { Labels = labels, Datasets = datasets }; + + barChartOptions = new BarChartOptions(); + barChartOptions.Responsive = true; + barChartOptions.Interaction = new Interaction { Mode = InteractionMode.Y }; + barChartOptions.IndexAxis = "y"; + + barChartOptions.Scales.X!.Title = new ChartAxesTitle { Text = "Visitors", Display = true }; + barChartOptions.Scales.Y!.Title = new ChartAxesTitle { Text = "Browser", Display = true }; + + barChartOptions.Plugins.Legend.Display = false; + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await barChart.InitializeAsync(chartData, barChartOptions); + } + await base.OnAfterRenderAsync(firstRender); + } +} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_01_NET_8_WebAssembly_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_01_NET_8_WebAssembly_Documentation.razor new file mode 100644 index 00000000..864ac732 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_01_NET_8_WebAssembly_Documentation.razor @@ -0,0 +1,111 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +
+
+ +
    +
  • .NET 8 SDK (Download) or later version
  • +
  • Visual Studio 2022 or later / VS Code / Other
  • +
  • Basic knowledge of Blazor WebAssembly
  • +
+
+
+ +
+ +
    +
  1. + Install the template: +
    +

    TODO: Update the instructions.

    + + The template sets up BlazorExpress.ChartJS, the required services, and sample components. + +
  2. +
+
+
+ +
+ +
    +
  1. + Add the NuGet package: + +
  2. +
  3. + Add JS references: + Insert the following references into the body section of the wwwroot/index.html file, immediately after the _framework/blazor.webassembly.js reference: + +
  4. +
  5. + Register services: + Add @@using BlazorExpress.ChartJS to _Imports.razor: + + + @* Register services in Program.cs (if required): + +

    + Note: If AddBlazorExpressBulma() is not available, check the official documentation for the latest setup instructions. +

    *@ +
  6. + @*
  7. + Remove default references: + In wwwroot/index.html, remove the default CSS and JS references that conflict with Bulma: +
  8. *@ +
+
+
+ +
+ +
    +
  1. + Add a Bulma component to Pages/Home.razor: + +
  2. +
+
+
+ +
+ +
    +
  • Ensure all JS references are correct in index.html.
  • +
  • Restart the development server after making changes to static files.
  • +
  • Check the browser console for errors if components do not render as expected.
  • +
+
+
+ +
+ + + +
+
+ +@code { + private const string pageUrl = DemoRouteConstants.Docs_Getting_Started_Blazor_WebAssembly_NET8; + private const string pageTitle = "Getting started - Blazor WebAssembly (.NET 8)"; + private const string pageDescription = "Learn how to quickly set up BlazorExpress.ChartJS in your Blazor WebAssembly project using dotnet templates or manual installation, and how to register the required services."; + private const string metaTitle = "Getting started - Blazor WebAssembly (.NET 8)"; + private const string metaDescription = "Step-by-step guide to using BlazorExpress.ChartJS: dotnet templates, manual install, and service registration for Blazor WebAssembly apps."; + private const string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; // TODO: update +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_02_NET_8_WebApp_Server_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_02_NET_8_WebApp_Server_Documentation.razor new file mode 100644 index 00000000..8f63029a --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_02_NET_8_WebApp_Server_Documentation.razor @@ -0,0 +1,111 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +
+
+ +
    +
  • .NET 8 SDK (Download) or later version
  • +
  • Visual Studio 2022 or later / VS Code / Other
  • +
  • Basic knowledge of Blazor WebAssembly
  • +
+
+
+ +
+ +
    +
  1. + Install the template: +
    +

    TODO: Update the instructions.

    + + The template sets up BlazorExpress.ChartJS, the required services, and sample components. + +
  2. +
+
+
+ +
+ +
    +
  1. + Add the NuGet package: + +
  2. +
  3. + Add JS references: + Insert the following references into the body section of the Components/App.razor file, immediately after the _framework/blazor.web.js reference: + +
  4. +
  5. + Register services: + Add @@using BlazorExpress.ChartJS to _Imports.razor: + + + @* Register services in Program.cs (if required): + +

    + Note: If AddBlazorExpressBulma() is not available, check the official documentation for the latest setup instructions. +

    *@ +
  6. + @*
  7. + Remove default references: + In wwwroot/index.html, remove the default CSS and JS references that conflict with Bulma: +
  8. *@ +
+
+
+ +
+ +
    +
  1. + Add a Bulma component to Components/Pages/Home.razor: + +
  2. +
+
+
+ +
+ +
    +
  • Ensure all JS references are correct in App.razor.
  • +
  • Restart the development server after making changes to static files.
  • +
  • Check the browser console for errors if components do not render as expected.
  • +
+
+
+ +
+ + + +
+
+ +@code { + private const string pageUrl = DemoRouteConstants.Docs_Getting_Started_Blazor_WebApp_NET_8_Interactive_Render_Mode_Server_Global_Location; + private const string pageTitle = "Getting started - Blazor WebApp (.NET 8) - Interactive render mode Server - Global location"; + private const string pageDescription = "Learn how to quickly set up BlazorExpress.Bulma in your Blazor WebApp (Server) project using dotnet templates or manual installation, and how to register required services."; + private const string metaTitle = "Getting started - Blazor WebApp (.NET 8) - Interactive render mode Server - Global location"; + private const string metaDescription = "Step-by-step guide to using BlazorExpress.Bulma: dotnet templates, manual install, and service registration for Blazor WebApp (Server) apps."; + private const string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; // TODO: update +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_03_NET_8_WebApp_Auto_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_03_NET_8_WebApp_Auto_Documentation.razor new file mode 100644 index 00000000..b753b4f4 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_03_NET_8_WebApp_Auto_Documentation.razor @@ -0,0 +1,118 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +
+

Prerequisites

+
    +
  • .NET 8 SDK (Download)
  • +
  • Visual Studio 2022 (v17.8 or later) / VS Code / Other
  • +
  • Basic knowledge of Blazor WebApp (Interactive Render Mode: Auto)
  • +
+ +

1. Using dotnet Templates

+
    +
  1. + Install the template: +
    dotnet new install BlazorExpress.Bulma.Templates
    +
  2. +
  3. + Create a new project: +
    dotnet new blazorexpress-bulma -n MyBlazorApp
    +
  4. +
  5. + Run your app: +
    cd MyBlazorApp
    +dotnet run
    +
  6. +
+

+ The template sets up Bulma CSS, required services, and sample components. +

+ +

2. Manual Installation

+
    +
  1. + Add the NuGet package: +
    dotnet add package BlazorExpress.Bulma
    +
  2. +
  3. + Add Bulma and BlazorExpress.Bulma CSS to Components/Layouts/MainLayout.razor or _Host.cshtml: +
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.0/css/bulma.min.css">
    +<link rel="stylesheet" href="_content/BlazorExpress.Bulma/css/blazorexpress.bulma.css">
    +
    +
  4. +
  5. + Add BlazorExpress.Bulma JS to Components/Layouts/MainLayout.razor or _Host.cshtml: +
    <script src="_content/BlazorExpress.Bulma/js/blazorexpress.bulma.js"></script>
    +
    +
  6. +
  7. + Add @@using BlazorExpress.Bulma to _Imports.razor: +
    
    +@using BlazorExpress.Bulma
    +            
    +
  8. +
  9. + Register services in Program.cs (if required): +
    
    +// Program.cs
    +using BlazorExpress.Bulma;
    +
    +var builder = WebApplication.CreateBuilder(args);
    +// ... your existing setup
    +
    +// Register BlazorExpress.Bulma services (if required)
    +builder.Services.AddBlazorExpressBulma();
    +
    +var app = builder.Build();
    +// ... your existing setup
    +app.Run();
    +            
    +

    + Note: If AddBlazorExpressBulma() is not available, check the official documentation for the latest setup instructions. +

    +
  10. +
+ +

3. Usage Example

+

+ Add a Bulma component to Pages/Index.razor: +

+

+<BeButton Color="Color.Primary">Hello Bulma!</BeButton>
+    
+ +

4. Troubleshooting

+
    +
  • Ensure all CSS and JS references are correct in your layout or host file.
  • +
  • Restart the development server after changes to static files.
  • +
  • Check browser console for errors if components do not render as expected.
  • +
+ +

References

+ +
+ +@code { + private const string pageUrl = DemoRouteConstants.Docs_Getting_Started_Blazor_WebApp_NET_8_Interactive_Render_Mode_Auto_Global_Location; + private const string pageTitle = "Getting started - Blazor WebApp (.NET 8) - Interactive render mode Auto - Global location"; + private const string pageDescription = "Learn how to quickly set up BlazorExpress.Bulma in your Blazor WebApp (Auto) project using dotnet templates or manual installation, and how to register required services."; + private const string metaTitle = "Getting started - Blazor WebApp (.NET 8) - Interactive render mode Auto - Global location"; + private const string metaDescription = "Step-by-step guide to using BlazorExpress.Bulma: dotnet templates, manual install, and service registration for Blazor WebApp (Auto) apps."; + private const string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; // TODO: update +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_04_NET_8_MAUI_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_04_NET_8_MAUI_Documentation.razor new file mode 100644 index 00000000..99a64ce4 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/GettingStarted/net8/GettingStarted_04_NET_8_MAUI_Documentation.razor @@ -0,0 +1,108 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +
+

1. Using dotnet Templates

+

+ The fastest way to get started is with the official BlazorExpress.Bulma project template. +

+
    +
  1. + Install the template: +
    dotnet new install BlazorExpress.Bulma.Templates
    +
  2. +
  3. + Create a new project: +
    dotnet new blazorexpress-bulma -n MyBlazorApp
    +
  4. +
  5. + Run your app: +
    cd MyBlazorApp
    +dotnet run
    +
  6. +
+

+ The template sets up everything you need, including Bulma CSS, required services, and sample components. +

+ +

2. Manual Install

+

+ To add BlazorExpress.Bulma to an existing Blazor project: +

+
    +
  1. + Add the NuGet package: +
    dotnet add package BlazorExpress.Bulma
    +
  2. +
  3. + Add Bulma and BlazorExpress.Bulma CSS to your wwwroot/index.html (Blazor WASM) or _Host.cshtml (Blazor Server): +
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.0/css/bulma.min.css">
    +<link rel="stylesheet" href="_content/BlazorExpress.Bulma/css/blazorexpress.bulma.css">
    +
    +
  4. +
  5. + Add BlazorExpress.Bulma JS: +
    <script src="_content/BlazorExpress.Bulma/js/blazorexpress.bulma.js"></script>
    +
    +
  6. +
  7. + Add _Imports.razor references: +

    + To use BlazorExpress.Bulma components in your pages without fully qualified names, add the following to your _Imports.razor: +

    +
    
    +@using BlazorExpress.Bulma
    +            
    +

    + Add any other namespaces as needed for your project. +

    +
  8. +
+ +

3. Register Services

+

+ In your Program.cs, register any required services. For most scenarios, no extra registration is needed, but if the library introduces services, add them as follows: +

+

+// Program.cs
+using BlazorExpress.Bulma;
+
+var builder = WebAssemblyHostBuilder.CreateDefault(args);
+// ... your existing setup
+
+// Register BlazorExpress.Bulma services (if required)
+builder.Services.AddBlazorExpressBulma();
+
+await builder.Build().RunAsync();
+
+

+ Note: If AddBlazorExpressBulma() is not available, check the official documentation for the latest setup instructions. +

+ +

References

+ +
+ +@code { + private const string pageUrl = DemoRouteConstants.Docs_Getting_Started_MAUI_NET_8; + private const string pageTitle = "Getting started - MAUI Blazor Hybrid App (.NET 8)"; + private const string pageDescription = "Learn how to quickly set up BlazorExpress.Bulma in your Blazor project using dotnet templates or manual installation, and how to register required services."; + private const string metaTitle = "Getting started - MAUI Blazor Hybrid App (.NET 8)"; + private const string metaDescription = "Step-by-step guide to using BlazorExpress.Bulma: dotnet templates, manual install, and service registration for Blazor apps."; + private const string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; // TODO: update +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/LineChart/LineChart_Doc_01_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/LineChart/LineChart_Doc_01_Documentation.razor new file mode 100644 index 00000000..0e970b24 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/LineChart/LineChart_Doc_01_Documentation.razor @@ -0,0 +1,52 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +Blazor Line Chart - API Documentation + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +@code { + private const string componentName = nameof(LineChart); + private const string pageUrl = DemoRouteConstants.Docs_LineChart; + private const string pageTitle = $"Blazor {componentName} component"; + private const string pageDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string metaTitle = $"Blazor {componentName} component API Reference & Configuration Guide"; + private const string metaDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string imageUrl = @DemoImageSrcConstants.LineChart; +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/PieChart/PieChart_Doc_01_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/PieChart/PieChart_Doc_01_Documentation.razor new file mode 100644 index 00000000..0fcf4631 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/PieChart/PieChart_Doc_01_Documentation.razor @@ -0,0 +1,52 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +Blazor Pie Chart - API Documentation + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +@code { + private const string componentName = nameof(PieChart); + private const string pageUrl = DemoRouteConstants.Docs_PieChart; + private const string pageTitle = $"Blazor {componentName} component"; + private const string pageDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string metaTitle = $"Blazor {componentName} component API Reference & Configuration Guide"; + private const string metaDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string imageUrl = @DemoImageSrcConstants.PieChart; +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/PolarAreaChart/PolarAreaChart_Doc_01_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/PolarAreaChart/PolarAreaChart_Doc_01_Documentation.razor new file mode 100644 index 00000000..80d7ee1b --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/PolarAreaChart/PolarAreaChart_Doc_01_Documentation.razor @@ -0,0 +1,52 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +Blazor PolarArea Chart - API Documentation + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +@code { + private const string componentName = nameof(PolarAreaChart); + private const string pageUrl = DemoRouteConstants.Docs_PolarAreaChart; + private const string pageTitle = $"Blazor {componentName} component"; + private const string pageDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string metaTitle = $"Blazor {componentName} component API Reference & Configuration Guide"; + private const string metaDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string imageUrl = @DemoImageSrcConstants.PolarAreaChart; +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/RadarChart/RadarChart_Doc_01_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/RadarChart/RadarChart_Doc_01_Documentation.razor new file mode 100644 index 00000000..d88d8704 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/RadarChart/RadarChart_Doc_01_Documentation.razor @@ -0,0 +1,52 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +Blazor Radar Chart - API Documentation + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +@code { + private const string componentName = nameof(RadarChart); + private const string pageUrl = DemoRouteConstants.Docs_RadarChart; + private const string pageTitle = $"Blazor {componentName} component"; + private const string pageDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string metaTitle = $"Blazor {componentName} component API Reference & Configuration Guide"; + private const string metaDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string imageUrl = @DemoImageSrcConstants.RadarChart; +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/ScatterChart/ScatterChart_Doc_01_Documentation.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/ScatterChart/ScatterChart_Doc_01_Documentation.razor new file mode 100644 index 00000000..48c389e4 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Docs/ScatterChart/ScatterChart_Doc_01_Documentation.razor @@ -0,0 +1,52 @@ +@attribute [Route(pageUrl)] +@layout DocsMainLayout + + + + + + @((MarkupString)pageDescription) + + + +Blazor Scatter Chart - API Documentation + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +@code { + private const string componentName = nameof(ScatterChart); + private const string pageUrl = DemoRouteConstants.Docs_ScatterChart; + private const string pageTitle = $"Blazor {componentName} component"; + private const string pageDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string metaTitle = $"Blazor {componentName} component API Reference & Configuration Guide"; + private const string metaDescription = $"Comprehensive API documentation for the Blazor {componentName} component, including configuration options, parameters, methods, events, child component parameters, and model properties."; + private const string imageUrl = @DemoImageSrcConstants.ScatterChart; +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Home/Index.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Home/Index.razor new file mode 100644 index 00000000..c2bfc94f --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Home/Index.razor @@ -0,0 +1,66 @@ +@attribute [Route(pageUrl)] + + + +
+
+
+
+ New in @version + @releaseShortDescription +
+
+ BlazorExpress Logo +
+
+ + + @((MarkupString)pageTitle) + + + @((MarkupString)pageDescription) + + +
+ Nuget + + Nuget +
+
+
+ +
+ + + + + + + +
+ +@code { + private const string pageUrl = "/"; + private const string pageTitle = $"{DemoStringConstants.NugetPackageName} Components
Fast, Free & Open Source"; + private const string pageDescription = $"Get started with {DemoStringConstants.NugetPackageDisplayName}. Build high-performance, responsive Blazor apps quickly with our free, open-source UI library. Developers, build in minutes!"; + private const string metaTitle = $"{DemoStringConstants.NugetPackageName} Components: Fast, Free & Open Source"; + private const string metaDescription = $"Get started with {DemoStringConstants.NugetPackageDisplayName}. Build high-performance, responsive Blazor apps quickly with our free, open-source UI library. Developers, build in minutes!"; + private const string imageUrl = "https://i.imgur.com/FGgEMp6.jpg"; // TODO: update + + private string version = default!; + private string releaseShortDescription = default!; + private string githubUrl = default!; + private string nugetUrl = default!; + + [Inject] public IConfiguration Configuration { get; set; } = default!; + + protected override void OnInitialized() + { + version = $"v{Configuration["version"]}"; // example: v0.6.1 + releaseShortDescription = Configuration["release:short_description"]!; + githubUrl = $"{Configuration["urls:github"]}"; + nugetUrl = $"{Configuration["urls:nuget"]}"; + } +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/Home/IndexComponentLinks.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/Home/IndexComponentLinks.razor new file mode 100644 index 00000000..748d7833 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/Home/IndexComponentLinks.razor @@ -0,0 +1,54 @@ +
+

@Title

+
+
+ +
+ +@code { + private HashSet componentsLinks = null!; + + [Parameter] + public string Title { get; set; } = default!; + + [Parameter] + public DemoPageLinkCategory Category { get; set; } = DemoPageLinkCategory.All; + + protected override void OnInitialized() + { + componentsLinks = DemoPageLinkUtil.GetDemosLinks() + .Where(link => link.Categories.Contains(Category) && link.IsActive && !link.ExcludedFromHomePage) + .ToHashSet(); + } +} \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/Pages/blog/Index.razor b/BlazorExpress.ChartJS.Demo.RCL/Pages/blog/Index.razor new file mode 100644 index 00000000..4fd2a78b --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Pages/blog/Index.razor @@ -0,0 +1,48 @@ +@attribute [Route(pageUrl)] +@attribute [Route(pageUrl2)] +@layout BlogMainLayout + + + + + + @((MarkupString)pageDescription) + + + +
+ + Welcome to the official BlazorExpress.ChartJS Blog! Here you’ll find the latest news, tutorials, and best practices for building interactive charts and data visualizations in your Blazor WebAssembly applications using ChartJS. +

+
    +
  • Getting Started Guides: Step-by-step instructions for integrating ChartJS with Blazor.
  • +
  • Feature Highlights: Deep dives into new and advanced charting features.
  • +
  • Practical Examples: Real-world use cases and code samples for bar, line, pie, and custom charts.
  • +
  • Performance Tips: Learn how to optimize chart rendering and interactivity in Blazor WebAssembly.
  • +
  • Release Notes: Stay up to date with the latest updates and improvements to BlazorExpress.ChartJS.
  • +
+ Whether you’re new to Blazor or looking to enhance your data visualization skills, our blog provides practical insights and inspiration for your next project. +
+
+ +
+ +
    +
  • How to create interactive charts in Blazor WebAssembly
  • +
  • Customizing ChartJS components for your Blazor app
  • +
  • Responsive and accessible data visualizations
  • +
  • Integrating ChartJS plugins and advanced options
  • +
  • Best practices for Blazor and ChartJS performance
  • +
+
+
+ +@code { + private const string pageUrl = DemoRouteConstants.Blog_Home; + private const string pageUrl2 = DemoRouteConstants.Blog_Prefix; + private const string pageTitle = "BlazorExpress.ChartJS Blog – Tutorials, News & ChartJS Tips for Blazor"; + private const string pageDescription = "Discover tutorials, news, and practical examples for BlazorExpress.ChartJS. Learn how to build interactive charts in Blazor WebAssembly with ChartJS."; + private const string metaTitle = "BlazorExpress.ChartJS Blog – Tutorials, News & ChartJS Tips for Blazor"; + private const string metaDescription = "Explore the official BlazorExpress.ChartJS blog for tutorials, updates, and practical examples on building interactive charts in Blazor WebAssembly using ChartJS."; + private const string imageUrl = "https://i.imgur.com/IX3bajc.png"; // TODO: update with the actual image URL for the Bar Chart demo +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/Usings.cs b/BlazorExpress.ChartJS.Demo.RCL/Usings.cs index b10d3a15..bbb3b10f 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/Usings.cs +++ b/BlazorExpress.ChartJS.Demo.RCL/Usings.cs @@ -1,10 +1,7 @@ -global using BlazorExpress.ChartJS.Demo.RCL; +global using BlazorExpress.Bulma; +global using BlazorExpress.Bulma.Docx; +global using BlazorExpress.ChartJS.Demo.RCL; global using Microsoft.AspNetCore.Components; -global using Microsoft.AspNetCore.Components.Rendering; -global using Microsoft.AspNetCore.Components.Routing; global using Microsoft.Extensions.Configuration; -global using Microsoft.Extensions.DependencyInjection; global using Microsoft.JSInterop; -global using System.Linq.Expressions; -global using System.Net.Http.Json; -global using BlazorBootstrap; +global using System.ComponentModel; diff --git a/BlazorExpress.ChartJS.Demo.RCL/Utils/DemoPageLinkUtil.cs b/BlazorExpress.ChartJS.Demo.RCL/Utils/DemoPageLinkUtil.cs new file mode 100644 index 00000000..07c775f2 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/Utils/DemoPageLinkUtil.cs @@ -0,0 +1,42 @@ +namespace BlazorExpress.ChartJS.Demo.RCL; + +public static class DemoPageLinkUtil +{ + public static HashSet GetDemosLinks() + { + var index = 1; + var links = new HashSet(); + + index += 1; + links.Add(new PageLink { Id = index, IconName = BootstrapIconName.HouseDoorFill, Href = DemoRouteConstants.Docs_Getting_Started_Prefix, Text = "Getting Started", Categories = new() { DemoPageLinkCategory.All, DemoPageLinkCategory.GettingStarted }, Status = PageLinkStatus.None, IsActive = true, ExcludedFromHomePage = true }); + + index += 1; + links.Add(new PageLink { Id = index, IconName = BootstrapIconName.BarChartFill, Href = DemoRouteConstants.Demos_BarChart, Text = "Bar Chart", Categories = new() { DemoPageLinkCategory.All, DemoPageLinkCategory.Charts }, Status = PageLinkStatus.None, IsActive = true }); + + index += 1; + links.Add(new PageLink { Id = index, IconName = BootstrapIconName.Diagram3Fill, Href = DemoRouteConstants.Demos_BubbleChart, Text = "Bubble Chart", Categories = new() { DemoPageLinkCategory.All, DemoPageLinkCategory.Charts }, Status = PageLinkStatus.New, IsActive = true }); + + index += 1; + links.Add(new PageLink { Id = index, IconName = BootstrapIconName.CircleFill, Href = DemoRouteConstants.Demos_DoughnutChart, Text = "Doughnut Chart", Categories = new() { DemoPageLinkCategory.All, DemoPageLinkCategory.Charts }, Status = PageLinkStatus.None, IsActive = true }); + + index += 1; + links.Add(new PageLink { Id = index, IconName = BootstrapIconName.GraphUp, Href = DemoRouteConstants.Demos_LineChart, Text = "Line Chart", Categories = new() { DemoPageLinkCategory.All, DemoPageLinkCategory.Charts }, Status = PageLinkStatus.None, IsActive = true }); + + index += 1; + links.Add(new PageLink { Id = index, IconName = BootstrapIconName.PieChart, Href = DemoRouteConstants.Demos_PieChart, Text = "Pie Chart", Categories = new() { DemoPageLinkCategory.All, DemoPageLinkCategory.Charts }, Status = PageLinkStatus.None, IsActive = true }); + + index += 1; + links.Add(new PageLink { Id = index, IconName = BootstrapIconName.PieChartFill, Href = DemoRouteConstants.Demos_PolarAreaChart, Text = "PolarArea Chart", Categories = new() { DemoPageLinkCategory.All, DemoPageLinkCategory.Charts }, Status = PageLinkStatus.None, IsActive = true }); + + index += 1; + links.Add(new PageLink { Id = index, IconName = BootstrapIconName.Radar, Href = DemoRouteConstants.Demos_RadarChart, Text = "Radar Chart", Categories = new() { DemoPageLinkCategory.All, DemoPageLinkCategory.Charts }, Status = PageLinkStatus.None, IsActive = true }); + + index += 1; + links.Add(new PageLink { Id = index, IconName = BootstrapIconName.GraphUpArrow, Href = DemoRouteConstants.Demos_ScatterChart, Text = "Scatter Chart", Categories = new() { DemoPageLinkCategory.All, DemoPageLinkCategory.Charts }, Status = PageLinkStatus.None, IsActive = true }); + + index += 1; + links.Add(new PageLink { Id = index, IconName = BootstrapIconName.Palette2, Href = DemoRouteConstants.Demos_ColorUtils, Text = "Color Utils", Categories = new() { DemoPageLinkCategory.All, DemoPageLinkCategory.Utils }, Status = PageLinkStatus.None, IsActive = true }); + + return links; + } +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/_Imports.razor b/BlazorExpress.ChartJS.Demo.RCL/_Imports.razor index a025b7bd..9f7125bd 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/_Imports.razor +++ b/BlazorExpress.ChartJS.Demo.RCL/_Imports.razor @@ -1,3 +1,6 @@ -@using BlazorExpress.ChartJS +@using BlazorExpress.Bulma +@using BlazorExpress.Bulma.Docx +@using BlazorExpress.ChartJS @using BlazroExpress.ChartJS.Demo.RCL -@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.RCL/wwwroot/css/blazorexpress.chartjs.demo.rcl.css b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/css/blazorexpress.chartjs.demo.rcl.css index d43d65c5..a72dbf13 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/wwwroot/css/blazorexpress.chartjs.demo.rcl.css +++ b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/css/blazorexpress.chartjs.demo.rcl.css @@ -1,382 +1,82 @@ :root { - --bd-purple: #4c0bce; - --bd-violet: #712cf9; - --bd-accent: #ffe484; - --bd-violet-rgb: 112.520718,44.062154,249.437846; - --bd-accent-rgb: 255,228,132; - --bd-pink-rgb: 214,51,132; - --bd-teal-rgb: 32,201,151; - --docsearch-primary-color: var(--bd-violet); - --docsearch-logo-color: var(--bd-violet); - --bs-body-color: #212529; - --bs-tertiary-bg: #f8f9fa; + --be-bulma-border-color: #dee2e6; + --be-bulma-border-radius: 0.375rem; + --be-bulma-pre-bg: #f8f9fa; + /*masthead*/ + --be-bulma-body-bg-rgb: 255,255,255; + --be-bulma-primary-rgb: 13,110,253; + --be-bulma-accent-rgb: 255, 228, 132; + --be-bulma-violet-rgb: 112.520718, 44.062154, 249.437846; + --be-bulma-pink-rgb: 214, 51, 132; } -h1:focus-visible { - outline: inherit !important; -} - -.skippy { - color: #fff !important; - background-color: #4c0bce !important; -} - - .skippy a { - color: #fff !important; - } - -.bd-navbar { - padding: .75rem 0; - background-color: transparent; - background-image: linear-gradient(to bottom, rgba(var(--bd-violet-rgb), 1), rgba(var(--bd-violet-rgb), 0.95)); - box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15) -} - -@media (max-width: 991.98px) { - .bd-navbar .bd-navbar-toggle { - width: 4.25rem - } -} - -.bd-navbar .navbar-toggler { - padding: 0; - margin-right: -.5rem; - border: 0 -} - - .bd-navbar .navbar-toggler:first-child { - margin-left: -.5rem - } - - .bd-navbar .navbar-toggler .bi { - width: 1.5rem; - height: 1.5rem - } - - .bd-navbar .navbar-toggler:focus { - box-shadow: none - } - -.bd-navbar .navbar-brand { - transition: .2s ease-in-out transform -} - - .bd-navbar .navbar-brand:hover { - transform: rotate(-5deg) scale(1.1) - } - -.bd-navbar .navbar-toggler, .bd-navbar .nav-link { - padding-right: .25rem; - padding-left: .25rem; - color: rgba(255,255,255,0.85) -} - - .bd-navbar .navbar-toggler:hover, .bd-navbar .navbar-toggler:focus, .bd-navbar .nav-link:hover, .bd-navbar .nav-link:focus { - color: #fff - } - - .bd-navbar .navbar-toggler.active, .bd-navbar .nav-link.active { - font-weight: 600; - color: #fff - } - -.bd-navbar .navbar-nav-svg { - display: inline-block; - vertical-align: -.125rem +[data-theme=light] { + --be-bulma-pre-bg: #f5f2f0; } -.bd-navbar .offcanvas-lg { - background-color: var(--bd-violet); - border-left: 0 +[data-theme=dark] { + --be-bulma-border-color: #495057; + --be-bulma-pre-bg: #1b1f22; } -@media (max-width: 991.98px) { - .bd-navbar .offcanvas-lg { - box-shadow: 0 1rem 3rem rgba(0,0,0,0.175) - } -} - -.bd-navbar .dropdown-toggle:focus:not(:focus-visible) { - outline: 0 -} - -.bd-navbar .dropdown-menu { - --bs-dropdown-min-width: 12rem; - --bs-dropdown-link-hover-bg: rgba(var(--bd-violet-rgb), .1); - --bs-dropdown-font-size: .875rem; - box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.15) -} - -.bd-navbar .dropdown-item.current { - font-weight: 600; - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right 1rem top 0.6rem; - background-size: .75rem .75rem -} - -.bd-masthead { - --bd-pink-rgb: 214,51,132; - padding: 3rem 0; - background-image: linear-gradient(180deg, rgba(var(--bs-body-bg-rgb), 0.01), rgba(var(--bs-body-bg-rgb), 1) 85%),radial-gradient(ellipse at top left, rgba(var(--bs-primary-rgb), 0.5), transparent 50%),radial-gradient(ellipse at top right, rgba(var(--bd-accent-rgb), 0.5), transparent 50%),radial-gradient(ellipse at center right, rgba(var(--bd-violet-rgb), 0.5), transparent 50%),radial-gradient(ellipse at center left, rgba(var(--bd-pink-rgb), 0.5), transparent 50%) -} - - .bd-masthead h1 { - font-size: calc(1.525rem + 3.3vw); - line-height: 1 - } - -@media (min-width: 1200px) { - .bd-masthead h1 { - font-size: 4rem - } -} - -.bd-masthead .lead { - font-size: 1rem; - font-weight: 400; - color: #495057 -} - -.bd-masthead .bd-code-snippet { - margin: 0; - border-radius: .5rem -} - -.bd-masthead .highlight { - width: 100%; - padding: .5rem 1rem; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - background-color: rgba(var(--bs-body-color-rgb), 0.075); - border-radius: .5rem -} - -@media (min-width: 992px) { - .bd-masthead .highlight { - padding-right: 4rem - } -} - -.bd-masthead .btn-clipboard { - position: absolute; - top: -.125rem; - right: 0; - background-color: transparent -} - -.bd-masthead #carbonads { - margin-right: auto; - margin-left: auto -} - -@media (min-width: 768px) { - .bd-masthead .lead { - font-size: calc(1.275rem + .3vw) - } -} - -@media (min-width: 768px) and (min-width: 1200px) { - .bd-masthead .lead { - font-size: 1.5rem - } -} - -.masthead-followup .lead { - font-size: 1rem -} - -.masthead-followup .highlight { - border-radius: .5rem -} - -@media (min-width: 768px) { - .masthead-followup .lead { - font-size: 1.25rem - } -} - -.bd-btn-lg { - padding: .8rem 2rem -} - -.masthead-followup-icon { - padding: 1rem; - color: rgba(var(--bg-rgb), 1); - background-color: rgba(var(--bg-rgb), 0.1); - background-blend-mode: multiple; - border-radius: 1rem; - mix-blend-mode: darken -} - - .masthead-followup-icon svg { - filter: drop-shadow(0 1px 1px #fff) - } - -.masthead-notice { - background-color: var(--bd-accent); - box-shadow: inset 0 -1px 1px rgba(var(--bs-body-color-rgb), 0.15),0 0.25rem 1.5rem rgba(var(--bs-body-bg-rgb), 0.75) -} - -.bd-gutter { - --bs-gutter-x: 3rem; -} - -.bd-footer a { - color: #495057; - text-decoration: none -} - - .bd-footer a:hover, .bd-footer a:focus { - color: #0d6efd; - text-decoration: underline - } - -/*** END: home ***/ - -.anchor-link { - font-weight: 400; - color: rgba(13,110,253,0.5); - transition: color 0.15s ease-in-out; - opacity: 0; - padding-left: 0.375em; - text-decoration: none; - -webkit-font-smoothing: antialiased; -} - -@media (prefers-reduced-motion: reduce) { - .anchor-link { - transition: none - } -} - -.anchor-link:focus, .anchor-link:hover { - color: #0d6efd; - text-decoration: none -} - -:hover > .anchor-link, .anchor-link:focus { - opacity: 1; -} - -.bb-example { - position: relative; - padding: 1rem; - margin-top: 1rem; - border: solid #dee2e6; - border-width: 1px; - border-top-left-radius: .25rem; - border-top-right-radius: .25rem; -} - - .bb-example::after { - display: block; - clear: both; - content: "" - } - -@media (min-width: 576px) { - .bb-example { - padding: 1.5rem; - } +h1:focus-visible { + outline: inherit !important; } -.bb-example + p { - margin-top: 2rem; +.be-bulma-masthead { + background-image: linear-gradient(180deg, rgba(var(--be-bulma-body-bg-rgb), 0.01), rgba(var(--be-bulma-body-bg-rgb), 1) 85%),radial-gradient(ellipse at top left, rgba(var(--be-bulma-primary-rgb), 0.5), transparent 50%),radial-gradient(ellipse at top right, rgba(var(--be-bulma-accent-rgb), 0.5), transparent 50%),radial-gradient(ellipse at center right, rgba(var(--be-bulma-violet-rgb), 0.5), transparent 50%),radial-gradient(ellipse at center left, rgba(var(--be-bulma-pink-rgb), 0.5), transparent 50%) } -.bb-example > .btn, .bb-example > .btn-group { - margin: .25rem .125rem; +.be-bulma-doc-example { + margin-bottom: 1rem; + border: 1px solid var(--be-bulma-border-color); + border-radius: var(--be-bulma-border-radius); } -.tab-pane.fade.active.show .bb-example { - border-top-left-radius: 0 !important; - border-top-right-radius: 0 !important; +.be-bulma-doc-example-demo { + border: 0 !important; + margin: 0 !important; } -.highlight { +.be-bulma-doc-example-demo { padding: 1rem; - margin-bottom: 1rem; - background-color: #f8f9fa; - border: solid #dee2e6; - border-width: 0 1px 1px 1px; - border-bottom-left-radius: .25rem; - border-bottom-right-radius: .25rem; } -@media (min-width: 576px) { - .highlight { - padding: 1rem 1.5rem - } +.be-bulma-doc-example-toolbar { + background-color: var(--be-bulma-pre-bg); + border-top: 1px solid var(--be-bulma-border-color); + border-bottom: 1px solid var(--be-bulma-border-color); } -.highlight pre { - padding: 0; - padding-bottom: 1rem !important; - margin-top: .65rem; - margin-bottom: .65rem; - white-space: pre; - background-color: transparent; - border: 0 +.be-bulma-doc-example-snippet { + background-color: var(--be-bulma-pre-bg); } - .highlight pre code { - font-size: inherit; - color: #212529; - word-wrap: normal + .be-bulma-doc-example-snippet pre { + background-color: var(--be-bulma-pre-bg) !important; + border: 0 !important; + margin-top: 0 !important; + margin-bottom: 0 !important; } -.tab-pane.fade.active.show .highlight { - border: 1px solid #dee2e6; - border-top-width: 0; -} - -.show-code-only { - border-width: 1px; - border-top-left-radius: 0.25rem; - border-top-right-radius: 0.25rem; - margin-top: 1rem; -} - -/* display */ -.display-7 { - font-size: 2rem -} - -.display-8 { - font-size: 1.5rem +.be-bulma-doc-float-end { + float: right !important; } -.display-9 { - font-size: 1.25rem +.be-bulma-doc-hr { + background-color: var(--bulma-primary) !important; + border-radius: 9999px; + height: .25rem; + margin: 1em auto; + width: 4em; } -.display-10 { - font-size: 1rem +.be-bulma-doc-hr-title { + margin-left: 0; } -/* position */ -.top-30 { - top: 30% !important; -} - -.top-40 { - top: 40% !important; -} - -/* icons */ -.list div:hover, .list div:hover .name, .list div:focus, .list div:focus .name { - color: #0d6efd !important; - cursor: pointer; -} - -/* HACK: sidebar */ -@media (min-width: 641px) { - .bb-example .nav-scrollable { - height: auto !important; - overflow-y: auto !important; - } +.be-bulma-doc-subtitle { + color: var(--bulma-text-weak); } /* carbon ads */ diff --git a/BlazorExpress.ChartJS.Demo.RCL/wwwroot/css/prism-vs.min.css b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/css/prism-vs.min.css new file mode 100644 index 00000000..61239881 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/css/prism-vs.min.css @@ -0,0 +1,117 @@ +code[class*=language-], pre[class*=language-] { + color: #393a34; + text-shadow: none; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + line-height: 1.5em; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none +} + + code[class*=language-] ::-moz-selection, code[class*=language-]::-moz-selection, pre[class*=language-] ::-moz-selection, pre[class*=language-]::-moz-selection { + background: #c1def1 + } + + code[class*=language-] ::selection, code[class*=language-]::selection, pre[class*=language-] ::selection, pre[class*=language-]::selection { + background: #c1def1 + } + +pre[class*=language-] { + padding: 1em; + margin: .5em 0; + overflow: auto; + background-color: #fff +} + +:not(pre) > code[class*=language-] { + padding: .1em .3em; + border-radius: .3em; + background: #f8f8f8; +} + +.prism-token.prism-cdata, .prism-token.prism-comment, .prism-token.prism-doctype, .prism-token.prism-prolog { + color: green; +} + +.prism-token.prism-namespace { + opacity: .7 +} + +.prism-token.prism-string { + color: #a31515 +} + +.prism-token.prism-operator, .prism-token.prism-punctuation { + color: #393a34 +} + +.prism-token.prism-boolean, .prism-token.prism-constant, .prism-token.prism-inserted, .prism-token.prism-number, .prism-token.prism-symbol, .prism-token.prism-url, .prism-token.prism-variable { + color: #36acaa +} + +.language-autohotkey .prism-token.prism-selector, .prism-language-json .prism-token.prism-boolean, .prism-language-json .prism-token.prism-number, .prism-token.prism-atrule, .prism-token.prism-attr-value, .prism-token.prism-keyword, code[class*=language-css] { + color: #00f +} + +.prism-token.prism-function { + color: #393a34 +} + +.language-autohotkey .prism-token.prism-tag, .prism-token.prism-deleted { + color: #9a050f +} + +.language-autohotkey .prism-token.prism-keyword, .prism-token.prism-selector { + color: #00009f +} + +.prism-token.prism-important { + color: #e90 +} + +.prism-token.prism-bold, .prism-token.prism-important { + font-weight: 700 +} + +.prism-token.prism-italic { + font-style: italic +} + +.language-json .prism-token.prism-property, .prism-token.prism-class-name { + color: #2b91af +} + +.prism-token.prism-selector, .prism-token.prism-tag { + color: maroon +} + +.prism-token.prism-attr-name, .prism-token.prism-entity, .prism-token.prism-property, .prism-token.prism-regex { + color: red +} + +.prism-token.prism-directive.prism-tag .prism-tag { + background: #ff0; + color: #393a34 +} + +.prism-line-numbers.prism-line-numbers .prism-line-numbers-rows { + border-right-color: #a5a5a5 +} + +.prism-line-numbers .prism-line-numbers-rows > span:before { + color: #2b91af +} + +.line-highlight.line-highlight { + background: rgba(193,222,241,.2); + background: -webkit-linear-gradient(left,rgba(193,222,241,.2) 70%,rgba(221,222,241,0)); + background: linear-gradient(to right,rgba(193,222,241,.2) 70%,rgba(221,222,241,0)) +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/wwwroot/css/prism-vsc-dark-plus.min.css b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/css/prism-vsc-dark-plus.min.css new file mode 100644 index 00000000..0e85e720 --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/css/prism-vsc-dark-plus.min.css @@ -0,0 +1,226 @@ +code[class*=language-], pre[class*=language-] { + color: #d4d4d4; + text-shadow: none; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + line-height: 1.5; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none +} + + code[class*=language-] ::selection, code[class*=language-]::selection, pre[class*=language-] ::selection, pre[class*=language-]::selection { + text-shadow: none; + background: #264f78 + } + +@media print { + code[class*=language-], pre[class*=language-] { + text-shadow: none + } +} + +pre[class*=language-] { + padding: 1em; + margin: .5em 0; + overflow: auto; + background: #1e1e1e +} + +:not(pre) > code[class*=language-] { + padding: .1em .3em; + border-radius: .3em; + color: #db4c69; + background: #1e1e1e +} + +.prism-namespace { + opacity: .7 +} + +.prism-token.prism-doctype .prism-token.prism-doctype-tag { + color: #569cd6 +} + +.prism-token.prism-doctype .prism-token.prism-name { + color: #9cdcfe +} + +.prism-token.prism-comment, .prism-token.prism-prolog { + color: #6a9955 +} + +.language-html .language-css .prism-token.prism-punctuation, .language-html .language-javascript .prism-token.prism-punctuation, .prism-token.prism-punctuation { + color: #d4d4d4 +} + +.prism-token.prism-boolean, .prism-token.prism-constant, .prism-token.prism-inserted, .prism-token.prism-number, .prism-token.prism-property, .prism-token.prism-symbol, .prism-token.prism-tag, .prism-token.prism-unit { + color: #b5cea8 +} + +.prism-token.prism-attr-name, .prism-token.prism-builtin, .prism-token.prism-char, .prism-token.prism-deleted, .prism-token.prism-selector, .prism-token.prism-string { + color: #ce9178 +} + +.language-css .prism-token.prism-string.prism-url { + text-decoration: underline +} + +.prism-token.prism-entity, .prism-token.prism-operator { + color: #d4d4d4 +} + + .prism-token.prism-operator.prism-arrow { + color: #569cd6 + } + +.prism-token.prism-atrule { + color: #ce9178 +} + + .prism-token.prism-atrule .prism-token.prism-rule { + color: #c586c0 + } + + .prism-token.prism-atrule .prism-token.prism-url { + color: #9cdcfe + } + + .prism-token.prism-atrule .prism-token.prism-url .prism-token.prism-function { + color: #dcdcaa + } + + .prism-token.prism-atrule .prism-token.prism-url .prism-token.prism-punctuation { + color: #d4d4d4 + } + +.prism-token.prism-keyword { + color: #569cd6 +} + + .prism-token.prism-keyword.prism-control-flow, .prism-token.prism-keyword.prism-module { + color: #c586c0 + } + +.prism-token.prism-function, .prism-token.prism-function .prism-token.prism-maybe-class-name { + color: #dcdcaa +} + +.prism-token.prism-regex { + color: #d16969 +} + +.prism-token.prism-important { + color: #569cd6 +} + +.prism-token.prism-bold, .prism-token.prism-important { + font-weight: 700 +} + +.prism-token.prism-italic { + font-style: italic +} + +.prism-token.prism-constant { + color: #9cdcfe +} + +.prism-token.prism-class-name, .prism-token.prism-maybe-class-name { + color: #4ec9b0 +} + +.prism-token.prism-console { + color: #9cdcfe +} + +.prism-token.prism-parameter { + color: #9cdcfe +} + +.prism-token.prism-interpolation { + color: #9cdcfe +} + +.prism-token.prism-punctuation.prism-interpolation-punctuation { + color: #569cd6 +} + +.prism-token.prism-boolean { + color: #569cd6 +} + +.prism-token.prism-exports .prism-token.prism-maybe-class-name, .prism-token.prism-imports .prism-token.prism-maybe-class-name, .prism-token.prism-property, .prism-token.prism-variable { + color: #9cdcfe +} + +.prism-token.prism-selector { + color: #d7ba7d +} + +.prism-token.prism-escape { + color: #d7ba7d +} + +.prism-token.prism-tag { + color: #569cd6 +} + + .prism-token.prism-tag .prism-token.prism-punctuation { + color: grey + } + +.prism-token.prism-cdata { + color: grey +} + +.prism-token.prism-attr-name { + color: #9cdcfe +} + +.prism-token.prism-attr-value, .prism-token.prism-attr-value .prism-token.prism-punctuation { + color: #ce9178 +} + + .prism-token.prism-attr-value .prism-token.prism-punctuation.prism-attr-equals { + color: #d4d4d4 + } + +.prism-token.prism-entity { + color: #569cd6 +} + +.prism-token.prism-namespace { + color: #4ec9b0 +} + +code[class*=language-javascript], code[class*=language-jsx], code[class*=language-tsx], code[class*=language-typescript], pre[class*=language-javascript], pre[class*=language-jsx], pre[class*=language-tsx], pre[class*=language-typescript] { + color: #9cdcfe +} + +code[class*=language-css], pre[class*=language-css] { + color: #ce9178 +} + +code[class*=language-html], pre[class*=language-html] { + color: #d4d4d4 +} + +.language-regex .prism-token.prism-anchor { + color: #dcdcaa +} + +.language-html .prism-token.prism-punctuation { + color: grey +} + +.line-highlight.line-highlight { + background: #f7ebc6; +} diff --git a/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo-dark.png b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo-dark.png new file mode 100644 index 00000000..a71dd0d7 Binary files /dev/null and b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo-dark.png differ diff --git a/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo-dark.svg b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo-dark.svg new file mode 100644 index 00000000..42efe9fb --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo-dark.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo.png b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo.png new file mode 100644 index 00000000..e50f36d5 Binary files /dev/null and b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo.png differ diff --git a/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo.svg b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo.svg new file mode 100644 index 00000000..973ec61e --- /dev/null +++ b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/icons/logo.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BlazorExpress.ChartJS.Demo.RCL/wwwroot/js/blazorexpress.chartjs.demo.rcl.js b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/js/blazorexpress.chartjs.demo.rcl.js index 139fbbc2..e817ab8b 100644 --- a/BlazorExpress.ChartJS.Demo.RCL/wwwroot/js/blazorexpress.chartjs.demo.rcl.js +++ b/BlazorExpress.ChartJS.Demo.RCL/wwwroot/js/blazorexpress.chartjs.demo.rcl.js @@ -17,6 +17,7 @@ async function copyToClipboard(text, dotNetHelper) { function highlightCode() { if (Prism) { + Prism.plugins.customClass.prefix('prism-'); Prism.highlightAll(); } }; @@ -32,3 +33,93 @@ function navigateToHeading() { } } } + +// THEMES +const STORAGE_KEY = "be-bulma-theme"; +const DEFAULT_THEME = "light"; +const SYSTEM_THEME = "system"; + +const state = { + chosenTheme: SYSTEM_THEME, // light|dark|system + appliedTheme: DEFAULT_THEME // light|dark +}; + +const showActiveTheme = () => { + let $themeIndicator = document.querySelector(".be-bulma-theme-indicator i"); + if (state.appliedTheme === "light") { + $themeIndicator.className = "bi bi-sun"; + } else if (state.appliedTheme === "dark") { + $themeIndicator.className = "bi bi-moon-stars-fill"; + } else { + $themeIndicator.className = "bi bi-circle-half"; + } + + let $themeSwitchers = document.querySelectorAll(".be-bulma-theme-item"); + $themeSwitchers.forEach((el) => { + const dataScheme = el.dataset.scheme; + if (state.chosenTheme === dataScheme) { + el.classList.add("is-selected"); + } else { + el.classList.remove("is-selected"); + } + }); +}; + +function setTheme(theme, save = true) { + state.chosenTheme = theme; + state.appliedTheme = theme; + + if (theme === SYSTEM_THEME) { + state.appliedTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; + } + + document.documentElement.setAttribute("data-theme", state.appliedTheme); + if (save) { + window.localStorage.setItem(STORAGE_KEY, state.chosenTheme); + } + showActiveTheme(); + updateDemoCodeThemeCss(state.appliedTheme); +}; + +function initializeTheme() { + const localTheme = window.localStorage.getItem(STORAGE_KEY); + if (localTheme) { + setTheme(localTheme, false); + } else { + setTheme(SYSTEM_THEME); + } +} + +window + .matchMedia("(prefers-color-scheme: dark)") + .addEventListener("change", (event) => { + const theme = event.matches ? "dark" : "light"; + setTheme(theme); + }); + +function updateDemoCodeThemeCss(theme) { + if (theme === "dark") { + let prismThemeLightLinkEl = document.getElementById('prismThemeLightLink'); + if (prismThemeLightLinkEl) + prismThemeLightLinkEl?.remove(); + + let prismThemeDarkLinkEl = document.createElement("link"); + prismThemeDarkLinkEl.setAttribute("rel", "stylesheet"); + prismThemeDarkLinkEl.setAttribute("href", "/_content/BlazorExpress.ChartJS.Demo.RCL/css/prism-vsc-dark-plus.min.css"); + prismThemeDarkLinkEl.setAttribute("id", "prismThemeDarkLink"); + + document.head.append(prismThemeDarkLinkEl); + } + else if (theme === "light") { + let prismThemeDarkLinkEl = document.getElementById('prismThemeDarkLink'); + if (prismThemeDarkLinkEl) + prismThemeDarkLinkEl?.remove(); + + let prismThemeLightLinkEl = document.createElement("link"); + prismThemeLightLinkEl.setAttribute("rel", "stylesheet"); + prismThemeLightLinkEl.setAttribute("href", "/_content/BlazorExpress.ChartJS.Demo.RCL/css/prism-vs.min.css"); + prismThemeLightLinkEl.setAttribute("id", "prismThemeLightLink"); + + document.head.append(prismThemeLightLinkEl); + } +} diff --git a/BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/appsettings.json b/BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/appsettings.json index 013d3b1d..060cce91 100644 --- a/BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/appsettings.json +++ b/BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/appsettings.json @@ -3,17 +3,22 @@ "release": { "short_description": "Bar, Doughnut, Line and Pie chart components!!!" }, + "NugetPackageName": "BlazorExpress.ChartJS", + "NugetPackageDisplayName": "BlazorExpress ChartJS", "urls": { "home": "//chartjs.blazorexpress.com", "docs": "//chartjs.blazorexpress.com/docs", + "demos": "//chartjs.blazorexpress.com/demos", "blog": "//chartjs.blazorexpress.com/blog", "github": "//github.com/BlazorExpress/BlazorExpress.ChartJS", "nuget": "//www.nuget.org/packages/BlazorExpress.ChartJS", "twitter": "//twitter.com/blazorexpress", "linkedin": "//www.linkedin.com/groups/14161025", "youtube": "//www.youtube.com/@BlazorExpress", + "opencollective": "//opencollective.com/blazorexpress", "github_issues": "//github.com/BlazorExpress/BlazorExpress.ChartJS/issues", "github_discussions": "//github.com/BlazorExpress/BlazorExpress.ChartJS/discussions", - "stackoverflow": "//stackoverflow.com/questions/tagged/blazor-express" - } + "stackoverflow": "//stackoverflow.com/questions/tagged/blazorexpress-chartjs" + }, + "dotNetVersion": "8.0.0" } \ No newline at end of file diff --git a/BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/index.html b/BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/index.html index feea0d84..60faaf42 100644 --- a/BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/index.html +++ b/BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/index.html @@ -7,11 +7,14 @@ BlazorExpress.ChartJS.Demo.WebAssembly - - + + - + + + + @@ -28,26 +31,29 @@
-
-
- Blazor Bootstrap - The BlazorExpress.ChartJs component library is a production-ready library built with Blazor and the Chart.js JavaScript library. +
+
+ Blazor Bootstrap - The BlazorExpress.ChartJs component library is a production-ready library built with Blazor and the Chart.js JavaScript library.
Loading...
- + + - + - - + - + + + + diff --git a/BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/logo-180.png b/BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/logo.png similarity index 100% rename from BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/logo-180.png rename to BlazorExpress.ChartJS.Demo.WebAssembly/wwwroot/logo.png diff --git a/BlazorExpress.ChartJS.sln b/BlazorExpress.ChartJS.sln index 1afa0eef..29244aa1 100644 --- a/BlazorExpress.ChartJS.sln +++ b/BlazorExpress.ChartJS.sln @@ -9,6 +9,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlazorExpress.ChartJS.Demo. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlazorExpress.ChartJS.Demo.WebAssembly", "BlazorExpress.ChartJS.Demo.WebAssembly\BlazorExpress.ChartJS.Demo.WebAssembly.csproj", "{7064944C-CF0A-4D64-AF1B-1F57EFBDA108}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "demos", "demos", "{1B73E52F-BE4E-4EF2-B8E5-A795BA44FF5F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -31,6 +35,11 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {F618FB87-B86A-4A57-950A-9DD032E090CB} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8} + {B719B79F-9D20-4D39-96EB-7386B40EE693} = {1B73E52F-BE4E-4EF2-B8E5-A795BA44FF5F} + {7064944C-CF0A-4D64-AF1B-1F57EFBDA108} = {1B73E52F-BE4E-4EF2-B8E5-A795BA44FF5F} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F3AC9875-2CDD-4111-B39A-FFBF5066FFFF} EndGlobalSection diff --git a/BlazorExpress.ChartJS/BlazorExpress.ChartJS.csproj b/BlazorExpress.ChartJS/BlazorExpress.ChartJS.csproj index 6b403d49..1d316b48 100644 --- a/BlazorExpress.ChartJS/BlazorExpress.ChartJS.csproj +++ b/BlazorExpress.ChartJS/BlazorExpress.ChartJS.csproj @@ -6,7 +6,7 @@ 1.0.0 1.0.0 - logo-180.png + logo.png Apache-2.0 https://chartjs.blazorexpress.com https://github.com/BlazorExpress/BlazorExpress.ChartJS @@ -14,8 +14,8 @@ Blazor, BlazorExpress, Charts, BlazorBarChart, BlazorDoughnutChart, BlazorLineChart, BlazorPieChart An open-source, production-ready Blazor charts component library built on the Blazor and Chart.js JavaScript library. Vikram Reddy - - Copyright © 2024 Blazor Express + Blazor Express + Copyright © 2025 Blazor Express net8.0 enable @@ -24,7 +24,7 @@ - + @@ -32,7 +32,8 @@ - + + diff --git a/BlazorExpress.ChartJS/ChartComponents/BarChart.razor b/BlazorExpress.ChartJS/ChartComponents/BarChart.razor index fdb4f50d..547a7665 100644 --- a/BlazorExpress.ChartJS/ChartComponents/BarChart.razor +++ b/BlazorExpress.ChartJS/ChartComponents/BarChart.razor @@ -1,6 +1,6 @@ @namespace BlazorExpress.ChartJS @inherits ChartComponentBase -
+
\ No newline at end of file diff --git a/BlazorExpress.ChartJS/ChartComponents/BarChart.razor.cs b/BlazorExpress.ChartJS/ChartComponents/BarChart.razor.cs index 4bc2a7f9..928a73db 100644 --- a/BlazorExpress.ChartJS/ChartComponents/BarChart.razor.cs +++ b/BlazorExpress.ChartJS/ChartComponents/BarChart.razor.cs @@ -2,12 +2,6 @@ public partial class BarChart : ChartComponentBase { - #region Fields and Constants - - private const string _jsObjectName = "window.blazorexpress.chartjs.bar"; - - #endregion - #region Constructors public BarChart() @@ -19,13 +13,23 @@ public BarChart() #region Methods + /// + /// Asynchronously adds a new data entry to the specified chart data. + /// + /// The chart data to which the new entry will be added. + /// The label associated with the new data entry. + /// The dataset containing the data to be added. + /// A task representing the asynchronous operation, with a result of the updated . + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new data entry to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDataAsync(ChartData chartData, string dataLabel, IChartDatasetData data) { if (chartData is null) throw new ArgumentNullException(nameof(chartData)); if (chartData.Datasets is null) - throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Datasets)); if (data is null) throw new ArgumentNullException(nameof(data)); @@ -33,23 +37,34 @@ public override async Task AddDataAsync(ChartData chartData, string d foreach (var dataset in chartData.Datasets) if (dataset is BarChartDataset barChartDataset && barChartDataset.Label == dataLabel) if (data is BarChartDatasetData barChartDatasetData) - barChartDataset.Data?.Add(barChartDatasetData.Data); + barChartDataset.Data?.Add(barChartDatasetData.Data as double?); - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data); + await JSRuntime.InvokeVoidAsync(BarChartInterop.AddDatasetData, Id, dataLabel, data); return chartData; } + /// + /// Asynchronously adds a new dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The label for the new dataset. + /// A read-only collection of data points to be included in the new dataset. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDataAsync(ChartData chartData, string dataLabel, IReadOnlyCollection data) { if (chartData is null) throw new ArgumentNullException(nameof(chartData)); if (chartData.Datasets is null) - throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Datasets)); if (chartData.Labels is null) - throw new ArgumentException("chartData.Labels must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Labels)); if (dataLabel is null) throw new ArgumentNullException(nameof(dataLabel)); @@ -77,21 +92,32 @@ public override async Task AddDataAsync(ChartData chartData, string d var chartDatasetData = data.FirstOrDefault(x => x is BarChartDatasetData barChartDatasetData && barChartDatasetData.DatasetLabel == barChartDataset.Label); if (chartDatasetData is BarChartDatasetData barChartDatasetData) - barChartDataset.Data?.Add(barChartDatasetData.Data); + barChartDataset.Data?.Add(barChartDatasetData.Data as double?); } - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (BarChartDatasetData)x)); + await JSRuntime.InvokeVoidAsync(BarChartInterop.AddDatasetsData, Id, dataLabel, data?.Select(x => (BarChartDatasetData)x)); return chartData; } + /// + /// Asynchronously adds a dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The dataset to add to the chart data. + /// The options that configure the chart's appearance and behavior. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) { if (chartData is null) throw new ArgumentNullException(nameof(chartData)); if (chartData.Datasets is null) - throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Datasets)); if (chartDataset is null) throw new ArgumentNullException(nameof(chartDataset)); @@ -99,29 +125,53 @@ public override async Task AddDatasetAsync(ChartData chartData, IChar if (chartDataset is BarChartDataset) { chartData.Datasets.Add(chartDataset); - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDataset", Id, (BarChartDataset)chartDataset); + await JSRuntime.InvokeVoidAsync(BarChartInterop.AddDataset, Id, (BarChartDataset)chartDataset); } return chartData; } + /// + /// Asynchronously initializes the chart with the specified data and options. + /// + /// This method prepares the chart for rendering by invoking the necessary JavaScript functions + /// to set up the chart with the provided data and options. Ensure that contains valid + /// datasets before calling this method. + /// The data to be used for the chart. Must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// An optional array of plugin identifiers to enhance the chart's functionality. + /// A task that represents the asynchronous initialization operation. + [AddedVersion("1.0.0")] + [Description("Asynchronously initializes the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions, string[]? plugins = null) { if (chartData is not null && chartData.Datasets is not null) { var datasets = chartData.Datasets.OfType(); var data = new { chartData.Labels, Datasets = datasets }; - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (BarChartOptions)chartOptions, plugins); + await JSRuntime.InvokeVoidAsync(BarChartInterop.Initialize, Id, GetChartType(), data, (BarChartOptions)chartOptions, plugins); } } + /// + /// Asynchronously updates the chart with the specified data and options. + /// + /// This method updates the chart by invoking a JavaScript function to render the new data and + /// options. Ensure that contains valid datasets to avoid no operation. + /// The data to be displayed on the chart. Must not be null and must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// + [AddedVersion("1.0.0")] + [Description("Asynchronously updates the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] public override async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions) { if (chartData is not null && chartData.Datasets is not null) { var datasets = chartData.Datasets.OfType(); var data = new { chartData.Labels, Datasets = datasets }; - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (BarChartOptions)chartOptions); + await JSRuntime.InvokeVoidAsync(BarChartInterop.Update, Id, GetChartType(), data, (BarChartOptions)chartOptions); } } diff --git a/BlazorExpress.ChartJS/ChartComponents/BubbleChart.razor b/BlazorExpress.ChartJS/ChartComponents/BubbleChart.razor new file mode 100644 index 00000000..c8bf8846 --- /dev/null +++ b/BlazorExpress.ChartJS/ChartComponents/BubbleChart.razor @@ -0,0 +1,6 @@ +@namespace BlazorExpress.ChartJS +@inherits ChartComponentBase + +
+ +
diff --git a/BlazorExpress.ChartJS/ChartComponents/BubbleChart.razor.cs b/BlazorExpress.ChartJS/ChartComponents/BubbleChart.razor.cs new file mode 100644 index 00000000..1547854e --- /dev/null +++ b/BlazorExpress.ChartJS/ChartComponents/BubbleChart.razor.cs @@ -0,0 +1,191 @@ +namespace BlazorExpress.ChartJS; + +public partial class BubbleChart : ChartComponentBase +{ + #region Constructors + + public BubbleChart() + { + _chartType = ChartType.Bubble; + } + + #endregion + + #region Methods + + /// + /// Asynchronously adds a new data entry to the specified chart data. + /// + /// The chart data to which the new entry will be added. + /// The label associated with the new data entry. + /// The dataset containing the data to be added. + /// A task representing the asynchronous operation, with a result of the updated . + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new data entry to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDataAsync(ChartData chartData, string dataLabel, IChartDatasetData data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + foreach (var dataset in chartData.Datasets) + if (dataset is BubbleChartDataset bubbleChartDataset && bubbleChartDataset.Label == dataLabel) + if (data is BubbleChartDatasetData bubbleChartDatasetData && bubbleChartDatasetData.Data is BubbleChartDataPoint bubbleChartDataPoint) + bubbleChartDataset.Data?.Add(bubbleChartDataPoint); + + await JSRuntime.InvokeVoidAsync(BubbleChartInterop.AddDatasetData, Id, dataLabel, data); + + return chartData; + } + + /// + /// Asynchronously adds a new dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The label for the new dataset. + /// A read-only collection of data points to be included in the new dataset. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDataAsync(ChartData chartData, string dataLabel, IReadOnlyCollection data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + + if (chartData.Labels is null) + throw new ArgumentException("chartData.Labels must not be null", nameof(chartData)); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(dataLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + if (!data.Any()) + throw new ArgumentException($"{nameof(data)} cannot be empty.", nameof(data)); + + if (chartData.Datasets.Count != data.Count) + throw new InvalidDataException("The chart dataset count and the new data points count do not match."); + + if (chartData.Labels.Contains(dataLabel)) + throw new Exception($"{dataLabel} already exists."); + + chartData.Labels.Add(dataLabel); + + foreach (var dataset in chartData.Datasets) + if (dataset is BubbleChartDataset bubbleChartDataset) + { + var chartDatasetData = data.FirstOrDefault(x => x is BubbleChartDatasetData bubbleChartDatasetData && bubbleChartDatasetData.DatasetLabel == bubbleChartDataset.Label); + + if (chartDatasetData is BubbleChartDatasetData bubbleChartDatasetData && bubbleChartDatasetData.Data is BubbleChartDataPoint bubbleChartDataPoint) + bubbleChartDataset.Data?.Add(bubbleChartDataPoint); + } + + await JSRuntime.InvokeVoidAsync(BubbleChartInterop.AddDatasetsData, Id, dataLabel, data?.Select(x => (BubbleChartDatasetData)x)); + + return chartData; + } + + /// + /// Asynchronously adds a dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The dataset to add to the chart data. + /// The options that configure the chart's appearance and behavior. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartDataset is null) + throw new ArgumentNullException(nameof(chartDataset)); + + if (chartDataset is BubbleChartDataset) + { + chartData.Datasets.Add(chartDataset); + await JSRuntime.InvokeVoidAsync(BubbleChartInterop.AddDataset, Id, (BubbleChartDataset)chartDataset); + } + + return chartData; + } + + /// + /// Asynchronously initializes the chart with the specified data and options. + /// + /// This method prepares the chart for rendering by invoking the necessary JavaScript functions + /// to set up the chart with the provided data and options. Ensure that contains valid + /// datasets before calling this method. + /// The data to be used for the chart. Must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// An optional array of plugin identifiers to enhance the chart's functionality. + /// A task that represents the asynchronous initialization operation. + [AddedVersion("1.0.0")] + [Description("Asynchronously initializes the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] + public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions, string[]? plugins = null) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartOptions is null) + throw new ArgumentNullException(nameof(chartOptions)); + + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JSRuntime.InvokeVoidAsync(BubbleChartInterop.Initialize, Id, GetChartType(), data, (BubbleChartOptions)chartOptions, plugins); + } + + /// + /// Asynchronously updates the chart with the specified data and options. + /// + /// This method updates the chart by invoking a JavaScript function to render the new data and + /// options. Ensure that contains valid datasets to avoid no operation. + /// The data to be displayed on the chart. Must not be null and must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// + [AddedVersion("1.0.0")] + [Description("Asynchronously updates the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] + public override async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (chartOptions is null) + throw new ArgumentNullException(nameof(chartOptions)); + + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JSRuntime.InvokeVoidAsync(BubbleChartInterop.Update, Id, GetChartType(), data, (BubbleChartOptions)chartOptions); + } + + #endregion +} diff --git a/BlazorExpress.ChartJS/ChartComponents/Core/ChartComponentBase.cs b/BlazorExpress.ChartJS/ChartComponents/Core/ChartComponentBase.cs index ffb11b0d..9c4ae2d7 100644 --- a/BlazorExpress.ChartJS/ChartComponents/Core/ChartComponentBase.cs +++ b/BlazorExpress.ChartJS/ChartComponents/Core/ChartComponentBase.cs @@ -1,6 +1,12 @@ namespace BlazorExpress.ChartJS; -public abstract class ChartComponentBase : ComponentBase, IDisposable, IAsyncDisposable +/// +/// Base class for Chart components. +/// +/// +/// +/// +public abstract class ChartComponentBase : BlazorExpressComponentCore, IDisposable, IAsyncDisposable { #region Fields and Constants @@ -14,73 +20,67 @@ public abstract class ChartComponentBase : ComponentBase, IDisposable, IAsyncDis #region Methods - /// - protected override async Task OnAfterRenderAsync(bool firstRender) - { - IsRenderComplete = true; - - await base.OnAfterRenderAsync(firstRender); - } - - /// - protected override void OnInitialized() - { - Id ??= IdUtility.GetNextId(); - - base.OnInitialized(); - } - //public async Task Stop() { } //public async Task ToBase64Image() { } //public async Task ToBase64Image(string type, double quality) { } + /// + /// Asynchronously adds a new data entry to the specified chart data. + /// + /// The chart data to which the new entry will be added. + /// The label associated with the new data entry. + /// The dataset containing the data to be added. + /// A task representing the asynchronous operation, with a result of the updated . + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new data entry to the specified chart data.")] public virtual async Task AddDataAsync(ChartData chartData, string dataLabel, IChartDatasetData data) => await Task.FromResult(chartData); + /// + /// Asynchronously adds a new dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The label for the new dataset. + /// A read-only collection of data points to be included in the new dataset. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new dataset to the specified chart data.")] public virtual async Task AddDataAsync(ChartData chartData, string dataLabel, IReadOnlyCollection data) => await Task.FromResult(chartData); + /// + /// Asynchronously adds a dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The dataset to add to the chart data. + /// The options that configure the chart's appearance and behavior. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a dataset to the specified chart data.")] public virtual async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) => await Task.FromResult(chartData); - /// - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// - public async ValueTask DisposeAsync() - { - await DisposeAsyncCore(true).ConfigureAwait(false); - - Dispose(false); - GC.SuppressFinalize(this); - } - //public async Task Clear() { } /// - /// Initialize the chart. + /// Asynchronously initializes the chart with the specified data and options. /// - /// - /// - /// + /// This method prepares the chart for rendering by invoking the necessary JavaScript functions + /// to set up the chart with the provided data and options. Ensure that contains valid + /// datasets before calling this method. + /// The data to be used for the chart. Must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// An optional array of plugin identifiers to enhance the chart's functionality. + /// A task that represents the asynchronous initialization operation. + [AddedVersion("1.0.0")] + [Description("Asynchronously initializes the chart with the specified data and options.")] public virtual async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions, string[]? plugins = null) { if (chartData is not null && chartData.Datasets is not null && chartData.Datasets.Any()) { var _data = GetChartDataObject(chartData); - - if (_chartType == ChartType.Bar) - await JSRuntime.InvokeVoidAsync("window.blazorChart.bar.initialize", Id, GetChartType(), _data, (BarChartOptions)chartOptions, plugins); - else if (_chartType == ChartType.Line) - await JSRuntime.InvokeVoidAsync("window.blazorChart.line.initialize", Id, GetChartType(), _data, (LineChartOptions)chartOptions, plugins); - else - await JSRuntime.InvokeVoidAsync("window.blazorChart.initialize", Id, GetChartType(), _data, chartOptions, plugins); + await JSRuntime.InvokeVoidAsync(ChartInterop.Initialize, Id, GetChartType(), _data, chartOptions, plugins); } } @@ -89,65 +89,42 @@ public virtual async Task InitializeAsync(ChartData chartData, IChartOptions cha //public async Task Reset() { } /// - /// Resize the chart. + /// Asynchronously resizes the chart to the specified dimensions. /// - /// - /// - /// - /// + /// This method updates the chart's dimensions by invoking a JavaScript function. Ensure that the + /// chart is properly initialized before calling this method. The operation is performed asynchronously and will not + /// block the calling thread. + /// The new width of the chart. Must be a non-negative integer. + /// The new height of the chart. Must be a non-negative integer. + /// The unit of measurement for the width. Defaults to pixels. + /// The unit of measurement for the height. Defaults to pixels. + /// A task that represents the asynchronous resize operation. + [AddedVersion("1.0.0")] + [Description("Asynchronously resizes the chart to the specified dimensions.")] public async Task ResizeAsync(int width, int height, Unit widthUnit = Unit.Px, Unit heightUnit = Unit.Px) { var widthWithUnit = $"width:{width.ToString(CultureInfo.InvariantCulture)}{widthUnit.ToCssString()}"; var heightWithUnit = $"height:{height.ToString(CultureInfo.InvariantCulture)}{heightUnit.ToCssString()}"; - await JSRuntime.InvokeVoidAsync("window.blazorChart.resize", Id, widthWithUnit, heightWithUnit); + await JSRuntime.InvokeVoidAsync(ChartInterop.Resize, Id, widthWithUnit, heightWithUnit); } /// - /// Update the chart. + /// Asynchronously updates the chart with the specified data and options. /// - /// - /// + /// This method updates the chart by invoking a JavaScript function to render the new data and + /// options. Ensure that contains valid datasets to avoid no operation. + /// The data to be displayed on the chart. Must not be null and must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// + [AddedVersion("1.0.0")] + [Description("Asynchronously updates the chart with the specified data and options.")] public virtual async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions) { - if (chartData is not null && chartData.Datasets is not null && chartData.Datasets.Any()) - { - var _data = GetChartDataObject(chartData); + if (chartData is null || chartData.Datasets is null || !chartData.Datasets.Any()) + return; - if (_chartType == ChartType.Bar) - await JSRuntime.InvokeVoidAsync("window.blazorChart.bar.update", Id, GetChartType(), _data, (BarChartOptions)chartOptions); - else if (_chartType == ChartType.Line) - await JSRuntime.InvokeVoidAsync("window.blazorChart.line.update", Id, GetChartType(), _data, (LineChartOptions)chartOptions); - else - await JSRuntime.InvokeVoidAsync("window.blazorChart.update", Id, GetChartType(), _data, chartOptions); - } - } - - protected virtual void Dispose(bool disposing) - { - if (!isDisposed) - { - if (disposing) - { - // cleanup - } - - isDisposed = true; - } - } - - protected virtual ValueTask DisposeAsyncCore(bool disposing) - { - if (!isAsyncDisposed) - { - if (disposing) - { - // cleanup - } - - isAsyncDisposed = true; - } - - return ValueTask.CompletedTask; + var _data = GetChartDataObject(chartData); + await JSRuntime.InvokeVoidAsync(ChartInterop.Update, Id, GetChartType(), _data, chartOptions); } protected string GetChartType() => @@ -164,18 +141,14 @@ protected string GetChartType() => _ => "line" // default }; - private string GetChartContainerSizeAsStyle() - { - var style = ""; - - if (Width > 0) - style += $"width:{Width.Value.ToString(CultureInfo.InvariantCulture)}{WidthUnit.ToCssString()};"; + protected string ContainerClassNames => ContainerClass!; - if (Height > 0) - style += $"height:{Height.Value.ToString(CultureInfo.InvariantCulture)}{HeightUnit.ToCssString()};"; - - return style; - } + protected string ContainerStyleNames => + BuildStyleNames( + ContainerStyle, + (Width.HasValue && Width.Value > 0 ? $"width:{Width.Value.ToString(CultureInfo.InvariantCulture)}{WidthUnit.ToCssString()};" : null, Width.HasValue && Width.Value > 0), + (Height.HasValue && Height.Value > 0 ? $"height:{Height.Value.ToString(CultureInfo.InvariantCulture)}{HeightUnit.ToCssString()};" : null, Height.HasValue && Height.Value > 0) + ); private object GetChartDataObject(ChartData chartData) { @@ -185,14 +158,18 @@ private object GetChartDataObject(ChartData chartData) foreach (var dataset in chartData.Datasets) if (dataset is BarChartDataset) datasets.Add((BarChartDataset)dataset); - else if (dataset is BubbleChartDataset) - datasets.Add((BubbleChartDataset)dataset); else if (dataset is DoughnutChartDataset) datasets.Add((DoughnutChartDataset)dataset); else if (dataset is LineChartDataset) datasets.Add((LineChartDataset)dataset); else if (dataset is PieChartDataset) datasets.Add((PieChartDataset)dataset); + else if (dataset is PolarAreaChartDataset) + datasets.Add((PolarAreaChartDataset)dataset); + else if (dataset is RadarChartDataset) + datasets.Add((RadarChartDataset)dataset); + else if (dataset is ScatterChartDataset) + datasets.Add((ScatterChartDataset)dataset); var data = new { chartData?.Labels, Datasets = datasets }; @@ -203,60 +180,95 @@ private object GetChartDataObject(ChartData chartData) #region Properties, Indexers - [Parameter(CaptureUnmatchedValues = true)] - public Dictionary AdditionalAttributes { get; set; } = default!; - - [Parameter] public string? Class { get; set; } - - internal string ContainerStyle => GetChartContainerSizeAsStyle(); + /// + /// Gets or sets the CSS class name for the container element. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the CSS class name for the container element.")] + [Parameter] + public string? ContainerClass { get; set; } - public ElementReference Element { get; set; } + /// + /// Gets or sets the CSS style string applied to the container element. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the CSS style string applied to the container element.")] + [Parameter] + public string? ContainerStyle { get; set; } /// /// Gets or sets chart container height. /// The default unit of measure is . /// To change the unit of measure see . + /// + /// Default value is . + /// /// - /// - /// Default value is null. - /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets chart container height.")] + [ParameterTypeName("int?")] [Parameter] public int? Height { get; set; } /// /// Gets or sets chart container height unit of measure. - /// - /// + /// /// Default value is . - /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(Unit.Px)] + [Description("Gets or sets chart container height unit of measure.")] [Parameter] public Unit HeightUnit { get; set; } = Unit.Px; - [Parameter] public string? Id { get; set; } + /// + /// Gets or sets a value indicating whether the container is fluid. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(false)] + [Description("Gets or sets a value indicating whether the container is fluid.")] + [Parameter] + public bool IsContainerFluid { get; set; } protected bool IsRenderComplete { get; private set; } - [Inject] protected IJSRuntime JSRuntime { get; set; } = default!; - - [Parameter] public string? Style { get; set; } - /// - /// Get or sets chart container width. + /// Gets or sets chart container width. /// The default unit of measure is . /// To change the unit of measure see . + /// + /// Default value is . + /// /// - /// - /// Default value is null. - /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets chart container width.")] + [ParameterTypeName("int?")] [Parameter] public int? Width { get; set; } /// /// Gets or sets chart container width unit of measure. - /// - /// + /// /// Default value is . - /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(Unit.Px)] + [Description("Gets or sets chart container width unit of measure.")] [Parameter] public Unit WidthUnit { get; set; } = Unit.Px; diff --git a/BlazorExpress.ChartJS/ChartComponents/DoughnutChart.razor b/BlazorExpress.ChartJS/ChartComponents/DoughnutChart.razor index fdb4f50d..547a7665 100644 --- a/BlazorExpress.ChartJS/ChartComponents/DoughnutChart.razor +++ b/BlazorExpress.ChartJS/ChartComponents/DoughnutChart.razor @@ -1,6 +1,6 @@ @namespace BlazorExpress.ChartJS @inherits ChartComponentBase -
+
\ No newline at end of file diff --git a/BlazorExpress.ChartJS/ChartComponents/DoughnutChart.razor.cs b/BlazorExpress.ChartJS/ChartComponents/DoughnutChart.razor.cs index 24b67aa7..1bce4978 100644 --- a/BlazorExpress.ChartJS/ChartComponents/DoughnutChart.razor.cs +++ b/BlazorExpress.ChartJS/ChartComponents/DoughnutChart.razor.cs @@ -2,12 +2,6 @@ public partial class DoughnutChart : ChartComponentBase { - #region Fields and Constants - - private const string _jsObjectName = "window.blazorexpress.chartjs.doughnut"; - - #endregion - #region Constructors public DoughnutChart() @@ -19,13 +13,23 @@ public DoughnutChart() #region Methods + /// + /// Asynchronously adds a new data entry to the specified chart data. + /// + /// The chart data to which the new entry will be added. + /// The label associated with the new data entry. + /// The dataset containing the data to be added. + /// A task representing the asynchronous operation, with a result of the updated . + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new data entry to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDataAsync(ChartData chartData, string dataLabel, IChartDatasetData data) { if (chartData is null) throw new ArgumentNullException(nameof(chartData)); if (chartData.Datasets is null) - throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Datasets)); if (data is null) throw new ArgumentNullException(nameof(data)); @@ -34,25 +38,36 @@ public override async Task AddDataAsync(ChartData chartData, string d if (dataset is DoughnutChartDataset doughnutChartDataset && doughnutChartDataset.Label == dataLabel) if (data is DoughnutChartDatasetData doughnutChartDatasetData) { - doughnutChartDataset.Data?.Add(doughnutChartDatasetData.Data); + doughnutChartDataset.Data?.Add(doughnutChartDatasetData.Data as double?); doughnutChartDataset.BackgroundColor?.Add(doughnutChartDatasetData.BackgroundColor!); } - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data); + await JSRuntime.InvokeVoidAsync(DoughnutChartInterop.AddDatasetData, Id, dataLabel, data); return chartData; } + /// + /// Asynchronously adds a new dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The label for the new dataset. + /// A read-only collection of data points to be included in the new dataset. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDataAsync(ChartData chartData, string dataLabel, IReadOnlyCollection data) { if (chartData is null) throw new ArgumentNullException(nameof(chartData)); if (chartData.Datasets is null) - throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Datasets)); if (chartData.Labels is null) - throw new ArgumentException("chartData.Labels must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Labels)); if (dataLabel is null) throw new ArgumentNullException(nameof(dataLabel)); @@ -81,23 +96,34 @@ public override async Task AddDataAsync(ChartData chartData, string d if (chartDatasetData is DoughnutChartDatasetData doughnutChartDatasetData) { - doughnutChartDataset.Data?.Add(doughnutChartDatasetData.Data); + doughnutChartDataset.Data?.Add(doughnutChartDatasetData.Data as double?); doughnutChartDataset.BackgroundColor?.Add(doughnutChartDatasetData.BackgroundColor!); } } - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (DoughnutChartDatasetData)x)); + await JSRuntime.InvokeVoidAsync(DoughnutChartInterop.AddDatasetsData, Id, dataLabel, data?.Select(x => (DoughnutChartDatasetData)x)); return chartData; } + /// + /// Asynchronously adds a dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The dataset to add to the chart data. + /// The options that configure the chart's appearance and behavior. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) { if (chartData is null) throw new ArgumentNullException(nameof(chartData)); if (chartData.Datasets is null) - throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Datasets)); if (chartDataset is null) throw new ArgumentNullException(nameof(chartDataset)); @@ -105,29 +131,53 @@ public override async Task AddDatasetAsync(ChartData chartData, IChar if (chartDataset is DoughnutChartDataset doughnutChartDataset) { chartData.Datasets.Add(doughnutChartDataset); - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDataset", Id, doughnutChartDataset); + await JSRuntime.InvokeVoidAsync(DoughnutChartInterop.AddDataset, Id, doughnutChartDataset); } return chartData; } + /// + /// Asynchronously initializes the chart with the specified data and options. + /// + /// This method prepares the chart for rendering by invoking the necessary JavaScript functions + /// to set up the chart with the provided data and options. Ensure that contains valid + /// datasets before calling this method. + /// The data to be used for the chart. Must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// An optional array of plugin identifiers to enhance the chart's functionality. + /// A task that represents the asynchronous initialization operation. + [AddedVersion("1.0.0")] + [Description("Asynchronously initializes the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions, string[]? plugins = null) { if (chartData is not null && chartData.Datasets is not null) { var datasets = chartData.Datasets.OfType(); var data = new { chartData.Labels, Datasets = datasets }; - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (DoughnutChartOptions)chartOptions, plugins); + await JSRuntime.InvokeVoidAsync(DoughnutChartInterop.Initialize, Id, GetChartType(), data, (DoughnutChartOptions)chartOptions, plugins); } } + /// + /// Asynchronously updates the chart with the specified data and options. + /// + /// This method updates the chart by invoking a JavaScript function to render the new data and + /// options. Ensure that contains valid datasets to avoid no operation. + /// The data to be displayed on the chart. Must not be null and must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// + [AddedVersion("1.0.0")] + [Description("Asynchronously updates the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] public override async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions) { if (chartData is not null && chartData.Datasets is not null) { var datasets = chartData.Datasets.OfType(); var data = new { chartData.Labels, Datasets = datasets }; - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (DoughnutChartOptions)chartOptions); + await JSRuntime.InvokeVoidAsync(DoughnutChartInterop.Update, Id, GetChartType(), data, (DoughnutChartOptions)chartOptions); } } diff --git a/BlazorExpress.ChartJS/ChartComponents/LineChart.razor b/BlazorExpress.ChartJS/ChartComponents/LineChart.razor index 292106c5..c8bf8846 100644 --- a/BlazorExpress.ChartJS/ChartComponents/LineChart.razor +++ b/BlazorExpress.ChartJS/ChartComponents/LineChart.razor @@ -1,6 +1,6 @@ @namespace BlazorExpress.ChartJS @inherits ChartComponentBase -
+
diff --git a/BlazorExpress.ChartJS/ChartComponents/LineChart.razor.cs b/BlazorExpress.ChartJS/ChartComponents/LineChart.razor.cs index b2070322..33baa22f 100644 --- a/BlazorExpress.ChartJS/ChartComponents/LineChart.razor.cs +++ b/BlazorExpress.ChartJS/ChartComponents/LineChart.razor.cs @@ -2,12 +2,6 @@ public partial class LineChart : ChartComponentBase { - #region Fields and Constants - - private const string _jsObjectName = "window.blazorexpress.chartjs.line"; - - #endregion - #region Constructors public LineChart() @@ -19,13 +13,23 @@ public LineChart() #region Methods + /// + /// Asynchronously adds a new data entry to the specified chart data. + /// + /// The chart data to which the new entry will be added. + /// The label associated with the new data entry. + /// The dataset containing the data to be added. + /// A task representing the asynchronous operation, with a result of the updated . + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new data entry to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDataAsync(ChartData chartData, string dataLabel, IChartDatasetData data) { if (chartData is null) throw new ArgumentNullException(nameof(chartData)); if (chartData.Datasets is null) - throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Datasets)); if (data is null) throw new ArgumentNullException(nameof(data)); @@ -33,13 +37,24 @@ public override async Task AddDataAsync(ChartData chartData, string d foreach (var dataset in chartData.Datasets) if (dataset is LineChartDataset lineChartDataset && lineChartDataset.Label == dataLabel) if (data is LineChartDatasetData lineChartDatasetData) - lineChartDataset.Data?.Add(lineChartDatasetData.Data); + lineChartDataset.Data?.Add(lineChartDatasetData.Data as double?); - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data); + await JSRuntime.InvokeVoidAsync(LineChartInterop.AddDatasetData, Id, dataLabel, data); return chartData; } + /// + /// Asynchronously adds a new dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The label for the new dataset. + /// A read-only collection of data points to be included in the new dataset. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDataAsync(ChartData chartData, string dataLabel, IReadOnlyCollection data) { if (chartData is null) @@ -61,7 +76,7 @@ public override async Task AddDataAsync(ChartData chartData, string d throw new ArgumentNullException(nameof(data)); if (!data.Any()) - throw new Exception($"{nameof(data)} cannot be empty."); + throw new ArgumentException($"{nameof(data)} cannot be empty.", nameof(data)); if (chartData.Datasets.Count != data.Count) throw new InvalidDataException("The chart dataset count and the new data points count do not match."); @@ -77,14 +92,25 @@ public override async Task AddDataAsync(ChartData chartData, string d var chartDatasetData = data.FirstOrDefault(x => x is LineChartDatasetData lineChartDatasetData && lineChartDatasetData.DatasetLabel == lineChartDataset.Label); if (chartDatasetData is LineChartDatasetData lineChartDatasetData) - lineChartDataset.Data?.Add(lineChartDatasetData.Data); + lineChartDataset.Data?.Add(lineChartDatasetData.Data as double?); } - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (LineChartDatasetData)x)); + await JSRuntime.InvokeVoidAsync(LineChartInterop.AddDatasetsData, Id, dataLabel, data?.Select(x => (LineChartDatasetData)x)); return chartData; } + /// + /// Asynchronously adds a dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The dataset to add to the chart data. + /// The options that configure the chart's appearance and behavior. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) { if (chartData is null) @@ -99,12 +125,25 @@ public override async Task AddDatasetAsync(ChartData chartData, IChar if (chartDataset is LineChartDataset) { chartData.Datasets.Add(chartDataset); - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDataset", Id, (LineChartDataset)chartDataset); + await JSRuntime.InvokeVoidAsync(LineChartInterop.AddDataset, Id, (LineChartDataset)chartDataset); } return chartData; } + /// + /// Asynchronously initializes the chart with the specified data and options. + /// + /// This method prepares the chart for rendering by invoking the necessary JavaScript functions + /// to set up the chart with the provided data and options. Ensure that contains valid + /// datasets before calling this method. + /// The data to be used for the chart. Must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// An optional array of plugin identifiers to enhance the chart's functionality. + /// A task that represents the asynchronous initialization operation. + [AddedVersion("1.0.0")] + [Description("Asynchronously initializes the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions, string[]? plugins = null) { if (chartData is null) @@ -118,9 +157,20 @@ public override async Task InitializeAsync(ChartData chartData, IChartOptions ch var datasets = chartData.Datasets.OfType(); var data = new { chartData.Labels, Datasets = datasets }; - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (LineChartOptions)chartOptions, plugins); + await JSRuntime.InvokeVoidAsync(LineChartInterop.Initialize, Id, GetChartType(), data, (LineChartOptions)chartOptions, plugins); } + /// + /// Asynchronously updates the chart with the specified data and options. + /// + /// This method updates the chart by invoking a JavaScript function to render the new data and + /// options. Ensure that contains valid datasets to avoid no operation. + /// The data to be displayed on the chart. Must not be null and must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// + [AddedVersion("1.0.0")] + [Description("Asynchronously updates the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] public override async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions) { if (chartData is null) @@ -134,7 +184,7 @@ public override async Task UpdateAsync(ChartData chartData, IChartOptions chartO var datasets = chartData.Datasets.OfType(); var data = new { chartData.Labels, Datasets = datasets }; - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (LineChartOptions)chartOptions); + await JSRuntime.InvokeVoidAsync(LineChartInterop.Update, Id, GetChartType(), data, (LineChartOptions)chartOptions); } #endregion diff --git a/BlazorExpress.ChartJS/ChartComponents/PieChart.razor b/BlazorExpress.ChartJS/ChartComponents/PieChart.razor index fdb4f50d..547a7665 100644 --- a/BlazorExpress.ChartJS/ChartComponents/PieChart.razor +++ b/BlazorExpress.ChartJS/ChartComponents/PieChart.razor @@ -1,6 +1,6 @@ @namespace BlazorExpress.ChartJS @inherits ChartComponentBase -
+
\ No newline at end of file diff --git a/BlazorExpress.ChartJS/ChartComponents/PieChart.razor.cs b/BlazorExpress.ChartJS/ChartComponents/PieChart.razor.cs index ab4c7191..bf303122 100644 --- a/BlazorExpress.ChartJS/ChartComponents/PieChart.razor.cs +++ b/BlazorExpress.ChartJS/ChartComponents/PieChart.razor.cs @@ -2,12 +2,6 @@ public partial class PieChart : ChartComponentBase { - #region Fields and Constants - - private const string _jsObjectName = "window.blazorexpress.chartjs.pie"; - - #endregion - #region Constructors public PieChart() @@ -19,13 +13,23 @@ public PieChart() #region Methods + /// + /// Asynchronously adds a new data entry to the specified chart data. + /// + /// The chart data to which the new entry will be added. + /// The label associated with the new data entry. + /// The dataset containing the data to be added. + /// A task representing the asynchronous operation, with a result of the updated . + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new data entry to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDataAsync(ChartData chartData, string dataLabel, IChartDatasetData data) { if (chartData is null) throw new ArgumentNullException(nameof(chartData)); if (chartData.Datasets is null) - throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Datasets)); if (data is null) throw new ArgumentNullException(nameof(data)); @@ -34,25 +38,36 @@ public override async Task AddDataAsync(ChartData chartData, string d if (dataset is PieChartDataset pieChartDataset && pieChartDataset.Label == dataLabel) if (data is PieChartDatasetData pieChartDatasetData) { - pieChartDataset.Data?.Add(pieChartDatasetData.Data); + pieChartDataset.Data?.Add(pieChartDatasetData.Data as double?); pieChartDataset.BackgroundColor?.Add(pieChartDatasetData.BackgroundColor!); } - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data); + await JSRuntime.InvokeVoidAsync(PieChartInterop.AddDatasetData, Id, dataLabel, data); return chartData; } + /// + /// Asynchronously adds a new dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The label for the new dataset. + /// A read-only collection of data points to be included in the new dataset. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDataAsync(ChartData chartData, string dataLabel, IReadOnlyCollection data) { if (chartData is null) throw new ArgumentNullException(nameof(chartData)); if (chartData.Datasets is null) - throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Datasets)); if (chartData.Labels is null) - throw new ArgumentException("chartData.Labels must not be null", nameof(chartData)); + throw new ArgumentNullException(nameof(chartData.Labels)); if (dataLabel is null) throw new ArgumentNullException(nameof(dataLabel)); @@ -81,16 +96,27 @@ public override async Task AddDataAsync(ChartData chartData, string d if (chartDatasetData is PieChartDatasetData pieChartDatasetData) { - pieChartDataset.Data?.Add(pieChartDatasetData.Data); + pieChartDataset.Data?.Add(pieChartDatasetData.Data as double?); pieChartDataset.BackgroundColor?.Add(pieChartDatasetData.BackgroundColor!); } } - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (PieChartDatasetData)x)); + await JSRuntime.InvokeVoidAsync(PieChartInterop.AddDatasetsData, Id, dataLabel, data?.Select(x => (PieChartDatasetData)x)); return chartData; } + /// + /// Asynchronously adds a dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The dataset to add to the chart data. + /// The options that configure the chart's appearance and behavior. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) { if (chartData is null) @@ -105,29 +131,53 @@ public override async Task AddDatasetAsync(ChartData chartData, IChar if (chartDataset is PieChartDataset pieChartDataset) { chartData.Datasets.Add(pieChartDataset); - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDataset", Id, pieChartDataset); + await JSRuntime.InvokeVoidAsync(PieChartInterop.AddDataset, Id, pieChartDataset); } return chartData; } + /// + /// Asynchronously initializes the chart with the specified data and options. + /// + /// This method prepares the chart for rendering by invoking the necessary JavaScript functions + /// to set up the chart with the provided data and options. Ensure that contains valid + /// datasets before calling this method. + /// The data to be used for the chart. Must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// An optional array of plugin identifiers to enhance the chart's functionality. + /// A task that represents the asynchronous initialization operation. + [AddedVersion("1.0.0")] + [Description("Asynchronously initializes the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions, string[]? plugins = null) { if (chartData is not null && chartData.Datasets is not null) { var datasets = chartData.Datasets.OfType(); var data = new { chartData.Labels, Datasets = datasets }; - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (PieChartOptions)chartOptions, plugins); + await JSRuntime.InvokeVoidAsync(PieChartInterop.Initialize, Id, GetChartType(), data, (PieChartOptions)chartOptions, plugins); } } + /// + /// Asynchronously updates the chart with the specified data and options. + /// + /// This method updates the chart by invoking a JavaScript function to render the new data and + /// options. Ensure that contains valid datasets to avoid no operation. + /// The data to be displayed on the chart. Must not be null and must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// + [AddedVersion("1.0.0")] + [Description("Asynchronously updates the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] public override async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions) { if (chartData is not null && chartData.Datasets is not null) { var datasets = chartData.Datasets.OfType(); var data = new { chartData.Labels, Datasets = datasets }; - await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (PieChartOptions)chartOptions); + await JSRuntime.InvokeVoidAsync(PieChartInterop.Update, Id, GetChartType(), data, (PieChartOptions)chartOptions); } } diff --git a/BlazorExpress.ChartJS/ChartComponents/PolarAreaChart.razor b/BlazorExpress.ChartJS/ChartComponents/PolarAreaChart.razor new file mode 100644 index 00000000..547a7665 --- /dev/null +++ b/BlazorExpress.ChartJS/ChartComponents/PolarAreaChart.razor @@ -0,0 +1,6 @@ +@namespace BlazorExpress.ChartJS +@inherits ChartComponentBase + +
+ +
\ No newline at end of file diff --git a/BlazorExpress.ChartJS/ChartComponents/PolarAreaChart.razor.cs b/BlazorExpress.ChartJS/ChartComponents/PolarAreaChart.razor.cs new file mode 100644 index 00000000..e97ae02a --- /dev/null +++ b/BlazorExpress.ChartJS/ChartComponents/PolarAreaChart.razor.cs @@ -0,0 +1,179 @@ +namespace BlazorExpress.ChartJS; + +public partial class PolarAreaChart : ChartComponentBase +{ + #region Constructors + + public PolarAreaChart() + { + _chartType = ChartType.PolarArea; + } + + #endregion + + #region Methods + + /// + /// Asynchronously adds a new data entry to the specified chart data. + /// + /// The chart data to which the new entry will be added. + /// The label associated with the new data entry. + /// The dataset containing the data to be added. + /// A task representing the asynchronous operation, with a result of the updated . + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new data entry to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDataAsync(ChartData chartData, string dataLabel, IChartDatasetData data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + foreach (var dataset in chartData.Datasets) + if (dataset is PolarAreaChartDataset barChartDataset && barChartDataset.Label == dataLabel) + if (data is PolarAreaChartDatasetData barChartDatasetData) + barChartDataset.Data?.Add(barChartDatasetData.Data as double?); + + await JSRuntime.InvokeVoidAsync(PolarAreaChartInterop.AddDatasetData, Id, dataLabel, data); + + return chartData; + } + + /// + /// Asynchronously adds a new dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The label for the new dataset. + /// A read-only collection of data points to be included in the new dataset. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDataAsync(ChartData chartData, string dataLabel, IReadOnlyCollection data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + + if (chartData.Labels is null) + throw new ArgumentException("chartData.Labels must not be null", nameof(chartData)); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(dataLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + if (!data.Any()) + throw new Exception($"{nameof(data)} cannot be empty."); + + if (chartData.Datasets.Count != data.Count) + throw new InvalidDataException("The chart dataset count and the new data points count do not match."); + + if (chartData.Labels.Contains(dataLabel)) + throw new Exception($"{dataLabel} already exists."); + + chartData.Labels.Add(dataLabel); + + foreach (var dataset in chartData.Datasets) + if (dataset is PolarAreaChartDataset barChartDataset) + { + var chartDatasetData = data.FirstOrDefault(x => x is PolarAreaChartDatasetData barChartDatasetData && barChartDatasetData.DatasetLabel == barChartDataset.Label); + + if (chartDatasetData is PolarAreaChartDatasetData barChartDatasetData) + barChartDataset.Data?.Add(barChartDatasetData.Data as double?); + } + + await JSRuntime.InvokeVoidAsync(PolarAreaChartInterop.AddDatasetsData, Id, dataLabel, data?.Select(x => (PolarAreaChartDatasetData)x)); + + return chartData; + } + + /// + /// Asynchronously adds a dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The dataset to add to the chart data. + /// The options that configure the chart's appearance and behavior. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + + if (chartDataset is null) + throw new ArgumentNullException(nameof(chartDataset)); + + if (chartDataset is PolarAreaChartDataset) + { + chartData.Datasets.Add(chartDataset); + await JSRuntime.InvokeVoidAsync(PolarAreaChartInterop.AddDataset, Id, (PolarAreaChartDataset)chartDataset); + } + + return chartData; + } + + /// + /// Asynchronously initializes the chart with the specified data and options. + /// + /// This method prepares the chart for rendering by invoking the necessary JavaScript functions + /// to set up the chart with the provided data and options. Ensure that contains valid + /// datasets before calling this method. + /// The data to be used for the chart. Must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// An optional array of plugin identifiers to enhance the chart's functionality. + /// A task that represents the asynchronous initialization operation. + [AddedVersion("1.0.0")] + [Description("Asynchronously initializes the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] + public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions, string[]? plugins = null) + { + if (chartData is not null && chartData.Datasets is not null) + { + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JSRuntime.InvokeVoidAsync(PolarAreaChartInterop.Initialize, Id, GetChartType(), data, (PolarAreaChartOptions)chartOptions, plugins); + } + } + + /// + /// Asynchronously updates the chart with the specified data and options. + /// + /// This method updates the chart by invoking a JavaScript function to render the new data and + /// options. Ensure that contains valid datasets to avoid no operation. + /// The data to be displayed on the chart. Must not be null and must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// + [AddedVersion("1.0.0")] + [Description("Asynchronously updates the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] + public override async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions) + { + if (chartData is not null && chartData.Datasets is not null) + { + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JSRuntime.InvokeVoidAsync(PolarAreaChartInterop.Update, Id, GetChartType(), data, (PolarAreaChartOptions)chartOptions); + } + } + + #endregion +} diff --git a/BlazorExpress.ChartJS/ChartComponents/RadarChart.razor b/BlazorExpress.ChartJS/ChartComponents/RadarChart.razor new file mode 100644 index 00000000..547a7665 --- /dev/null +++ b/BlazorExpress.ChartJS/ChartComponents/RadarChart.razor @@ -0,0 +1,6 @@ +@namespace BlazorExpress.ChartJS +@inherits ChartComponentBase + +
+ +
\ No newline at end of file diff --git a/BlazorExpress.ChartJS/ChartComponents/RadarChart.razor.cs b/BlazorExpress.ChartJS/ChartComponents/RadarChart.razor.cs new file mode 100644 index 00000000..fe27d8da --- /dev/null +++ b/BlazorExpress.ChartJS/ChartComponents/RadarChart.razor.cs @@ -0,0 +1,179 @@ +namespace BlazorExpress.ChartJS; + +public partial class RadarChart : ChartComponentBase +{ + #region Constructors + + public RadarChart() + { + _chartType = ChartType.Radar; + } + + #endregion + + #region Methods + + /// + /// Asynchronously adds a new data entry to the specified chart data. + /// + /// The chart data to which the new entry will be added. + /// The label associated with the new data entry. + /// The dataset containing the data to be added. + /// A task representing the asynchronous operation, with a result of the updated . + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new data entry to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDataAsync(ChartData chartData, string dataLabel, IChartDatasetData data) // TODO: May be this method is not required + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + foreach (var dataset in chartData.Datasets) + if (dataset is RadarChartDataset radarChartDataset && radarChartDataset.Label == dataLabel) + if (data is RadarChartDatasetData radarChartDatasetData) + radarChartDataset.Data?.Add(radarChartDatasetData.Data as double?); + + await JSRuntime.InvokeVoidAsync(RadarChartInterop.AddDatasetData, Id, dataLabel, data); + + return chartData; + } + + /// + /// Asynchronously adds a new dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The label for the new dataset. + /// A read-only collection of data points to be included in the new dataset. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDataAsync(ChartData chartData, string dataLabel, IReadOnlyCollection data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + + if (chartData.Labels is null) + throw new ArgumentException("chartData.Labels must not be null", nameof(chartData)); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(dataLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + if (!data.Any()) + throw new Exception($"{nameof(data)} cannot be empty."); + + if (chartData.Datasets.Count != data.Count) + throw new InvalidDataException("The chart dataset count and the new data points count do not match."); + + if (chartData.Labels.Contains(dataLabel)) + throw new Exception($"{dataLabel} already exists."); + + chartData.Labels.Add(dataLabel); + + foreach (var dataset in chartData.Datasets) + if (dataset is RadarChartDataset radarChartDataset) + { + var chartDatasetData = data.FirstOrDefault(x => x is RadarChartDatasetData radarChartDatasetData && radarChartDatasetData.DatasetLabel == radarChartDataset.Label); + + if (chartDatasetData is RadarChartDatasetData radarChartDatasetData) + radarChartDataset.Data?.Add(radarChartDatasetData.Data as double?); + } + + await JSRuntime.InvokeVoidAsync(RadarChartInterop.AddDatasetsData, Id, dataLabel, data?.Select(x => (RadarChartDatasetData)x)); + + return chartData; + } + + /// + /// Asynchronously adds a dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The dataset to add to the chart data. + /// The options that configure the chart's appearance and behavior. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + + if (chartDataset is null) + throw new ArgumentNullException(nameof(chartDataset)); + + if (chartDataset is RadarChartDataset) + { + chartData.Datasets.Add(chartDataset); + await JSRuntime.InvokeVoidAsync(RadarChartInterop.AddDataset, Id, (RadarChartDataset)chartDataset); + } + + return chartData; + } + + /// + /// Asynchronously initializes the chart with the specified data and options. + /// + /// This method prepares the chart for rendering by invoking the necessary JavaScript functions + /// to set up the chart with the provided data and options. Ensure that contains valid + /// datasets before calling this method. + /// The data to be used for the chart. Must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// An optional array of plugin identifiers to enhance the chart's functionality. + /// A task that represents the asynchronous initialization operation. + [AddedVersion("1.0.0")] + [Description("Asynchronously initializes the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] + public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions, string[]? plugins = null) + { + if (chartData is not null && chartData.Datasets is not null) + { + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JSRuntime.InvokeVoidAsync(RadarChartInterop.Initialize, Id, GetChartType(), data, (RadarChartOptions)chartOptions, plugins); + } + } + + /// + /// Asynchronously updates the chart with the specified data and options. + /// + /// This method updates the chart by invoking a JavaScript function to render the new data and + /// options. Ensure that contains valid datasets to avoid no operation. + /// The data to be displayed on the chart. Must not be null and must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// + [AddedVersion("1.0.0")] + [Description("Asynchronously updates the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] + public override async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions) + { + if (chartData is not null && chartData.Datasets is not null) + { + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JSRuntime.InvokeVoidAsync(RadarChartInterop.Update, Id, GetChartType(), data, (RadarChartOptions)chartOptions); + } + } + + #endregion +} diff --git a/BlazorExpress.ChartJS/ChartComponents/ScatterChart.razor b/BlazorExpress.ChartJS/ChartComponents/ScatterChart.razor new file mode 100644 index 00000000..547a7665 --- /dev/null +++ b/BlazorExpress.ChartJS/ChartComponents/ScatterChart.razor @@ -0,0 +1,6 @@ +@namespace BlazorExpress.ChartJS +@inherits ChartComponentBase + +
+ +
\ No newline at end of file diff --git a/BlazorExpress.ChartJS/ChartComponents/ScatterChart.razor.cs b/BlazorExpress.ChartJS/ChartComponents/ScatterChart.razor.cs new file mode 100644 index 00000000..2321dcf1 --- /dev/null +++ b/BlazorExpress.ChartJS/ChartComponents/ScatterChart.razor.cs @@ -0,0 +1,191 @@ +namespace BlazorExpress.ChartJS; + +public partial class ScatterChart : ChartComponentBase +{ + #region Constructors + + public ScatterChart() + { + _chartType = ChartType.Scatter; + } + + #endregion + + #region Methods + + /// + /// Asynchronously adds a new data entry to the specified chart data. + /// + /// The chart data to which the new entry will be added. + /// The label associated with the new data entry. + /// The dataset containing the data to be added. + /// A task representing the asynchronous operation, with a result of the updated . + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new data entry to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDataAsync(ChartData chartData, string dataLabel, IChartDatasetData data) // TODO: May be this method is not required + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentNullException(nameof(chartData.Datasets)); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + foreach (var dataset in chartData.Datasets) + if (dataset is ScatterChartDataset scatterChartDataset && scatterChartDataset.Label == dataLabel) + if (data is ScatterChartDatasetData scatterChartDatasetData && scatterChartDatasetData.Data is ScatterChartDataPoint scatterChartDataPoint) + scatterChartDataset.Data?.Add(scatterChartDataPoint); + + await JSRuntime.InvokeVoidAsync(ScatterChartInterop.AddDatasetData, Id, dataLabel, data); + + return chartData; + } + + /// + /// Asynchronously adds a new dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The label for the new dataset. + /// A read-only collection of data points to be included in the new dataset. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a new dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDataAsync(ChartData chartData, string dataLabel, IReadOnlyCollection data) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + + if (chartData.Labels is null) + throw new ArgumentException("chartData.Labels must not be null", nameof(chartData)); + + if (dataLabel is null) + throw new ArgumentNullException(nameof(dataLabel)); + + if (string.IsNullOrWhiteSpace(dataLabel)) + throw new Exception($"{nameof(dataLabel)} cannot be empty."); + + if (data is null) + throw new ArgumentNullException(nameof(data)); + + if (!data.Any()) + throw new ArgumentException($"{nameof(data)} cannot be empty.", nameof(data)); + + if (chartData.Datasets.Count != data.Count) + throw new InvalidDataException("The chart dataset count and the new data points count do not match."); + + if (chartData.Labels.Contains(dataLabel)) + throw new Exception($"{dataLabel} already exists."); + + chartData.Labels.Add(dataLabel); + + foreach (var dataset in chartData.Datasets) + if (dataset is ScatterChartDataset scatterChartDataset) + { + var chartDatasetData = data.FirstOrDefault(x => x is ScatterChartDatasetData scatterChartDatasetData && scatterChartDatasetData.DatasetLabel == scatterChartDataset.Label); + + if (chartDatasetData is ScatterChartDatasetData scatterChartDatasetData && scatterChartDatasetData.Data is ScatterChartDataPoint scatterChartDataPoint) + scatterChartDataset.Data?.Add(scatterChartDataPoint); + } + + await JSRuntime.InvokeVoidAsync(ScatterChartInterop.AddDatasetsData, Id, dataLabel, data?.Select(x => (ScatterChartDatasetData)x)); + + return chartData; + } + + /// + /// Asynchronously adds a dataset to the specified chart data. + /// + /// The chart data to which the dataset will be added. + /// The dataset to add to the chart data. + /// The options that configure the chart's appearance and behavior. + /// A task that represents the asynchronous operation. The task result contains the updated chart data with the new + /// dataset added. + [AddedVersion("1.0.0")] + [Description("Asynchronously adds a dataset to the specified chart data.")] + [MethodReturnTypeName($"Task<{nameof(ChartData)}>")] + public override async Task AddDatasetAsync(ChartData chartData, IChartDataset chartDataset, IChartOptions chartOptions) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + + if (chartDataset is null) + throw new ArgumentNullException(nameof(chartDataset)); + + if (chartDataset is ScatterChartDataset) + { + chartData.Datasets.Add(chartDataset); + await JSRuntime.InvokeVoidAsync(ScatterChartInterop.AddDataset, Id, (ScatterChartDataset)chartDataset); + } + + return chartData; + } + + /// + /// Asynchronously initializes the chart with the specified data and options. + /// + /// This method prepares the chart for rendering by invoking the necessary JavaScript functions + /// to set up the chart with the provided data and options. Ensure that contains valid + /// datasets before calling this method. + /// The data to be used for the chart. Must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// An optional array of plugin identifiers to enhance the chart's functionality. + /// A task that represents the asynchronous initialization operation. + [AddedVersion("1.0.0")] + [Description("Asynchronously initializes the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] + public override async Task InitializeAsync(ChartData chartData, IChartOptions chartOptions, string[]? plugins = null) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + + if (chartOptions is null) + throw new ArgumentNullException(nameof(chartOptions)); + + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JSRuntime.InvokeVoidAsync(ScatterChartInterop.Initialize, Id, GetChartType(), data, (ScatterChartOptions)chartOptions, plugins); + } + + /// + /// Asynchronously updates the chart with the specified data and options. + /// + /// This method updates the chart by invoking a JavaScript function to render the new data and + /// options. Ensure that contains valid datasets to avoid no operation. + /// The data to be displayed on the chart. Must not be null and must contain at least one dataset. + /// The options to configure the chart's appearance and behavior. + /// + [AddedVersion("1.0.0")] + [Description("Asynchronously updates the chart with the specified data and options.")] + [MethodReturnTypeName(nameof(Task))] + public override async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions) + { + if (chartData is null) + throw new ArgumentNullException(nameof(chartData)); + + if (chartData.Datasets is null) + throw new ArgumentException("chartData.Datasets must not be null", nameof(chartData)); + + if (chartOptions is null) + throw new ArgumentNullException(nameof(chartOptions)); + + var datasets = chartData.Datasets.OfType(); + var data = new { chartData.Labels, Datasets = datasets }; + await JSRuntime.InvokeVoidAsync(ScatterChartInterop.Update, Id, GetChartType(), data, (ScatterChartOptions)chartOptions); + } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Enums/Alignment.cs b/BlazorExpress.ChartJS/Enums/Alignment.cs deleted file mode 100644 index 8b88ce43..00000000 --- a/BlazorExpress.ChartJS/Enums/Alignment.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace BlazorExpress.ChartJS; - -public enum Alignment -{ - Center, // default - Start, - End -} diff --git a/BlazorExpress.ChartJS/Enums/Anchor.cs b/BlazorExpress.ChartJS/Enums/Anchor.cs deleted file mode 100644 index 7285526a..00000000 --- a/BlazorExpress.ChartJS/Enums/Anchor.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace BlazorExpress.ChartJS.Enums; - -public enum Anchor -{ - None, - Center, // default - Start, - End -} diff --git a/BlazorExpress.ChartJS/Enums/DataLabelAlignment.cs b/BlazorExpress.ChartJS/Enums/DataLabelAlignment.cs new file mode 100644 index 00000000..6adffb13 --- /dev/null +++ b/BlazorExpress.ChartJS/Enums/DataLabelAlignment.cs @@ -0,0 +1,45 @@ +namespace BlazorExpress.ChartJS; + +/// +/// The align option defines the position of the label relative to the anchor point position and orientation. +/// +/// +/// +/// +public enum DataLabelAlignment +{ + /// + /// 'center' (default): the label is centered on the anchor point + /// + Center, + + /// + /// 'start': the label is positioned before the anchor point, following the same direction + /// + Start, + + /// + /// 'end': the label is positioned after the anchor point, following the same direction + /// + End, + + /// + /// 'left': the label is positioned to the left of the anchor point (180°) + /// + Left, + + /// + /// 'top': the label is positioned to the top of the anchor point (270°) + /// + Top, + + /// + /// 'right': the label is positioned to the right of the anchor point (0°) + /// + Right, + + /// + /// 'bottom': the label is positioned to the bottom of the anchor point (90°) + /// + Bottom +} diff --git a/BlazorExpress.ChartJS/Enums/DataLabelAnchor.cs b/BlazorExpress.ChartJS/Enums/DataLabelAnchor.cs new file mode 100644 index 00000000..79be6ec9 --- /dev/null +++ b/BlazorExpress.ChartJS/Enums/DataLabelAnchor.cs @@ -0,0 +1,27 @@ +namespace BlazorExpress.ChartJS; + +/// +/// An anchor point is defined by an orientation vector and a position on the data element. +/// The orientation depends on the scale type (vertical, horizontal or radial). +/// The position is calculated based on the anchor option and the orientation vector. +/// +/// +/// +/// +public enum DataLabelAnchor +{ + /// + /// 'center' (default): element center + /// + Center, + + /// + /// 'start': lowest element boundary + /// + Start, + + /// + /// 'end': highest element boundary + /// + End +} diff --git a/BlazorExpress.ChartJS/Enums/InteractionMode.cs b/BlazorExpress.ChartJS/Enums/InteractionMode.cs index 6216bf6a..f4b34b20 100644 --- a/BlazorExpress.ChartJS/Enums/InteractionMode.cs +++ b/BlazorExpress.ChartJS/Enums/InteractionMode.cs @@ -2,10 +2,33 @@ public enum InteractionMode { + /// + /// Finds items in the same dataset. + /// Dataset, + + /// + /// Finds item at the same index. + /// Index, + + /// + /// Gets the items that are at the nearest distance to the point. + /// Nearest, + + /// + /// Finds all of the items that intersect the point + /// Point, + + /// + /// Returns all items that would intersect based on the X coordinate of the position only. Would be useful for a vertical cursor implementation. Note that this only applies to cartesian charts. + /// X, + + /// + /// Returns all items that would intersect based on the Y coordinate of the position. This would be useful for a horizontal cursor implementation. Note that this only applies to cartesian charts. + /// Y } diff --git a/BlazorExpress.ChartJS/Extensions/EnumExtensions.cs b/BlazorExpress.ChartJS/Extensions/EnumExtensions.cs index b91fd4bf..adbb5df6 100644 --- a/BlazorExpress.ChartJS/Extensions/EnumExtensions.cs +++ b/BlazorExpress.ChartJS/Extensions/EnumExtensions.cs @@ -1,26 +1,24 @@ -using BlazorExpress.ChartJS.Enums; - -namespace BlazorExpress.ChartJS; +namespace BlazorExpress.ChartJS; public static class EnumExtensions { #region Methods - public static string? ToAlignmentString(this Alignment alignment) => + public static string? ToChartDatasetDataLabelAlignmentString(this DataLabelAlignment alignment) => alignment switch { - Alignment.Center => "center", // default - Alignment.Start => "start", - Alignment.End => "end", + DataLabelAlignment.Start => "start", + DataLabelAlignment.Center => "center", // default + DataLabelAlignment.End => "end", _ => null }; - public static string? ToAnchorString(this Anchor anchor) => + public static string? ToChartDatasetDataLabelAnchorString(this DataLabelAnchor anchor) => anchor switch { - Anchor.Center => "center", // default - Anchor.Start => "start", - Anchor.End => "end", + DataLabelAnchor.Start => "start", + DataLabelAnchor.Center => "center", // default + DataLabelAnchor.End => "end", _ => null }; diff --git a/BlazorExpress.ChartJS/Interop/BarChartInterop.cs b/BlazorExpress.ChartJS/Interop/BarChartInterop.cs new file mode 100644 index 00000000..3d7ac898 --- /dev/null +++ b/BlazorExpress.ChartJS/Interop/BarChartInterop.cs @@ -0,0 +1,20 @@ +namespace BlazorExpress.ChartJS; + +public class BarChartInterop +{ + #region Fields and Constants + + private const string Prefix = "window.blazorexpress.chartjs.bar."; + + public const string AddDatasetData = Prefix + "addDatasetData"; + + public const string AddDatasetsData = Prefix + "addDatasetsData"; + + public const string AddDataset = Prefix + "addDataset"; + + public const string Initialize = Prefix + "initialize"; + + public const string Update = Prefix + "update"; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Interop/BubbleChartInterop.cs b/BlazorExpress.ChartJS/Interop/BubbleChartInterop.cs new file mode 100644 index 00000000..05f91c45 --- /dev/null +++ b/BlazorExpress.ChartJS/Interop/BubbleChartInterop.cs @@ -0,0 +1,20 @@ +namespace BlazorExpress.ChartJS; + +public class BubbleChartInterop +{ + #region Fields and Constants + + private const string Prefix = "window.blazorexpress.chartjs.bubble."; + + public const string AddDatasetData = Prefix + "addDatasetData"; + + public const string AddDatasetsData = Prefix + "addDatasetsData"; + + public const string AddDataset = Prefix + "addDataset"; + + public const string Initialize = Prefix + "initialize"; + + public const string Update = Prefix + "update"; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Interop/ChartInterop.cs b/BlazorExpress.ChartJS/Interop/ChartInterop.cs new file mode 100644 index 00000000..e45b8039 --- /dev/null +++ b/BlazorExpress.ChartJS/Interop/ChartInterop.cs @@ -0,0 +1,22 @@ +namespace BlazorExpress.ChartJS; + +public class ChartInterop +{ + #region Fields and Constants + + private const string Prefix = "window.blazorexpress.chartjs."; + + public const string AddDatasetData = Prefix + "addDatasetData"; + + public const string AddDatasetsData = Prefix + "addDatasetsData"; + + public const string AddDataset = Prefix + "addDataset"; + + public const string Initialize = Prefix + "initialize"; + + public const string Resize = Prefix + "resize"; + + public const string Update = Prefix + "update"; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Interop/DoughnutChartInterop.cs b/BlazorExpress.ChartJS/Interop/DoughnutChartInterop.cs new file mode 100644 index 00000000..e9df4446 --- /dev/null +++ b/BlazorExpress.ChartJS/Interop/DoughnutChartInterop.cs @@ -0,0 +1,20 @@ +namespace BlazorExpress.ChartJS; + +public class DoughnutChartInterop +{ + #region Fields and Constants + + private const string Prefix = "window.blazorexpress.chartjs.doughnut."; + + public const string AddDatasetData = Prefix + "addDatasetData"; + + public const string AddDatasetsData = Prefix + "addDatasetsData"; + + public const string AddDataset = Prefix + "addDataset"; + + public const string Initialize = Prefix + "initialize"; + + public const string Update = Prefix + "update"; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Interop/LineChartInterop.cs b/BlazorExpress.ChartJS/Interop/LineChartInterop.cs new file mode 100644 index 00000000..3bf069d7 --- /dev/null +++ b/BlazorExpress.ChartJS/Interop/LineChartInterop.cs @@ -0,0 +1,20 @@ +namespace BlazorExpress.ChartJS; + +public class LineChartInterop +{ + #region Fields and Constants + + private const string Prefix = "window.blazorexpress.chartjs.line."; + + public const string AddDatasetData = Prefix + "addDatasetData"; + + public const string AddDatasetsData = Prefix + "addDatasetsData"; + + public const string AddDataset = Prefix + "addDataset"; + + public const string Initialize = Prefix + "initialize"; + + public const string Update = Prefix + "update"; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Interop/PieChartInterop.cs b/BlazorExpress.ChartJS/Interop/PieChartInterop.cs new file mode 100644 index 00000000..cf4a2e55 --- /dev/null +++ b/BlazorExpress.ChartJS/Interop/PieChartInterop.cs @@ -0,0 +1,20 @@ +namespace BlazorExpress.ChartJS; + +public class PieChartInterop +{ + #region Fields and Constants + + private const string Prefix = "window.blazorexpress.chartjs.pie."; + + public const string AddDatasetData = Prefix + "addDatasetData"; + + public const string AddDatasetsData = Prefix + "addDatasetsData"; + + public const string AddDataset = Prefix + "addDataset"; + + public const string Initialize = Prefix + "initialize"; + + public const string Update = Prefix + "update"; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Interop/PolarAreaChartInterop.cs b/BlazorExpress.ChartJS/Interop/PolarAreaChartInterop.cs new file mode 100644 index 00000000..51a21c5a --- /dev/null +++ b/BlazorExpress.ChartJS/Interop/PolarAreaChartInterop.cs @@ -0,0 +1,20 @@ +namespace BlazorExpress.ChartJS; + +public class PolarAreaChartInterop +{ + #region Fields and Constants + + private const string Prefix = "window.blazorexpress.chartjs.polarArea."; + + public const string AddDatasetData = Prefix + "addDatasetData"; + + public const string AddDatasetsData = Prefix + "addDatasetsData"; + + public const string AddDataset = Prefix + "addDataset"; + + public const string Initialize = Prefix + "initialize"; + + public const string Update = Prefix + "update"; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Interop/RadarChartInterop.cs b/BlazorExpress.ChartJS/Interop/RadarChartInterop.cs new file mode 100644 index 00000000..ab245702 --- /dev/null +++ b/BlazorExpress.ChartJS/Interop/RadarChartInterop.cs @@ -0,0 +1,20 @@ +namespace BlazorExpress.ChartJS; + +public class RadarChartInterop +{ + #region Fields and Constants + + private const string Prefix = "window.blazorexpress.chartjs.radar."; + + public const string AddDatasetData = Prefix + "addDatasetData"; + + public const string AddDatasetsData = Prefix + "addDatasetsData"; + + public const string AddDataset = Prefix + "addDataset"; + + public const string Initialize = Prefix + "initialize"; + + public const string Update = Prefix + "update"; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Interop/ScatterChartInterop.cs b/BlazorExpress.ChartJS/Interop/ScatterChartInterop.cs new file mode 100644 index 00000000..2ff1f5d1 --- /dev/null +++ b/BlazorExpress.ChartJS/Interop/ScatterChartInterop.cs @@ -0,0 +1,20 @@ +namespace BlazorExpress.ChartJS; + +public class ScatterChartInterop +{ + #region Fields and Constants + + private const string Prefix = "window.blazorexpress.chartjs.scatter."; + + public const string AddDatasetData = Prefix + "addDatasetData"; + + public const string AddDatasetsData = Prefix + "addDatasetsData"; + + public const string AddDataset = Prefix + "addDataset"; + + public const string Initialize = Prefix + "initialize"; + + public const string Update = Prefix + "update"; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartData.cs b/BlazorExpress.ChartJS/Models/ChartData.cs index e7240a68..5c8cbfff 100644 --- a/BlazorExpress.ChartJS/Models/ChartData.cs +++ b/BlazorExpress.ChartJS/Models/ChartData.cs @@ -1,12 +1,39 @@ namespace BlazorExpress.ChartJS; +/// +/// Represents the data structure for a Chart.js chart, including datasets and labels. +/// public class ChartData { #region Properties, Indexers - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? Datasets { get; set; } + /// + /// Gets or sets the collection of datasets to be displayed in the chart. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the collection of datasets to be displayed in the chart.")] + [EditorRequired] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? Datasets { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public List? Labels { get; set; } + /// + /// Gets or sets the labels for the chart, typically used for the x-axis or categories. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the labels for the chart, typically used for the x-axis or categories.")] + [EditorRequired] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? Labels { get; set; } #endregion } diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDataset.cs new file mode 100644 index 00000000..4daba71d --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDataset.cs @@ -0,0 +1,289 @@ +namespace BlazorExpress.ChartJS; + +/// +/// The bar chart allows a number of properties to be specified for each dataset. +/// These are used to set display properties for a specific dataset. +/// +/// +/// +/// +/// +/// +/// +public class BarChartDataset : ChartDataset +{ + #region Properties, Indexers + + /// + /// The bar background color. + /// + /// Default value is rgba(0, 0, 0, 0.1). + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("Gets or sets the bar background color.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BackgroundColor { get; set; } + + /// + /// Percent (0-1) of the available width each bar should be within the category width. + /// 1.0 will take the whole category width and put the bars right next to each other. + /// + /// Default value is 0.9. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0.9)] + [Description("Percent (0-1) of the available width each bar should be within the category width. 1.0 will take the whole category width and put the bars right next to each other.")] + public double BarPercentage { get; set; } = 0.9; + + /// + /// If this value is a number, it is applied to the width of each bar, in pixels. + /// When this is enforced, and are ignored. + /// + /// Default value is . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the width of each bar, in pixels. When this is enforced, BarPercentage and CategoryPercentage are ignored.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? BarThickness { get; set; } + + /// + /// The bar border color. + /// + /// Default value is rgba(0, 0, 0, 0.1). + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The bar border color.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderColor { get; set; } + + /// + /// The bar border radius (in pixels). + /// + /// Default value is 0. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("The bar border radius (in pixels).")] + [ParameterTypeName("List?")] + public List? BorderRadius { get; set; } + + //BorderSkipped + //https://www.chartjs.org/docs/latest/charts/bar.html#styling + //https://www.chartjs.org/docs/latest/api/interfaces/BarControllerDatasetOptions.html#borderskipped + + /// + /// The bar border width (in pixels). + /// + /// Default value is 0. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("The bar border width (in pixels).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderWidth { get; set; } + + /// + /// Percent (0-1) of the available width each category should be within the sample width. + /// + /// Default value is 0.8. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0.8)] + [Description("Percent (0-1) of the available width each category should be within the sample width.")] + public double CategoryPercentage { get; set; } = 0.8; + + /// + /// Gets or sets the data labels configuration for the bar chart dataset. + /// + /// This property allows customization of data labels, such as their appearance, positioning, and + /// formatting. If not set, the default configuration will be used. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the data labels configuration for the bar chart dataset. This property allows customization of data labels, such as their appearance, positioning, and formatting. If not set, the default configuration will be used.")] + [ParameterTypeName("BarChartDatasetDataLabels")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public BarChartDatasetDataLabels Datalabels { get; set; } = new(); + + /// + /// Should the bars be grouped on index axis. + /// When true, all the datasets at same index value will be placed next to each other centering on that index value. + /// When false, each bar is placed on its actual index-axis value. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(true)] + [Description("Should the bars be grouped on index axis. When true, all the datasets at same index value will be placed next to each other centering on that index value. When false, each bar is placed on its actual index-axis value.")] + public bool Grouped { get; set; } = true; + + /// + /// The bar background color when hovered. + /// + /// Default value is . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The bar background color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBackgroundColor { get; set; } + + /// + /// The bar border color when hovered. + /// + /// Default value is . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The bar border color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderColor { get; set; } + + /// + /// The bar border radius when hovered (in pixels). + /// + /// Default value is 0. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("The bar border radius when hovered (in pixels).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderRadius { get; set; } + + /// + /// The bar border width when hovered (in pixels). + /// + /// Default value is 1. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("The bar border width when hovered (in pixels).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderWidth { get; set; } + + /// + /// The base axis of the dataset. 'x' for vertical bars and 'y' for horizontal bars. + /// + /// Default value is 'x'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("x")] + [Description("The base axis of the dataset. 'x' for vertical bars and 'y' for horizontal bars.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IndexAxis { get; set; } + + //InflateAmount + //https://www.chartjs.org/docs/latest/charts/bar.html#inflateamount + + /// + /// Set this to ensure that bars are not sized thicker than this. + /// + /// Default value is . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Set this to ensure that bars are not sized thicker than this.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? MaxBarThickness { get; set; } + + /// + /// Set this to ensure that bars have a minimum length in pixels. + /// + /// Default value is . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Set this to ensure that bars have a minimum length in pixels.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? MinBarLength { get; set; } + + //PointStyle + //https://www.chartjs.org/docs/latest/charts/bar.html#styling + //https://www.chartjs.org/docs/latest/configuration/elements.html#point-styles + + /// + /// If true, null or undefined values will not be used for spacing calculations when determining bar size. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(false)] + [Description("If true, null or undefined values will not be used for spacing calculations when determining bar size.")] + public bool SkipNull { get; set; } + + //Stack + //https://www.chartjs.org/docs/latest/charts/bar.html#general + + /// + /// The ID of the x-axis to plot this dataset on. + /// + /// Default value is first x axis. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The ID of the x-axis to plot this dataset on.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? XAxisID { get; set; } + + /// + /// The ID of the y-axis to plot this dataset on. + /// + /// Default value is first y axis. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The ID of the y-axis to plot this dataset on.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? YAxisID { get; set; } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/BarChartDatasetData.cs b/BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDatasetData.cs similarity index 100% rename from BlazorExpress.ChartJS/Models/ChartDataset/BarChartDatasetData.cs rename to BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDatasetData.cs diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDatasetDataLabels.cs b/BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDatasetDataLabels.cs new file mode 100644 index 00000000..052d1310 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/BarChart/BarChartDatasetDataLabels.cs @@ -0,0 +1,3 @@ +namespace BlazorExpress.ChartJS; + +public class BarChartDatasetDataLabels : ChartDatasetDataLabels { } diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/BarChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/BarChartDataset.cs deleted file mode 100644 index 813bedac..00000000 --- a/BlazorExpress.ChartJS/Models/ChartDataset/BarChartDataset.cs +++ /dev/null @@ -1,122 +0,0 @@ -using BlazorExpress.ChartJS.Enums; - -namespace BlazorExpress.ChartJS; - -public class BarChartDataset : ChartDataset -{ - #region Properties, Indexers - - /// - /// Percent (0-1) of the available width each bar should be within the category width. - /// 1.0 will take the whole category width and put the bars right next to each other. - /// - public double BarPercentage { get; set; } = 0.8; - - /// - /// Border radius - /// - public int BorderRadius { get; set; } - - //BarThickness - //https://www.chartjs.org/docs/latest/api/interfaces/BarControllerDatasetOptions.html#barthickness - - //BorderSkipped - //https://www.chartjs.org/docs/latest/api/interfaces/BarControllerDatasetOptions.html#borderskipped - - /// - /// Percent (0-1) of the available width each category should be within the sample width. - /// - public double CategoryPercentage { get; set; } = 0.8; - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public BarChartDatasetDataLabels Datalabels { get; set; } = new(); - - /// - /// The label for the dataset which appears in the legend and tooltips. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Label { get; set; } - - //MaxBarThickness - //https://www.chartjs.org/docs/latest/api/interfaces/BarControllerDatasetOptions.html#maxbarthickness - - //MinBarLength - //https://www.chartjs.org/docs/latest/api/interfaces/BarControllerDatasetOptions.html#minbarlength - - /// - /// The ID of the x axis to plot this dataset on. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? XAxisID { get; set; } - - /// - /// The ID of the y axis to plot this dataset on. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? YAxisID { get; set; } - - #endregion -} - -public class BarChartDatasetDataLabels -{ - #region Fields and Constants - - private Alignment alignment; - - private Anchor anchor; - - #endregion - - #region Properties, Indexers - - /// - /// Gets or sets the data labels alignment. - /// - /// - /// Default value is . - /// - [JsonIgnore] - public Alignment Alignment - { - get => alignment; - set - { - alignment = value; - DataLabelsAlignment = value.ToAlignmentString(); - } - } - - /// - /// Gets or sets the data labels anchor. - /// - /// - /// Default value is . - /// - [JsonIgnore] - public Anchor Anchor - { - get => anchor; - set - { - anchor = value; - DataLabelsAnchor = value.ToAnchorString(); - } - } - - /// - /// Gets or sets the data labels alignment. - /// Possible values: start, center, and end. - /// - [JsonPropertyName("align")] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? DataLabelsAlignment { get; private set; } - - /// - /// Gets or sets the data labels anchor. - /// Possible values: start, center, and end. - /// - [JsonPropertyName("anchor")] - public string? DataLabelsAnchor { get; private set; } - - #endregion -} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDataPoint.cs b/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDataPoint.cs new file mode 100644 index 00000000..84f2a915 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDataPoint.cs @@ -0,0 +1,6 @@ +namespace BlazorExpress.ChartJS; + +/// +/// +/// +public record BubbleChartDataPoint(double X, double Y, double R); diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDataset.cs new file mode 100644 index 00000000..2cf02ad5 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDataset.cs @@ -0,0 +1,193 @@ +namespace BlazorExpress.ChartJS; + +/// +/// A bubble chart is used to display three dimensions of data at the same time. +/// The location of the bubble is determined by the first two dimensions and the corresponding horizontal and vertical axes. +/// The third dimension is represented by the size of the individual bubbles. +/// +/// +/// +/// +public class BubbleChartDataset : ChartDataset +{ + #region Properties, Indexers + + /// + /// The line fill color. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The line fill color.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BackgroundColor { get; set; } + + /// + /// The line color. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The line color.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderColor { get; set; } + + /// + /// The line width (in pixels). + /// + /// Default value is 3. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(3)] + [Description("The line width (in pixels).")] + public double BorderWidth { get; set; } = 3; + + //clip + //https://www.chartjs.org/docs/latest/charts/bubble.html#general + + /// + /// Gets or sets the data labels configuration for the bubble chart dataset. + /// + /// Use this property to customize the display of data labels, such as their position, + /// formatting, and visibility, for the dataset in the bubble chart. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the data labels configuration for the bubble chart dataset. Use this property to customize the display of data labels, such as their position, formatting, and visibility, for the dataset in the bubble chart.")] + [ParameterTypeName(nameof(BubbleChartDatasetDataLabels))] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public BubbleChartDatasetDataLabels Datalabels { get; set; } = new(); + + /// + /// Draw the active points of a dataset over the other points of the dataset. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(true)] + [Description("Draw the active points of a dataset over the other points of the dataset.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? DrawActiveElementsOnTop { get; set; } + + /// + /// The line fill color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The line fill color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBackgroundColor { get; set; } + + /// + /// The line color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The line color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderColor { get; set; } + + /// + /// The line width (in pixels) when hovered. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("The line width (in pixels) when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderWidth { get; set; } + + /// + /// The pixel size of the non-displayed point that reacts to mouse events. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("The pixel size of the non-displayed point that reacts to mouse events.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HitRadius { get; set; } + + /// + /// The pixel size of the non-displayed point that reacts to mouse events. + /// + /// Default value is 4. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(4)] + [Description("The pixel size of the non-displayed point that reacts to mouse events.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverRadius { get; set; } + + //Label + //https://www.chartjs.org/docs/latest/charts/bubble.html#general + + /// + /// The radius of the point shape. If set to 0, the point is not rendered. + /// + /// Default value is 3. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(3)] + [Description("The radius of the point shape. If set to 0, the point is not rendered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? Radius { get; set; } + + /// + /// The rotation of the point in degrees. + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("The rotation of the point in degrees.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? Rotation { get; set; } + + /// + /// Style of the point. + /// Supported values are 'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', and 'triangle'. + /// + /// Default value is 'circle'. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("circle")] + [Description("Style of the point. Supported values are 'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', and 'triangle'.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointStyle { get; set; } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDatasetData.cs b/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDatasetData.cs new file mode 100644 index 00000000..20a7cb76 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDatasetData.cs @@ -0,0 +1,10 @@ +namespace BlazorExpress.ChartJS; + +public record BubbleChartDatasetData : ChartDatasetData +{ + #region Constructors + + public BubbleChartDatasetData(string? datasetLabel, BubbleChartDataPoint data) : base(datasetLabel, data) { } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDatasetDataLabels.cs b/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDatasetDataLabels.cs new file mode 100644 index 00000000..a9e076ab --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChart/BubbleChartDatasetDataLabels.cs @@ -0,0 +1,3 @@ +namespace BlazorExpress.ChartJS; + +public class BubbleChartDatasetDataLabels : ChartDatasetDataLabels { } diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChartDataset.cs deleted file mode 100644 index ff810ce7..00000000 --- a/BlazorExpress.ChartJS/Models/ChartDataset/BubbleChartDataset.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace BlazorExpress.ChartJS; - -public class BubbleChartDataset : ChartDataset -{ - #region Properties, Indexers - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public new string? BackgroundColor { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public new string? BorderColor { get; set; } - - public new double BorderWidth { get; set; } - - public new List? Data { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public new string? HoverBackgroundColor { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public new string? HoverBorderColor { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public new string? HoverBorderWidth { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Label { get; set; } - - public int Radius { get; set; } = 3; - - #endregion -} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/BubbleData.cs b/BlazorExpress.ChartJS/Models/ChartDataset/BubbleData.cs deleted file mode 100644 index 415f4f66..00000000 --- a/BlazorExpress.ChartJS/Models/ChartDataset/BubbleData.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace BlazorExpress.ChartJS; - -public class BubbleData -{ - #region Constructors - - public BubbleData(double x, double y, double r) - { - X = x; - Y = y; - R = r; - } - - #endregion - - #region Properties, Indexers - - public double R { get; set; } - - public double X { get; set; } - public double Y { get; set; } - - #endregion -} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/ChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/ChartDataset.cs index 8e9d4794..420e0144 100644 --- a/BlazorExpress.ChartJS/Models/ChartDataset/ChartDataset.cs +++ b/BlazorExpress.ChartJS/Models/ChartDataset/ChartDataset.cs @@ -2,7 +2,11 @@ public interface IChartDataset { } -public class ChartDataset : IChartDataset +/// +/// Represents a dataset configuration for Chart.js charts. +/// See for more information. +/// +public class ChartDataset : IChartDataset { #region Constructors @@ -16,67 +20,94 @@ public ChartDataset() #region Properties, Indexers /// - /// Get or sets the BackgroundColor. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? BackgroundColor { get; set; } - - /// - /// Get or sets the BorderColor. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? BorderColor { get; set; } - - /// - /// Get or sets the BorderWidth. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? BorderWidth { get; set; } - - /// - /// How to clip relative to chartArea. Positive value allows overflow, negative value clips that many pixels inside - /// chartArea. 0 = clip at chartArea. - /// Clipping can also be configured per side: clip: {left: 5, top: false, right: -2, bottom: 0} + /// How to clip relative to chartArea. Positive value allows overflow, negative value clips that + /// many pixels inside chartArea. 0 = clip at chartArea. Clipping can also be configured + /// per side: clip: {left: 5, top: false, right: -2, bottom: 0} + /// + /// Default value is . + /// /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("How to clip relative to chartArea. Positive value allows overflow, negative value clips that many pixels inside chartArea. 0 = clip at chartArea. Clipping can also be configured per side: clip: {left: 5, top: false, right: -2, bottom: 0}")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Clip { get; set; } /// /// Get or sets the Data. + /// + /// Default value is . + /// /// - public List? Data { get; set; } + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Get or sets the Data.")] + [EditorRequired] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? Data { get; set; } /// - /// Configures the visibility state of the dataset. Set it to true, to hide the dataset from the chart. + /// Configure the visibility of the dataset. Setting Hidden to true will prevent the dataset from being rendered in the Chart. + /// + /// Default value is . + /// /// + [AddedVersion("1.0.0")] + [DefaultValue(false)] + [Description("Configure the visibility of the dataset. Setting Hidden to true will prevent the dataset from being rendered in the Chart.")] public bool Hidden { get; set; } /// - /// Get or sets the HoverBackgroundColor. + /// The label for the dataset which appears in the legend and tooltips. + /// + /// Default value is . + /// /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The label for the dataset which appears in the legend and tooltips.")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? HoverBackgroundColor { get; set; } + public string? Label { get; set; } /// - /// Get or sets the HoverBorderColor. + /// Gets the unique object identifier for this dataset instance. + /// + /// Default value is an auto-generated assigned at construction. + /// /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? HoverBorderColor { get; set; } + [AddedVersion("1.0.0")] + [DefaultValue("Guid.NewGuid()")] + [Description("Gets the unique object identifier for this dataset instance. This value is auto-generated when the dataset is created.")] + public Guid Oid { get; private set; } /// - /// Get or sets the HoverBorderWidth. + /// The drawing order of dataset. Also affects order for stacking, tooltip and legend. + /// + /// Default value is 0. + /// /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? HoverBorderWidth { get; set; } + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("The drawing order of dataset. Also affects order for stacking, tooltip and legend.")] + public int Order { get; set; } - /// - /// Get unique object id. - /// - public Guid Oid { get; private set; } + //Parsing + //https://www.chartjs.org/docs/latest/general/data-structures.html#dataset-configuration + + //Stack + //https://www.chartjs.org/docs/latest/general/data-structures.html#dataset-configuration /// /// Gets or sets the chart type. + /// + /// Default value is . + /// This value is auto-set based on the chart type. + /// /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the chart type. This value is auto-set based on the chart type.")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Type { get; protected set; } diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/ChartDatasetData.cs b/BlazorExpress.ChartJS/Models/ChartDataset/ChartDatasetData.cs index 7d0a5f6c..26c1b9e8 100644 --- a/BlazorExpress.ChartJS/Models/ChartDataset/ChartDatasetData.cs +++ b/BlazorExpress.ChartJS/Models/ChartDataset/ChartDatasetData.cs @@ -6,7 +6,7 @@ public record ChartDatasetData : IChartDatasetData { #region Constructors - public ChartDatasetData(string? datasetLabel, double data) + public ChartDatasetData(string? datasetLabel, object? data) { DatasetLabel = datasetLabel; Data = data; @@ -16,9 +16,29 @@ public ChartDatasetData(string? datasetLabel, double data) #region Properties, Indexers - public double Data { get; init; } - + /// + /// Gets the label for the dataset this data belongs to. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets the label for the dataset this data belongs to.")] + [ParameterTypeName("string?")] public string? DatasetLabel { get; init; } + /// + /// Gets the data value or values for the dataset. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets the data value or values for the dataset.")] + [ParameterTypeName("object?")] + public object? Data { get; init; } + #endregion } diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/ChartDatasetDataLabels.cs b/BlazorExpress.ChartJS/Models/ChartDataset/ChartDatasetDataLabels.cs new file mode 100644 index 00000000..3b067c1c --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/ChartDatasetDataLabels.cs @@ -0,0 +1,121 @@ +namespace BlazorExpress.ChartJS; + +/// +/// Highly customizable Chart.js plugin that displays labels on data for any type of charts. +/// . +/// +public class ChartDatasetDataLabels +{ + #region Fields and Constants + + private DataLabelAlignment alignment; + + private DataLabelAnchor anchor; + + #endregion + + #region Properties, Indexers + + /// + /// Gets or sets the data labels alignment. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(DataLabelAlignment.Center)] + [Description("Gets or sets the data labels alignment.")] + [JsonIgnore] + public DataLabelAlignment Alignment + { + get => alignment; + set + { + alignment = value; + DataLabelsAlignmentAsString = value.ToChartDatasetDataLabelAlignmentString(); + } + } + + /// + /// Gets or sets the data labels anchor. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(DataLabelAnchor.Center)] + [Description("Gets or sets the data labels anchor.")] + [JsonIgnore] + public DataLabelAnchor Anchor + { + get => anchor; + set + { + anchor = value; + DataLabelsAnchorAsString = value.ToChartDatasetDataLabelAnchorString(); + } + } + + /// + /// Gets or sets the data label background color. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the data label background color.")] + public string? BackgroundColor { get; set; } + + + /// + /// Gets or sets the data label border color. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the data label border color.")] + public string? BorderColor { get; set; } + + /// + /// Gets or sets the width of the border. + /// + /// Default value is 2. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(2)] + [Description("Gets or sets the width of the border.")] + public double BorderWidth { get; set; } = 2; + + /// + /// Gets the data labels alignment as a string. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets the data labels alignment as a string.")] + [ParameterTypeName("string?")] + [JsonPropertyName("align")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? DataLabelsAlignmentAsString { get; private set; } + + /// + /// Gets the data labels anchor as a string. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets the data labels anchor as a string.")] + [ParameterTypeName("string?")] + [JsonPropertyName("anchor")] + public string? DataLabelsAnchorAsString { get; private set; } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChart/DoughnutChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChart/DoughnutChartDataset.cs new file mode 100644 index 00000000..ff8ec62c --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChart/DoughnutChartDataset.cs @@ -0,0 +1,294 @@ +namespace BlazorExpress.ChartJS; + +/// +/// The doughnut/pie chart allows a number of properties to be specified for each dataset. +/// These are used to set display properties for a specific dataset. +/// . +/// +public class DoughnutChartDataset : ChartDataset +{ + #region Properties, Indexers + + /// + /// Arc background color. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("Arc background color.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BackgroundColor { get; set; } + + /// + /// Supported values are 'center' and 'inner'. + /// When 'center' is set, the borders of arcs next to each other will overlap. + /// When 'inner' is set, it is guaranteed that all borders will not overlap. + /// + /// Default value is 'center'. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("center")] + [Description("Supported values are center and inner. When center is set, the borders of arcs next to each other will overlap. When inner is set, it is guaranteed that all borders will not overlap.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderAlign { get; set; } // TODO: change this to enum + + /// + /// Arc border color. + /// + /// Default value is '#fff'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("#fff")] + [Description("Arc border color.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderColor { get; set; } + + /// + /// Arc border length and spacing of dashes. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border length and spacing of dashes.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderDash { get; set; } + + /// + /// Arc border offset for line dashes. + /// + /// Default value is 0.0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("0.0")] + [Description("Arc border offset for line dashes.")] + //[ParameterTypeName("")] + public double BorderDashOffset { get; set; } + + /// + /// Arc border join style. + /// Supported values are 'round', 'bevel', and 'miter'. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border join style. Supported values are round, bevel, and miter.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderJoinStyle { get; set; } // TODO: change this to enum + + /// + /// It is applied to all corners of the arc (outerStart, outerEnd, innerStart, innerRight). + /// + /// Default value is 0. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("It is applied to all corners of the arc (outerStart, outerEnd, innerStart, innerRight).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderRadius { get; set; } + + /// + /// Arc border width (in pixels). + /// + /// Default value is 2. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(2)] + [Description("Arc border width (in pixels).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderWidth { get; set; } + + /// + /// Per-dataset override for the sweep that the arcs cover. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Per-dataset override for the sweep that the arcs cover.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? Circumference { get; set; } + + //Clip + //https://www.chartjs.org/docs/latest/charts/doughnut.html#general + + /// + /// Gets or sets the data labels configuration for the doughnut chart dataset. + /// + /// Use this property to customize the display of data labels, such as their font, color, + /// alignment, and visibility, for the doughnut chart dataset. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the data labels configuration for the doughnut chart dataset. Use this property to customize the display of data labels, such as their font, color, alignment, and visibility, for the doughnut chart dataset.")] + [ParameterTypeName("DoughnutChartDatasetDataLabels")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public DoughnutChartDatasetDataLabels Datalabels { get; set; } = new(); + + /// + /// Arc background color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc background color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBackgroundColor { get; set; } + + /// + /// Arc border color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderColor { get; set; } + + /// + /// Arc border length and spacing of dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border length and spacing of dashes when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderDash { get; set; } + + /// + /// Arc border offset for line dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border offset for line dashes when hovered.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? HoverBorderDashOffset { get; set; } + + /// + /// Arc border join style when hovered. + /// Supported values are 'round', 'bevel', and 'miter'. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border join style when hovered. Supported values are round, bevel, and miter.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderJoinStyle { get; set; } // TODO: change this to enum + + /// + /// Arc border width when hovered (in pixels). + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border width when hovered (in pixels).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderWidth { get; set; } + + /// + /// Arc offset when hovered (in pixels). + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("Arc offset when hovered (in pixels).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverOffset { get; set; } + + /// + /// Arc offset (in pixels). + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("Arc offset (in pixels).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? Offset { get; set; } + + /// + /// Per-dataset override for the starting angle to draw arcs from. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Per-dataset override for the starting angle to draw arcs from.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? Rotation { get; set; } + + /// + /// Fixed arc offset (in pixels). Similar to but applies to all arcs. + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("Fixed arc offset (in pixels). Similar to Offset but applies to all arcs.")] + public double Spacing { get; set; } + + /// + /// The relative thickness of the dataset. + /// Providing a value for weight will cause the pie or doughnut dataset to be drawn + /// with a thickness relative to the sum of all the dataset weight values. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("The relative thickness of the dataset. Providing a value for weight will cause the pie or doughnut dataset to be drawn with a thickness relative to the sum of all the dataset weight values.")] + public double Weight { get; set; } = 1; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChartDatasetData.cs b/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChart/DoughnutChartDatasetData.cs similarity index 66% rename from BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChartDatasetData.cs rename to BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChart/DoughnutChartDatasetData.cs index e8f2a60b..b0665a99 100644 --- a/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChartDatasetData.cs +++ b/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChart/DoughnutChartDatasetData.cs @@ -13,6 +13,13 @@ public DoughnutChartDatasetData(string? datasetLabel, double data, string? backg #region Properties, Indexers + /// + /// Gets or initializes the background color as a string. + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("")] + [ParameterTypeName("string?")] public string? BackgroundColor { get; init; } #endregion diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChart/DoughnutChartDatasetDataLabels.cs b/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChart/DoughnutChartDatasetDataLabels.cs new file mode 100644 index 00000000..3d2a0106 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChart/DoughnutChartDatasetDataLabels.cs @@ -0,0 +1,3 @@ +namespace BlazorExpress.ChartJS; + +public class DoughnutChartDatasetDataLabels : ChartDatasetDataLabels { } \ No newline at end of file diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChartDataset.cs deleted file mode 100644 index 9318e0db..00000000 --- a/BlazorExpress.ChartJS/Models/ChartDataset/DoughnutChartDataset.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BlazorExpress.ChartJS.Enums; - -namespace BlazorExpress.ChartJS; - -public class DoughnutChartDataset : ChartDataset -{ - #region Properties, Indexers - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public DoughnutChartDatasetDataLabels Datalabels { get; set; } = new(); - - /// - /// The label for the dataset which appears in the legend and tooltips. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Label { get; set; } - - #endregion -} - -public class DoughnutChartDatasetDataLabels -{ - #region Fields and Constants - - private Anchor anchor; - - #endregion - - #region Properties, Indexers - - /// - /// Gets or sets the data labels anchor. - /// - /// - /// Default value is . - /// - [JsonIgnore] - public Anchor Anchor - { - get => anchor; - set - { - anchor = value; - DataLabelsAnchor = value.ToAnchorString(); - } - } - - //public string? BackgroundColor { get; set; } - - public double? BorderWidth { get; set; } = 2; - - /// - /// Gets or sets the data labels anchor. - /// Possible values: start, center, and end. - /// - [JsonPropertyName("anchor")] - public string? DataLabelsAnchor { get; private set; } - - #endregion -} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDataset.cs new file mode 100644 index 00000000..6686fa32 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDataset.cs @@ -0,0 +1,602 @@ +using System.Diagnostics.Metrics; +using System.Reflection; + +namespace BlazorExpress.ChartJS; + +/// +/// A line chart is a way of plotting data points on a line. +/// Often, it is used to show trend data, or the comparison of two data sets. +/// +/// . +/// +/// +public class LineChartDataset : ChartDataset +{ + #region Methods + + /// + /// Fill between this dataset and the other dataset, specified by absolute index (zero based) or relative index. + /// + /// The index of the dataset to fill to + /// Whether the specified index is relative or absolute (zero based) + /// The dataset, for method chaining + /// If the relative index is zero. + public LineChartDataset FillToDataset(int index, bool relativeIndex = false) + { + if (relativeIndex && index == 0) + throw new ArgumentException("The relative index must be non-zero."); + + Fill = relativeIndex ? index.ToString("+0;-0", CultureInfo.InvariantCulture) : index; + + return this; + } + + /// + /// Fill between this dataset and the other dataset, specified by passing a dataset in the same chart. + /// + /// The chart data of the chart both datasets live in. + /// The other dataset to fill to. + /// Whether to specify the fill index relative ("+/-n" string) or absolute (as zero-based int) + /// The dataset, for method chaining + /// If any of the datasets is not in the chart data, or if both datasets are the same. + public LineChartDataset FillToDataset(ChartData chartData, IChartDataset dataset, bool relativeIndex = false) + { + var index = chartData?.Datasets?.IndexOf(dataset) ?? -1; + + if (index < 0) + throw new ArgumentException("The dataset is not in the chart data."); + + if (relativeIndex) + { + var myIndex = relativeIndex ? chartData.Datasets.IndexOf(this) : 0; + + if (myIndex < 0) + throw new ArgumentException("The dataset is not in the chart data."); + + if (myIndex == index) + throw new ArgumentException("The dataset is the same as this dataset."); + + Fill = (index - myIndex).ToString("+0;-0", CultureInfo.InvariantCulture); + } + else + { + Fill = index; + } + + return this; + } + + /// + /// Fills between the current dataset and the top of the chart (fill: 'end'). + /// + /// The dataset, for method chaining + public LineChartDataset FillToEnd() + { + Fill = "end"; + + return this; + } + + /// + /// Fills between the current dataset and the origin. For legacy reasons, this is the same as fill: true. + /// + /// The dataset, for method chaining + public LineChartDataset FillToOrigin() + { + Fill = "origin"; + + return this; + } + + /// + /// Fill to the line below the current dataset (fill: 'stack'). + /// + /// The dataset, for method chaining + public LineChartDataset FillToStackedValueBelow() + { + Fill = "stack"; + + return this; + } + + /// + /// Fills between the current dataset and the start (fill: 'start'). + /// + /// The dataset, for method chaining + public LineChartDataset FillToStart() + { + Fill = "start"; + + return this; + } + + /// + /// Fill to the line of the given constant value. + /// + /// The value to fill to + /// The dataset, for method chaining + public LineChartDataset FillToValue(double value) + { + Fill = new { value }; + + return this; + } + + #endregion + + #region Properties, Indexers + + /// + /// The line fill color. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The line fill color.")] + public string BackgroundColor { get; set; } = "rgba(0, 0, 0, 0.1)"; + + /// + /// Cap style of the line. + /// Supported values are 'butt', 'round', and 'square'. + /// + /// Default value is 'butt'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("butt")] + [Description("Cap style of the line. Supported values are 'butt', 'round', and 'square'.")] + public string BorderCapStyle { get; set; } = "butt"; + + /// + /// The line color. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The line color.")] + public string BorderColor { get; set; } = "rgba(0, 0, 0, 0.1)"; + + /// + /// Length and spacing of dashes. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Length and spacing of dashes.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderDash { get; set; } + + /// + /// Offset for line dashes. + /// + /// Default value is 0.0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0.0)] + [Description("Offset for line dashes.")] + public double BorderDashOffset { get; set; } + + /// + /// Line joint style. + /// There are three possible values for this property: 'round', 'bevel', and 'miter'. + /// + /// Default value is 'miter'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("miter")] + [Description("Line joint style. There are three possible values for this property: 'round', 'bevel', and 'miter'.")] + public string BorderJoinStyle { get; set; } = "miter"; + + /// + /// The line width (in pixels). + /// + /// Default value is 3. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(3)] + [Description("The line width (in pixels).")] + public double BorderWidth { get; set; } = 3; + + //clip + //https://www.chartjs.org/docs/latest/charts/line.html#general + + /// + /// Supported values are 'default', and 'monotone'. + /// + /// Default value is 'default'. + /// + /// . + /// + [AddedVersion("1.0.0")] + [DefaultValue("default")] + [Description("Supported values are 'default', and 'monotone'.")] + public string CubicInterpolationMode { get; set; } = "default"; + + /// + /// Gets or sets the data labels configuration for the line chart dataset. + /// + /// Use this property to customize the display of data labels, such as their position, + /// formatting, and visibility, for the dataset in the line chart. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the data labels configuration for the line chart dataset. Use this property to customize the display of data labels, such as their position, formatting, and visibility, for the dataset in the line chart.")] + [ParameterTypeName("LineChartDatasetDataLabels")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public LineChartDatasetDataLabels Datalabels { get; set; } = new(); + + /// + /// Draw the active points of a dataset over the other points of the dataset. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Draw the active points of a dataset over the other points of the dataset.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? DrawActiveElementsOnTop { get; set; } + + /// + /// How to fill the area under the line. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(false)] + [Description("How to fill the area under the line.")] + public object Fill { get; set; } = false; + + /// + /// The line fill color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The line fill color when hovered.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? HoverBackgroundColor { get; set; } + + /// + /// Cap style of the line when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Cap style of the line when hovered.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? HoverBorderCapStyle { get; set; } + + /// + /// The line color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The line color when hovered.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? HoverBorderColor { get; set; } + + /// + /// Length and spacing of dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Length and spacing of dashes when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderDash { get; set; } + + /// + /// Offset for line dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Offset for line dashes when hovered.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? HoverBorderDashOffset { get; set; } + + /// + /// Line joint style when hovered. + /// There are three possible values for this property: 'round', 'bevel', and 'miter'. + /// + /// Default value is 'miter'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("miter")] + [Description("Line joint style. There are three possible values for this property: 'round', 'bevel', and 'miter'.")] + public string HoverBorderJoinStyle { get; set; } = "miter"; + + /// + /// The line width (in pixels) when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The line width (in pixels) when hovered.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? HoverBorderWidth { get; set; } + + /// + /// The base axis of the dataset. 'x' for horizontal lines and 'y' for vertical lines. + /// + /// Default value is 'x'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("x")] + [Description("The base axis of the dataset. 'x' for horizontal lines and 'y' for vertical lines.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IndexAxis { get; set; } = "x"; + + /// + /// The fill color for points. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The fill color for points.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointBackgroundColor { get; set; } + + /// + /// The border color for points. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The border color for points.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointBorderColor { get; set; } + + /// + /// The width of the point border in pixels. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("The width of the point border in pixels.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointBorderWidth { get; set; } + + /// + /// The pixel size of the non-displayed point that reacts to mouse events. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("The pixel size of the non-displayed point that reacts to mouse events.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHitRadius { get; set; } + + /// + /// Point background color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Point background color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverBackgroundColor { get; set; } + + /// + /// Point border color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Point border color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverBorderColor { get; set; } + + /// + /// Border width of point when hovered. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("Border width of point when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverBorderWidth { get; set; } + + /// + /// The radius of the point when hovered. + /// + /// Default value is 4. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(4)] + [Description("The radius of the point when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverRadius { get; set; } + + /// + /// The radius of the point shape. If set to 0, the point is not rendered. + /// + /// Default value is 3. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(3)] + [Description("The radius of the point shape. If set to 0, the point is not rendered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointRadius { get; set; } + + /// + /// The rotation of the point in degrees. + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("The rotation of the point in degrees.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointRotation { get; set; } + + /// + /// Style of the point. + /// Supported values are 'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', and 'triangle'. + /// + /// Default value is 'circle'. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("circle")] + [Description("Style of the point. Supported values are 'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', and 'triangle'.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointStyle { get; set; } + + //segment + //https://www.chartjs.org/docs/latest/charts/line.html#segment + + /// + /// If , the line is not drawn for this dataset. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(true)] + [Description("If false, the line is not drawn for this dataset.")] + public bool ShowLine { get; set; } = true; + + /// + /// If , lines will be drawn between points with no or null data. + /// If , points with null data will create a break in the line. + /// Can also be a number specifying the maximum gap length to span. + /// The unit of the value depends on the scale used. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("If true, lines will be drawn between points with no or null data. If false, points with null data will create a break in the line. Can also be a number specifying the maximum gap length to span. The unit of the value depends on the scale used.")] + [ParameterTypeName("bool?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SpanGaps { get; set; } + + //stack + //https://www.chartjs.org/docs/latest/charts/line.html#general + + /// + /// If the stepped value is set to anything other than , tension will be ignored. + /// The following values are supported for stepped. + /// - false: No Step Interpolation(default) + /// - true: Step-before Interpolation(eq. 'before') + /// - 'before': Step-before Interpolation + /// - 'after': Step-after Interpolation + /// - 'middle': Step-middle Interpolation + /// + /// Default value is . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(false)] + [Description("If the stepped value is set to anything other than false, tension will be ignored.
The following values are supported for stepped.
  1. false: No Step Interpolation(default)
  2. true: Step-before Interpolation(eq. 'before')
  3. 'before': Step-before Interpolation
  4. 'after': Step-after Interpolation
  5. 'middle': Step-middle Interpolation
")] + public object Stepped { get; set; } = false; + + /// + /// Bezier curve tension of the line. Set to 0 to draw straight lines. + /// This option is ignored if monotone cubic interpolation is used. + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("Bezier curve tension of the line. Set to 0 to draw straightlines. This option is ignored if monotone cubic interpolation is used.")] + public double Tension { get; set; } + + /// + /// The ID of the x axis to plot this dataset on. + /// + /// Default value is 'first x axis'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("Default value is 'first x axis'.")] + [Description("The ID of the x-axis to plot this dataset on. Default value is 'first x axis'.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? XAxisID { get; set; } + + /// + /// The ID of the y axis to plot this dataset on. + /// + /// Default value is 'first y axis'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("Default value is 'first y axis'.")] + [Description("The ID of the y-axis to plot this dataset on. Default value is 'first y axis'.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? YAxisID { get; set; } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/LineChartDatasetData.cs b/BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDatasetData.cs similarity index 100% rename from BlazorExpress.ChartJS/Models/ChartDataset/LineChartDatasetData.cs rename to BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDatasetData.cs diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDatasetDataLabels.cs b/BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDatasetDataLabels.cs new file mode 100644 index 00000000..d49e37da --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/LineChart/LineChartDatasetDataLabels.cs @@ -0,0 +1,3 @@ +namespace BlazorExpress.ChartJS; + +public class LineChartDatasetDataLabels : ChartDatasetDataLabels { } diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/LineChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/LineChartDataset.cs deleted file mode 100644 index a8f02463..00000000 --- a/BlazorExpress.ChartJS/Models/ChartDataset/LineChartDataset.cs +++ /dev/null @@ -1,216 +0,0 @@ -using BlazorExpress.ChartJS.Enums; - -namespace BlazorExpress.ChartJS; - -public class LineChartDataset : ChartDataset -{ - #region Properties, Indexers - - /// - /// Line dash. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? BorderDash { get; set; } - - /// - /// Line dash offset. - /// - public double BorderDashOffset { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public LineChartDatasetDataLabels Datalabels { get; set; } = new(); - - /// - /// Both line and radar charts support a fill option on the dataset object - /// which can be used to create area between two datasets or a dataset and - /// a boundary, i.e. the scale origin, start or end. - /// - public bool Fill { get; set; } - - /// - /// Configures the visibility state of the dataset. Set it to true, to hide the dataset from the chart. - /// - public new bool Hidden { get; set; } - - /// - /// Hover line dash. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? HoverBorderDash { get; set; } - - /// - /// The label for the dataset which appears in the legend and tooltips. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Label { get; set; } - - /// - /// The fill color for points. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List PointBackgroundColor { get; set; } = new() { "rgba(0, 0, 0, 0.1)" }; - - /// - /// The border color for points. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List PointBorderColor { get; set; } = new() { "rgba(0, 0, 0, 0.1)" }; - - /// - /// The width of the point border in pixels. - /// - public List PointBorderWidth { get; set; } = new() { 1 }; - - /// - /// The pixel size of the non-displayed point that reacts to mouse events. - /// - public List PointHitRadius { get; set; } = new() { 1 }; - - /// - /// Point background color when hovered. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? PointHoverBackgroundColor { get; set; } - - /// - /// Point border color when hovered. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List? PointHoverBorderColor { get; set; } - - /// - /// Border width of point when hovered. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List PointHoverBorderWidth { get; set; } = new() { 1 }; - - /// - /// The radius of the point when hovered. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List PointHoverRadius { get; set; } = new() { 1 }; // Default: 4 - - /// - /// The radius of the point shape. If set to 0, the point is not rendered. - /// Default: 3 - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List PointRadius { get; set; } = new() { 1 }; // Default: 3 - - /// - /// The rotation of the point in degrees. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public List PointRotation { get; set; } = new() { 0 }; - - /// - /// Style of the point. - /// Use 'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', and 'triangle' to style - /// the point. - /// - public List PointStyle { get; set; } = new() { "circle" }; - - // Segment - // https://www.chartjs.org/docs/latest/api/interfaces/LineControllerDatasetOptions.html#segment - - /// - /// If , the lines between points are not drawn. - /// - public bool ShowLine { get; set; } = true; - - /// - /// If , lines will be drawn between points with no or null data. - /// If , points with null data will create a break in the line. - /// Can also be a number specifying the maximum gap length to span. - /// The unit of the value depends on the scale used. - /// - public bool SpanGaps { get; set; } - - /// - /// true to show the line as a stepped line (tension will be ignored). - /// - public bool Stepped { get; set; } - - /// - /// Bezier curve tension of the line. Set to 0 to draw straight lines. - /// This option is ignored if monotone cubic interpolation is used. - /// - public double Tension { get; set; } = 0.2; - - /// - /// The ID of the x axis to plot this dataset on. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? XAxisID { get; set; } - - /// - /// The ID of the y axis to plot this dataset on. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? YAxisID { get; set; } - - #endregion -} - -public class LineChartDatasetDataLabels -{ - #region Fields and Constants - - private Alignment alignment; - - private Anchor anchor; - - #endregion - - #region Properties, Indexers - - /// - /// Gets or sets the data labels alignment. - /// - /// - /// Default value is . - /// - [JsonIgnore] - public Alignment Alignment - { - get => alignment; - set - { - alignment = value; - DataLabelsAlignment = value.ToAlignmentString(); - } - } - - /// - /// Gets or sets the data labels anchor. - /// - /// - /// Default value is . - /// - [JsonIgnore] - public Anchor Anchor - { - get => anchor; - set - { - anchor = value; - DataLabelsAnchor = value.ToAnchorString(); - } - } - - /// - /// Gets or sets the data labels alignment. - /// Possible values: start, center, and end. - /// - [JsonPropertyName("align")] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? DataLabelsAlignment { get; private set; } - - /// - /// Gets or sets the data labels anchor. - /// Possible values: start, center, and end. - /// - [JsonPropertyName("anchor")] - public string? DataLabelsAnchor { get; private set; } - - #endregion -} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/PieChart/PieChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/PieChart/PieChartDataset.cs new file mode 100644 index 00000000..13ddba99 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/PieChart/PieChartDataset.cs @@ -0,0 +1,289 @@ +namespace BlazorExpress.ChartJS; + +/// +/// The doughnut/pie chart allows a number of properties to be specified for each dataset. +/// These are used to set display properties for a specific dataset. +/// . +/// +public class PieChartDataset : ChartDataset +{ + #region Properties, Indexers + + /// + /// Arc background color. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("Arc background color.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BackgroundColor { get; set; } + + /// + /// Supported values are 'center' and 'inner'. + /// When 'center' is set, the borders of arcs next to each other will overlap. + /// When 'inner' is set, it is guaranteed that all borders will not overlap. + /// + /// Default value is 'center'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("center")] + [Description("Supported values are center and inner. When center is set, the borders of arcs next to each other will overlap. When inner is set, it is guaranteed that all borders will not overlap.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderAlign { get; set; } // TODO: change this to enum + + /// + /// Arc border color. + /// + /// Default value is '#fff'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("#fff")] + [Description("Arc border color.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderColor { get; set; } + + /// + /// Arc border length and spacing of dashes. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border length and spacing of dashes.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderDash { get; set; } + + /// + /// Arc border offset for line dashes. + /// + /// Default value is 0.0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0.0)] + [Description("Arc border offset for line dashes.")] + //[ParameterTypeName("")] + public double BorderDashOffset { get; set; } + + /// + /// Arc border join style. + /// Supported values are 'round', 'bevel', and 'miter'. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border join style. Supported values are round, bevel, and miter.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderJoinStyle { get; set; } // TODO: change this to enum + + /// + /// It is applied to all corners of the arc (outerStart, outerEnd, innerStart, innerRight). + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("It is applied to all corners of the arc (outerStart, outerEnd, innerStart, innerRight).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderRadius { get; set; } + + /// + /// Arc border width (in pixels). + /// + /// Default value is 2. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(2)] + [Description("Arc border width (in pixels).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderWidth { get; set; } + + /// + /// Per-dataset override for the sweep that the arcs cover. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Per-dataset override for the sweep that the arcs cover.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? Circumference { get; set; } + + /// + /// Gets or sets the data labels configuration for the pie chart dataset. + /// + /// Use this property to customize the display of data labels, such as their position, format, or + /// visibility, in the pie chart dataset. If not set, a default configuration is applied. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the data labels configuration for the pie chart dataset. Use this property to customize the display of data labels, such as their position, format, or visibility, in the pie chart dataset. If not set, a default configuration is applied.")] + [ParameterTypeName("PieChartDatasetDataLabels")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public PieChartDatasetDataLabels Datalabels { get; set; } = new(); + + /// + /// Arc background color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc background color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBackgroundColor { get; set; } + + /// + /// Arc border color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderColor { get; set; } + + /// + /// Arc border length and spacing of dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border length and spacing of dashes when hovered. ")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderDash { get; set; } + + /// + /// Arc border offset for line dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border offset for line dashes when hovered.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? HoverBorderDashOffset { get; set; } + + /// + /// Arc border join style when hovered. + /// Supported values are 'round', 'bevel', and 'miter'. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border join style when hovered. Supported values are round, bevel, and miter.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderJoinStyle { get; set; } // TODO: change this to enum + + /// + /// Arc border width when hovered (in pixels). + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderWidth { get; set; } + + /// + /// Arc offset when hovered (in pixels). + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverOffset { get; set; } + + /// + /// Arc offset (in pixels). + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("Arc offset (in pixels).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? Offset { get; set; } + + /// + /// Per-dataset override for the starting angle to draw arcs from. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Per-dataset override for the starting angle to draw arcs from.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? Rotation { get; set; } + + /// + /// Fixed arc offset (in pixels). Similar to but applies to all arcs. + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("Fixed arc offset (in pixels). Similar to Offset but applies to all arcs.")] + public double Spacing { get; set; } + + /// + /// The relative thickness of the dataset. + /// Providing a value for weight will cause the pie or doughnut dataset to be drawn + /// with a thickness relative to the sum of all the dataset weight values. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("The relative thickness of the dataset. Providing a value for weight will cause the pie or doughnut dataset to be drawn with a thickness relative to the sum of all the dataset weight values.")] + public double Weight { get; set; } = 1; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/PieChartDatasetData.cs b/BlazorExpress.ChartJS/Models/ChartDataset/PieChart/PieChartDatasetData.cs similarity index 100% rename from BlazorExpress.ChartJS/Models/ChartDataset/PieChartDatasetData.cs rename to BlazorExpress.ChartJS/Models/ChartDataset/PieChart/PieChartDatasetData.cs diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/PieChart/PieChartDatasetDataLabels.cs b/BlazorExpress.ChartJS/Models/ChartDataset/PieChart/PieChartDatasetDataLabels.cs new file mode 100644 index 00000000..3db41501 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/PieChart/PieChartDatasetDataLabels.cs @@ -0,0 +1,3 @@ +namespace BlazorExpress.ChartJS; + +public class PieChartDatasetDataLabels : ChartDatasetDataLabels { } \ No newline at end of file diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/PieChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/PieChartDataset.cs deleted file mode 100644 index 0dc0d83a..00000000 --- a/BlazorExpress.ChartJS/Models/ChartDataset/PieChartDataset.cs +++ /dev/null @@ -1,59 +0,0 @@ -using BlazorExpress.ChartJS.Enums; - -namespace BlazorExpress.ChartJS; - -public class PieChartDataset : ChartDataset -{ - #region Properties, Indexers - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public PieChartDatasetDataLabels Datalabels { get; set; } = new(); - - /// - /// The label for the dataset which appears in the legend and tooltips. - /// - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Label { get; set; } - - #endregion -} - -public class PieChartDatasetDataLabels -{ - #region Fields and Constants - - private Anchor anchor; - - #endregion - - #region Properties, Indexers - - /// - /// Gets or sets the data labels anchor. - /// - /// - /// Default value is . - /// - [JsonIgnore] - public Anchor Anchor - { - get => anchor; - set - { - anchor = value; - DataLabelsAnchor = value.ToAnchorString(); - } - } - - //public string? BackgroundColor { get; set; } - - public double? BorderWidth { get; set; } = 2; - - /// - /// Gets or sets the data labels anchor. - /// Possible values: start, center, and end. - /// - [JsonPropertyName("anchor")] - public string? DataLabelsAnchor { get; private set; } - - #endregion -} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/PolarAreaChart/PolarAreaChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/PolarAreaChart/PolarAreaChartDataset.cs new file mode 100644 index 00000000..02922b41 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/PolarAreaChart/PolarAreaChartDataset.cs @@ -0,0 +1,205 @@ +namespace BlazorExpress.ChartJS; + +public class PolarAreaChartDataset : ChartDataset +{ + #region Properties, Indexers + + /// + /// Arc background color. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("Arc background color.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BackgroundColor { get; set; } + + /// + /// Supported values are 'center' and 'inner'. + /// When 'center' is set, the borders of arcs next to each other will overlap. + /// When 'inner' is set, it is guaranteed that all borders will not overlap. + /// + /// Default value is 'center'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("center")] + [Description("Supported values are center and inner. When center is set, the borders of arcs next to each other will overlap. When inner is set, it is guaranteed that all borders will not overlap.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderAlign { get; set; } // TODO: change this to enum + + /// + /// Arc border color. + /// + /// Default value is '#fff'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("#fff")] + [Description("Arc border color.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderColor { get; set; } + + /// + /// Arc border length and spacing of dashes. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border length and spacing of dashes.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderDash { get; set; } + + /// + /// Arc border offset for line dashes. + /// + /// Default value is 0.0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0.0)] + [Description("Arc border offset for line dashes.")] + public double BorderDashOffset { get; set; } + + /// + /// Arc border join style. + /// Supported values are 'round', 'bevel', and 'miter'. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border join style. Supported values are round, bevel, and miter.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderJoinStyle { get; set; } // TODO: change this to enum + + /// + /// Arc border width (in pixels). + /// + /// Default value is 2. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(2)] + [Description("Arc border width (in pixels).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderWidth { get; set; } + + /// + /// By default the Arc is curved. If , the Arc will be flat. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(true)] + [Description("By default the Arc is curved. If false, the Arc will be flat.")] + public bool Circular { get; set; } = true; + + /// + /// Gets or sets the data labels configuration for the polar area chart dataset. + /// + /// Use this property to customize the display of data labels, such as their position, format, or + /// visibility, in the pie chart dataset. If not set, a default configuration is applied. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the data labels configuration for the polar area chart dataset. Use this property to customize the display of data labels, such as their position, format, or visibility, in the polar area chart dataset. If not set, a default configuration is applied.")] + [ParameterTypeName(nameof(PolarAreaChartDatasetDataLabels))] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public PolarAreaChartDatasetDataLabels Datalabels { get; set; } = new(); + + /// + /// Arc background color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc background color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBackgroundColor { get; set; } + + /// + /// Arc border color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderColor { get; set; } + + /// + /// Arc border length and spacing of dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border length and spacing of dashes when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderDash { get; set; } + + /// + /// Arc border offset for line dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border offset for line dashes when hovered.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? HoverBorderDashOffset { get; set; } + + /// + /// Arc border join style when hovered. + /// Supported values are 'round', 'bevel', and 'miter'. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border join style when hovered. Supported values are round, bevel, and miter.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderJoinStyle { get; set; } // TODO: change this to enum + + /// + /// Arc border width when hovered (in pixels). + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Arc border width when hovered (in pixels).")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderWidth { get; set; } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/PolarAreaChart/PolarAreaChartDatasetData.cs b/BlazorExpress.ChartJS/Models/ChartDataset/PolarAreaChart/PolarAreaChartDatasetData.cs new file mode 100644 index 00000000..74bbff24 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/PolarAreaChart/PolarAreaChartDatasetData.cs @@ -0,0 +1,26 @@ +namespace BlazorExpress.ChartJS; + +public record PolarAreaChartDatasetData : ChartDatasetData +{ + #region Constructors + + public PolarAreaChartDatasetData( + string? datasetLabel, + double data, + string? backgroundColor, + string? borderColor) : base(datasetLabel, data) + { + BackgroundColor = backgroundColor; + BorderColor = borderColor; + } + + #endregion + + #region Properties, Indexers + + public string? BackgroundColor { get; init; } + + public string? BorderColor { get; init; } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/PolarAreaChart/PolarAreaChartDatasetDataLabels.cs b/BlazorExpress.ChartJS/Models/ChartDataset/PolarAreaChart/PolarAreaChartDatasetDataLabels.cs new file mode 100644 index 00000000..32465a12 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/PolarAreaChart/PolarAreaChartDatasetDataLabels.cs @@ -0,0 +1,3 @@ +namespace BlazorExpress.ChartJS; + +public class PolarAreaChartDatasetDataLabels : ChartDatasetDataLabels { } \ No newline at end of file diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/RadarChart/RadarChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/RadarChart/RadarChartDataset.cs new file mode 100644 index 00000000..37455342 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/RadarChart/RadarChartDataset.cs @@ -0,0 +1,384 @@ +namespace BlazorExpress.ChartJS; + +/// +/// A radar chart is a way of showing multiple data points and the variation between them. +/// They are often useful for comparing the points of two or more different data sets. +/// . +/// +public class RadarChartDataset : ChartDataset +{ + #region Properties, Indexers + + /// + /// Get or sets the line fill color. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("Get or sets the line fill color.")] + public string BackgroundColor { get; set; } = "rgba(0, 0, 0, 0.1)"; + + /// + /// Cap style of the line. + /// Supported values are 'butt', 'round', and 'square'. + /// + /// Default value is 'butt'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("butt")] + [Description("Cap style of the line. Supported values are butt, round, and square.")] + public string BorderCapStyle { get; set; } = "butt"; + + /// + /// Get or sets the line color. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("Get or sets the line color.")] + public string BorderColor { get; set; } = "rgba(0, 0, 0, 0.1)"; + + /// + /// Gets or sets the length and spacing of dashes. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the length and spacing of dashes.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderDash { get; set; } + + /// + /// Offset for line dashes. + /// + /// Default value is 0.0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0.0)] + [Description("Offset for line dashes.")] + public double BorderDashOffset { get; set; } + + /// + /// Line joint style. + /// There are three possible values for this property: 'round', 'bevel', and 'miter'. + /// + /// Default value is 'miter'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("miter")] + [Description("Line joint style. There are three possible values for this property: round, bevel, and miter.")] + public string BorderJoinStyle { get; set; } = "miter"; + + /// + /// Gets or sets the line width (in pixels). + /// + /// Default value is 3. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(3)] + [Description("Gets or sets the line width (in pixels).")] + public double BorderWidth { get; set; } = 3; + + /// + /// Gets or sets the data labels configuration for the radar chart dataset. + /// + /// Use this property to customize the display of data labels, such as their position, format, or + /// visibility, in the pie chart dataset. If not set, a default configuration is applied. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the data labels configuration for the radar chart dataset. Use this property to customize the display of data labels, such as their position, format, or visibility, in the radar chart dataset. If not set, a default configuration is applied.")] + [ParameterTypeName(nameof(RadarChartDatasetDataLabels))] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public RadarChartDatasetDataLabels Datalabels { get; set; } = new(); + + /// + /// How to fill the area under the line. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(false)] + [Description("How to fill the area under the line.")] + public object Fill { get; set; } = false; + + /// + /// The line fill color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The line fill color when hovered.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? HoverBackgroundColor { get; set; } + + /// + /// Cap style of the line when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Cap style of the line when hovered.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? HoverBorderCapStyle { get; set; } + + /// + /// The line color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The line color when hovered.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? HoverBorderColor { get; set; } + + /// + /// Gets or sets the length and spacing of dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the length and spacing of dashes when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderDash { get; set; } + + /// + /// Offset for line dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Offset for line dashes when hovered.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? HoverBorderDashOffset { get; set; } + + /// + /// Line joint style. + /// There are three possible values for this property: 'round', 'bevel', and 'miter'. + /// + /// Default value is 'miter'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Line joint style. There are three possible values for this property: 'round', 'bevel', and 'miter'.")] + public string HoverBorderJoinStyle { get; set; } = "miter"; + + /// + /// The bar border width when hovered (in pixels) when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The bar border width when hovered (in pixels) when hovered.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? HoverBorderWidth { get; set; } + + /// + /// The fill color for points. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The fill color for points.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointBackgroundColor { get; set; } + + /// + /// The border color for points. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The border color for points.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointBorderColor { get; set; } + + /// + /// The width of the point border in pixels. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("The width of the point border in pixels.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointBorderWidth { get; set; } + + /// + /// The pixel size of the non-displayed point that reacts to mouse events. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("The pixel size of the non-displayed point that reacts to mouse events.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHitRadius { get; set; } + + /// + /// Point background color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Point background color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverBackgroundColor { get; set; } + + /// + /// Point border color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Point border color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverBorderColor { get; set; } + + /// + /// Border width of point when hovered. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("Border width of point when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverBorderWidth { get; set; } + + /// + /// The radius of the point when hovered. + /// + /// Default value is 4. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(4)] + [Description("The radius of the point when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverRadius { get; set; } + + /// + /// The radius of the point shape. If set to 0, the point is not rendered. + /// + /// Default value is 3. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(3)] + [Description("The radius of the point shape. If set to 0, the point is not rendered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointRadius { get; set; } + + /// + /// The rotation of the point in degrees. + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("The rotation of the point in degrees.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointRotation { get; set; } + + /// + /// Style of the point. + /// Supported values are 'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', 'triangle' and false. + /// the point. + /// + /// Default value is 'circle'. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("circle")] + [Description("Style of the point. Supported values are 'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', 'triangle' and false.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointStyle { get; set; } + + /// + /// If , lines will be drawn between points with no or null data. + /// If , points with null data will create a break in the line. + /// Can also be a number specifying the maximum gap length to span. + /// The unit of the value depends on the scale used. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("If true, lines will be drawn between points with no or null data. If false, points with null data will create a break in the line.")] + [ParameterTypeName("bool?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SpanGaps { get; set; } + + /// + /// Bezier curve tension of the line. Set to 0 to draw straight lines. + /// This option is ignored if monotone cubic interpolation is used. + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("Bezier curve tension of the line. Set to 0 to draw straight lines. This option is ignored if monotone cubic interpolation is used.")] + public double Tension { get; set; } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/RadarChart/RadarChartDatasetData.cs b/BlazorExpress.ChartJS/Models/ChartDataset/RadarChart/RadarChartDatasetData.cs new file mode 100644 index 00000000..71ff71b9 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/RadarChart/RadarChartDatasetData.cs @@ -0,0 +1,25 @@ +namespace BlazorExpress.ChartJS; + +public record RadarChartDatasetData : ChartDatasetData +{ + #region Constructors + + public RadarChartDatasetData( + string? datasetLabel, + double data, + string? backgroundColor = null, + string? borderColor = null) : base(datasetLabel, data) + { + BackgroundColor = backgroundColor; + BorderColor = borderColor; + } + + #endregion + + #region Properties, Indexers + + public string? BackgroundColor { get; init; } + public string? BorderColor { get; init; } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/RadarChart/RadarChartDatasetDataLabels.cs b/BlazorExpress.ChartJS/Models/ChartDataset/RadarChart/RadarChartDatasetDataLabels.cs new file mode 100644 index 00000000..2a6e2b64 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/RadarChart/RadarChartDatasetDataLabels.cs @@ -0,0 +1,3 @@ +namespace BlazorExpress.ChartJS; + +public class RadarChartDatasetDataLabels : ChartDatasetDataLabels { } diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDataPoint.cs b/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDataPoint.cs new file mode 100644 index 00000000..467cf0b0 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDataPoint.cs @@ -0,0 +1,3 @@ +namespace BlazorExpress.ChartJS; + +public record ScatterChartDataPoint(double X, double Y); diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDataset.cs b/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDataset.cs new file mode 100644 index 00000000..5e8916ad --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDataset.cs @@ -0,0 +1,487 @@ +namespace BlazorExpress.ChartJS; + +/// +/// Scatter charts are based on basic line charts with the x-axis changed to a linear axis. +/// To use a scatter chart, data must be passed as objects containing X and Y properties. +/// . +/// The scatter chart supports all the same properties as the line chart. +/// By default, the scatter chart will override the showLine property of the line chart to . +/// +public class ScatterChartDataset : ChartDataset +{ + #region Properties, Indexers + + /// + /// The line fill color. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The line fill color.")] + public string BackgroundColor { get; set; } = "rgba(0, 0, 0, 0.1)"; + + /// + /// Cap style of the line. + /// Supported values are 'butt', 'round', and 'square'. + /// + /// Default value is 'butt'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("butt")] + [Description("Cap style of the line. Supported values are 'butt', 'round', and 'square'.")] + public string BorderCapStyle { get; set; } = "butt"; + + /// + /// The line color. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The line color.")] + public string BorderColor { get; set; } = "rgba(0, 0, 0, 0.1)"; + + /// + /// Length and spacing of dashes. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Length and spacing of dashes.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? BorderDash { get; set; } + + /// + /// Offset for line dashes. + /// + /// Default value is 0.0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0.0)] + [Description("Offset for line dashes.")] + public double BorderDashOffset { get; set; } + + /// + /// Line joint style. + /// There are three possible values for this property: 'round', 'bevel', and 'miter'. + /// + /// Default value is 'miter'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("miter")] + [Description("Line joint style. There are three possible values for this property: 'round', 'bevel', and 'miter'.")] + public string BorderJoinStyle { get; set; } = "miter"; + + /// + /// The line width (in pixels). + /// + /// Default value is 3. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(3)] + [Description("The line width (in pixels).")] + public double BorderWidth { get; set; } = 3; + + //clip + //https://www.chartjs.org/docs/latest/charts/line.html#general + + /// + /// Supported values are 'default', and 'monotone'. + /// + /// Default value is 'default'. + /// + /// . + /// + [AddedVersion("1.0.0")] + [DefaultValue("default")] + [Description("Supported values are 'default', and 'monotone'.")] + public string CubicInterpolationMode { get; set; } = "default"; + + /// + /// Gets or sets the data labels configuration for the scatter chart dataset. + /// + /// Use this property to customize the display of data labels, such as their position, format, or + /// visibility, in the pie chart dataset. If not set, a default configuration is applied. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the data labels configuration for the scatter chart dataset. Use this property to customize the display of data labels, such as their position, format, or visibility, in the scatter chart dataset. If not set, a default configuration is applied.")] + [ParameterTypeName(nameof(ScatterChartDatasetDataLabels))] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ScatterChartDatasetDataLabels Datalabels { get; set; } = new(); + + /// + /// Draw the active points of a dataset over the other points of the dataset. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Draw the active points of a dataset over the other points of the dataset.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? DrawActiveElementsOnTop { get; set; } + + /// + /// How to fill the area under the line. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(false)] + [Description("How to fill the area under the line.")] + public bool Fill { get; set; } + + /// + /// The line fill color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The line fill color when hovered.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? HoverBackgroundColor { get; set; } + + /// + /// Cap style of the line when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Cap style of the line when hovered.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? HoverBorderCapStyle { get; set; } + + /// + /// The line color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The line color when hovered.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? HoverBorderColor { get; set; } + + /// + /// Length and spacing of dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Length and spacing of dashes when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? HoverBorderDash { get; set; } + + /// + /// Offset for line dashes when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Offset for line dashes when hovered.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? HoverBorderDashOffset { get; set; } + + /// + /// Line joint style when hovered. + /// There are three possible values for this property: 'round', 'bevel', and 'miter'. + /// + /// Default value is 'miter'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("miter")] + [Description("Line joint style. There are three possible values for this property: 'round', 'bevel', and 'miter'.")] + public string HoverBorderJoinStyle { get; set; } = "miter"; + + /// + /// The line width (in pixels) when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The line width (in pixels) when hovered.")] + [ParameterTypeName("double?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public double? HoverBorderWidth { get; set; } + + /// + /// The base axis of the dataset. 'x' for horizontal lines and 'y' for vertical lines. + /// + /// Default value is 'x'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("x")] + [Description("The base axis of the dataset. 'x' for horizontal lines and 'y' for vertical lines.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IndexAxis { get; set; } + + /// + /// The fill color for points. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The fill color for points.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointBackgroundColor { get; set; } + + /// + /// The border color for points. + /// + /// Default value is 'rgba(0, 0, 0, 0.1)'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("rgba(0, 0, 0, 0.1)")] + [Description("The border color for points.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointBorderColor { get; set; } + + /// + /// The width of the point border in pixels. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("The width of the point border in pixels.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointBorderWidth { get; set; } + + /// + /// The pixel size of the non-displayed point that reacts to mouse events. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("The pixel size of the non-displayed point that reacts to mouse events.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHitRadius { get; set; } + + /// + /// Point background color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Point background color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverBackgroundColor { get; set; } + + /// + /// Point border color when hovered. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Point border color when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverBorderColor { get; set; } + + /// + /// Border width of point when hovered. + /// + /// Default value is 1. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(1)] + [Description("Border width of point when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverBorderWidth { get; set; } + + /// + /// The radius of the point when hovered. + /// + /// Default value is 4. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(4)] + [Description("The radius of the point when hovered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointHoverRadius { get; set; } + + /// + /// The radius of the point shape. If set to 0, the point is not rendered. + /// + /// Default value is 3. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(3)] + [Description("The radius of the point shape. If set to 0, the point is not rendered.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointRadius { get; set; } + + /// + /// The rotation of the point in degrees. + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("The rotation of the point in degrees.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointRotation { get; set; } + + /// + /// Style of the point. + /// Supported values are 'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', and 'triangle'. + /// + /// Default value is 'circle'. + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("circle")] + [Description("Style of the point. Supported values are 'circle', 'cross', 'crossRot', 'dash', 'line', 'rect', 'rectRounded', 'rectRot', 'star', and 'triangle'.")] + [ParameterTypeName("List?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public List? PointStyle { get; set; } + + //segment + //https://www.chartjs.org/docs/latest/charts/line.html#segment + + /// + /// If , the line is not drawn for this dataset. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(true)] + [Description("If false, the line is not drawn for this dataset.")] + public bool ShowLine { get; } = false; + + /// + /// If , lines will be drawn between points with no or null data. + /// If , points with null data will create a break in the line. + /// Can also be a number specifying the maximum gap length to span. + /// The unit of the value depends on the scale used. + /// + /// Default value is . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("If true, lines will be drawn between points with no or null data. If false, points with null data will create a break in the line. Can also be a number specifying the maximum gap length to span. The unit of the value depends on the scale used.")] + [ParameterTypeName("bool?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public bool? SpanGaps { get; set; } + + //stack + //https://www.chartjs.org/docs/latest/charts/line.html#general + + /// + /// If the stepped value is set to anything other than , tension will be ignored. + /// The following values are supported for stepped. + /// - false: No Step Interpolation(default) + /// - true: Step-before Interpolation(eq. 'before') + /// - 'before': Step-before Interpolation + /// - 'after': Step-after Interpolation + /// - 'middle': Step-middle Interpolation + /// + /// Default value is . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(false)] + [Description("If the stepped value is set to anything other than false, tension will be ignored.
The following values are supported for stepped.
  1. false: No Step Interpolation(default)
  2. true: Step-before Interpolation(eq. 'before')
  3. 'before': Step-before Interpolation
  4. 'after': Step-after Interpolation
  5. 'middle': Step-middle Interpolation
")] + public object Stepped { get; set; } = false; + + /// + /// Bezier curve tension of the line. Set to 0 to draw straight lines. + /// This option is ignored if monotone cubic interpolation is used. + /// + /// Default value is 0. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("Bezier curve tension of the line. Set to 0 to draw straightlines. This option is ignored if monotone cubic interpolation is used.")] + public double Tension { get; set; } + + /// + /// The ID of the x axis to plot this dataset on. + /// + /// Default value is 'first x axis'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("Default value is 'first x axis'.")] + [Description("The ID of the x-axis to plot this dataset on. Default value is 'first x axis'.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? XAxisID { get; set; } + + /// + /// The ID of the y axis to plot this dataset on. + /// + /// Default value is 'first y axis'. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("Default value is 'first y axis'.")] + [Description("The ID of the y-axis to plot this dataset on. Default value is 'first y axis'.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? YAxisID { get; set; } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDatasetData.cs b/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDatasetData.cs new file mode 100644 index 00000000..50be24c4 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDatasetData.cs @@ -0,0 +1,10 @@ +namespace BlazorExpress.ChartJS; + +public record ScatterChartDatasetData : ChartDatasetData +{ + #region Constructors + + public ScatterChartDatasetData(string? datasetLabel, ScatterChartDataPoint? data) : base(datasetLabel, data) { } + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDatasetDataLabels.cs b/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDatasetDataLabels.cs new file mode 100644 index 00000000..c37e4a15 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartDataset/ScatterChart/ScatterChartDatasetDataLabels.cs @@ -0,0 +1,3 @@ +namespace BlazorExpress.ChartJS; + +public class ScatterChartDatasetDataLabels : ChartDatasetDataLabels { } \ No newline at end of file diff --git a/BlazorExpress.ChartJS/Models/ChartOptions/BarChartOptions.cs b/BlazorExpress.ChartJS/Models/ChartOptions/BarChartOptions.cs index 5d20dc67..e9aa53ba 100644 --- a/BlazorExpress.ChartJS/Models/ChartOptions/BarChartOptions.cs +++ b/BlazorExpress.ChartJS/Models/ChartOptions/BarChartOptions.cs @@ -1,5 +1,11 @@ namespace BlazorExpress.ChartJS; +/// +/// Provides configuration options specific to bar charts. +/// +/// +/// +/// public class BarChartOptions : ChartOptions { #region Properties, Indexers @@ -9,17 +15,70 @@ public class BarChartOptions : ChartOptions //plugins -> title -> display, text /// - /// The base axis of the chart. 'x' for vertical charts and 'y' for horizontal charts. + /// Gets or sets the base axis of the chart. Use 'x' for vertical charts and 'y' for horizontal charts. + /// Supported values are 'x' and 'y'. + /// + /// Default value is . + /// /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string IndexAxis { get; set; } = "x"; + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the base axis of the chart. Use 'x' for vertical charts and 'y' for horizontal charts. Supported values are 'x' and 'y'.")] + //[ParameterTypeName("string?")] + [Parameter] + public string? IndexAxis { get; set; } + /// + /// Gets or sets the interaction options for the bar chart. + /// + /// Default value is a new instance. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the interaction options for the bar chart.")] + //[ParameterTypeName("Interaction")] + [Parameter] public Interaction Interaction { get; set; } = new(); + /// + /// Gets or sets the layout options for the bar chart. + /// + /// Default value is a new instance. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the layout options for the bar chart.")] + [ParameterTypeName("ChartLayout")] + [Parameter] public ChartLayout Layout { get; set; } = new(); + /// + /// Gets or sets the plugins configuration for the bar chart. + /// + /// Default value is a new instance. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the plugins configuration for the bar chart.")] + [ParameterTypeName("BarChartPlugins")] + [Parameter] public BarChartPlugins Plugins { get; set; } = new(); + /// + /// Gets or sets the scales configuration for the bar chart. + /// + /// Default value is a new instance. + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("Gets or sets the scales configuration for the bar chart.")] + //[ParameterTypeName("Scales")] + [Parameter] public Scales Scales { get; set; } = new(); #endregion diff --git a/BlazorExpress.ChartJS/Models/ChartOptions/BubbleChartOptions.cs b/BlazorExpress.ChartJS/Models/ChartOptions/BubbleChartOptions.cs new file mode 100644 index 00000000..a4a99211 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartOptions/BubbleChartOptions.cs @@ -0,0 +1,76 @@ +namespace BlazorExpress.ChartJS; + +public class BubbleChartOptions : ChartOptions +{ + #region Properties, Indexers + + //hover -> mode, intersect + //maintainAspectRatio + //plugins -> title -> display, text + /* + /// + /// The base axis of the dataset. 'x' for horizontal lines and 'y' for vertical lines. + /// + /// + /// Default value is . + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The base axis of the dataset. 'x' for horizontal lines and 'y' for vertical lines.")] + [ParameterTypeName("string?")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IndexAxis { get; set; } + + /// + /// Gets or sets the interaction options for the chart. + /// By default, these options apply to both the hover and tooltip interactions. + /// + /// Default value is a new instance of . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the interaction options for the chart.")] + public Interaction Interaction { get; set; } = new(); + + /// + /// Gets or sets the layout configuration for the chart. + /// + /// Default value is a new instance of . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the layout configuration for the chart.")] + [ParameterTypeName(nameof(ChartLayout))] + public ChartLayout Layout { get; set; } = new(); + + /// + /// Gets or sets the collection of plugins associated with the line chart. + /// + /// Default value is a new instance of . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the collection of plugins associated with the line chart.")] + [ParameterTypeName(nameof(LineChartPlugins))] + public LineChartPlugins Plugins { get; set; } = new(); + + /// + /// Gets or sets the collection of scales used for measurement or calibration. + /// + /// Default value is a new instance of . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the collection of scales used for measurement or calibration.")] + public Scales Scales { get; set; } = new(); + */ + #endregion + + //tooltips -> mode, intersect +} diff --git a/BlazorExpress.ChartJS/Models/ChartOptions/ChartOptions.cs b/BlazorExpress.ChartJS/Models/ChartOptions/ChartOptions.cs index 27a40dba..8a2366b1 100644 --- a/BlazorExpress.ChartJS/Models/ChartOptions/ChartOptions.cs +++ b/BlazorExpress.ChartJS/Models/ChartOptions/ChartOptions.cs @@ -3,51 +3,111 @@ public interface IChartOptions { } /// -/// +/// Represents the base configuration options for all chart types. +/// +/// See for more information. +/// /// public class ChartOptions : IChartOptions { #region Properties, Indexers + //aspectRatio + //https://www.chartjs.org/docs/latest/configuration/responsive.html#configuration-options + /// - /// Gets or sets the locale. + /// Gets or sets the locale for the chart. + /// /// By default, the chart is using the default locale of the platform which is running on. + /// + /// /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [AddedVersion("1.0.0")] + [DefaultValue("By default, the chart is using the default locale of the platform which is running on.")] + [Description("Gets or sets the locale for the chart.")] + [ParameterTypeName("string?")] + [Parameter] public string? Locale { get; set; } /// - /// Gets or sets the MaintainAspectRatio of the chart. - /// + /// Gets or sets a value indicating whether to maintain the original canvas aspect ratio (width / height) when resizing. + /// + /// Default value is . + /// + /// + /// See for more information. + /// /// + [AddedVersion("1.0.0")] + [DefaultValue(true)] + [Description("Gets or sets a value indicating whether to maintain the original canvas aspect ratio (width / height) when resizing.")] + [Parameter] public bool MaintainAspectRatio { get; set; } = true; + //onResize + //https://www.chartjs.org/docs/latest/configuration/responsive.html#configuration-options + + //resizeDelay + //https://www.chartjs.org/docs/latest/configuration/responsive.html#configuration-options + /// - /// Gets or set the responsive. - /// + /// Gets or sets a value indicating whether the chart canvas should resize when its container does. + /// + /// Default value is . + /// + /// + /// See for more information. + /// /// - public bool Responsive { get; set; } + [AddedVersion("1.0.0")] + [DefaultValue(true)] + [Description("Gets or sets a value indicating whether the chart canvas should resize when its container does.")] + [Parameter] + public bool Responsive { get; set; } = true; #endregion } +/// +/// Namespace: options.layout, the global options for the chart layout is defined in Chart.defaults.layout. +/// for more information. +/// public class ChartLayout { #region Properties, Indexers /// - /// Apply automatic padding so visible elements are completely drawn. + /// Gets or sets a value indicating whether to apply automatic padding so visible elements are completely drawn. + /// + /// Default value is . + /// /// - public bool AutoPadding { get; set; } = false; + [AddedVersion("1.0.0")] + [DefaultValue(true)] + [Description("Gets or sets a value indicating whether to apply automatic padding so visible elements are completely drawn.")] + [Parameter] + public bool AutoPadding { get; set; } = true; /// - /// The padding to add inside the chart. + /// Gets or sets the padding to add inside the chart. + /// + /// Default value is 0. + /// /// + [AddedVersion("1.0.0")] + [DefaultValue(0)] + [Description("Gets or sets the padding to add inside the chart.")] + [Parameter] public int Padding { get; set; } = 0; #endregion } +/// +/// Namespace: options.interaction, the global interaction configuration is at Chart.defaults.interaction. +/// . +/// public class Interaction { #region Fields and Constants @@ -58,17 +118,34 @@ public class Interaction #region Constructors -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. public Interaction() -#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. { Mode = InteractionMode.Nearest; } #endregion + #region Methods + + private void SetMode(InteractionMode interactionMode) => + ChartInteractionMode = interactionMode switch + { + InteractionMode.Dataset => "dataset", + InteractionMode.Index => "index", + InteractionMode.Nearest => "nearest", + InteractionMode.Point => "point", + InteractionMode.X => "x", + InteractionMode.Y => "y", + _ => "" + }; + + #endregion + #region Properties, Indexers + //axis + //https://www.chartjs.org/docs/latest/configuration/interactions.html#interactions + /// /// Sets which elements appear in the interaction. /// @@ -78,7 +155,10 @@ public Interaction() /// /// if , the interaction mode only applies when the mouse position intersects an item on the chart. /// - public bool Intersect { get; set; } + /// + /// Default value is . + /// + public bool Intersect { get; set; } = true; /// /// Sets which elements appear in the tooltip. See Interaction Modes for details. @@ -90,11 +170,14 @@ public InteractionMode Mode set { mode = value; - ChartInteractionMode = value.ToInteractionModeString(); + SetMode(value); } } #endregion + + //includeInvisible + //https://www.chartjs.org/docs/latest/configuration/interactions.html#interactions } public class Scales @@ -108,11 +191,23 @@ public class Scales #endregion } +public class ChartAxesType +{ + #region Fields and Constants + + public static readonly string Linear = "linear"; + public static readonly string Logarithmic = "logarithmic"; + public static readonly string Category = "category"; + public static readonly string Time = "time"; + public static readonly string Timeseries = "timeseries"; + + #endregion +} + public class ChartAxes { #region Properties, Indexers - // Stacked public bool BeginAtZero { get; set; } = true; /// @@ -171,6 +266,15 @@ public class ChartAxes [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ChartAxesTitle? Title { get; set; } + /// + /// Gets or sets the index scale type. See . + /// + /// + /// Default value is . + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Type { get; set; } + #endregion } @@ -309,6 +413,20 @@ public class ChartAxesGrid #endregion } +public enum TicksAlignment +{ + Center, // default + Start, + End +} + +public enum TitleAlignment +{ + Center, // default + Start, + End +} + /// /// Chart axes tick styling /// @@ -317,22 +435,28 @@ public class ChartAxesTicks { #region Fields and Constants - private Alignment alignment; + private TicksAlignment ticksAlignment; #endregion - #region Properties, Indexers + #region Methods - [JsonIgnore] - public Alignment Alignment - { - get => alignment; - set + private void SetTicksAlignment(TicksAlignment interactionMode) => + Alignment = interactionMode switch { - alignment = value; - TicksAlignment = value.ToAlignmentString(); - } - } + TicksAlignment.Center => "center", + TicksAlignment.Start => "start", + TicksAlignment.End => "end", + _ => null + }; + + #endregion + + #region Properties, Indexers + + [JsonPropertyName("align")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Alignment { get; private set; } /// /// Color of label backdrops @@ -387,9 +511,16 @@ public Alignment Alignment [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public int? TextStrokeWidth { get; set; } - [JsonPropertyName("align")] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? TicksAlignment { get; private set; } + [JsonIgnore] + public TicksAlignment TicksAlignment + { + get => ticksAlignment; + set + { + ticksAlignment = value; + SetTicksAlignment(value); + } + } #endregion } @@ -418,22 +549,32 @@ public class ChartAxesTitle { #region Fields and Constants - private Alignment alignment; + private TitleAlignment titleAlignment; #endregion - #region Properties, Indexers + #region Methods - [JsonIgnore] - public Alignment Alignment - { - get => alignment; - set + private void SetTitleAlignment(TitleAlignment interactionMode) => + Alignment = interactionMode switch { - alignment = value; - TitleAlignment = value.ToAlignmentString(); - } - } + TitleAlignment.Center => "center", // default + TitleAlignment.Start => "start", + TitleAlignment.End => "end", + _ => null + }; + + #endregion + + #region Properties, Indexers + + /// + /// Alignment of the title. + /// Options are: 'start', 'center', and 'end' + /// + [JsonPropertyName("align")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Alignment { get; private set; } /// /// Color of text. @@ -454,13 +595,16 @@ public Alignment Alignment [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Text { get; set; } - /// - /// Alignment of the title. - /// Options are: 'start', 'center', and 'end' - /// - [JsonPropertyName("align")] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? TitleAlignment { get; private set; } + [JsonIgnore] + public TitleAlignment TitleAlignment + { + get => titleAlignment; + set + { + titleAlignment = value; + SetTitleAlignment(value); + } + } #endregion } diff --git a/BlazorExpress.ChartJS/Models/ChartOptions/LineChartOptions.cs b/BlazorExpress.ChartJS/Models/ChartOptions/LineChartOptions.cs index 28d69313..85a05f47 100644 --- a/BlazorExpress.ChartJS/Models/ChartOptions/LineChartOptions.cs +++ b/BlazorExpress.ChartJS/Models/ChartOptions/LineChartOptions.cs @@ -9,17 +9,65 @@ public class LineChartOptions : ChartOptions //plugins -> title -> display, text /// - /// The base axis of the chart. 'x' for vertical charts and 'y' for horizontal charts. + /// The base axis of the dataset. 'x' for horizontal lines and 'y' for vertical lines. /// + /// + /// Default value is . + /// + [AddedVersion("1.0.0")] + [DefaultValue(null)] + [Description("The base axis of the dataset. 'x' for horizontal lines and 'y' for vertical lines.")] + [ParameterTypeName("string?")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string IndexAxis { get; set; } = "x"; + public string? IndexAxis { get; set; } + /// + /// Gets or sets the interaction options for the chart. + /// By default, these options apply to both the hover and tooltip interactions. + /// + /// Default value is a new instance of . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the interaction options for the chart.")] public Interaction Interaction { get; set; } = new(); + /// + /// Gets or sets the layout configuration for the chart. + /// + /// Default value is a new instance of . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the layout configuration for the chart.")] + [ParameterTypeName(nameof(ChartLayout))] public ChartLayout Layout { get; set; } = new(); + /// + /// Gets or sets the collection of plugins associated with the line chart. + /// + /// Default value is a new instance of . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the collection of plugins associated with the line chart.")] + [ParameterTypeName(nameof(LineChartPlugins))] public LineChartPlugins Plugins { get; set; } = new(); + /// + /// Gets or sets the collection of scales used for measurement or calibration. + /// + /// Default value is a new instance of . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the collection of scales used for measurement or calibration.")] public Scales Scales { get; set; } = new(); #endregion diff --git a/BlazorExpress.ChartJS/Models/ChartOptions/PieChartOptions.cs b/BlazorExpress.ChartJS/Models/ChartOptions/PieChartOptions.cs index c86ad7ce..84acd0a6 100644 --- a/BlazorExpress.ChartJS/Models/ChartOptions/PieChartOptions.cs +++ b/BlazorExpress.ChartJS/Models/ChartOptions/PieChartOptions.cs @@ -4,6 +4,16 @@ public class PieChartOptions : ChartOptions { #region Properties, Indexers + /// + /// Gets or sets the collection of plugins associated with the pie chart. + /// + /// Default value is a new instance of . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the collection of plugins associated with the pie chart.")] + [ParameterTypeName(nameof(PieChartPlugins))] public PieChartPlugins Plugins { get; set; } = new(); #endregion diff --git a/BlazorExpress.ChartJS/Models/ChartOptions/PolarAreaChartOptions.cs b/BlazorExpress.ChartJS/Models/ChartOptions/PolarAreaChartOptions.cs new file mode 100644 index 00000000..ed65145d --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartOptions/PolarAreaChartOptions.cs @@ -0,0 +1,20 @@ +namespace BlazorExpress.ChartJS; + +public class PolarAreaChartOptions : ChartOptions +{ + #region Properties, Indexers + + /// + /// Gets or sets the collection of plugins associated with the polar area chart. + /// + /// Default value is a new instance of . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the collection of plugins associated with the polar area chart.")] + [ParameterTypeName(nameof(PolarAreaChartPlugins))] + public PolarAreaChartPlugins Plugins { get; set; } = new(); + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartOptions/RadarChartOptions.cs b/BlazorExpress.ChartJS/Models/ChartOptions/RadarChartOptions.cs new file mode 100644 index 00000000..4899e6b3 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartOptions/RadarChartOptions.cs @@ -0,0 +1,5 @@ +namespace BlazorExpress.ChartJS; + +public class RadarChartOptions : ChartOptions +{ +} diff --git a/BlazorExpress.ChartJS/Models/ChartOptions/ScatterChartOptions.cs b/BlazorExpress.ChartJS/Models/ChartOptions/ScatterChartOptions.cs new file mode 100644 index 00000000..a510bdee --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartOptions/ScatterChartOptions.cs @@ -0,0 +1,72 @@ +namespace BlazorExpress.ChartJS; + +public class ScatterChartOptions : ChartOptions +{ + #region Properties, Indexers + + //hover -> mode, intersect + //maintainAspectRatio + //plugins -> title -> display, text + + /// + /// The base axis of the dataset. 'x' for horizontal lines and 'y' for vertical lines. + /// + /// + /// Default value is 'x'. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? IndexAxis { get; set; } + + /// + /// Gets or sets the interaction options for the chart. + /// By default, these options apply to both the hover and tooltip interactions. + /// + /// Default value is a new instance of . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the interaction options for the chart.")] + public Interaction Interaction { get; set; } = new(); + + /// + /// Gets or sets the layout configuration for the chart. + /// + /// Default value is a new instance of . + /// + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the layout configuration for the chart.")] + [ParameterTypeName(nameof(ChartLayout))] + public ChartLayout Layout { get; set; } = new(); + + /// + /// Gets or sets the collection of plugins associated with the scatter chart. + /// + /// Default value is a new instance of . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the collection of plugins associated with the scatter chart.")] + [ParameterTypeName(nameof(ScatterChartPlugins))] + public ScatterChartPlugins Plugins { get; set; } = new(); + + /// + /// Gets or sets the collection of scales used for measurement or calibration. + /// + /// Default value is a new instance of . + /// + /// + [AddedVersion("1.0.0")] + [DefaultValue("new()")] + [Description("Gets or sets the collection of scales used for measurement or calibration.")] + public Scales Scales { get; set; } = new(); + + #endregion + + //tooltips -> mode, intersect +} diff --git a/BlazorExpress.ChartJS/Models/ChartPlugins/ChartPlugins.cs b/BlazorExpress.ChartJS/Models/ChartPlugins/ChartPlugins.cs index 1840d8f1..3520b149 100644 --- a/BlazorExpress.ChartJS/Models/ChartPlugins/ChartPlugins.cs +++ b/BlazorExpress.ChartJS/Models/ChartPlugins/ChartPlugins.cs @@ -11,18 +11,20 @@ public class ChartPlugins /// /// The chart title defines text to draw at the top of the chart. - /// + /// /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ChartPluginsTitle? Title { get; set; } = new(); /// /// Tooltip for the element. - /// + /// /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ChartPluginsTooltip? Tooltip { get; set; } + + #endregion } @@ -41,8 +43,7 @@ public class ChartPluginsLegend public bool Display { get; set; } = true; /// - /// If , Marks that this box should take the full width/height of the canvas (moving other boxes). - /// This is unlikely to need to be changed in day-to-day use. + /// If , Marks that this box should take the full width/height of the canvas (moving other boxes). This is unlikely to need to be changed in day-to-day use. /// public bool FullSize { get; set; } = true; @@ -80,8 +81,7 @@ public class ChartPluginsLegend public bool Rtl { get; set; } = false; /// - /// This will force the text direction 'rtl' or 'ltr' on the canvas for rendering the legend, regardless of the css - /// specified on the canvas + /// This will force the text direction 'rtl' or 'ltr' on the canvas for rendering the legend, regardless of the css specified on the canvas /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? TextDirection { get; set; } @@ -97,8 +97,6 @@ public class ChartPluginsLegend public class ChartPluginsLegendTitle { - #region Properties, Indexers - /// /// Color of the legend. Default value is 'black'. /// @@ -121,8 +119,6 @@ public class ChartPluginsLegendTitle /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Text { get; set; } - - #endregion } /// @@ -131,13 +127,11 @@ public class ChartPluginsLegendTitle /// public class ChartPluginsLegendLabels { - #region Properties, Indexers - /// - /// Override the borderRadius to use. + /// Width of coloured box. /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public int? BorderRadius { get; set; } + public int? BoxWidth { get; set; } /// /// Height of the coloured box @@ -146,10 +140,10 @@ public class ChartPluginsLegendLabels public int? BoxHeight { get; set; } /// - /// Width of coloured box. + /// Override the borderRadius to use. /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public int? BoxWidth { get; set; } + public int? BorderRadius { get; set; } /// /// Color of label and the strikethrough. @@ -157,7 +151,8 @@ public class ChartPluginsLegendLabels [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Color { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public ChartFont? Font { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public ChartFont? Font { get; set; } /// /// Padding between rows of colored boxes. @@ -166,29 +161,27 @@ public class ChartPluginsLegendLabels public int? Padding { get; set; } /// - /// If specified, this style of point is used for the legend. Only used if > is true. + /// If specified, this style of point is used for the legend. Only used if > is true. /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? PointStyle { get; set; } /// - /// If is , the width of the point style used for the legend. + /// If is , the width of the point style used for the legend. /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public int? PointStyleWidth { get; set; } /// - /// Label borderRadius will match corresponding . + /// Label borderRadius will match corresponding . /// public bool UseBorderRadius { get; set; } = false; /// - /// If , Label style will match corresponding point style (size is based on pointStyleWidth or the - /// minimum value between and -> Size). + /// If , Label style will match corresponding point style (size is based on pointStyleWidth or the minimum value between and -> Size). /// public bool UsePointStyle { get; set; } = false; - #endregion } /// @@ -205,7 +198,6 @@ public class ChartPluginsTitle /// [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? Align { get; set; } = "center"; - /// /// Color of text. /// diff --git a/BlazorExpress.ChartJS/Models/ChartPlugins/PolarAreaChartPlugins.cs b/BlazorExpress.ChartJS/Models/ChartPlugins/PolarAreaChartPlugins.cs new file mode 100644 index 00000000..60684045 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartPlugins/PolarAreaChartPlugins.cs @@ -0,0 +1,33 @@ +namespace BlazorExpress.ChartJS; + +public class PolarAreaChartPlugins : ChartPlugins +{ + #region Properties, Indexers + + public PolarAreaChartDataLabels Datalabels { get; set; } = new(); + + #endregion +} + +public class PolarAreaChartDataLabels +{ + #region Properties, Indexers + + public string? BorderColor { get; set; } = "white"; + public double BorderRadius { get; set; } = 25; + public double BorderWidth { get; set; } = 2; + public string? Color { get; set; } = "white"; + public PolarAreaChartDataLabelsFont Font { get; set; } = new(); + public double Padding { get; set; } = 6; + + #endregion +} + +public class PolarAreaChartDataLabelsFont +{ + #region Properties, Indexers + + public string? Weight { get; set; } = "bold"; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Models/ChartPlugins/ScatterChartPlugins.cs b/BlazorExpress.ChartJS/Models/ChartPlugins/ScatterChartPlugins.cs new file mode 100644 index 00000000..44894793 --- /dev/null +++ b/BlazorExpress.ChartJS/Models/ChartPlugins/ScatterChartPlugins.cs @@ -0,0 +1,31 @@ +namespace BlazorExpress.ChartJS; + +public class ScatterChartPlugins : ChartPlugins +{ + #region Properties, Indexers + + public ScatterChartDataLabels Datalabels { get; set; } = new(); + + #endregion +} + +public class ScatterChartDataLabels +{ + #region Properties, Indexers + + public double BorderRadius { get; set; } = 4; + public string? Color { get; set; } = "white"; + public ScatterChartDataLabelsFont Font { get; set; } = new(); + public double Padding { get; set; } = 6; + + #endregion +} + +public class ScatterChartDataLabelsFont +{ + #region Properties, Indexers + + public string? Weight { get; set; } = "bold"; + + #endregion +} diff --git a/BlazorExpress.ChartJS/Usings.cs b/BlazorExpress.ChartJS/Usings.cs index be97dc7b..7f28513a 100644 --- a/BlazorExpress.ChartJS/Usings.cs +++ b/BlazorExpress.ChartJS/Usings.cs @@ -1,5 +1,7 @@ -global using Microsoft.AspNetCore.Components; +global using BlazorExpress.Core; +global using Microsoft.AspNetCore.Components; global using Microsoft.JSInterop; +global using System.ComponentModel; global using System.Drawing; global using System.Globalization; global using System.Text.Json.Serialization; diff --git a/BlazorExpress.ChartJS/Utils/ColorUtility.cs b/BlazorExpress.ChartJS/Utils/ColorUtility.cs index 7ac46d36..a38b088c 100644 --- a/BlazorExpress.ChartJS/Utils/ColorUtility.cs +++ b/BlazorExpress.ChartJS/Utils/ColorUtility.cs @@ -8,7 +8,7 @@ public static class ColorUtility /// Returns 6 categorical colors in the format #RRGGBB. /// /// - public static string[] CategoricalSixColors => new[] { "#0fb5ae", "#4046ca", "#f68511", "#de3d82", "#7e84fa", "#72e06a", "#147af3", "#7326d3", "#e8c600", "#e8c600", "#e8c600", "#e8c600" }; + public static string[] CategoricalSixColors => new[] { "#0fb5ae", "#4046ca", "#f68511", "#de3d82", "#7e84fa", "#72e06a" }; /// /// Returns 12 categorical colors in the format #RRGGBB. diff --git a/BlazorExpress.ChartJS/wwwroot/blazorexpress.chartjs.js b/BlazorExpress.ChartJS/wwwroot/blazorexpress.chartjs.js index 6131234d..794b9b38 100644 --- a/BlazorExpress.ChartJS/wwwroot/blazorexpress.chartjs.js +++ b/BlazorExpress.ChartJS/wwwroot/blazorexpress.chartjs.js @@ -6,22 +6,38 @@ if (!window.blazorexpress.chartjs) { window.blazorexpress.chartjs = {}; } -if (!window.blazorexpress.chartjs.line) { - window.blazorexpress.chartjs.line = {}; -} - if (!window.blazorexpress.chartjs.bar) { window.blazorexpress.chartjs.bar = {}; } +if (!window.blazorexpress.chartjs.bubble) { + window.blazorexpress.chartjs.bubble = {}; +} + if (!window.blazorexpress.chartjs.doughnut) { window.blazorexpress.chartjs.doughnut = {}; } +if (!window.blazorexpress.chartjs.line) { + window.blazorexpress.chartjs.line = {}; +} + if (!window.blazorexpress.chartjs.pie) { window.blazorexpress.chartjs.pie = {}; } +if (!window.blazorexpress.chartjs.polarArea) { + window.blazorexpress.chartjs.polarArea = {}; +} + +if (!window.blazorexpress.chartjs.radar) { + window.blazorexpress.chartjs.radar = {}; +} + +if (!window.blazorexpress.chartjs.scatter) { + window.blazorexpress.chartjs.scatter = {}; +} + window.blazorexpress.chartjs = { create: (elementId, type, data, options, plugins) => { let chartEl = document.getElementById(elementId); @@ -87,6 +103,23 @@ window.blazorexpress.chartjs = { console.warn(`The chart is not initialized. Initialize it and then call update.`); } }, + updateDataValues: (elementId, data) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart) { + chart.data.datasets.splice(data.datasets.length); + + for (var datasetIndex = 0; datasetIndex < chart.data.datasets.length; ++datasetIndex) { + chart.data.datasets[datasetIndex].data = data.datasets[datasetIndex].data; + chart.data.labels = data.labels; + } + + for (var datasetIndex = chart.data.datasets.length; datasetIndex < data.datasets.length; ++datasetIndex) { + chart.data.datasets.push(data.datasets[datasetIndex]); + } + + chart.update(); + } + } } window.blazorexpress.chartjs.bar = { @@ -201,6 +234,118 @@ window.blazorexpress.chartjs.bar = { }, } +window.blazorexpress.chartjs.bubble = { + addDatasetData: (elementId, dataLabel, data) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart) { + const chartData = chart.data; + const chartDatasetData = data; + + if (!chartData.labels.includes(dataLabel)) + chartData.labels.push(dataLabel); + + const chartDatasets = chartData.datasets; + + if (chartDatasets.length > 0) { + let datasetIndex = chartDatasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + if (datasetIndex > -1) { + chartDatasets[datasetIndex].data.push(chartDatasetData.data); + chart.update(); + } + } + } + }, + addDatasetsData: (elementId, dataLabel, data) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart && data) { + const chartData = chart.data; + + if (!chartData.labels.includes(dataLabel)) { + chartData.labels.push(dataLabel); + + if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { + data.forEach(chartDatasetData => { + let datasetIndex = chartData.datasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + chartData.datasets[datasetIndex].data.push(chartDatasetData.data); + }); + chart.update(); + } + } + } + }, + addDataset: (elementId, newDataset) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart) { + chart.data.datasets.push(newDataset); + chart.update(); + } + }, + create: (elementId, type, data, options, plugins) => { + let chartEl = document.getElementById(elementId); + let _plugins = []; + + if (plugins && plugins.length > 0) { + // register `ChartDataLabels` plugin + if (plugins.includes('ChartDataLabels')) { + _plugins.push(ChartDataLabels); + } + } + + const config = { + type: type, + data: data, + options: options, + plugins: _plugins + }; + + const chart = new Chart( + chartEl, + config + ); + }, + get: (elementId) => { + let chart; + Chart.helpers.each(Chart.instances, function (instance) { + if (instance.canvas.id === elementId) { + chart = instance; + } + }); + + return chart; + }, + initialize: (elementId, type, data, options, plugins) => { + let chart = window.blazorexpress.chartjs.bubble.get(elementId); + if (chart) return; + else + window.blazorexpress.chartjs.bubble.create(elementId, type, data, options, plugins); + }, + resize: (elementId, width, height) => { + let chart = window.blazorexpress.chartjs.bubble.get(elementId); + if (chart) { + chart.canvas.parentNode.style.height = height; + chart.canvas.parentNode.style.width = width; + } + }, + update: (elementId, type, data, options) => { + let chart = window.blazorexpress.chartjs.bubble.get(elementId); + if (chart) { + if (chart.config.plugins && chart.config.plugins.findIndex(x => x.id == 'datalabels') > -1) { + // set datalabel background color + options.plugins.datalabels.backgroundColor = function (context) { + return context.dataset.backgroundColor; + }; + } + + chart.data = data; + chart.options = options; + chart.update(); + } + else { + console.warn(`The chart is not initialized. Initialize it and then call update.`); + } + }, +} + window.blazorexpress.chartjs.doughnut = { addDatasetData: (elementId, dataLabel, data) => { let chart = window.blazorexpress.chartjs.get(elementId); @@ -534,6 +679,7 @@ window.blazorexpress.chartjs.pie = { } } + // https://www.chartjs.org/docs/latest/configuration/#configuration-object-structure const config = { type: type, data: data, @@ -588,3 +734,392 @@ window.blazorexpress.chartjs.pie = { } }, } + +window.blazorexpress.chartjs.polarArea = { + addDatasetData: (elementId, dataLabel, data) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart) { + const chartData = chart.data; + const chartDatasetData = data; + + if (!chartData.labels.includes(dataLabel)) + chartData.labels.push(dataLabel); + + const chartDatasets = chartData.datasets; + + if (chartDatasets.length > 0) { + let datasetIndex = chartDatasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + if (datasetIndex > -1) { + chartDatasets[datasetIndex].data.push(chartDatasetData.data); + chart.update(); + } + } + } + }, + addDatasetsData: (elementId, dataLabel, data) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart && data) { + const chartData = chart.data; + + if (!chartData.labels.includes(dataLabel)) { + chartData.labels.push(dataLabel); + + if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { + data.forEach(chartDatasetData => { + let datasetIndex = chartData.datasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + chartData.datasets[datasetIndex].data.push(chartDatasetData.data); + chartData.datasets[datasetIndex].backgroundColor.push(chartDatasetData.backgroundColor); + }); + chart.update(); + } + } + } + }, + addDataset: (elementId, newDataset) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart) { + chart.data.datasets.push(newDataset); + chart.update(); + } + }, + create: (elementId, type, data, options, plugins) => { + let chartEl = document.getElementById(elementId); + let _plugins = []; + + if (plugins && plugins.length > 0) { + // register `ChartDataLabels` plugin + if (plugins.includes('ChartDataLabels')) { + _plugins.push(ChartDataLabels); + + // set datalabel background color + options.plugins.datalabels.backgroundColor = function (context) { + return context.dataset.backgroundColor; + }; + } + } + + // https://www.chartjs.org/docs/latest/configuration/#configuration-object-structure + const config = { + type: type, + data: data, + options: options, + plugins: _plugins + }; + + const chart = new Chart( + chartEl, + config + ); + }, + get: (elementId) => { + let chart; + Chart.helpers.each(Chart.instances, function (instance) { + if (instance.canvas.id === elementId) { + chart = instance; + } + }); + + return chart; + }, + initialize: (elementId, type, data, options, plugins) => { + let chart = window.blazorexpress.chartjs.polarArea.get(elementId); + if (chart) return; + else + window.blazorexpress.chartjs.polarArea.create(elementId, type, data, options, plugins); + }, + resize: (elementId, width, height) => { + let chart = window.blazorexpress.chartjs.polarArea.get(elementId); + if (chart) { + chart.canvas.parentNode.style.height = height; + chart.canvas.parentNode.style.width = width; + } + }, + update: (elementId, type, data, options) => { + let chart = window.blazorexpress.chartjs.polarArea.get(elementId); + if (chart) { + if (chart.config.plugins && chart.config.plugins.findIndex(x => x.id == 'datalabels') > -1) { + // set datalabel background color + options.plugins.datalabels.backgroundColor = function (context) { + return context.dataset.backgroundColor; + }; + } + + chart.data = data; + chart.options = options; + chart.update(); + } + else { + console.warn(`The chart is not initialized. Initialize it and then call update.`); + } + }, +} + +window.blazorexpress.chartjs.radar = { + addDatasetData: (elementId, dataLabel, data) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart) { + const chartData = chart.data; + const chartDatasetData = data; + + if (!chartData.labels.includes(dataLabel)) + chartData.labels.push(dataLabel); + + const chartDatasets = chartData.datasets; + + if (chartDatasets.length > 0) { + let datasetIndex = chartDatasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + if (datasetIndex > -1) { + chartDatasets[datasetIndex].data.push(chartDatasetData.data); + chart.update(); + } + } + } + }, + addDatasetsData: (elementId, dataLabel, data) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart && data) { + const chartData = chart.data; + + if (!chartData.labels.includes(dataLabel)) { + chartData.labels.push(dataLabel); + + if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { + data.forEach(chartDatasetData => { + let datasetIndex = chartData.datasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + chartData.datasets[datasetIndex].data.push(chartDatasetData.data); + }); + chart.update(); + } + } + } + }, + addDataset: (elementId, newDataset) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart) { + chart.data.datasets.push(newDataset); + chart.update(); + } + }, + create: (elementId, type, data, options, plugins) => { + let chartEl = document.getElementById(elementId); + let _plugins = []; + + if (plugins && plugins.length > 0) { + // register `ChartDataLabels` plugin + if (plugins.includes('ChartDataLabels')) { + _plugins.push(ChartDataLabels); + + // set datalabel background color + options.plugins.datalabels.backgroundColor = function (context) { + return context.dataset.backgroundColor; + }; + } + } + + // https://www.chartjs.org/docs/latest/configuration/#configuration-object-structure + const config = { + type: type, + data: data, + options: options, + plugins: _plugins + }; + + const chart = new Chart( + chartEl, + config + ); + }, + get: (elementId) => { + let chart; + Chart.helpers.each(Chart.instances, function (instance) { + if (instance.canvas.id === elementId) { + chart = instance; + } + }); + + return chart; + }, + initialize: (elementId, type, data, options, plugins) => { + let chart = window.blazorexpress.chartjs.radar.get(elementId); + if (chart) return; + else + window.blazorexpress.chartjs.radar.create(elementId, type, data, options, plugins); + }, + resize: (elementId, width, height) => { + let chart = window.blazorexpress.chartjs.radar.get(elementId); + if (chart) { + chart.canvas.parentNode.style.height = height; + chart.canvas.parentNode.style.width = width; + } + }, + update: (elementId, type, data, options) => { + let chart = window.blazorexpress.chartjs.radar.get(elementId); + if (chart) { + if (chart.config.plugins && chart.config.plugins.findIndex(x => x.id == 'datalabels') > -1) { + // set datalabel background color + options.plugins.datalabels.backgroundColor = function (context) { + return context.dataset.backgroundColor; + }; + } + + chart.data = data; + chart.options = options; + chart.update(); + } + else { + console.warn(`The chart is not initialized. Initialize it and then call update.`); + } + }, + updateDataValues: (elementId, data) => { + let chart = window.blazorexpress.chartjs.radar.get(elementId); + if (chart) { + chart.data.datasets.splice(data.datasets.length); + + for (var datasetIndex = 0; datasetIndex < chart.data.datasets.length; ++datasetIndex) { + chart.data.datasets[datasetIndex].data = data.datasets[datasetIndex].data; + chart.data.labels = data.labels; + } + + for (var datasetIndex = chart.data.datasets.length; datasetIndex < data.datasets.length; ++datasetIndex) { + chart.data.datasets.push(data.datasets[datasetIndex]); + } + + chart.update(); + } + } +} + +window.blazorexpress.chartjs.scatter = { + addDatasetData: (elementId, dataLabel, data) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart) { + const chartData = chart.data; + const chartDatasetData = data; + + if (!chartData.labels.includes(dataLabel)) + chartData.labels.push(dataLabel); + + const chartDatasets = chartData.datasets; + + if (chartDatasets.length > 0) { + let datasetIndex = chartDatasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + if (datasetIndex > -1) { + chartDatasets[datasetIndex].data.push(chartDatasetData.data); + chart.update(); + } + } + } + }, + addDatasetsData: (elementId, dataLabel, data) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart && data) { + const chartData = chart.data; + + if (!chartData.labels.includes(dataLabel)) { + chartData.labels.push(dataLabel); + + if (chartData.datasets.length > 0 && chartData.datasets.length === data.length) { + data.forEach(chartDatasetData => { + let datasetIndex = chartData.datasets.findIndex(dataset => dataset.label === chartDatasetData.datasetLabel); + chartData.datasets[datasetIndex].data.push(chartDatasetData.data); + }); + chart.update(); + } + } + } + }, + addDataset: (elementId, newDataset) => { + let chart = window.blazorexpress.chartjs.get(elementId); + if (chart) { + chart.data.datasets.push(newDataset); + chart.update(); + } + }, + create: (elementId, type, data, options, plugins) => { + let chartEl = document.getElementById(elementId); + let _plugins = []; + + if (plugins && plugins.length > 0) { + // register `ChartDataLabels` plugin + if (plugins.includes('ChartDataLabels')) { + _plugins.push(ChartDataLabels); + + // set datalabel background color + options.plugins.datalabels.backgroundColor = function (context) { + return context.dataset.backgroundColor; + }; + } + } + + // https://www.chartjs.org/docs/latest/configuration/#configuration-object-structure + const config = { + type: type, + data: data, + options: options, + plugins: _plugins + }; + + const chart = new Chart( + chartEl, + config + ); + }, + get: (elementId) => { + let chart; + Chart.helpers.each(Chart.instances, function (instance) { + if (instance.canvas.id === elementId) { + chart = instance; + } + }); + + return chart; + }, + initialize: (elementId, type, data, options, plugins) => { + let chart = window.blazorexpress.chartjs.scatter.get(elementId); + if (chart) return; + else + window.blazorexpress.chartjs.scatter.create(elementId, type, data, options, plugins); + }, + resize: (elementId, width, height) => { + let chart = window.blazorexpress.chartjs.scatter.get(elementId); + if (chart) { + chart.canvas.parentNode.style.height = height; + chart.canvas.parentNode.style.width = width; + } + }, + update: (elementId, type, data, options) => { + let chart = window.blazorexpress.chartjs.scatter.get(elementId); + if (chart) { + if (chart.config.plugins && chart.config.plugins.findIndex(x => x.id == 'datalabels') > -1) { + // set datalabel background color + options.plugins.datalabels.backgroundColor = function (context) { + return context.dataset.backgroundColor; + }; + } + + chart.data = data; + chart.options = options; + chart.update(); + } + else { + console.warn(`The chart is not initialized. Initialize it and then call update.`); + } + }, + updateDataValues: (elementId, data) => { + let chart = window.blazorexpress.chartjs.scatter.get(elementId); + if (chart) { + chart.data.datasets.splice(data.datasets.length); + + for (var datasetIndex = 0; datasetIndex < chart.data.datasets.length; ++datasetIndex) { + chart.data.datasets[datasetIndex].data = data.datasets[datasetIndex].data; + chart.data.labels = data.labels; + } + + for (var datasetIndex = chart.data.datasets.length; datasetIndex < data.datasets.length; ++datasetIndex) { + chart.data.datasets.push(data.datasets[datasetIndex]); + } + + chart.update(); + } + } +} \ No newline at end of file diff --git a/nuget/logo-180.png b/nuget/logo.png similarity index 100% rename from nuget/logo-180.png rename to nuget/logo.png