diff --git a/.github/workflows/bit.full.ci.yml b/.github/workflows/bit.full.ci.yml
index 2143f22a84..7e34849b23 100644
--- a/.github/workflows/bit.full.ci.yml
+++ b/.github/workflows/bit.full.ci.yml
@@ -480,6 +480,14 @@ jobs:
dotnet build src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false
dotnet pack src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj --output ./packages --configuration Release
+ - name: Generate CSS/JS files BlazorUI.Legacy
+ run: dotnet build src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj -t:BeforeBuildTasks --no-restore -f:net10.0 -c Release
+
+ - name: Build and pack BlazorUI.Legacy
+ run: |
+ dotnet build src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false
+ dotnet pack src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj --output ./packages --configuration Release
+
- name: Generate CSS/JS files BlazorUI.Assets
run: dotnet build src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj -t:BeforeBuildTasks --no-restore -f:net10.0 -c Release
diff --git a/.github/workflows/nuget.org.yml b/.github/workflows/nuget.org.yml
index d13e9c30af..f5f2594a8f 100644
--- a/.github/workflows/nuget.org.yml
+++ b/.github/workflows/nuget.org.yml
@@ -103,6 +103,13 @@ jobs:
- name: dotnet pack BlazorUI.Extras
run: dotnet pack src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj --output . --configuration Release
+ - name: Generate CSS/JS files BlazorUI.Legacy
+ run: dotnet build src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj -t:BeforeBuildTasks --no-restore -f:net10.0 -c Release
+ - name: dotnet build BlazorUI.Legacy
+ run: dotnet build src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false
+ - name: dotnet pack BlazorUI.Legacy
+ run: dotnet pack src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj --output . --configuration Release
+
- name: Generate CSS/JS files BlazorUI.Assets
run: dotnet build src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj -t:BeforeBuildTasks --no-restore -f:net10.0 -c Release
- name: dotnet build BlazorUI.Assets
diff --git a/.github/workflows/prerelease.nuget.org.yml b/.github/workflows/prerelease.nuget.org.yml
index 9e8371bcc8..4a41d6140f 100644
--- a/.github/workflows/prerelease.nuget.org.yml
+++ b/.github/workflows/prerelease.nuget.org.yml
@@ -92,6 +92,13 @@ jobs:
- name: dotnet pack BlazorUI.Extras
run: dotnet pack src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj --output . --configuration Release
+ - name: Generate CSS/JS files BlazorUI.Legacy
+ run: dotnet build src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj -t:BeforeBuildTasks --no-restore -f:net10.0 -c Release
+ - name: dotnet build BlazorUI.Legacy
+ run: dotnet build src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false
+ - name: dotnet pack BlazorUI.Legacy
+ run: dotnet pack src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj --output . --configuration Release
+
- name: Generate CSS/JS files BlazorUI.Assets
run: dotnet build src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj -t:BeforeBuildTasks --no-restore -f:net10.0 -c Release
- name: dotnet build BlazorUI.Assets
diff --git a/.gitignore b/.gitignore
index f2f3953377..85aabc07d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -251,6 +251,12 @@ _book
!/src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/quilljs/*.css
!/src/BlazorUI/Bit.BlazorUI.Extras/wwwroot/leaflet/*.css
+/src/BlazorUI/Bit.BlazorUI.Legacy/**/*.css
+/src/BlazorUI/Bit.BlazorUI.Legacy/Scripts/*.js
+/src/BlazorUI/Bit.BlazorUI.Legacy/wwwroot/scripts/*.js
+/src/BlazorUI/Bit.BlazorUI.Legacy/wwwroot/**/*.css.gz
+!/src/BlazorUI/Bit.BlazorUI.Legacy/wwwroot/quilljs/*.css
+
/src/BlazorUI/Bit.BlazorUI.Assets/**/*.css
/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/scripts/*.js
/src/BlazorUI/Bit.BlazorUI.Assets/wwwroot/**/*.css.gz
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj b/src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj
new file mode 100644
index 0000000000..077a29d059
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Bit.BlazorUI.Legacy.csproj
@@ -0,0 +1,87 @@
+
+
+
+
+
+ net10.0;net9.0;net8.0
+ true
+ enable
+
+ BeforeBuildTasks;
+ $(ResolveStaticWebAssetsInputsDependsOn)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarCategoryAxis.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarCategoryAxis.cs
new file mode 100644
index 0000000000..3e525586ac
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarCategoryAxis.cs
@@ -0,0 +1,74 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Extended version of for use in a bar chart.
+/// As per documentation here (Chart.js).
+///
+public class BitChartBarCategoryAxis : BitChartCategoryAxis
+{
+ ///
+ /// Gets or sets the percentage (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; }
+
+ ///
+ /// Gets or sets the percentage (0-1) of the available width each category should be within the sample width.
+ ///
+ public double? CategoryPercentage { get; set; }
+
+ ///
+ /// Gets or sets the width of each bar in pixels.
+ /// If set to , it computes "optimal" sample widths that globally arrange bars side by side. If not set (default), bars are equally sized based on the smallest interval.
+ ///
+ public BitChartBarThickness BarThickness { get; set; } = default!;
+
+ ///
+ /// Gets or sets the maximum bar thickness.
+ /// Set this to ensure that bars are not sized thicker than this.
+ ///
+ public double? MaxBarThickness { get; set; }
+
+ ///
+ /// Gets or sets the minimum bar length.
+ /// Set this to ensure that bars have a minimum length in pixels.
+ ///
+ public double? MinBarLength { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether grid lines will be shifted to be between labels or not.
+ /// If , the bars for a particular data point fall between the grid lines.
+ /// The grid line will move to the left by one half of the tick interval.
+ /// If , the grid line will go right down the middle of the bars.
+ /// Changing this value will directly affect of the property in this instance.
+ ///
+ public bool? OffsetGridLines
+ {
+ get => GridLines?.OffsetGridLines;
+ set
+ {
+ if (GridLines == null)
+ {
+ if (value == null)
+ {
+ return;
+ }
+ else
+ {
+ GridLines = new BitChartGridLines();
+ }
+ }
+
+ GridLines.OffsetGridLines = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the bar chart is stacked or not.
+ /// Bar charts can be configured into stacked bar charts by changing the settings on the X and Y axes to enable stacking.
+ /// Stacked bar charts can be used to show how one data series is made up of a number of smaller pieces.
+ /// As per documentation here (Chart.js).
+ ///
+ public bool? Stacked { get; set; }
+}
+
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarLinearCartesianAxis.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarLinearCartesianAxis.cs
new file mode 100644
index 0000000000..04519e4ed0
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarLinearCartesianAxis.cs
@@ -0,0 +1,74 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Extended version of for use in a bar chart.
+/// As per documentation here (Chart.js).
+///
+public class BitChartBarLinearCartesianAxis : BitChartLinearCartesianAxis
+{
+ ///
+ /// Gets or sets the percentage (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; }
+
+ ///
+ /// Gets or sets the percentage (0-1) of the available width each category should be within the sample width.
+ ///
+ public double? CategoryPercentage { get; set; }
+
+ ///
+ /// Gets or sets the width of each bar in pixels.
+ /// If set to , it computes "optimal" sample widths that globally arrange bars side by side. If not set (default), bars are equally sized based on the smallest interval.
+ ///
+ public BitChartBarThickness BarThickness { get; set; } = default!;
+
+ ///
+ /// Gets or sets the maximum bar thickness.
+ /// Set this to ensure that bars are not sized thicker than this.
+ ///
+ public double? MaxBarThickness { get; set; }
+
+ ///
+ /// Gets or sets the minimum bar length.
+ /// Set this to ensure that bars have a minimum length in pixels.
+ ///
+ public double? MinBarLength { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether grid lines will be shifted to be between labels or not.
+ /// If , the bars for a particular data point fall between the grid lines.
+ /// The grid line will move to the left by one half of the tick interval.
+ /// If , the grid line will go right down the middle of the bars.
+ /// Changing this value will directly affect of the property in this instance.
+ ///
+ public bool? OffsetGridLines
+ {
+ get => GridLines?.OffsetGridLines;
+ set
+ {
+ if (GridLines == null)
+ {
+ if (value == null)
+ {
+ return;
+ }
+ else
+ {
+ GridLines = new BitChartGridLines();
+ }
+ }
+
+ GridLines.OffsetGridLines = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the bar chart is stacked or not.
+ /// Bar charts can be configured into stacked bar charts by changing the settings on the X and Y axes to enable stacking.
+ /// Stacked bar charts can be used to show how one data series is made up of a number of smaller pieces.
+ /// As per documentation here (Chart.js).
+ ///
+ public bool? Stacked { get; set; }
+}
+
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarLogarithmicAxis.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarLogarithmicAxis.cs
new file mode 100644
index 0000000000..5e82e14063
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarLogarithmicAxis.cs
@@ -0,0 +1,74 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Extended version of for use in a bar chart.
+/// As per documentation here (Chart.js).
+///
+public class BitChartBarLogarithmicAxis : BitChartLogarithmicAxis
+{
+ ///
+ /// Gets or sets the percentage (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; }
+
+ ///
+ /// Gets or sets the percentage (0-1) of the available width each category should be within the sample width.
+ ///
+ public double? CategoryPercentage { get; set; }
+
+ ///
+ /// Gets or sets the width of each bar in pixels.
+ /// If set to , it computes "optimal" sample widths that globally arrange bars side by side. If not set (default), bars are equally sized based on the smallest interval.
+ ///
+ public BitChartBarThickness BarThickness { get; set; } = default!;
+
+ ///
+ /// Gets or sets the maximum bar thickness.
+ /// Set this to ensure that bars are not sized thicker than this.
+ ///
+ public double? MaxBarThickness { get; set; }
+
+ ///
+ /// Gets or sets the minimum bar length.
+ /// Set this to ensure that bars have a minimum length in pixels.
+ ///
+ public double? MinBarLength { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether grid lines will be shifted to be between labels or not.
+ /// If , the bars for a particular data point fall between the grid lines.
+ /// The grid line will move to the left by one half of the tick interval.
+ /// If , the grid line will go right down the middle of the bars.
+ /// Changing this value will directly affect of the property in this instance.
+ ///
+ public bool? OffsetGridLines
+ {
+ get => GridLines?.OffsetGridLines;
+ set
+ {
+ if (GridLines == null)
+ {
+ if (value == null)
+ {
+ return;
+ }
+ else
+ {
+ GridLines = new BitChartGridLines();
+ }
+ }
+
+ GridLines.OffsetGridLines = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the bar chart is stacked or not.
+ /// Bar charts can be configured into stacked bar charts by changing the settings on the X and Y axes to enable stacking.
+ /// Stacked bar charts can be used to show how one data series is made up of a number of smaller pieces.
+ /// As per documentation here (Chart.js).
+ ///
+ public bool? Stacked { get; set; }
+}
+
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarTimeAxis.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarTimeAxis.cs
new file mode 100644
index 0000000000..e14745b0a0
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/BitChartBarTimeAxis.cs
@@ -0,0 +1,74 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Extended version of for use in a bar chart.
+/// As per documentation here (Chart.js).
+///
+public class BitChartBarTimeAxis : BitChartTimeAxis
+{
+ ///
+ /// Gets or sets the percentage (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; }
+
+ ///
+ /// Gets or sets the percentage (0-1) of the available width each category should be within the sample width.
+ ///
+ public double? CategoryPercentage { get; set; }
+
+ ///
+ /// Gets or sets the width of each bar in pixels.
+ /// If set to , it computes "optimal" sample widths that globally arrange bars side by side. If not set (default), bars are equally sized based on the smallest interval.
+ ///
+ public BitChartBarThickness BarThickness { get; set; } = default!;
+
+ ///
+ /// Gets or sets the maximum bar thickness.
+ /// Set this to ensure that bars are not sized thicker than this.
+ ///
+ public double? MaxBarThickness { get; set; }
+
+ ///
+ /// Gets or sets the minimum bar length.
+ /// Set this to ensure that bars have a minimum length in pixels.
+ ///
+ public double? MinBarLength { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether grid lines will be shifted to be between labels or not.
+ /// If , the bars for a particular data point fall between the grid lines.
+ /// The grid line will move to the left by one half of the tick interval.
+ /// If , the grid line will go right down the middle of the bars.
+ /// Changing this value will directly affect of the property in this instance.
+ ///
+ public bool? OffsetGridLines
+ {
+ get => GridLines?.OffsetGridLines;
+ set
+ {
+ if (GridLines == null)
+ {
+ if (value == null)
+ {
+ return;
+ }
+ else
+ {
+ GridLines = new BitChartGridLines();
+ }
+ }
+
+ GridLines.OffsetGridLines = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the bar chart is stacked or not.
+ /// Bar charts can be configured into stacked bar charts by changing the settings on the X and Y axes to enable stacking.
+ /// Stacked bar charts can be used to show how one data series is made up of a number of smaller pieces.
+ /// As per documentation here (Chart.js).
+ ///
+ public bool? Stacked { get; set; }
+}
+
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/ExtendedCartesianAxes.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/ExtendedCartesianAxes.cs
new file mode 100644
index 0000000000..5f282702bb
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/ExtendedCartesianAxes.cs
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/ExtendedCartesianAxes.tt b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/ExtendedCartesianAxes.tt
new file mode 100644
index 0000000000..0919e2c04b
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/Axes/ExtendedCartesianAxes.tt
@@ -0,0 +1,102 @@
+<#@ template debug="false" hostspecific="true" language="C#" #>
+<#@ output extension=".cs" #>
+<#@ assembly name="System.Core" #>
+<#@ assembly name="$(TargetPath)" #>
+<#@ import namespace="System.IO" #>
+
+<#
+ string[] cartesianAxesNames = new[] { "CategoryAxis", "LinearCartesianAxis", "LogarithmicAxis", "TimeAxis" };
+ foreach (string baseName in cartesianAxesNames)
+ {
+ string className = "BitChartBar" + baseName;
+#>
+
+namespace Bit.BlazorUI
+{
+ ///
+ /// Extended version of for use in a bar chart.
+ /// As per documentation here (Chart.js).
+ ///
+ public class <#= className #> : <#= baseName #>
+ {
+ ///
+ /// Gets or sets the percentage (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; }
+
+ ///
+ /// Gets or sets the percentage (0-1) of the available width each category should be within the sample width.
+ ///
+ public double? CategoryPercentage { get; set; }
+
+ ///
+ /// Gets or sets the width of each bar in pixels.
+ /// If set to , it computes "optimal" sample widths that globally arrange bars side by side. If not set (default), bars are equally sized based on the smallest interval.
+ ///
+ public BarThickness BarThickness { get; set; }
+
+ ///
+ /// Gets or sets the maximum bar thickness.
+ /// Set this to ensure that bars are not sized thicker than this.
+ ///
+ public double? MaxBarThickness { get; set; }
+
+ ///
+ /// Gets or sets the minimum bar length.
+ /// Set this to ensure that bars have a minimum length in pixels.
+ ///
+ public double? MinBarLength { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether grid lines will be shifted to be between labels or not.
+ /// If , the bars for a particular data point fall between the grid lines.
+ /// The grid line will move to the left by one half of the tick interval.
+ /// If , the grid line will go right down the middle of the bars.
+ /// Changing this value will directly affect of the property in this instance.
+ ///
+ public bool? OffsetGridLines
+ {
+ get => GridLines?.OffsetGridLines;
+ set
+ {
+ if (GridLines == null)
+ {
+ if (value == null)
+ {
+ return;
+ }
+ else
+ {
+ GridLines = new GridLines();
+ }
+ }
+
+ GridLines.OffsetGridLines = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the bar chart is stacked or not.
+ /// Bar charts can be configured into stacked bar charts by changing the settings on the X and Y axes to enable stacking.
+ /// Stacked bar charts can be used to show how one data series is made up of a number of smaller pieces.
+ /// As per documentation here (Chart.js).
+ ///
+ public bool? Stacked { get; set; }
+ }
+}
+
+<#
+ // End of file.
+ SaveOutput($"{className}.cs");
+}
+#>
+<#+
+private void SaveOutput(string outputFileName)
+{
+ string templateDirectory = Path.GetDirectoryName(Host.TemplateFile);
+ string outputFilePath = Path.Combine(templateDirectory, outputFileName);
+ File.WriteAllText(outputFilePath, this.GenerationEnvironment.ToString());
+ this.GenerationEnvironment.Remove(0, this.GenerationEnvironment.Length);
+}
+#>
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarConfig.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarConfig.cs
new file mode 100644
index 0000000000..99f8b16b9b
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarConfig.cs
@@ -0,0 +1,18 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Represents the config for a bar chart.
+///
+public class BitChartBarConfig : BitChartConfigBase
+{
+ ///
+ /// Creates a new instance of the class.
+ ///
+ ///
+ /// If , the chart-type will be set to
+ /// instead of which turns this chart into a horizontal
+ /// bar chart. If set to , you also have to pass in for
+ /// the s.
+ ///
+ public BitChartBarConfig(bool horizontal = false) : base(horizontal ? BitChartChartType.HorizontalBar : BitChartChartType.Bar) { }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarDataset.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarDataset.cs
new file mode 100644
index 0000000000..5b82398e4c
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarDataset.cs
@@ -0,0 +1,150 @@
+using Newtonsoft.Json;
+
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Represents a dataset for a bar chart.
+/// As per documentation here (Chart.js).
+///
+/// The type of data this contains.
+public class BitChartBarDataset : BitChartDataset
+{
+ ///
+ /// Creates a new instance of .
+ ///
+ ///
+ /// If , the dataset-type will be set to
+ /// instead of . Set this to when using a horizontal
+ /// bar chart. If this is set to in a horizontal bar chart, the bars won't be displayed.
+ ///
+ public BitChartBarDataset(bool horizontal = false) : base(horizontal ? BitChartChartType.HorizontalBar : BitChartChartType.Bar) { }
+
+ ///
+ /// Creates a new instance of with initial data.
+ ///
+ ///
+ public BitChartBarDataset(IEnumerable data, bool horizontal = false) : this(horizontal)
+ {
+ AddRange(data);
+ }
+
+ ///
+ /// Creates a new instance of with
+ /// a custom . Use this constructor when
+ /// you implement a bar-like chart.
+ ///
+ /// The to use instead of .
+ protected BitChartBarDataset(BitChartChartType type) : base(type) { }
+
+ ///
+ /// Gets or sets the fill color of the bars in the dataset.
+ /// See for working with colors.
+ ///
+ public BitChartIndexableOption? BackgroundColor { get; set; }
+
+ ///
+ /// Gets or sets the border color of the bars in the dataset.
+ /// See for working with colors.
+ ///
+ public BitChartIndexableOption? BorderColor { get; set; }
+
+ ///
+ /// Gets or sets a value to avoid drawing the bar stroke at the base of the fill.
+ /// In general, this does not need to be changed except when creating chart types that derive from a bar chart.
+ ///
+ public BitChartIndexableOption? BorderSkipped { get; set; }
+
+ ///
+ /// Gets or sets the border width of the bars in the dataset.
+ ///
+ public BitChartIndexableOption? BorderWidth { get; set; }
+
+ ///
+ /// Gets or sets the percentage (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.
+ /// As per documentation here (Chart.js).
+ ///
+ public double? BarPercentage { get; set; }
+
+ ///
+ /// Gets or sets the percentage (0-1) of the available width each category should be within the sample width.
+ /// As per documentation here (Chart.js)..
+ ///
+ public double? CategoryPercentage { get; set; }
+
+ ///
+ /// Gets or sets the width of each bar in pixels.
+ /// If set to , it computes "optimal" sample widths that globally
+ /// arrange bars side by side. If not set (default), bars are equally sized based on the smallest interval.
+ ///
+ public BitChartBarThickness? BarThickness { get; set; }
+
+ ///
+ /// Gets or sets how to clip relative to the chart area. Positive values allow overflow,
+ /// negative values clip that many pixels inside the chart area.
+ ///
+ public BitChartClipping? Clip { get; set; }
+
+ ///
+ /// Gets or sets the fill color of the bars when hovered.
+ /// See for working with colors.
+ ///
+ public BitChartIndexableOption? HoverBackgroundColor { get; set; }
+
+ ///
+ /// Gets or sets the stroke color of the bars when hovered.
+ /// See for working with colors.
+ ///
+ public BitChartIndexableOption? HoverBorderColor { get; set; }
+
+ ///
+ /// Gets or sets the stroke width of the bars when hovered.
+ ///
+ public BitChartIndexableOption? HoverBorderWidth { get; set; }
+
+ ///
+ /// Gets or sets the label for the dataset which appears in the legend and tooltips.
+ ///
+ public string? Label { get; set; }
+
+ ///
+ /// Gets or sets the maximum thickness of the bars in pixels.
+ ///
+ public double? MaxBarThickness { get; set; }
+
+ ///
+ /// Gets or sets the minimum length of the bars in pixels.
+ ///
+ public double? MinBarLength { get; set; }
+
+ ///
+ /// Gets or sets the id of the group to which this dataset belongs to
+ /// (when stacked, each group will be a separate stack).
+ ///
+ /// In order to use this, the 'Stacked' property of the corresponding
+ /// axis has to be set to . The 'Stacked' property
+ /// is only available in axes.
+ ///
+ ///
+ public string? Stack { get; set; }
+
+ ///
+ /// Gets or sets the drawing order of this dataset.
+ /// Also affects the order for stacking, tooltips, and the legend.
+ ///
+ public int? Order { get; set; }
+
+ ///
+ /// Gets or sets the ID of the x axis to plot this dataset on. If not specified,
+ /// this defaults to the ID of the first found x axis.
+ ///
+ [JsonProperty("xAxisID")]
+ public string? XAxisId { get; set; }
+
+ ///
+ /// Gets or sets the ID of the y axis to plot this dataset on. If not specified,
+ /// this defaults to the ID of the first found y axis.
+ ///
+ [JsonProperty("yAxisID")]
+ public string? YAxisId { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarOptions.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarOptions.cs
new file mode 100644
index 0000000000..86927f5a16
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarOptions.cs
@@ -0,0 +1,12 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The options-subconfig of a .
+///
+public class BitChartBarOptions : BitChartBaseConfigOptions
+{
+ ///
+ /// Gets or sets the scales for this chart.
+ ///
+ public BitChartBarScales? Scales { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarScales.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarScales.cs
new file mode 100644
index 0000000000..3782f6cdde
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarScales.cs
@@ -0,0 +1,23 @@
+using Newtonsoft.Json;
+
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Defines the scales for bar charts by holding the x and y axes.
+///
+public class BitChartBarScales
+{
+ ///
+ /// Gets or sets the configurations for the x-axes.
+ /// You can use any but there are extended axes which contain additional properties to customize the bar chart axes.
+ ///
+ [JsonProperty("xAxes")]
+ public List? XAxes { get; set; }
+
+ ///
+ /// Gets or sets the configurations for the y-axes.
+ /// You can use any but there are extended axes which contain additional properties to customize the bar chart axes.
+ ///
+ [JsonProperty("yAxes")]
+ public List? YAxes { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarThickness.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarThickness.cs
new file mode 100644
index 0000000000..d168874ba3
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartBarThickness.cs
@@ -0,0 +1,39 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The bar thickness used to customize all bar axes.
+/// As per documentation here (Chart.js).
+///
+public class BitChartBarThickness : BitChartObjectEnum
+{
+ ///
+ /// Creates a new instance of the class.
+ ///
+ /// The value to set.
+ private BitChartBarThickness(string stringValue) : base(stringValue) { }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ /// The value to set.
+ private BitChartBarThickness(double doubleValue) : base(doubleValue) { }
+
+ ///
+ /// Gets a from a value (in pixels).
+ ///
+ /// The thickness value in pixels.
+ /// A from a value (in pixels).
+ public static BitChartBarThickness Absolute(double thickness) => new BitChartBarThickness(thickness);
+
+ ///
+ /// Converts a value to a value.
+ ///
+ /// The thickness value in pixels.
+ public static implicit operator BitChartBarThickness(double thickness) => new BitChartBarThickness(thickness);
+
+ ///
+ /// If set to , the base sample widths are calculated automatically
+ /// based on the previous and following samples so that they take the full available widths without overlap.
+ ///
+ public static BitChartBarThickness Flex => new BitChartBarThickness("flex");
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartFloatingBarPoint.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartFloatingBarPoint.cs
new file mode 100644
index 0000000000..dd32a354a3
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/BitChartFloatingBarPoint.cs
@@ -0,0 +1,45 @@
+using Newtonsoft.Json;
+
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Represents a floating bar within a bar chart (use in ).
+/// Using this type, the bars will be rendered with gaps between them (floating-bars).
+///
+/// When serialized, this value is represented as an array of two numbers.
+/// will be the first number in the array, the second one.
+///
+///
+[JsonConverter(typeof(FloatingBarPointConverter))]
+public readonly struct BitChartFloatingBarPoint : IEquatable
+{
+ ///
+ /// Gets the start-value of this .
+ /// When serialized, this will be the first value in the array.
+ ///
+ public double Start { get; }
+
+ ///
+ /// Gets the end-value of this .
+ /// When serialized, this will be the second value in the array.
+ ///
+ public double End { get; }
+
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The start-value for this .
+ /// The end-value for this .
+ public BitChartFloatingBarPoint(double start, double end)
+ {
+ Start = start;
+ End = end;
+ }
+
+ public override bool Equals(object? obj) => obj is BitChartFloatingBarPoint point && Equals(point);
+ public bool Equals(BitChartFloatingBarPoint other) => Start == other.Start && End == other.End;
+ public override int GetHashCode() => HashCode.Combine(Start, End);
+
+ public static bool operator ==(BitChartFloatingBarPoint left, BitChartFloatingBarPoint right) => left.Equals(right);
+ public static bool operator !=(BitChartFloatingBarPoint left, BitChartFloatingBarPoint right) => !(left == right);
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/FloatingBarPointConverter.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/FloatingBarPointConverter.cs
new file mode 100644
index 0000000000..70c9b244e7
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BarChart/FloatingBarPointConverter.cs
@@ -0,0 +1,26 @@
+using Newtonsoft.Json;
+
+namespace Bit.BlazorUI.Legacy;
+
+internal class FloatingBarPointConverter : JsonConverter
+{
+ public override BitChartFloatingBarPoint ReadJson(JsonReader reader, Type objectType, BitChartFloatingBarPoint existingValue, bool hasExistingValue, JsonSerializer serializer)
+ {
+ if (reader.TokenType != JsonToken.StartArray)
+ throw new JsonReaderException();
+
+ var arr = serializer.Deserialize(reader);
+ if (arr!.Length != 2)
+ throw new JsonReaderException();
+
+ return new BitChartFloatingBarPoint(arr[0], arr[1]);
+ }
+
+ public override void WriteJson(JsonWriter writer, BitChartFloatingBarPoint value, JsonSerializer serializer)
+ {
+ writer.WriteStartArray();
+ writer.WriteValue(value.Start);
+ writer.WriteValue(value.End);
+ writer.WriteEndArray();
+ }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BitChart.razor b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BitChart.razor
new file mode 100644
index 0000000000..a50cf8fc8a
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BitChart.razor
@@ -0,0 +1,3 @@
+@namespace Bit.BlazorUI.Legacy
+
+
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BitChart.razor.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BitChart.razor.cs
new file mode 100644
index 0000000000..2a5db7bafa
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BitChart.razor.cs
@@ -0,0 +1,183 @@
+// a fork from https://github.com/mariusmuntean/ChartJs.Blazor
+
+using System.Diagnostics.CodeAnalysis;
+
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Simple and flexible charting component for data visualization, which supports eight chart types: bar, line, area, pie, bubble, radar, polar, and scatter.
+///
+public partial class BitChart : IAsyncDisposable
+{
+ private bool _disposed;
+
+
+
+ [Inject] private IJSRuntime _js { get; set; } = default!;
+
+ ///
+ /// The configuration of the chart.
+ ///
+ [Parameter] public BitChartConfigBase? Config { get; set; }
+
+ ///
+ /// The height of the canvas HTML element.
+ /// Use when using .
+ ///
+ [Parameter] public int? Height { get; set; }
+
+ ///
+ /// This event is fired when the chart has been setup through interop and
+ /// the JavaScript chart object is available. Use this callback if you need to setup
+ /// custom JavaScript options or register plugins.
+ ///
+ [Parameter] public EventCallback SetupCompletedCallback { get; set; }
+
+ ///
+ /// The width of the canvas HTML element.
+ ///
+ [Parameter] public int? Width { get; set; }
+
+ ///
+ /// Whether the date adapter is required for the current configuration.
+ /// By default BitChart uses the date-fns adapter. you can change the adapter using .
+ /// for more info check out https://www.chartjs.org/docs/2.9.4/axes/cartesian/time.html#date-adapters
+ ///
+ [Parameter] public bool IsDateAdapterRequired { get; set; }
+
+ ///
+ /// The list of scripts required for the customized chartjs date adapter.
+ /// see available adapters here: https://github.com/chartjs/awesome#adapters
+ ///
+ [Parameter] public IEnumerable? DateAdapterScripts { get; set; }
+
+
+
+ ///
+ /// Updates the chart.
+ ///
+ /// Call this method after you've updated the .
+ ///
+ ///
+ public Task Update()
+ {
+ if (Config is null) return Task.CompletedTask;
+
+ return _js.BitChartJsUpdateChart(Config).AsTask();
+ }
+
+
+
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBarConfig))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBubbleConfig))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartLineConfig))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartPieConfig))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartPolarAreaConfig))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartRadarConfig))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartScatterConfig))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartConfigBase<,>))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartConfigBase<>))]
+
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(JsonStringEnumConverter))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(IndexableOptionConverter))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(FloatingBarPointConverter))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ClippingJsonConverter))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(JsonWriteOnlyConverter<>))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(JsonObjectEnumConverter))]
+
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBarOptions))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBubbleOptions))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBaseConfigOptions))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartLineOptions))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartPieOptions))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartPolarAreaOptions))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartRadarOptions))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartIndexableOption<>))]
+
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBarDataset<>))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBubbleDataset))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartDataset<>))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartLineDataset<>))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartPieDataset))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartPolarAreaDataset))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartRadarDataset))]
+
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartLegend))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartPosition))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartTooltips))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartAnimation))]
+
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBarScales))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartScales))]
+
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartCartesianTicks))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartCategoryTicks))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartLinearCartesianTicks))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartLogarithmicTicks))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartTimeTicks))]
+
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBarCategoryAxis))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBarLinearCartesianAxis))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBarLogarithmicAxis))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartBarTimeAxis))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartCartesianAxis))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartCartesianAxis<>))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartCategoryAxis))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartLinearCartesianAxis))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartLogarithmicAxis))]
+ [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(BitChartTimeAxis))]
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (firstRender)
+ {
+ await _js.BitLegacyInitScripts(["_content/Bit.BlazorUI.Legacy/chart.js/chartjs-2.9.4.js"]);
+
+ if (IsDateAdapterRequired && DateAdapterScripts is null)
+ {
+ await _js.BitLegacyInitScripts(["_content/Bit.BlazorUI.Legacy/chart.js/chartjs-2.9.4-adapter.js"]);
+ }
+
+ if (DateAdapterScripts is not null)
+ {
+ await _js.BitLegacyInitScripts(DateAdapterScripts);
+ }
+
+ if (Config is not null)
+ {
+ await _js.BitChartJsSetupChart(Config);
+ }
+
+ await SetupCompletedCallback.InvokeAsync(this);
+ return;
+ }
+
+ if (Config is not null)
+ {
+ await _js.BitChartJsSetupChart(Config);
+ }
+ }
+
+
+
+ public async ValueTask DisposeAsync()
+ {
+ await DisposeAsync(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual async ValueTask DisposeAsync(bool disposing)
+ {
+ if (_disposed || disposing is false) return;
+
+ try
+ {
+ if (Config is not null)
+ {
+ await _js.BitChartJsRemoveChart(Config.CanvasId);
+ }
+ }
+ catch (JSDisconnectedException) { } // we can ignore this exception here
+
+ _disposed = true;
+ }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BitChart.ts b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BitChart.ts
new file mode 100644
index 0000000000..85795c4131
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BitChart.ts
@@ -0,0 +1,368 @@
+namespace BitBlazorUI.Legacy {
+ interface BitChartConfiguration extends Chart.ChartConfiguration {
+ canvasId: string;
+ }
+
+ interface DotNetObjectReference {
+ invokeMethod(methodName: string, ...args: any[]): any;
+ invokeMethodAsync(methodName: string, ...args: any[]): Promise;
+ }
+
+ // maybe the interop could be improved somehow by using generic similar to how it's done in C#
+ // but since we don't need typesafety in JavaScript and can't rely on it anyway (just like we
+ // have to invoke the C# delegate dynamically) we're not using generics.
+ export interface IMethodHandler {
+ methodName: string;
+ }
+
+ interface DelegateHandler extends IMethodHandler {
+ handlerReference: DotNetObjectReference;
+ returnsValue: boolean;
+ ignoredIndices: number[];
+ }
+
+ export class BitChart {
+ private static _bitCharts = new Map();
+
+ public static getChartJs(canvasId: string) {
+ if (!BitChart._bitCharts.has(canvasId)) return null;
+
+ return BitChart._bitCharts.get(canvasId)!;
+ }
+
+ public static removeChart(canvasId: string) {
+ if (!BitChart._bitCharts.has(canvasId)) return;
+
+ var chart = BitChart._bitCharts.get(canvasId)!;
+ chart.destroy();
+ chart.config = {};
+ BitChart._bitCharts.delete(canvasId);
+ }
+
+ public static setupChart(config: BitChartConfiguration): boolean {
+ if (BitChart._bitCharts.has(config.canvasId)) {
+ return BitChart.updateChart(config);
+ } else {
+ BitChart.wireUpCallbacks(config);
+
+ let chart = new Chart(config.canvasId, config);
+ BitChart._bitCharts.set(config.canvasId, chart);
+
+ return true;
+ }
+ }
+
+ public static updateChart(config: BitChartConfiguration): boolean {
+ if (!BitChart._bitCharts.has(config.canvasId))
+ throw `Could not find a chart with the given id. ${config.canvasId}`;
+
+ let myChart = BitChart._bitCharts.get(config.canvasId);
+
+ if (!myChart) return false;
+
+ // Update datasets. This breaks the data-array-references; more in the function.
+ BitChart.mergeDatasets(myChart.config.data!.datasets!, config.data!.datasets!);
+ // Update labels while keeping array references intact.
+ BitChart.mergeLabels(myChart.config.data!, config.data!);
+ // Currently we only merge the datasets and the labels of the data subconfig but that
+ // could be expanded in a similar fashion as the dataset's data (if there's a use-case).
+
+ BitChart.wireUpCallbacks(config);
+
+ // This will add new options and update existing ones. Nothing is deleted.
+ // Calling extend instead of merge avoids the unnecessary deep copy as
+ // config.options is a brand new object (deserialized by blazor).
+ Chart.helpers.extend(myChart.config.options, config.options);
+
+ myChart.update();
+ return true;
+ }
+
+ private static mergeDatasets(oldDatasets: Array, newDatasets: Array) {
+ // iterate backwards so we can remove datasets as we go
+ for (let i = oldDatasets.length - 1; i >= 0; i--) {
+ let sameDatasetInNewConfig = newDatasets.find(newD => newD.id === oldDatasets[i].id);
+ if (sameDatasetInNewConfig === undefined) {
+ // Remove dataset if it's not in the new config
+ oldDatasets.splice(i, 1);
+ } else {
+ // This comment below would be the 'correct' way of updating the data while retaining the same reference.
+ // However, there's quite a big issue with BitChart. Chart.js actually listenes for modifications on
+ // the data array and will decide on the update-animation by looking at the latest modifications.
+ // Since this would clear the whole array and then add all the new data, Chart.js thinks every data
+ // point is fresh and plays the same animation it plays when initially creating the chart.
+ // To prevent Chart.js from doing that, we replace the reference which doesn't record any modifications.
+
+ //oldDatasets[i].data.length = 0; // Remove old data
+ //for (let j = 0; j < sameDatasetInNewConfig.data.length; j++) {
+ // // Add current data. Of course it won't be a number _and_ a ChartPoint but I don't how else to make ts happy
+ // oldDatasets[i].data.push(sameDatasetInNewConfig.data[j]);
+ //}
+ //delete sameDatasetInNewConfig.data; // Remove the array from the new dataset so it doesn't get copied in the next line
+
+ // Merge everything, including the data-array reference.
+ // As with the labels, deep copying(with helper.merge) is simply a waste here.
+ Chart.helpers.extend(oldDatasets[i], sameDatasetInNewConfig);
+ }
+ }
+
+ let currentIds = oldDatasets.map(dataset => dataset.id);
+ newDatasets.filter(newDataset => !currentIds.includes(newDataset.id))
+ .forEach(newDataset => oldDatasets.push(newDataset));
+
+ // Currently the order isn't respected so simply reordering the datasets and calling update
+ // won't do anything. You'd have to remove and readd them. Maybe this could be implemented later.
+ }
+
+ private static mergeLabels(oldChartData: Chart.ChartData, newChartData: Chart.ChartData): void {
+ const innerFunc = (oldLabels: Array,
+ newLabels: Array) => {
+ if (newLabels == null || newLabels.length === 0) {
+ if (oldLabels) {
+ oldLabels.length = 0;
+ }
+
+ return oldLabels;
+ }
+
+ if (oldLabels == null) {
+ return newLabels;
+ }
+
+ // clear existing labels
+ oldLabels.length = 0;
+
+ // add all the new labels
+ for (let i = 0; i < newLabels.length; i++) {
+ oldLabels.push(newLabels[i]);
+ }
+
+ return oldLabels;
+ }
+
+ // If it was null/undefined before it can't be done in-place so assignment is required.
+ oldChartData.labels = innerFunc(oldChartData.labels!, newChartData.labels!);
+ oldChartData.xLabels = innerFunc(oldChartData.xLabels!, newChartData.xLabels!);
+ oldChartData.yLabels = innerFunc(oldChartData.yLabels!, newChartData.yLabels!);
+ }
+
+ private static wireUpCallbacks(config: BitChartConfiguration) {
+ // Replace IMethodHandler objects with actual function (if present)
+ // This should be "automated" in some way. We shouldn't have to add
+ // (much) new code for a new callback.
+ BitChart.wireUpOptionsOnClick(config);
+ BitChart.wireUpOptionsOnHover(config);
+ BitChart.wireUpLegendOnClick(config);
+ BitChart.wireUpLegendOnHover(config);
+ BitChart.wireUpLegendItemFilter(config);
+ BitChart.wireUpGenerateLabels(config);
+ BitChart.wireUpTickCallback(config);
+ }
+
+ private static wireUpOptionsOnClick(config: BitChartConfiguration) {
+ let getDefaultFunc = (type: any) => {
+ let defaults = Chart.defaults[type] || Chart.defaults.global;
+ return defaults?.onClick || Chart.defaults.global.onClick;
+ };
+
+ if (!config.options) return;
+
+ config.options.onClick = BitChart.getMethodHandler(config.options.onClick, getDefaultFunc(config.type));
+ }
+
+ private static wireUpOptionsOnHover(config: BitChartConfiguration) {
+ let getDefaultFunc = (type: any) => {
+ let defaults = Chart.defaults[type] || Chart.defaults.global;
+ return defaults?.onHover || Chart.defaults.global.onHover;
+ };
+
+ if (!config.options)
+ return;
+
+ config.options.onHover = BitChart.getMethodHandler(config.options.onHover, getDefaultFunc(config.type));
+ }
+
+ private static wireUpLegendOnClick(config: BitChartConfiguration) {
+ let getDefaultHandler = (type: any) => {
+ let chartDefaults = Chart.defaults[type] || Chart.defaults.global;
+ return chartDefaults?.legend?.onClick || Chart.defaults.global.legend?.onClick;
+ };
+
+ if (!config.options?.legend)
+ return;
+
+ config.options.legend.onClick = BitChart.getMethodHandler(config.options.legend.onClick, getDefaultHandler(config.type));
+ }
+
+ private static wireUpLegendOnHover(config: BitChartConfiguration) {
+ let getDefaultFunc = (type: any) => {
+ let chartDefaults = Chart.defaults[type] || Chart.defaults.global;
+ return chartDefaults?.legend?.onHover || Chart.defaults.global.legend!.onHover;
+ };
+
+ if (!config.options?.legend)
+ return;
+
+ config.options.legend.onHover = BitChart.getMethodHandler(config.options.legend.onHover, getDefaultFunc(config.type));
+ }
+
+ private static wireUpLegendItemFilter(config: BitChartConfiguration) {
+ let getDefaultFunc = (type: any) => {
+ let chartDefaults = Chart.defaults[type] || Chart.defaults.global;
+ return chartDefaults?.legend?.labels?.filter || Chart.defaults.global.legend!.labels!.filter;
+ };
+
+ if (!config.options?.legend?.labels)
+ return;
+
+ config.options.legend.labels.filter = BitChart.getMethodHandler(config.options.legend.labels.filter, getDefaultFunc(config.type));
+ }
+
+ private static wireUpGenerateLabels(config: BitChartConfiguration) {
+ let getDefaultFunc = (type: any) => {
+ let chartDefaults = Chart.defaults[type] || Chart.defaults.global;
+ return chartDefaults?.legend?.labels?.generateLabels || Chart.defaults.global.legend!.labels!.generateLabels;
+ };
+
+ if (!config.options?.legend?.labels)
+ return;
+
+ config.options.legend.labels.generateLabels = BitChart.getMethodHandler(config.options.legend.labels.generateLabels, getDefaultFunc(config.type));
+ }
+
+ private static wireUpTickCallback(config: BitChartConfiguration) {
+ /* Defaults table (found out by checking Chart.defaults in console) -> everything undefined
+ * Bar (scales): undefined
+ * Bubble (scales): undefined
+ * Pie & Doughnut: don't even have scale(s) field
+ * HorizontalBar (scales): undefined
+ * Line (scales): undefined
+ * PolarArea (scale): undefined
+ * Radar (scale): undefined
+ * Scatter (scales): undefined
+ */
+
+ const assignCallbacks = (axes: any) => {
+ if (axes) {
+ for (let i = 0; i < axes.length; i++) {
+ if (!axes[i].ticks) continue;
+ axes[i].ticks.callback = BitChart.getMethodHandler(axes[i].ticks.callback, undefined);
+ if (!axes[i].ticks.callback) {
+ delete axes[i].ticks.callback; // undefined != deleted, Chart.js throws an error if it's undefined so we have to delete it
+ }
+ }
+ }
+ }
+
+ if (config.options?.scales) {
+ assignCallbacks(config.options.scales.xAxes);
+ assignCallbacks(config.options.scales.yAxes);
+ }
+
+ if (config.options?.scale?.ticks) {
+ config.options.scale.ticks.callback = BitChart.getMethodHandler(config.options.scale.ticks.callback, undefined);
+
+ if (!config.options.scale.ticks.callback) {
+ delete config.options.scale.ticks.callback; // undefined != deleted, Chart.js throws an error if it's undefined so we have to delete it
+ }
+ }
+ }
+
+ /**
+ * Given an IMethodHandler (see C# code), it tries to resolve the referenced method.
+ * It currently supports JavaScript functions, which are expected to be attached to the window object, and .Net delegates which can be
+ * bound to .Net static functions, .Net object instance methods and more.
+ *
+ * When failing to recover a method from the IMethodHandler, it returns the default handler.
+ *
+ * @param handler the serialized IMethodHandler (see C# code)
+ * @param defaultFunc the fallback value to use in case the method can't be resolved
+ */
+ private static getMethodHandler(handler: IMethodHandler, defaultFunc?: Function) {
+ if (handler == null) {
+ return defaultFunc;
+ }
+
+ if (BitChart.isDelegateHandler(handler)) {
+ // stringify args and ignore all circular references. This means that objects of type DotNetObject will not be
+ // deserialized correctly (since it's already a string when it reaches JSON.stringify in the blazor interop layer)
+ // but the values passed to chart callbacks should never contain such objects anyway.
+ // Also if we don't care about the value, don't bother to stringify.
+ const stringifyArgs = (args: any[]) => {
+ for (let i = 0; i < args.length; i++) {
+ if (handler.ignoredIndices.includes(i)) {
+ args[i] = '';
+ } else {
+ args[i] = BitChart.stringifyObjectIgnoreCircular(args[i]);
+ }
+ }
+
+ return args;
+ }
+
+ if (!handler.returnsValue) {
+ // https://stackoverflow.com/questions/59543973/use-async-function-when-consumer-doesnt-expect-a-promise
+ return (...args: any[]) => handler.handlerReference.invokeMethodAsync(handler.methodName, stringifyArgs(args));
+ } else {
+ if (window.hasOwnProperty('MONO')) {
+ return (...args: any[]) => handler.handlerReference.invokeMethod(handler.methodName, stringifyArgs(args)); // only works on client side
+ } else {
+ console.warn('Using C# delegates that return values in chart.js callbacks is not supported on ' +
+ "server side blazor because the server side dispatcher doesn't support synchronous interop calls. Falling back to default value.");
+
+ return defaultFunc;
+ }
+ }
+ } else {
+ if (handler.methodName == null) {
+ return defaultFunc;
+ }
+
+ const namespaceAndFunc: string[] = handler.methodName.split('.');
+ if (namespaceAndFunc.length !== 2) {
+ return defaultFunc;
+ }
+
+ const namespace = (window as any)[namespaceAndFunc[0]];
+ if (namespace == null) {
+ return defaultFunc;
+ }
+
+ const func = namespace[namespaceAndFunc[1]];
+ if (typeof func === 'function') {
+ return func;
+ } else {
+ return defaultFunc;
+ }
+ }
+ }
+
+ private static isDelegateHandler(handler: IMethodHandler): handler is DelegateHandler {
+ return 'handlerReference' in handler;
+ }
+
+ private static stringifyObjectIgnoreCircular(object: any) {
+ const seen = new WeakSet();
+ const replacer = (_name: any, value: any) => {
+ if (
+ typeof value === 'object' &&
+ value !== null &&
+ !(value instanceof Boolean) &&
+ !(value instanceof Date) &&
+ !(value instanceof Number) &&
+ !(value instanceof RegExp) &&
+ !(value instanceof String)
+ ) {
+ if (seen.has(value))
+ return undefined;
+
+ seen.add(value);
+ }
+
+ return value;
+ }
+
+ return JSON.stringify(object, replacer);
+ }
+ }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubbleConfig.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubbleConfig.cs
new file mode 100644
index 0000000000..cb34175fab
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubbleConfig.cs
@@ -0,0 +1,12 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Represents the config for a bubble chart.
+///
+public class BitChartBubbleConfig : BitChartConfigBase
+{
+ ///
+ /// Creates a new instance of .
+ ///
+ public BitChartBubbleConfig() : base(BitChartChartType.Bubble) { }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubbleDataset.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubbleDataset.cs
new file mode 100644
index 0000000000..c18a943889
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubbleDataset.cs
@@ -0,0 +1,99 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Represents a dataset for a bubble chart.
+/// As per documentation here (Chart.js).
+///
+public class BitChartBubbleDataset : BitChartDataset
+{
+ ///
+ /// Creates a new instance of .
+ ///
+ public BitChartBubbleDataset() : base(BitChartChartType.Bubble) { }
+
+ ///
+ /// Creates a new instance of with initial data.
+ ///
+ public BitChartBubbleDataset(IEnumerable data) : this()
+ {
+ AddRange(data);
+ }
+
+ ///
+ /// Creates a new instance of with
+ /// a custom . Use this constructor when
+ /// you implement a bubble-like chart.
+ ///
+ /// The to use instead of .
+ protected BitChartBubbleDataset(BitChartChartType type) : base(type) { }
+
+ ///
+ /// Gets or sets the bubble background color.
+ /// See for working with colors.
+ ///
+ public BitChartIndexableOption? BackgroundColor { get; set; }
+
+ ///
+ /// Gets or sets the bubble border color.
+ /// See for working with colors.
+ ///
+ public BitChartIndexableOption? BorderColor { get; set; }
+
+ ///
+ /// Gets or sets the bubble border width (in pixels).
+ ///
+ public BitChartIndexableOption? BorderWidth { get; set; }
+
+ ///
+ /// Gets or sets the bubble background color when hovered.
+ /// See for working with colors.
+ ///
+ public BitChartIndexableOption? HoverBackgroundColor { get; set; }
+
+ ///
+ /// Gets or sets the bubble border color when hovered.
+ /// See for working with colors.
+ ///
+ public BitChartIndexableOption? HoverBorderColor { get; set; }
+
+ ///
+ /// Gets or sets the bubble border width when hovered (in pixels).
+ ///
+ public BitChartIndexableOption? HoverBorderWidth { get; set; }
+
+ ///
+ /// Gets or sets the bubbles additional radius when hovered (in pixels).
+ ///
+ public BitChartIndexableOption? HoverRadius { get; set; }
+
+ ///
+ /// Gets or sets the bubbles additional radius for hit detection (in pixels).
+ ///
+ public BitChartIndexableOption? HitRadius { get; set; }
+
+ ///
+ /// Gets or sets the label for the dataset which appears in the legend and tooltips.
+ ///
+ public string? Label { get; set; }
+
+ ///
+ /// Gets or sets the drawing order of this dataset.
+ /// Also affects the order for stacking, tooltips, and the legend.
+ ///
+ public int? Order { get; set; }
+
+ ///
+ /// Gets or sets the for the bubbles in this dataset.
+ ///
+ public BitChartIndexableOption? PointStyle { get; set; }
+
+ ///
+ /// Gets or sets the bubble radius (in pixels).
+ ///
+ public BitChartIndexableOption? Radius { get; set; }
+
+ ///
+ /// Gets or sets the bubble rotation (in degrees).
+ ///
+ public BitChartIndexableOption? Rotation { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubbleOptions.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubbleOptions.cs
new file mode 100644
index 0000000000..8bed2fe46a
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubbleOptions.cs
@@ -0,0 +1,8 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The options-subconfig of a .
+///
+public class BitChartBubbleOptions : BitChartBaseConfigOptions
+{
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubblePoint.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubblePoint.cs
new file mode 100644
index 0000000000..2db92be874
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/BubbleChart/BitChartBubblePoint.cs
@@ -0,0 +1,47 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Represents a bubble on a plane with an X, Y and radius value.
+///
+public readonly struct BitChartBubblePoint : IEquatable
+{
+ ///
+ /// Gets the X-value of this .
+ ///
+ public double X { get; }
+
+ ///
+ /// Gets the Y-value of this .
+ ///
+ public double Y { get; }
+
+ ///
+ /// Gets the radius of this in pixels. Will be serialized as 'r'.
+ ///
+ /// Important: this property is not scaled by the chart,
+ /// it is the raw radius in pixels of the bubble that is drawn on the canvas.
+ ///
+ ///
+ [Newtonsoft.Json.JsonProperty("r")]
+ public double Radius { get; }
+
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The X-value for this .
+ /// The Y-value for this .
+ /// The radius for this in pixels.
+ public BitChartBubblePoint(double x, double y, double radius)
+ {
+ X = x;
+ Y = y;
+ Radius = radius;
+ }
+
+ public override bool Equals(object? obj) => obj is BitChartBubblePoint point && Equals(point);
+ public bool Equals(BitChartBubblePoint other) => X == other.X && Y == other.Y && Radius == other.Radius;
+ public override int GetHashCode() => HashCode.Combine(X, Y, Radius);
+
+ public static bool operator ==(BitChartBubblePoint left, BitChartBubblePoint right) => left.Equals(right);
+ public static bool operator !=(BitChartBubblePoint left, BitChartBubblePoint right) => !(left == right);
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Chartjs.d.ts b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Chartjs.d.ts
new file mode 100644
index 0000000000..7935c343f2
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Chartjs.d.ts
@@ -0,0 +1,906 @@
+// Type definitions for Chart.js 2.9
+// Modified for use in Bit.BlazorUI.BitChart (removed currently unsupported moment.js references)
+// Project: https://github.com/nnnick/Chart.js, https://www.chartjs.org
+// Definitions by: Alberto Nuti
+// Fabien Lavocat
+// KentarouTakeda
+// Larry Bahr
+// Daniel Luz
+// Joseph Page
+// Dan Manastireanu
+// Guillaume Rodriguez
+// Simon Archer
+// Ken Elkabany
+// Francesco Benedetto
+// Alexandros Dorodoulis
+// Manuel Heidrich
+// Conrad Holtzhausen
+// Adrin Caballero
+// wertzui
+// Martin Trobck
+// Elian Cordoba
+// Takuya Uehara
+// Ricardo Mello
+// Ray Nicholus
+// Oscar Cabrera
+// Carlos Anoceto
+// Nobuhiko Futagami
+// Marco Ru
+// Tony Liu
+// Mathias Helminger
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+// TypeScript Version: 2.3
+
+declare class Chart {
+ static readonly Chart: typeof Chart;
+ constructor(
+ context: string | CanvasRenderingContext2D | HTMLCanvasElement | ArrayLike,
+ options: Chart.ChartConfiguration
+ );
+ config: Chart.ChartConfiguration;
+ data: Chart.ChartData;
+ destroy: () => {};
+ update: ({ duration, lazy, easing }?: Chart.ChartUpdateProps) => {};
+ render: ({ duration, lazy, easing }?: Chart.ChartRenderProps) => {};
+ stop: () => Chart;
+ resize: () => Chart;
+ clear: () => Chart;
+ toBase64Image: () => string;
+ generateLegend: () => {};
+ getElementAtEvent: (e: any) => [{}];
+ getElementsAtEvent: (e: any) => Array<{}>;
+ getElementsAtXAxis: (e: any) => Array<{}>;
+ getDatasetAtEvent: (e: any) => Array<{}>;
+ getDatasetMeta: (index: number) => Meta;
+ getVisibleDatasetCount: () => number;
+ isDatasetVisible: (datasetIndex: number) => boolean;
+ setDatasetVisibility: (datasetIndex: number, visible: boolean) => void;
+ ctx: CanvasRenderingContext2D | null;
+ canvas: HTMLCanvasElement | null;
+ width: number | null;
+ height: number | null;
+ aspectRatio: number | null;
+ options: Chart.ChartOptions;
+ chartArea: Chart.ChartArea;
+ static pluginService: PluginServiceStatic;
+ static plugins: PluginServiceStatic;
+
+ static defaults: {
+ global: Chart.ChartOptions & Chart.ChartFontOptions & {
+ tooltips: Chart.ChartTooltipOptions
+ };
+ [key: string]: any;
+ };
+
+ static controllers: {
+ [key: string]: any;
+ };
+
+ static helpers: {
+ merge: (target: any, source: any, options?: {
+ merger?: Function;
+ }) => any;
+ extend: (target: any, ...args: any[]) => any;
+ [key: string]: any;
+ };
+
+ static platform: {
+ disableCSSInjection: boolean
+ };
+
+ static scaleService: {
+ updateScaleDefaults: (type: Chart.ScaleType, updates: Chart.ChartScales) => void;
+ };
+
+ // Tooltip Static Options
+ static Tooltip: Chart.ChartTooltipsStaticConfiguration;
+
+ static readonly instances: {
+ [key: string]: Chart;
+ };
+}
+declare class PluginServiceStatic {
+ register(plugin: Chart.PluginServiceGlobalRegistration & Chart.PluginServiceRegistrationOptions): void;
+ unregister(plugin: Chart.PluginServiceGlobalRegistration & Chart.PluginServiceRegistrationOptions): void;
+}
+
+interface Meta {
+ type: Chart.ChartType;
+ data: MetaData[];
+ dataset?: Chart.ChartDataSets;
+ controller: { [key: string]: any; };
+ hidden?: boolean;
+ total?: string;
+ xAxisID?: string;
+ yAxisID?: string;
+ "$filler"?: { [key: string]: any; };
+}
+
+interface MetaData {
+ _chart: Chart;
+ _datasetIndex: number;
+ _index: number;
+ _model: Model;
+ _start?: any;
+ _view: Model;
+ _xScale: Chart.ChartScales;
+ _yScale: Chart.ChartScales;
+ hidden?: boolean;
+}
+
+// NOTE: This model is generic with a bunch of optional properties to represent all types of chart models.
+// Each chart type defines their own unique model structure so some of these optional properties
+// might always have values depending on the chart type.
+interface Model {
+ backgroundColor: string;
+ borderAlign?: Chart.BorderAlignment;
+ borderColor: string;
+ borderWidth?: number;
+ circumference?: number;
+ controlPointNextX: number;
+ controlPointNextY: number;
+ controlPointPreviousX: number;
+ controlPointPreviousY: number;
+ endAngle?: number;
+ hitRadius: number;
+ innerRadius?: number;
+ outerRadius?: number;
+ pointStyle: string;
+ radius: string;
+ skip?: boolean;
+ startAngle?: number;
+ steppedLine?: undefined;
+ tension: number;
+ x: number;
+ y: number;
+ base: number;
+ head: number;
+}
+
+declare namespace Chart {
+ type ChartType = 'line' | 'bar' | 'horizontalBar' | 'radar' | 'doughnut' | 'polarArea' | 'bubble' | 'pie' | 'scatter';
+
+ type TimeUnit = 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year';
+
+ type ScaleType = 'category' | 'linear' | 'logarithmic' | 'time' | 'radialLinear';
+
+ type PointStyle = 'circle' | 'cross' | 'crossRot' | 'dash' | 'line' | 'rect' | 'rectRounded' | 'rectRot' | 'star' | 'triangle';
+
+ type PositionType = 'left' | 'right' | 'top' | 'bottom' | 'chartArea';
+
+ // Allow extending the IteractionMode type alias
+ // see https://github.com/microsoft/TypeScript/issues/28078#issuecomment-432339564
+ interface InteractionModeRegistry {
+ 'point': 'point';
+ 'nearest': 'nearest';
+ 'single': 'single';
+ 'label': 'label';
+ 'index': 'index';
+ 'x-axis': 'x-axis';
+ 'dataset': 'dataset';
+ 'x': 'x';
+ 'y': 'y';
+ }
+ type InteractionMode = InteractionModeRegistry[keyof InteractionModeRegistry];
+
+ type Easing = 'linear' | 'easeInQuad' | 'easeOutQuad' | 'easeInOutQuad' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic' |
+ 'easeInQuart' | 'easeOutQuart' | 'easeInOutQuart' | 'easeInQuint' | 'easeOutQuint' | 'easeInOutQuint' | 'easeInSine' | 'easeOutSine' |
+ 'easeInOutSine' | 'easeInExpo' | 'easeOutExpo' | 'easeInOutExpo' | 'easeInCirc' | 'easeOutCirc' | 'easeInOutCirc' | 'easeInElastic' |
+ 'easeOutElastic' | 'easeInOutElastic' | 'easeInBack' | 'easeOutBack' | 'easeInOutBack' | 'easeInBounce' | 'easeOutBounce' | 'easeInOutBounce';
+
+ type TextAlignment = 'left' | 'center' | 'right';
+
+ type BorderAlignment = 'center' | 'inner';
+
+ type BorderWidth = number | { [key in PositionType]?: number };
+
+ interface ChartArea {
+ top: number;
+ right: number;
+ bottom: number;
+ left: number;
+ }
+
+ interface ChartLegendItem {
+ text?: string;
+ fillStyle?: string;
+ hidden?: boolean;
+ index?: number;
+ lineCap?: 'butt' | 'round' | 'square';
+ lineDash?: number[];
+ lineDashOffset?: number;
+ lineJoin?: 'bevel' | 'round' | 'miter';
+ lineWidth?: number;
+ strokeStyle?: string;
+ pointStyle?: PointStyle;
+ }
+
+ interface ChartLegendLabelItem extends ChartLegendItem {
+ datasetIndex?: number;
+ }
+
+ interface ChartTooltipItem {
+ label?: string;
+ value?: string;
+ xLabel?: string | number;
+ yLabel?: string | number;
+ datasetIndex?: number;
+ index?: number;
+ x?: number;
+ y?: number;
+ }
+
+ interface ChartTooltipLabelColor {
+ borderColor: ChartColor;
+ backgroundColor: ChartColor;
+ }
+
+ interface ChartTooltipCallback {
+ beforeTitle?(item: ChartTooltipItem[], data: ChartData): string | string[];
+ title?(item: ChartTooltipItem[], data: ChartData): string | string[];
+ afterTitle?(item: ChartTooltipItem[], data: ChartData): string | string[];
+ beforeBody?(item: ChartTooltipItem[], data: ChartData): string | string[];
+ beforeLabel?(tooltipItem: ChartTooltipItem, data: ChartData): string | string[];
+ label?(tooltipItem: ChartTooltipItem, data: ChartData): string | string[];
+ labelColor?(tooltipItem: ChartTooltipItem, chart: Chart): ChartTooltipLabelColor;
+ labelTextColor?(tooltipItem: ChartTooltipItem, chart: Chart): string;
+ afterLabel?(tooltipItem: ChartTooltipItem, data: ChartData): string | string[];
+ afterBody?(item: ChartTooltipItem[], data: ChartData): string | string[];
+ beforeFooter?(item: ChartTooltipItem[], data: ChartData): string | string[];
+ footer?(item: ChartTooltipItem[], data: ChartData): string | string[];
+ afterFooter?(item: ChartTooltipItem[], data: ChartData): string | string[];
+ }
+
+ interface ChartAnimationParameter {
+ chartInstance?: any;
+ animationObject?: any;
+ }
+
+ interface ChartPoint {
+ x?: number | string | Date;
+ y?: number | string | Date;
+ r?: number;
+ t?: number | string | Date;
+ }
+
+ interface ChartConfiguration {
+ type?: ChartType | string;
+ data?: ChartData;
+ options?: ChartOptions;
+ plugins?: PluginServiceRegistrationOptions[];
+ }
+
+ interface ChartData {
+ labels?: Array;
+ xLabels?: Array;
+ yLabels?: Array;
+ datasets?: ChartDataSets[];
+ }
+
+ interface RadialChartOptions extends ChartOptions {
+ scale?: RadialLinearScale;
+ }
+
+ interface ChartSize {
+ height: number;
+ width: number;
+ }
+
+ interface ChartOptions {
+ responsive?: boolean;
+ responsiveAnimationDuration?: number;
+ aspectRatio?: number;
+ maintainAspectRatio?: boolean;
+ events?: string[];
+ legendCallback?(chart: Chart): string;
+ onHover?: BitBlazorUI.Legacy.IMethodHandler | ((this: Chart, event: MouseEvent, activeElements: Array<{}>) => any);
+ onClick?: BitBlazorUI.Legacy.IMethodHandler | ((event?: MouseEvent, activeElements?: Array<{}>) => any);
+ onResize?(this: Chart, newSize: ChartSize): void;
+ title?: ChartTitleOptions;
+ legend?: ChartLegendOptions;
+ tooltips?: ChartTooltipOptions;
+ hover?: ChartHoverOptions;
+ animation?: ChartAnimationOptions;
+ elements?: ChartElementsOptions;
+ layout?: ChartLayoutOptions;
+ scale?: RadialLinearScale;
+ scales?: ChartScales | LinearScale | LogarithmicScale | TimeScale;
+ showLines?: boolean;
+ spanGaps?: boolean;
+ cutoutPercentage?: number;
+ circumference?: number;
+ rotation?: number;
+ devicePixelRatio?: number;
+ plugins?: ChartPluginsOptions;
+ }
+
+ interface ChartFontOptions {
+ defaultFontColor?: ChartColor;
+ defaultFontFamily?: string;
+ defaultFontSize?: number;
+ defaultFontStyle?: string;
+ }
+
+ interface ChartTitleOptions {
+ display?: boolean;
+ position?: PositionType;
+ fullWidth?: boolean;
+ fontSize?: number;
+ fontFamily?: string;
+ fontColor?: ChartColor;
+ fontStyle?: string;
+ padding?: number;
+ text?: string | string[];
+ }
+
+ interface ChartLegendOptions {
+ align?: 'center' | 'end' | 'start';
+ display?: boolean;
+ position?: PositionType;
+ fullWidth?: boolean;
+ onClick?: BitBlazorUI.Legacy.IMethodHandler | ((event: MouseEvent, legendItem: ChartLegendLabelItem) => void);
+ onHover?: BitBlazorUI.Legacy.IMethodHandler | ((event: MouseEvent, legendItem: ChartLegendLabelItem) => void);
+ onLeave?(event: MouseEvent, legendItem: ChartLegendLabelItem): void;
+ labels?: ChartLegendLabelOptions;
+ reverse?: boolean;
+ }
+
+ interface ChartLegendLabelOptions {
+ boxWidth?: number;
+ fontSize?: number;
+ fontStyle?: string;
+ fontColor?: ChartColor;
+ fontFamily?: string;
+ padding?: number;
+ generateLabels?: BitBlazorUI.Legacy.IMethodHandler | ((chart: Chart) => ChartLegendLabelItem[]);
+ filter?: BitBlazorUI.Legacy.IMethodHandler | ((legendItem: ChartLegendLabelItem, data: ChartData) => any);
+ usePointStyle?: boolean;
+ }
+
+ interface ChartTooltipOptions {
+ axis?: 'x' | 'y' | 'xy';
+ enabled?: boolean;
+ custom?: (tooltipModel: ChartTooltipModel) => void;
+ mode?: InteractionMode;
+ intersect?: boolean;
+ backgroundColor?: ChartColor;
+ titleAlign?: TextAlignment;
+ titleFontFamily?: string;
+ titleFontSize?: number;
+ titleFontStyle?: string;
+ titleFontColor?: ChartColor;
+ titleSpacing?: number;
+ titleMarginBottom?: number;
+ bodyAlign?: TextAlignment;
+ bodyFontFamily?: string;
+ bodyFontSize?: number;
+ bodyFontStyle?: string;
+ bodyFontColor?: ChartColor;
+ bodySpacing?: number;
+ footerAlign?: TextAlignment;
+ footerFontFamily?: string;
+ footerFontSize?: number;
+ footerFontStyle?: string;
+ footerFontColor?: ChartColor;
+ footerSpacing?: number;
+ footerMarginTop?: number;
+ xPadding?: number;
+ yPadding?: number;
+ caretSize?: number;
+ cornerRadius?: number;
+ multiKeyBackground?: string;
+ callbacks?: ChartTooltipCallback;
+ filter?(item: ChartTooltipItem, data: ChartData): boolean;
+ itemSort?(itemA: ChartTooltipItem, itemB: ChartTooltipItem, data?: ChartData): number;
+ position?: string;
+ caretPadding?: number;
+ displayColors?: boolean;
+ borderColor?: ChartColor;
+ borderWidth?: number;
+ }
+
+ interface ChartTooltipModel {
+ afterBody: string[];
+ backgroundColor: string;
+ beforeBody: string[];
+ body: ChartTooltipModelBody[];
+ bodyFontColor: string;
+ bodyFontSize: number;
+ bodySpacing: number;
+ borderColor: string;
+ borderWidth: number;
+ caretPadding: number;
+ caretSize: number;
+ caretX: number;
+ caretY: number;
+ cornerRadius: number;
+ dataPoints: ChartTooltipItem[];
+ displayColors: boolean;
+ footer: string[];
+ footerFontColor: string;
+ footerFontSize: number;
+ footerMarginTop: number;
+ footerSpacing: number;
+ height: number;
+ labelColors: string[];
+ labelTextColors: string[];
+ legendColorBackground: string;
+ opacity: number;
+ title: string[];
+ titleFontColor: string;
+ titleFontSize: number;
+ titleMarginBottom: number;
+ titleSpacing: number;
+ width: number;
+ x: number;
+ xAlign: string;
+ xPadding: number;
+ y: number;
+ yAlign: string;
+ yPadding: number;
+ _bodyAlign: string;
+ _bodyFontFamily: string;
+ _bodyFontStyle: string;
+ _footerAlign: string;
+ _footerFontFamily: string;
+ _footerFontStyle: string;
+ _titleAlign: string;
+ _titleFontFamily: string;
+ _titleFontStyle: string;
+ }
+
+ interface ChartTooltipModelBody {
+ before: string[];
+ lines: string[];
+ after: string[];
+ }
+
+ // NOTE: declare plugin options as interface instead of inline '{ [plugin: string]: any }'
+ // to allow module augmentation in case some plugins want to strictly type their options.
+ interface ChartPluginsOptions {
+ [pluginId: string]: any;
+ }
+
+ interface ChartTooltipsStaticConfiguration {
+ positioners: { [mode: string]: ChartTooltipPositioner };
+ }
+
+ type ChartTooltipPositioner = (elements: any[], eventPosition: Point) => Point;
+
+ interface ChartHoverOptions {
+ mode?: InteractionMode;
+ animationDuration?: number;
+ intersect?: boolean;
+ axis?: 'x' | 'y' | 'xy';
+ onHover?(this: Chart, event: MouseEvent, activeElements: Array<{}>): any;
+ }
+
+ interface ChartAnimationObject {
+ currentStep?: number;
+ numSteps?: number;
+ easing?: Easing;
+ render?(arg: any): void;
+ onAnimationProgress?(arg: any): void;
+ onAnimationComplete?(arg: any): void;
+ }
+
+ interface ChartAnimationOptions {
+ duration?: number;
+ easing?: Easing;
+ onProgress?(chart: any): void;
+ onComplete?(chart: any): void;
+ animateRotate?: boolean;
+ animateScale?: boolean;
+ }
+
+ interface ChartElementsOptions {
+ point?: ChartPointOptions;
+ line?: ChartLineOptions;
+ arc?: ChartArcOptions;
+ rectangle?: ChartRectangleOptions;
+ }
+
+ interface ChartArcOptions {
+ backgroundColor?: ChartColor;
+ borderColor?: ChartColor;
+ borderWidth?: number;
+ }
+
+ interface ChartLineOptions {
+ cubicInterpolationMode?: 'default' | 'monotone';
+ tension?: number;
+ backgroundColor?: ChartColor;
+ borderWidth?: number;
+ borderColor?: ChartColor;
+ borderCapStyle?: string;
+ borderDash?: any[];
+ borderDashOffset?: number;
+ borderJoinStyle?: string;
+ capBezierPoints?: boolean;
+ fill?: 'zero' | 'top' | 'bottom' | boolean;
+ stepped?: boolean;
+ }
+
+ interface ChartPointOptions {
+ radius?: number;
+ pointStyle?: PointStyle;
+ backgroundColor?: ChartColor;
+ borderWidth?: number;
+ borderColor?: ChartColor;
+ hitRadius?: number;
+ hoverRadius?: number;
+ hoverBorderWidth?: number;
+ }
+
+ interface ChartRectangleOptions {
+ backgroundColor?: ChartColor;
+ borderWidth?: number;
+ borderColor?: ChartColor;
+ borderSkipped?: string;
+ }
+
+ interface ChartLayoutOptions {
+ padding?: ChartLayoutPaddingObject | number;
+ }
+
+ interface ChartLayoutPaddingObject {
+ top?: number;
+ right?: number;
+ bottom?: number;
+ left?: number;
+ }
+
+ interface GridLineOptions {
+ display?: boolean;
+ circular?: boolean;
+ color?: ChartColor;
+ borderDash?: number[];
+ borderDashOffset?: number;
+ lineWidth?: number | number[];
+ drawBorder?: boolean;
+ drawOnChartArea?: boolean;
+ drawTicks?: boolean;
+ tickMarkLength?: number;
+ zeroLineWidth?: number;
+ zeroLineColor?: ChartColor;
+ zeroLineBorderDash?: number[];
+ zeroLineBorderDashOffset?: number;
+ offsetGridLines?: boolean;
+ z?: number;
+ }
+
+ interface ScaleTitleOptions {
+ display?: boolean;
+ labelString?: string;
+ lineHeight?: number | string;
+ fontColor?: ChartColor;
+ fontFamily?: string;
+ fontSize?: number;
+ fontStyle?: string;
+ padding?: ChartLayoutPaddingObject | number;
+ }
+
+ interface TickOptions extends NestedTickOptions {
+ minor?: NestedTickOptions | false;
+ major?: MajorTickOptions | false;
+ }
+
+ interface NestedTickOptions {
+ autoSkip?: boolean;
+ autoSkipPadding?: number;
+ backdropColor?: ChartColor;
+ backdropPaddingX?: number;
+ backdropPaddingY?: number;
+ beginAtZero?: boolean;
+ /**
+ * If the callback returns null or undefined the associated grid line will be hidden.
+ */
+ callback?: BitBlazorUI.Legacy.IMethodHandler | ((value: number | string, index: number, values: number[] | string[]) => string | number | null | undefined);
+ display?: boolean;
+ fontColor?: ChartColor;
+ fontFamily?: string;
+ fontSize?: number;
+ fontStyle?: string;
+ labelOffset?: number;
+ lineHeight?: number;
+ max?: any;
+ maxRotation?: number;
+ maxTicksLimit?: number;
+ min?: any;
+ minRotation?: number;
+ mirror?: boolean;
+ padding?: number;
+ reverse?: boolean;
+ /**
+ * The number of ticks to examine when deciding how many labels will fit.
+ * Setting a smaller value will be faster, but may be less accurate
+ * when there is large variability in label length.
+ * Deault: `ticks.length`
+ */
+ sampleSize?: number;
+ showLabelBackdrop?: boolean;
+ source?: 'auto' | 'data' | 'labels';
+ stepSize?: number;
+ suggestedMax?: number;
+ suggestedMin?: number;
+ }
+
+ interface MajorTickOptions extends NestedTickOptions {
+ enabled?: boolean;
+ }
+
+ interface AngleLineOptions {
+ display?: boolean;
+ color?: ChartColor;
+ lineWidth?: number;
+ borderDash?: number[];
+ borderDashOffset?: number;
+ }
+
+ interface PointLabelOptions {
+ callback?(arg: any): any;
+ fontColor?: ChartColor;
+ fontFamily?: string;
+ fontSize?: number;
+ fontStyle?: string;
+ lineHeight?: number | string;
+ }
+
+ interface LinearTickOptions extends TickOptions {
+ maxTicksLimit?: number;
+ stepSize?: number;
+ precision?: number;
+ suggestedMin?: number;
+ suggestedMax?: number;
+ }
+
+ // tslint:disable-next-line no-empty-interface
+ interface LogarithmicTickOptions extends TickOptions {
+ }
+
+ type ChartColor = string | CanvasGradient | CanvasPattern | string[];
+
+ type Scriptable = (ctx: {
+ chart?: Chart;
+ dataIndex?: number;
+ dataset?: ChartDataSets
+ datasetIndex?: number;
+ }) => T;
+
+ interface ChartDataSets {
+ id: string;
+ cubicInterpolationMode?: 'default' | 'monotone';
+ backgroundColor?: ChartColor | ChartColor[] | Scriptable;
+ barPercentage?: number;
+ barThickness?: number | "flex";
+ borderAlign?: BorderAlignment | BorderAlignment[] | Scriptable;
+ borderWidth?: BorderWidth | BorderWidth[] | Scriptable;
+ borderColor?: ChartColor | ChartColor[] | Scriptable;
+ borderCapStyle?: 'butt' | 'round' | 'square';
+ borderDash?: number[];
+ borderDashOffset?: number;
+ borderJoinStyle?: 'bevel' | 'round' | 'miter';
+ borderSkipped?: PositionType | PositionType[] | Scriptable;
+ categoryPercentage?: number;
+ data?: Array | ChartPoint[];
+ fill?: boolean | number | string;
+ hitRadius?: number | number[] | Scriptable;
+ hoverBackgroundColor?: ChartColor | ChartColor[] | Scriptable;
+ hoverBorderColor?: ChartColor | ChartColor[] | Scriptable;
+ hoverBorderWidth?: number | number[] | Scriptable;
+ hoverRadius?: number;
+ label?: string;
+ lineTension?: number;
+ maxBarThickness?: number;
+ minBarLength?: number;
+ steppedLine?: 'before' | 'after' | 'middle' | boolean;
+ order?: number;
+ pointBorderColor?: ChartColor | ChartColor[] | Scriptable;
+ pointBackgroundColor?: ChartColor | ChartColor[] | Scriptable;
+ pointBorderWidth?: number | number[] | Scriptable;
+ pointRadius?: number | number[] | Scriptable;
+ pointRotation?: number | number[] | Scriptable;
+ pointHoverRadius?: number | number[] | Scriptable;
+ pointHitRadius?: number | number[] | Scriptable;
+ pointHoverBackgroundColor?: ChartColor | ChartColor[] | Scriptable;
+ pointHoverBorderColor?: ChartColor | ChartColor[] | Scriptable;
+ pointHoverBorderWidth?: number | number[] | Scriptable;
+ pointStyle?: PointStyle | HTMLImageElement | HTMLCanvasElement | Array | Scriptable;
+ radius?: number | number[] | Scriptable;
+ rotation?: number | number[] | Scriptable;
+ xAxisID?: string;
+ yAxisID?: string;
+ type?: ChartType | string;
+ hidden?: boolean;
+ hideInLegendAndTooltip?: boolean;
+ showLine?: boolean;
+ stack?: string;
+ spanGaps?: boolean;
+ weight?: number;
+ }
+
+ interface ChartScales {
+ type?: ScaleType | string;
+ display?: boolean;
+ position?: PositionType | string;
+ gridLines?: GridLineOptions;
+ scaleLabel?: ScaleTitleOptions;
+ ticks?: TickOptions;
+ xAxes?: ChartXAxe[];
+ yAxes?: ChartYAxe[];
+ }
+
+ interface CommonAxe {
+ bounds?: string;
+ type?: ScaleType | string;
+ display?: boolean | string;
+ id?: string;
+ stacked?: boolean;
+ position?: string;
+ ticks?: TickOptions;
+ gridLines?: GridLineOptions;
+ scaleLabel?: ScaleTitleOptions;
+ time?: TimeScale;
+ offset?: boolean;
+ beforeUpdate?(scale?: any): void;
+ beforeSetDimension?(scale?: any): void;
+ beforeDataLimits?(scale?: any): void;
+ beforeBuildTicks?(scale?: any): void;
+ beforeTickToLabelConversion?(scale?: any): void;
+ beforeCalculateTickRotation?(scale?: any): void;
+ beforeFit?(scale?: any): void;
+ afterUpdate?(scale?: any): void;
+ afterSetDimension?(scale?: any): void;
+ afterDataLimits?(scale?: any): void;
+ afterBuildTicks?(scale: any, ticks: number[]): number[];
+ afterTickToLabelConversion?(scale?: any): void;
+ afterCalculateTickRotation?(scale?: any): void;
+ afterFit?(scale?: any): void;
+ }
+
+ interface ChartXAxe extends CommonAxe {
+ distribution?: 'linear' | 'series';
+ }
+
+ // tslint:disable-next-line no-empty-interface
+ interface ChartYAxe extends CommonAxe {
+ }
+
+ interface LinearScale extends ChartScales {
+ ticks?: LinearTickOptions;
+ }
+
+ interface LogarithmicScale extends ChartScales {
+ ticks?: LogarithmicTickOptions;
+ }
+
+ interface TimeDisplayFormat {
+ millisecond?: string;
+ second?: string;
+ minute?: string;
+ hour?: string;
+ day?: string;
+ week?: string;
+ month?: string;
+ quarter?: string;
+ year?: string;
+ }
+
+ interface DateAdapterOptions {
+ date?: object;
+ }
+
+ interface TimeScale extends ChartScales {
+ adapters?: DateAdapterOptions;
+ displayFormats?: TimeDisplayFormat;
+ isoWeekday?: boolean;
+ max?: string;
+ min?: string;
+ parser?: string | ((arg: any) => any);
+ round?: TimeUnit;
+ tooltipFormat?: string;
+ unit?: TimeUnit;
+ unitStepSize?: number;
+ stepSize?: number;
+ minUnit?: TimeUnit;
+ }
+
+ interface RadialLinearScale {
+ animate?: boolean;
+ position?: PositionType;
+ angleLines?: AngleLineOptions;
+ pointLabels?: PointLabelOptions;
+ ticks?: LinearTickOptions;
+ display?: boolean;
+ gridLines?: GridLineOptions;
+ }
+
+ interface Point {
+ x: number;
+ y: number;
+ }
+
+ interface PluginServiceGlobalRegistration {
+ id?: string;
+ }
+
+ interface PluginServiceRegistrationOptions {
+ beforeInit?(chartInstance: Chart, options?: any): void;
+ afterInit?(chartInstance: Chart, options?: any): void;
+
+ beforeUpdate?(chartInstance: Chart, options?: any): void;
+ afterUpdate?(chartInstance: Chart, options?: any): void;
+
+ beforeLayout?(chartInstance: Chart, options?: any): void;
+ afterLayout?(chartInstance: Chart, options?: any): void;
+
+ beforeDatasetsUpdate?(chartInstance: Chart, options?: any): void;
+ afterDatasetsUpdate?(chartInstance: Chart, options?: any): void;
+
+ beforeDatasetUpdate?(chartInstance: Chart, options?: any): void;
+ afterDatasetUpdate?(chartInstance: Chart, options?: any): void;
+
+ // This is called at the start of a render. It is only called once, even if the animation will run for a number of frames. Use beforeDraw or afterDraw
+ // to do something on each animation frame
+ beforeRender?(chartInstance: Chart, options?: any): void;
+ afterRender?(chartInstance: Chart, options?: any): void;
+
+ // Easing is for animation
+ beforeDraw?(chartInstance: Chart, easing: Easing, options?: any): void;
+ afterDraw?(chartInstance: Chart, easing: Easing, options?: any): void;
+
+ // Before the datasets are drawn but after scales are drawn
+ beforeDatasetsDraw?(chartInstance: Chart, easing: Easing, options?: any): void;
+ afterDatasetsDraw?(chartInstance: Chart, easing: Easing, options?: any): void;
+
+ beforeDatasetDraw?(chartInstance: Chart, easing: Easing, options?: any): void;
+ afterDatasetDraw?(chartInstance: Chart, easing: Easing, options?: any): void;
+
+ // Called before drawing the `tooltip`. If any plugin returns `false`,
+ // the tooltip drawing is cancelled until another `render` is triggered.
+ beforeTooltipDraw?(chartInstance: Chart, tooltipData?: any, options?: any): void;
+ // Called after drawing the `tooltip`. Note that this hook will not,
+ // be called if the tooltip drawing has been previously cancelled.
+ afterTooltipDraw?(chartInstance: Chart, tooltipData?: any, options?: any): void;
+
+ // Called when an event occurs on the chart
+ beforeEvent?(chartInstance: Chart, event: Event, options?: any): void;
+ afterEvent?(chartInstance: Chart, event: Event, options?: any): void;
+
+ resize?(chartInstance: Chart, newChartSize: ChartSize, options?: any): void;
+ destroy?(chartInstance: Chart): void;
+
+ /** Deprecated since version 2.5.0. Use `afterLayout` instead. */
+ afterScaleUpdate?(chartInstance: Chart, options?: any): void;
+ }
+
+ interface ChartUpdateProps {
+ duration?: number;
+ lazy?: boolean;
+ easing?: Easing;
+ }
+
+ interface ChartRenderProps {
+ duration?: number;
+ lazy?: boolean;
+ easing?: Easing;
+ }
+
+ // Model used with the doughnut chart
+ interface DoughnutModel {
+ backgroundColor: ChartColor;
+ borderAlign: BorderAlignment;
+ borderColor: string;
+ borderWidth: number;
+ circumference: number;
+ endAngle: number;
+ innerRadius: number;
+ outerRadius: number;
+ startAngle: number;
+ x: number;
+ y: number;
+ }
+}
+
+export = Chart;
+export as namespace Chart;
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartAngleLines.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartAngleLines.cs
new file mode 100644
index 0000000000..84407d1992
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartAngleLines.cs
@@ -0,0 +1,36 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The angle lines sub-config of the linear-radial-axis-configuration (see ).
+/// As per documentation here (Chart.js).
+///
+public class BitChartAngleLines
+{
+ ///
+ /// Gets or sets the value indicating whether the angle line is displayed or not.
+ ///
+ public bool? Display { get; set; }
+
+ ///
+ /// Gets or sets the color of the angled lines.
+ /// See for working with colors.
+ ///
+ public string? Color { get; set; }
+
+ ///
+ /// Gets or sets the width of the angled lines.
+ ///
+ public int? LineWidth { get; set; }
+
+ ///
+ /// Gets or sets the length and spacing of dashes of the angled lines.
+ /// As per documentation here (MDN).
+ ///
+ public int[]? BorderDash { get; set; }
+
+ ///
+ /// Gets or sets the offset for line dashes.
+ /// As per documentation here (MDN).
+ ///
+ public double? BorderDashOffset { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartAxis.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartAxis.cs
new file mode 100644
index 0000000000..e79eb75f6d
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartAxis.cs
@@ -0,0 +1,21 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// As per documentation here (Chart.js).
+///
+public abstract class BitChartAxis
+{
+ ///
+ /// Controls the axis global visibility (visible when , hidden when ).
+ /// When display: , the axis is visible only if at least one associated dataset is visible.
+ ///
+ public BitChartAxisDisplay? Display { get; set; }
+
+ ///
+ /// The weight used to sort the axis. Higher weights are further away from the chart area.
+ ///
+ public int? Weight { get; set; }
+
+ // TODO: Maybe implement: https://www.chartjs.org/docs/latest/axes/#callbacks
+ // public object Callbacks { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartCartesianAxis.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartCartesianAxis.cs
new file mode 100644
index 0000000000..4c6002ebec
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartCartesianAxis.cs
@@ -0,0 +1,56 @@
+using Newtonsoft.Json;
+
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// As per documentation here (Chart.js).
+///
+public abstract class BitChartCartesianAxis : BitChartAxis
+{
+ ///
+ /// The type of axis this instance represents.
+ /// For js-interop/serialization purposes so Chart.js knows what axis to use.
+ ///
+ public abstract BitChartAxisType Type { get; }
+
+ ///
+ /// The ID is used to link / and together.
+ /// Referenced in and
+ /// ( and respectively).
+ ///
+ [JsonProperty("id")]
+ public string? ID { get; set; }
+
+ ///
+ /// Gets or sets the position of the axis in the chart.
+ ///
+ public BitChartPosition? Position { get; set; }
+
+ ///
+ /// If true, extra space is added to the both edges and the axis is scaled to fit into the chart area.
+ /// This is set to true for a category scale in a bar chart by default.
+ ///
+ public bool? Offset { get; set; }
+
+ ///
+ /// Gets or sets the scale title configuration.
+ ///
+ public BitChartScaleLabel? ScaleLabel { get; set; }
+
+ ///
+ /// Defines options for the grid lines that run perpendicular to the axis.
+ ///
+ public BitChartGridLines? GridLines { get; set; }
+}
+
+///
+/// which contains the ticks-subconfig.
+///
+///
+public abstract class BitChartCartesianAxis : BitChartCartesianAxis where TTicks : BitChartCartesianTicks
+{
+ ///
+ /// Defines options for the tick marks that are generated by the axis.
+ ///
+ public TTicks? Ticks { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartCategoryAxis.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartCategoryAxis.cs
new file mode 100644
index 0000000000..2c0e33c2db
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartCategoryAxis.cs
@@ -0,0 +1,12 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// This axis is to be used when you want to display values for an axis.
+/// This axis has to be used when using/defining , and/or .
+/// As per documentation here (Chart.js).
+///
+public class BitChartCategoryAxis : BitChartCartesianAxis
+{
+ ///
+ public override BitChartAxisType Type => BitChartAxisType.Category;
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartLinearCartesianAxis.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartLinearCartesianAxis.cs
new file mode 100644
index 0000000000..11efb9b365
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartLinearCartesianAxis.cs
@@ -0,0 +1,12 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The linear scale is use to chart numerical data. It can be placed on either the x or y axis.
+/// As the name suggests, linear interpolation is used to determine where a value lies on the axis.
+/// As per documentation here (Chart.js).
+///
+public class BitChartLinearCartesianAxis : BitChartCartesianAxis
+{
+ ///
+ public override BitChartAxisType Type => BitChartAxisType.Linear;
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartLinearRadialAxis.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartLinearRadialAxis.cs
new file mode 100644
index 0000000000..7d844971e4
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartLinearRadialAxis.cs
@@ -0,0 +1,32 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// A linear radial axis.
+/// As per documentation here (Chart.js).
+///
+public class BitChartLinearRadialAxis
+{
+ ///
+ /// Gets or sets the angle lines configuration.
+ /// As per documentation here (Chart.js).
+ ///
+ public BitChartAngleLines? AngleLines { get; set; }
+
+ ///
+ /// Gets or sets the grid lines configuration.
+ /// As per documentation here (Chart.js).
+ ///
+ public BitChartGridLines? GridLines { get; set; }
+
+ ///
+ /// Gets or sets the point labels configuration.
+ /// As per documentation here (Chart.js).
+ ///
+ public BitChartPointLabels? PointLabels { get; set; }
+
+ ///
+ /// Gets or sets the ticks configuration.
+ /// As per documentation here (Chart.js).
+ ///
+ public BitChartLinearRadialTicks? Ticks { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartLogarithmicAxis.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartLogarithmicAxis.cs
new file mode 100644
index 0000000000..1e0e1a06bb
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartLogarithmicAxis.cs
@@ -0,0 +1,12 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The logarithmic scale is use to chart numerical data. It can be placed on either the x or y axis.
+/// As the name suggests, logarithmic interpolation is used to determine where a value lies on the axis.
+/// As per documentation here (Chart.js).
+///
+public class BitChartLogarithmicAxis : BitChartCartesianAxis
+{
+ ///
+ public override BitChartAxisType Type => BitChartAxisType.Logarithmic;
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartPointLabels.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartPointLabels.cs
new file mode 100644
index 0000000000..2d5715bc65
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartPointLabels.cs
@@ -0,0 +1,30 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The point labels sub-config of the linear-radial-axis-configuration (see ).
+/// As per documentation here (Chart.js).
+///
+public class BitChartPointLabels
+{
+ ///
+ /// Gets or sets the font color for a point label.
+ /// See for working with colors.
+ ///
+ public BitChartIndexableOption? FontColor { get; set; }
+
+ ///
+ /// Gets or sets the font size in pixels.
+ ///
+ public int? FontSize { get; set; }
+
+ ///
+ /// Gets or sets the font style to use when rendering a point label.
+ ///
+ public BitChartFontStyle? FontStyle { get; set; }
+
+ ///
+ /// Gets or sets the height of an individual line of text.
+ /// As per documentation here (MDN).
+ ///
+ public double? LineHeight { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartScaleLabel.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartScaleLabel.cs
new file mode 100644
index 0000000000..03fe9663fe
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartScaleLabel.cs
@@ -0,0 +1,37 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Defines options for how to display an axis title.
+///
+public class BitChartScaleLabel
+{
+ ///
+ /// Creates a new instance of
+ ///
+ /// The initial value for
+ public BitChartScaleLabel(string? labelString = null)
+ {
+ LabelString = labelString;
+ }
+
+ ///
+ /// If true, display the axis title.
+ ///
+ public bool? Display { get; set; }
+
+ ///
+ /// Gets or sets the text for the title (i.e. "# of clicks").
+ ///
+ public string? LabelString { get; set; }
+
+ ///
+ /// Gets or sets the font color of the label.
+ /// See for working with colors.
+ ///
+ public string? FontColor { get; set; }
+
+ ///
+ /// Gets or sets the font size for scale title.
+ ///
+ public int? FontSize { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartTimeAxis.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartTimeAxis.cs
new file mode 100644
index 0000000000..41c1681d11
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/BitChartTimeAxis.cs
@@ -0,0 +1,27 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The time scale is used to display times and dates.
+/// When building its ticks, it will automatically calculate the most comfortable unit base on the size of the scale.
+/// As per documentation here (Chart.js).
+///
+public class BitChartTimeAxis : BitChartCartesianAxis
+{
+ ///
+ public override BitChartAxisType Type => BitChartAxisType.Time;
+
+ ///
+ /// Gets or sets the distribution which controls the data distribution along the scale.
+ ///
+ public BitChartTimeDistribution? Distribution { get; set; }
+
+ ///
+ /// Gets or sets the bounds which control the scale boundary strategy (bypassed by min/max time options).
+ ///
+ public BitChartScaleBound? Bounds { get; set; }
+
+ ///
+ /// Gets or sets the configuration for time related options.
+ ///
+ public BitChartTimeOptions? Time { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartCartesianTicks.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartCartesianTicks.cs
new file mode 100644
index 0000000000..ccf00a670f
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartCartesianTicks.cs
@@ -0,0 +1,60 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The base class for all tick mark configurations of cartesian axes (see ). Ticks-subconfig of .
+/// As per documentation here (Chart.js).
+///
+public abstract class BitChartCartesianTicks : BitChartTicks
+{
+ ///
+ /// Gets or sets the user defined minimum number for the scale, overrides minimum value from data.
+ ///
+ public double? Min { get; set; }
+
+ ///
+ /// Gets or sets the user defined maximum number for the scale, overrides maximum value from data.
+ ///
+ public double? Max { get; set; }
+
+ ///
+ /// The number of ticks to examine when deciding how many labels will fit.
+ /// Setting a smaller value will be faster, but may be less accurate when there is large variability in label length.
+ ///
+ public int? SampleSize { get; set; }
+
+ ///
+ /// If true, automatically calculates how many labels can be shown and hides labels accordingly.
+ /// Labels will be rotated up to maxRotation before skipping any. Turn off to show all labels no matter what.
+ ///
+ public bool? AutoSkip { get; set; }
+
+ ///
+ /// Gets or sets the padding between the ticks on the horizontal axis when is enabled.
+ ///
+ public int? AutoSkipPadding { get; set; }
+
+ ///
+ /// Gets or sets the distance in pixels to offset the label from the centre point of the tick (in the x direction for the x axis, and the y direction for the y axis).
+ /// Note: this can cause labels at the edges to be cropped by the edge of the canvas.
+ ///
+ public int? LabelOffset { get; set; }
+
+ ///
+ /// Gets or sets the maximum rotation for tick labels when rotating to condense labels.
+ /// Note: Rotation doesn't occur until necessary.
+ /// Note: Only applicable to horizontal scales.
+ ///
+ public int? MaxRotation { get; set; }
+
+ ///
+ /// Gets or sets the minimum rotation for tick labels.
+ /// Note: Only applicable to horizontal scales.
+ ///
+ public int? MinRotation { get; set; }
+
+ ///
+ /// If true, flips tick labels around axis, displaying the labels inside the chart instead of outside.
+ /// Note: Only applicable to vertical scales.
+ ///
+ public bool? Mirror { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartCategoryTicks.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartCategoryTicks.cs
new file mode 100644
index 0000000000..a921c116cc
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartCategoryTicks.cs
@@ -0,0 +1,24 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The ticks-subconfig of .
+///
+public class BitChartCategoryTicks : BitChartCartesianTicks
+{
+ ///
+ /// Gets or sets an array of labels to display.
+ ///
+ public List? Labels { get; set; }
+
+ ///
+ /// Gets or sets the minimum item to display. The item has to be present in .
+ /// Read more .
+ ///
+ public new string? Min { get; set; }
+
+ ///
+ /// Gets or sets the maximum item to display. The item has to be present in .
+ /// Read more .
+ ///
+ public new string? Max { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartLinearCartesianTicks.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartLinearCartesianTicks.cs
new file mode 100644
index 0000000000..ab2dbd28c8
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartLinearCartesianTicks.cs
@@ -0,0 +1,41 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The ticks-subconfig of .
+/// As per documentation here (Chart.js).
+///
+public class BitChartLinearCartesianTicks : BitChartCartesianTicks
+{
+ ///
+ /// If true, scale will include 0 if it is not already included.
+ ///
+ public bool? BeginAtZero { get; set; }
+
+ ///
+ /// Gets or sets the maximum number of ticks and gridlines to show.
+ ///
+ public int? MaxTicksLimit { get; set; }
+
+ ///
+ /// If defined and is not specified, the step size will be rounded to this many decimal places.
+ ///
+ public int? Precision { get; set; }
+
+ ///
+ /// Gets or sets the user defined fixed step size for the scale.
+ /// See for details.
+ ///
+ public double? StepSize { get; set; }
+
+ ///
+ /// Gets or sets the adjustment used when calculating the maximum data value.
+ /// This value is used as the highest value if it's higher than the maximum data-value.
+ ///
+ public int? SuggestedMax { get; set; }
+
+ ///
+ /// Gets or sets the adjustment used when calculating the minimum data value.
+ /// This value is used as the lowest value if it's lower than the minimum data-value.
+ ///
+ public int? SuggestedMin { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartLinearRadialTicks.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartLinearRadialTicks.cs
new file mode 100644
index 0000000000..b1c6274a0a
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartLinearRadialTicks.cs
@@ -0,0 +1,74 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The ticks sub-config of the .
+/// As per documentation here (Chart.js).
+///
+public class BitChartLinearRadialTicks : BitChartTicks
+{
+ ///
+ /// Gets or sets the color of the label backdrops.
+ /// See for working with colors.
+ ///
+ public string? BackdropColor { get; set; }
+
+ ///
+ /// Gets or sets the horizontal padding of label backdrop.
+ ///
+ public int? BackdropPaddingX { get; set; }
+
+ ///
+ /// Gets or sets the vertical padding of label backdrop.
+ ///
+ public int? BackdropPaddingY { get; set; }
+
+ ///
+ /// Gets or sets the value indicating whether the scale will include 0 if it is not already included.
+ ///
+ public bool? BeginAtZero { get; set; }
+
+ ///
+ /// Gets or sets the user defined minimum number for the scale, overrides minimum value from data.
+ /// As per documentation here (Chart.js).
+ ///
+ public double? Min { get; set; }
+
+ ///
+ /// Gets or sets the user defined maximum number for the scale, overrides minimum value from data.
+ /// As per documentation here (Chart.js).
+ ///
+ public double? Max { get; set; }
+
+ ///
+ /// Gets or sets the maximum number of ticks and gridlines to show.
+ ///
+ public int? MaxTicksLimit { get; set; }
+
+ ///
+ /// If defined and is not specified, the step size will be rounded to this many decimal places.
+ ///
+ public int? Precision { get; set; }
+
+ ///
+ /// Gets or sets the user defined fixed step size for the scale.
+ /// As per documentation here (Chart.js).
+ ///
+ public double? StepSize { get; set; }
+
+ ///
+ /// Gets or sets the adjustment used when calculating the maximum data value.
+ /// As per documentation here (Chart.js).
+ ///
+ public double? SuggestedMax { get; set; }
+
+ ///
+ /// Gets or sets the adjustment used when calculating the minimum data value.
+ /// As per documentation here (Chart.js).
+ ///
+ public double? SuggestedMin { get; set; }
+
+ ///
+ /// Gets or sets the value indicating whether a background is drawn behind the tick labels.
+ ///
+ public bool? ShowLabelBackdrop { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartLogarithmicTicks.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartLogarithmicTicks.cs
new file mode 100644
index 0000000000..0f794390c5
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartLogarithmicTicks.cs
@@ -0,0 +1,9 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The ticks-subconfig of . It has the same members as .
+/// As per documentation here (Chart.js).
+///
+public class BitChartLogarithmicTicks : BitChartCartesianTicks
+{
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartMajorTicks.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartMajorTicks.cs
new file mode 100644
index 0000000000..b9d6f3401d
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartMajorTicks.cs
@@ -0,0 +1,13 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The major ticks sub-config of the tick-configuration (see ).
+/// As per documentation here (Chart.js).
+///
+public class BitChartMajorTicks : BitChartSubTicks
+{
+ ///
+ /// Gets or sets the value indicating whether these options are used to show major ticks.
+ ///
+ public bool? Enabled { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartMinorTicks.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartMinorTicks.cs
new file mode 100644
index 0000000000..dee215992f
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartMinorTicks.cs
@@ -0,0 +1,9 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The minor ticks sub-config of the tick-configuration (see ).
+/// As per documentation here (Chart.js).
+///
+public class BitChartMinorTicks : BitChartSubTicks
+{
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartSubTicks.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartSubTicks.cs
new file mode 100644
index 0000000000..981f1b738f
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartSubTicks.cs
@@ -0,0 +1,34 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The ultimate base class for tick mark configurations.
+///
+public abstract class BitChartSubTicks
+{
+ ///
+ /// Gets or sets the font color for a tick's label.
+ /// See for working with colors.
+ ///
+ public string? FontColor { get; set; }
+
+ ///
+ /// Gets or sets the font family for a tick's label.
+ ///
+ public string? FontFamily { get; set; }
+
+ ///
+ /// Gets or sets the font size for a tick's label.
+ ///
+ public int? FontSize { get; set; }
+
+ ///
+ /// Gets or sets the font style for a tick's label.
+ ///
+ public BitChartFontStyle? FontStyle { get; set; }
+
+ ///
+ /// Gets or sets the height of an individual line of text.
+ /// As per documentation here (MDN).
+ ///
+ public double? LineHeight { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartTicks.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartTicks.cs
new file mode 100644
index 0000000000..1f03cc6762
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartTicks.cs
@@ -0,0 +1,46 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The base class for all tick mark configurations. Ticks-subconfig of the common .
+/// As per documentation here (Chart.js).
+///
+public abstract class BitChartTicks : BitChartSubTicks
+{
+ ///
+ /// Gets or sets the value indicating whether this axis displays tick marks.
+ ///
+ public bool? Display { get; set; }
+
+ ///
+ /// Gets or sets the value indicating whether the order of the tick labels is reversed.
+ ///
+ public bool? Reverse { get; set; }
+
+ ///
+ /// Gets or sets the minor ticks configuration. Omitted options are inherited.
+ ///
+ public BitChartMinorTicks? Minor { get; set; }
+
+ ///
+ /// Gets or sets the major ticks configuration. Omitted options are inherited.
+ ///
+ public BitChartMajorTicks? Major { get; set; }
+
+ ///
+ /// Gets or sets the offset of the tick labels from the axis. When set on a vertical axis, this applies in the horizontal (X) direction.
+ /// When set on a horizontal axis, this applies in the vertical (Y) direction.
+ ///
+ public int? Padding { get; set; }
+
+ ///
+ /// Gets or sets the Z-index of the tick layer. Useful when ticks are drawn on chart area. Values <= 0 are drawn under datasets, > 0 on top.
+ ///
+ public int? Z { get; set; }
+
+ ///
+ /// Gets or sets the callback to customize the string representation of the tick value as it should be displayed on the chart.
+ /// More on .
+ /// See and .
+ ///
+ public IBitChartMethodHandler? Callback { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartTimeTicks.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartTimeTicks.cs
new file mode 100644
index 0000000000..6465e5b444
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/Axes/Ticks/BitChartTimeTicks.cs
@@ -0,0 +1,12 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The ticks-subconfig of a .
+///
+public class BitChartTimeTicks : BitChartCartesianTicks
+{
+ ///
+ /// Gets or sets how ticks are generated.
+ ///
+ public BitChartTickSource? Source { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartAnimation.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartAnimation.cs
new file mode 100644
index 0000000000..930285c55d
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartAnimation.cs
@@ -0,0 +1,22 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The animation-subconfig of .
+/// Specifies options for the animations in this chart.
+///
+public class BitChartAnimation
+{
+ ///
+ /// Gets or sets the number of milliseconds an animation takes.
+ ///
+ public long? Duration { get; set; }
+
+ ///
+ /// Gets or sets the easing function to use.
+ /// See for reference.
+ ///
+ public BitChartEasing? Easing { get; set; }
+
+ // TODO OnProgress Callback called on each step of an animation.
+ // TODO OnComplete Callback called at the end of an animation.
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartArcAnimation.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartArcAnimation.cs
new file mode 100644
index 0000000000..18f26b40c3
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartArcAnimation.cs
@@ -0,0 +1,19 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The animation-subconfig of the options for a radial chart.
+///
+public class BitChartArcAnimation : BitChartAnimation
+{
+ ///
+ /// Gets or sets a value indicating whether the chart will
+ /// load in with a rotation animation or not.
+ ///
+ public bool? AnimateRotate { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the chart will
+ /// load in with a scaling animation (from the center outwards) or not.
+ ///
+ public bool? AnimateScale { get; set; }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartBaseConfigOptions.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartBaseConfigOptions.cs
new file mode 100644
index 0000000000..cab62794e2
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartBaseConfigOptions.cs
@@ -0,0 +1,96 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// The base config for the options-subconfig of a chart.
+///
+public class BitChartBaseConfigOptions
+{
+ ///
+ /// Gets or sets the title of this chart.
+ ///
+ public BitChartOptionsTitle? Title { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the chart canvas should be resized when its container is.
+ /// See important note: here (Chart.js).
+ ///
+ public bool? Responsive { get; set; }
+
+ ///
+ /// Gets or sets the canvas aspect ratio (i.e. width / height, a value of 1 representing a square canvas).
+ /// Note that this option is ignored if the height is explicitly defined either as attribute (of the canvas) or via the style.
+ ///
+ public double? AspectRatio { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether to maintain the original canvas aspect ratio (width / height) when resizing.
+ ///
+ public bool? MaintainAspectRatio { get; set; }
+
+ ///
+ /// Gets or sets the duration in milliseconds it takes to animate to new size after a resize event.
+ ///
+ public int? ResponsiveAnimationDuration { get; set; }
+
+ ///
+ /// Gets or sets the legend for this chart.
+ ///
+ public BitChartLegend? Legend { get; set; }
+
+ ///
+ /// Gets or sets the tooltip options for this chart.
+ ///
+ public BitChartTooltips? Tooltips { get; set; }
+
+ ///
+ /// Gets or sets the animation-configuration for this chart.
+ ///
+ public BitChartAnimation? Animation { get; set; }
+
+ ///
+ /// Gets the plugin options. The key has to be the unique
+ /// identification of the plugin.
+ ///
+ /// Reference for Chart.js plugin options:
+ ///
+ ///
+ ///
+ public Dictionary Plugins { get; } = [];
+
+ ///
+ /// Gets or sets the browser events that the chart should listen to for tooltips and hovering.
+ ///
+ /// If , this includes , ,
+ /// , and (by default).
+ ///
+ ///
+ public BitChartBrowserEvent[]? Events { get; set; }
+
+ ///
+ /// Gets or sets the callback to call when an event of type or
+ /// fires on the chart.
+ /// Called in the context of the chart and passed the event and an array of active elements.
+ /// See and .
+ ///
+ public IBitChartMethodHandler? OnClick { get; set; }
+
+ ///
+ /// Gets or sets the callback to call when any of the fire on the chart.
+ /// Called in the context of the chart and passed the event and an array of
+ /// active elements (bars, points, etc).
+ /// See and .
+ ///
+ public IBitChartMethodHandler? OnHover { get; set; }
+
+ ///
+ /// Gets or sets the hover configuration for this chart.
+ ///
+ public BitChartHover? Hover { get; set; }
+
+ ///
+ /// This method tells json.net to only serialize the plugin options when
+ /// there are plugin options, don't call it directly.
+ ///
+ [Obsolete("Only for json.net, don't call it.", true)]
+ public bool ShouldSerializePlugins() => Plugins.Count > 0;
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartChartData.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartChartData.cs
new file mode 100644
index 0000000000..a70e8b892d
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartChartData.cs
@@ -0,0 +1,57 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Represents the data-subconfig of any .
+///
+public class BitChartChartData
+{
+ ///
+ /// Creates a new instance of .
+ ///
+ public BitChartChartData()
+ {
+ Labels = [];
+ XLabels = [];
+ YLabels = [];
+ Datasets = [];
+ }
+
+ ///
+ /// Gets the labels the chart will use.
+ ///
+ /// If defined (1 or more labels) the corresponding axis has to be of type
+ /// for the chart to work correctly.
+ ///
+ ///
+ public virtual List Labels { get; }
+
+ ///
+ /// Gets the labels the horizontal axes will use.
+ ///
+ /// If defined (1 or more labels) the x-axis has to be of type
+ /// for the chart to work correctly.
+ ///
+ ///
+ public virtual List XLabels { get; }
+
+ ///
+ /// Gets the labels the vertical axes will use.
+ ///
+ /// If defined (1 or more labels) the y-axis has to be of type
+ /// for the chart to work correctly.
+ ///
+ ///
+ public virtual List YLabels { get; }
+
+ ///
+ /// Gets the datasets displayed in this chart.
+ ///
+ public List Datasets { get; }
+
+ [Obsolete("json.net", true)]
+ public bool ShouldSerializeLabels() => Labels?.Count > 0;
+ [Obsolete("json.net", true)]
+ public bool ShouldSerializeXLabels() => XLabels?.Count > 0;
+ [Obsolete("json.net", true)]
+ public bool ShouldSerializeYLabels() => YLabels?.Count > 0;
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartClipping.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartClipping.cs
new file mode 100644
index 0000000000..45ccc89400
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartClipping.cs
@@ -0,0 +1,190 @@
+using System.Diagnostics.CodeAnalysis;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Serialization;
+
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Represents how lines are clipped relative to the chart area.
+/// As per documentation here (Chart.js).
+/// For any given edge:
+///
+/// 0 means clipping at the chart area.
+/// negative values mean clipping inside the chart area.
+/// positive values mean clipping outside the chart area.
+/// means no clipping.
+///
+///
+///
+[JsonConverter(typeof(ClippingJsonConverter))]
+public readonly struct BitChartClipping : IEquatable
+{
+ internal readonly bool _equalSides;
+
+ ///
+ /// Gets the clipping for the top edge.
+ ///
+ public int? Top { get; }
+
+ ///
+ /// Gets the clipping for the right edge.
+ ///
+ public int? Right { get; }
+
+ ///
+ /// Gets the clipping for the bottom edge.
+ ///
+ public int? Bottom { get; }
+
+ ///
+ /// Gets the clipping for the left edge.
+ ///
+ public int? Left { get; }
+
+ ///
+ /// Creates a new instance of
+ /// using the supplied value for all edges.
+ ///
+ /// The clipping value for all edges.
+ public BitChartClipping(int all)
+ {
+ Top = Right = Bottom = Left = all;
+ _equalSides = true;
+ }
+
+ ///
+ /// Creates a new instance of
+ /// using individual values for all edges.
+ ///
+ /// The clipping value for the bottom edge.
+ /// The clipping value for the left edge.
+ /// The clipping value for the top edge.
+ /// The clipping value for the right edge.
+ public BitChartClipping(int? top = null, int? right = null, int? bottom = null, int? left = null)
+ {
+ Top = top;
+ Right = right;
+ Bottom = bottom;
+ Left = left;
+ _equalSides = false;
+ }
+
+ ///
+ /// Converts an value to a implicitly.
+ /// The supplied value will be used for all edges.
+ ///
+ /// The clipping value for all edges.
+ public static implicit operator BitChartClipping(int value) => new BitChartClipping(value);
+
+ ///
+ public override string ToString()
+ {
+ return $"{nameof(Top)}: {ValOrNull(Top)}, " +
+ $"{nameof(Right)}: {ValOrNull(Right)}, " +
+ $"{nameof(Bottom)}: {ValOrNull(Bottom)}, " +
+ $"{nameof(Left)}: {ValOrNull(Left)}";
+
+ static string ValOrNull(int? value) => value.HasValue ? value.Value.ToString() : "null";
+ }
+
+ public override bool Equals(object? obj) => obj is BitChartClipping clipping && Equals(clipping);
+
+ public bool Equals(BitChartClipping other)
+ {
+ if (_equalSides && other._equalSides) return Top == other.Top;
+
+ return Top == other.Top &&
+ Right == other.Right &&
+ Bottom == other.Bottom &&
+ Left == other.Left;
+ }
+
+ public override int GetHashCode() => HashCode.Combine(Bottom, Left, Top, Right);
+
+ public static bool operator ==(BitChartClipping left, BitChartClipping right) => left.Equals(right);
+ public static bool operator !=(BitChartClipping left, BitChartClipping right) => !(left == right);
+}
+
+internal class ClippingJsonConverter : JsonConverter
+{
+ public override BitChartClipping ReadJson(JsonReader reader, Type objectType, [AllowNull] BitChartClipping existingValue, bool hasExistingValue, JsonSerializer serializer)
+ {
+ if (reader.TokenType == JsonToken.Integer)
+ return new BitChartClipping((int?)(long?)reader.Value);
+
+ if (reader.TokenType != JsonToken.StartObject)
+ throw new JsonReaderException();
+
+ JObject obj = JObject.Load(reader);
+ int? top = GetClippingValue(obj, nameof(BitChartClipping.Top));
+ int? right = GetClippingValue(obj, nameof(BitChartClipping.Right));
+ int? bottom = GetClippingValue(obj, nameof(BitChartClipping.Bottom));
+ int? left = GetClippingValue(obj, nameof(BitChartClipping.Left));
+
+ return new BitChartClipping(top, right, bottom, left);
+ }
+
+ private static int? GetClippingValue(JObject obj, string name)
+ {
+ if (!obj.TryGetValue(name, StringComparison.OrdinalIgnoreCase, out JToken? token))
+ return null;
+
+ if (token.Type == JTokenType.Boolean && (bool)token is false)
+ return null;
+
+ if (token.Type == JTokenType.Integer)
+ return (int)token;
+
+ throw new JsonWriterException();
+ }
+
+ public override void WriteJson(JsonWriter writer, [AllowNull] BitChartClipping value, JsonSerializer serializer)
+ {
+ if (value._equalSides)
+ {
+ writer.WriteValue(value.Bottom!.Value);
+ return;
+ }
+
+ var naming = (serializer.ContractResolver as DefaultContractResolver)?.NamingStrategy;
+
+ writer.WriteStartObject();
+
+ WriteAdjustedName(writer, naming, nameof(BitChartClipping.Top));
+ WriteValueOrFalse(writer, value.Top);
+
+ WriteAdjustedName(writer, naming, nameof(BitChartClipping.Right));
+ WriteValueOrFalse(writer, value.Right);
+
+ WriteAdjustedName(writer, naming, nameof(BitChartClipping.Bottom));
+ WriteValueOrFalse(writer, value.Bottom);
+
+ WriteAdjustedName(writer, naming, nameof(BitChartClipping.Left));
+ WriteValueOrFalse(writer, value.Left);
+
+ writer.WriteEndObject();
+ }
+
+ private static void WriteAdjustedName(JsonWriter writer, NamingStrategy? namingStrategy, string name)
+ {
+ if (namingStrategy != null)
+ {
+ name = namingStrategy.GetPropertyName(name, false);
+ }
+
+ writer.WritePropertyName(name);
+ }
+
+ private static void WriteValueOrFalse(JsonWriter writer, int? value)
+ {
+ if (value.HasValue)
+ {
+ writer.WriteValue(value.Value);
+ }
+ else
+ {
+ writer.WriteValue(false);
+ }
+ }
+}
diff --git a/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartConfigBase.cs b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartConfigBase.cs
new file mode 100644
index 0000000000..4c16178c22
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI.Legacy/Components/Chart/Common/BitChartConfigBase.cs
@@ -0,0 +1,89 @@
+namespace Bit.BlazorUI.Legacy;
+
+///
+/// Base class for chart-configs
+/// Contains the most basic required information about a chart.
+///
+public abstract class BitChartConfigBase
+{
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The this config is for.
+ protected BitChartConfigBase(BitChartChartType chartType)
+ {
+ Type = chartType;
+ }
+
+ ///
+ /// Gets the type of chart this config is for.
+ ///
+ public BitChartChartType Type { get; }
+
+ ///
+ /// Gets the id for the html canvas element associated with this chart.
+ /// This property is initialized to a random GUID-string upon creation.
+ ///
+ public string CanvasId { get; } = Guid.NewGuid().ToString();
+
+ ///
+ /// Gets the list of inline plugins for this chart. Consider
+ /// registering global plugins (through JavaScript) or assigning the
+ /// plugins through JavaScript instead of using this property
+ /// since these plugins work mostly with method hooks and methods
+ /// can't be serialized. It could be supported, but just isn't yet.
+ ///
+ /// Reference for Chart.js inline plugins:
+ /// .
+ ///
+ ///
+ /// For configuring plugins (plugin options), you need to use
+ /// instead.
+ ///
+ ///
+ public List