BlazorBasics.Charts
1.3.19
dotnet add package BlazorBasics.Charts --version 1.3.19
NuGet\Install-Package BlazorBasics.Charts -Version 1.3.19
<PackageReference Include="BlazorBasics.Charts" Version="1.3.19" />
<PackageVersion Include="BlazorBasics.Charts" Version="1.3.19" />
<PackageReference Include="BlazorBasics.Charts" />
paket add BlazorBasics.Charts --version 1.3.19
#r "nuget: BlazorBasics.Charts, 1.3.19"
#:package BlazorBasics.Charts@1.3.19
#addin nuget:?package=BlazorBasics.Charts&version=1.3.19
#tool nuget:?package=BlazorBasics.Charts&version=1.3.19
Description
Create charts simples from data. You can create a Pie Chart, Columns Chart, Bar Chart or Stacked Bar Chart.
How to use simple way
Import the name space adding to _Imports.razor this line:
@using BlazorBasics.Charts
Pie Chart
Example about Pie Chart. Values can't be more than 100% about total values.
<PieChartComponent DataSource=GetPieSegments />
@code {
Task<IReadOnlyList<ChartSegment>> GetPieSegments()
{
IReadOnlyList<ChartSegment> segments = new();
...
return Task.FromResult(segments);
}
}
Also you can set some parameters
public class PieChartParams
{
public PieChartParams(int width = 150, int height = 150,
double saturation = 100.0, double luminosity = 50.0,
int separationOffset = 15, int separationOnSelectOffset = 15,
double delayTime = 0, string title = "",
IEnumerable<ChartColor> chartColours = null,
bool showLabels = false, double centerTextSeparationPercentage = 0.85,
bool separateBiggerByDefault = true, bool showBiggestLabel = false,
bool showLegend = true)
{
Width = width;
Height = height;
Saturation = saturation;
Luminosity = luminosity;
SeparationOffset = separationOffset;
SeparationOnSelectOffset = separationOnSelectOffset;
DelayTime = delayTime;
Title = title;
ChartColors = new(chartColours ?? ChartColourHelper
.InitializeColours(256, separationOffset));
ShowLabels = showLabels;
CenterTextSeparationPercentage = centerTextSeparationPercentage;
SeparateBiggerByDefault = separateBiggerByDefault;
ShowBiggestLabel = showBiggestLabel;
ShowLegend = showLegend;
}
public int Width { get; init; }
public int Height { get; init; }
public double Saturation { get; init; }
public double Luminosity { get; init; }
public double DelayTime { get; init; }
public int SeparationOffset { get; init; }
public int SeparationOnSelectOffset { get; init; }
public string Title { get; set; }
public List<ChartColor> ChartColors { get; set; }
public int MaxColours => ChartColors.Count;
public bool ShowLabels { get; set; }
public double CenterTextSeparationPercentage { get; set; }
public bool SeparateBiggerByDefault { get; init; }
public bool ShowBiggestLabel { get; set; }
public bool ShowLegend { get; set; }
}
Then you can do
<PieChartComponent DataSource=GetPieSegments Parameters=PieParams />
@code {
PieChartParams PieParams = new PieChartParams(title: "Totals");
Task<IReadOnlyList<ChartSegment>> GetPieSegments()
{
IReadOnlyList<ChartSegment> segments = new();
...
return Task.FromResult(segments);
}
}
Column or Bar Chart
Example about Column or Bar Chart.
<ColumnChartComponent Topics=Totals />
@code {
IEnumerable<ChartSegment> Totals;
protected override void OnInitialized()
{
Totals =
[
new ChartSegment
{
Value = "1",
Name = "Total Requests"
},
...
];
}
}
Also you can set some parameters
public class ColumnsBarChartParams
{
public const double VERTICAL_LABEL_ANGLE = -90;
public ColumnsBarChartParams(
string backgroundColour = "#D3D3D3",
int thickness = 20,
int dimension = 100,
bool showValues = false,
IEnumerable<ChartColor> chartColours = null,
int gap = 5,
int maxWidth = 600,
bool rotatedLabels = false,
double labelRotationAngle = VERTICAL_LABEL_ANGLE,
int labelFontSize = 12,
ColumnLabelPlacement? labelPlacement = null,
ColumnFillReference fillReference = ColumnFillReference.HighestValue)
{
BackgroundColour = backgroundColour;
Thickness = thickness;
Dimension = dimension;
MaxWidth = maxWidth;
ShowValues = showValues;
Gap = gap;
ChartColors = new(chartColours ?? ChartColourHelper
.InitializeColours(256, 30));
MaxWidth = maxWidth;
RotatedLabels = rotatedLabels;
LabelRotationAngle = labelRotationAngle;
LabelFontSize = labelFontSize;
LabelPlacement = labelPlacement;
FillReference = fillReference;
}
public string BackgroundColour { get; init; }
public int Thickness { get; init; }
public int Dimension { get; init; }
public int MaxWidth { get; init; }
public int Gap { get; init; }
public bool ShowValues { get; init; }
public bool RotatedLabels { get; init; }
public double LabelRotationAngle { get; init; }
public int LabelFontSize { get; init; }
public ColumnLabelPlacement? LabelPlacement { get; init; }
public ColumnFillReference FillReference { get; init; }
public List<ChartColor> ChartColors { get; set; }
public int MaxColours => ChartColors.Count;
}
Then you can do
<BarChartComponent Topics=Totals Parameters=BarParams />
@code {
ColumnsBarChartParams BarParams = new ColumnsBarChartParams();
IEnumerable<ChartSegment> Totals;
protected override void OnInitialized()
{
Totals =
[
new ChartSegment
{
Value = "1",
Name = "Total Requests"
},
...
];
}
}
How much of the column or bar gets filled
FillReference decides what a completely filled shape means.
public enum ColumnFillReference
{
HighestValue, // default
TotalOfAllValues
}
HighestValue: the biggest value fills its shape completely and every other one is drawn against it. Use it to compare the values with each other. The empty part means nothing.TotalOfAllValues: the values are added together and each one fills its own share of that total, so a value worth a fifth of everything fills a fifth of its shape. Use it to read each value as part of the whole. The empty part is what the other values take.
TotalOfAllValues reads much better on BarChartComponent than on ColumnChartComponent, because a bar spreads the share along the whole width while a column only has its height, and a flat set of values leaves every column looking almost empty.
<BarChartComponent Topics=Totals Parameters=BarParams />
@code {
ColumnsBarChartParams BarParams =
new(fillReference: ColumnFillReference.TotalOfAllValues);
}
Where the labels go
LabelPlacement moves the label of every column or bar.
public enum ColumnLabelPlacement
{
Bottom,
Top,
Left,
Right
}
Left null, each chart keeps the placement it has always had: Bottom for ColumnChartComponent with horizontal labels, Left for ColumnChartComponent once the labels are rotated, and Right for BarChartComponent.
On ColumnChartComponent:
BottomandTopwrite the label outside the plotting area and the chart grows as much as the longest label needs, so nothing is ever cut.LeftandRightrun the label alongside its own column. The room a label has becomes the height of the chart instead of the width of the slot, so it is only shortened with an ellipsis when it does not fit in that height. This is the placement to use when the names are longer than the columns are wide.
On BarChartComponent:
Rightcloses every row with its label, andLeftreserves a column on the left and moves the bars across.TopandBottomgive the label a line of its own above or below its bar, with the full width to itself, so long names never need shortening. The rows grow to make room for it.
Vertical labels on a column chart
RotatedLabels turns the labels of ColumnChartComponent by LabelRotationAngle. Negative angles read from bottom to top, positive ones from top to bottom, and ColumnsBarChartParams.VERTICAL_LABEL_ANGLE (-90) is fully vertical. LabelFontSize sets their size, in both charts.
<ColumnChartComponent Topics=Totals Parameters=ColumnParams />
@code {
ColumnsBarChartParams ColumnParams =
new(thickness: 34, dimension: 240, rotatedLabels: true);
}
The rotation is only applied by ColumnChartComponent; on a horizontal bar chart it would not help, so BarChartComponent ignores it and uses LabelPlacement alone.
Stacked Bar Chart
Draws every value as a slice of one single bar, so what is read is the share each value takes of the whole rather than how the values compare to each other. It is the data of a pie chart drawn as a bar.
<StackedBarChartComponent Topics=Totals />
@code {
IEnumerable<ChartSegment> Totals;
protected override void OnInitialized()
{
Totals =
[
new ChartSegment { Name = "Tagum", Value = 1204 },
new ChartSegment { Name = "Asuncion", Value = 486 },
...
];
}
}
Also you can set some parameters
public class StackedBarChartParams
{
public StackedBarChartParams(
StackedBarOrientation orientation = StackedBarOrientation.Horizontal,
int thickness = 40,
int length = 600,
string backgroundColour = "#D3D3D3",
IEnumerable<ChartColor> chartColours = null,
bool showValues = false,
StackedBarLabelSide labelSide = StackedBarLabelSide.After,
StackedBarLabelAlignment labelAlignment = StackedBarLabelAlignment.Start,
int labelFontSize = 12,
double minimumLabelShare = 0.03,
double total = 0)
public StackedBarOrientation Orientation { get; init; }
public int Thickness { get; init; }
public int Length { get; init; }
public string BackgroundColour { get; init; }
public bool ShowValues { get; init; }
public StackedBarLabelSide LabelSide { get; init; }
public StackedBarLabelAlignment LabelAlignment { get; init; }
public int LabelFontSize { get; init; }
public double MinimumLabelShare { get; init; }
public double Total { get; init; }
public List<ChartColor> ChartColors { get; set; }
public int MaxColours => ChartColors.Count;
}
public enum StackedBarOrientation
{
Vertical, // one column, stacked from the top downwards
Horizontal // one bar, stacked from left to right
}
public enum StackedBarLabelSide
{
Before, // left of a vertical bar, above a horizontal one
After, // right of a vertical bar, below a horizontal one
Inside // over its own segment, in the contrasting colour of the segment
}
public enum StackedBarLabelAlignment
{
Start,
Middle,
End
}
Thicknessis how wide a vertical bar is, or how tall a horizontal one is.Lengthis how long it runs in the direction it stacks in.- The labels turn with the orientation and that is not configurable: they read horizontally beside a vertical bar and vertically above or below a horizontal one, which is the only way round they can be read in each case.
LabelSideandLabelAlignmentthen work the same in both. MinimumLabelShareleaves out the label of any segment smaller than that share of the whole, given as a fraction, because there is no room to write one without it landing on its neighbours. The room reserved for the labels is measured only over the ones that are actually drawn, so leaving the small ones out also makes the chart smaller. Set it to zero to label every segment.ShowValueswrites the value across the middle of its own segment, in the contrasting colour, and only when the segment is long enough to hold it. It is ignored when the names already goInside, so the two never collide.Totalis what the complete bar is worth. Left at zero the values are added together and the bar is always full; set to a known total, whatever the values do not account for stays as unfilled bar inBackgroundColour.
<StackedBarChartComponent Topics=Totals Parameters=StackedParams />
@code {
StackedBarChartParams StackedParams = new(
StackedBarOrientation.Vertical,
thickness: 46,
length: 320,
showValues: true,
labelSide: StackedBarLabelSide.After,
labelAlignment: StackedBarLabelAlignment.Start);
}
The chart asks for its own size, which for a vertical bar is narrow and tall. Its wrapper carries the stacked-bar-chart class plus is-vertical or is-horizontal, so stretching it, or leaving it alone, is up to the css of the page:
.my-card ::deep .stacked-bar-chart.is-horizontal svg { width: 100%; height: auto; }
.my-card ::deep .stacked-bar-chart.is-vertical svg { width: auto; max-width: 100%; }
Personalize Charts
All chart automatic set the colours depending in how many items have the data. But also you can personalize colours in the charts using the property ChartColours.
@code {
ColumnsBarChartParams BarParams = new ColumnsBarChartParams();
List<ChartColor> ChartColours =
[
new("#2E3092"),
new("#00AEEF"),
new("#EDF5FF"),
new("#2E78E8"),
new("#0C5FBA"),
new("#D1E7FF"),
new("#03B15E"),
new("#E6FFEA"),
new("#CEEED3"),
new("#F98316"),
new("#FFF2DA"),
new("#FFD8B1"),
new("#D94D4D"),
new("#FFE7E7"),
new("#FFCFCF")
];
protected override void OnInitialized()
{
BarParams = new ColumnsBarChartParams(chartColours: ChartColours);
// or BarParams.ChartColors = ChartColours;
}
}
This is aplicable for Pie Chart, Column Chart, Bar Chart and Stacked Bar Chart. Color can be rgb(0,0,0), HEX #000000 or hsl(1,80,40).
A ChartColor can also be given the colour of the text written over it, which is what the Stacked Bar Chart uses for the labels and values it writes inside a segment. With one colour only, the contrasting one is worked out for you.
new ChartColor("#2E3092", "#FFFFFF") // background and text over it
new ChartColor("#2E3092") // text colour worked out from the background
Line Chart
Example about Line Chart.
<LineChartComponent Data=ChartData ParsingCulture=CultureInfo.InvariantCulture/>
@code {
private LineChartData ChartData = new(new List<LineData>
{
new LineData("Line 1", "green", new List<string> { "10", "50", "15", "100", "20", "30", "25" }),
new LineData("Line 2", "blue", new List<string> { "0", "5", "50", "33", "33", "8", "12" }),
new LineData("Line 3", "red", new List<string> { "5", "50", "10", "33", "8", "12", "15" })
});
}
Example about Line Chart with event.
<LineChartComponent Data=ChartData OnLoading=CharLoading ParsingCulture=CultureInfo.InvariantCulture />
@code {
private LineChartData ChartData = new(new List<LineData>
{
new LineData("Line 1", "green", new List<string> { "10", "50", "15", "100", "20", "30", "25" }),
new LineData("Line 2", "blue", new List<string> { "0", "5", "50", "33", "33", "8", "12" }),
new LineData("Line 3", "red", new List<string> { "5", "50", "10", "33", "8", "12", "15" })
});
bool IsChartLoading;
void CharLoading(bool state)
{
IsChartLoading = state;
}
}
Also you can set some parameters
public class LineChartParams(
int width = 600,
int height = 300,
string backgroundColor = "transparent",
string axisStroke = "black",
int axisWidth = 2,
string gridLineStroke = "black",
int gridWidth = 1,
string lineSeriesFill = "none",
int lineSeriesWidth = 1,
int dotRadius = 4,
int stepsY = 3,
bool showX = true,
bool showY = true,
bool showLegend = true,
bool rotatedXLabels = false,
double rotationAngleXLabel = 45,
Func<string, string> formatterLabelPopup = null,
Func<LineData, string> legendLabel = null,
LineChartPointOptions pointOptions = null,
int maxPointPerLine = 50,
bool showLoading = true,
bool showXLines = true,
bool showYLines = true
)
{
public int Width => width;
public int Height => height;
public string BackgroundColor => backgroundColor;
public string AxisStroke => axisStroke;
public int AxisWidth => axisWidth;
public string GridLineStroke => gridLineStroke;
public int GridWidth => gridWidth;
public string LineSeriesFill => lineSeriesFill;
public int LineSeriesWidth => lineSeriesWidth;
public int DotRadius => dotRadius;
public int StepsY => stepsY;
public bool ShowX => showX;
public bool ShowY => showY;
public bool ShowLegend => showLegend;
public bool RotatedXLabels => rotatedXLabels;
public double RotationAngleXLabel
{
get
{
if (rotationAngleXLabel < 0)
throw new ArgumentException($"Must be positive", nameof(RotationAngleXLabel));
if (rotationAngleXLabel > 90)
throw new ArgumentException($"Must be less than 90", nameof(RotationAngleXLabel));
return rotationAngleXLabel;
}
}
public Func<string, string> FormatterLabelPopup => formatterLabelPopup;
public Func<LineData, string> LegendLabel => legendLabel;
public LineChartPointOptions PointOptions { get; } = pointOptions ?? new LineChartPointOptions();
public int MaxPointPerLine => maxPointPerLine;
public bool ShowLoading => showLoading;
public bool ShowYLines => showYLines;
public bool ShowXLines => showXLines;
}
public class LineChartPointOptions(
bool visibleAllPoints = false,
bool visibleMaxPoint = true,
bool visibleMinPoint = true,
bool visibleMaxPointLine = false,
bool visibleMinPointLine = false
)
{
public bool VisibleAllPoints => visibleAllPoints;
public bool VisibleMaxPoint => visibleMaxPoint;
public bool VisibleMinPoint => visibleMinPoint;
public bool VisibleMaxPointLine => visibleMaxPointLine;
public bool VisibleMinPointLine => visibleMinPointLine;
}
Then you can do
<LineChartComponent Data=ChartData Params=LineParams ParsingCulture=CultureInfo.InvariantCulture />
@code {
LineChartParams LineParams = new LineChartParams();
private LineChartData ChartData = new(new List<LineData>
{
new LineData("Line 1", "green", new List<string> { "10", "50", "15", "100", "20", "30", "25" }),
new LineData("Line 2", "blue", new List<string> { "0", "5", "50", "33", "33", "8", "12" }),
new LineData("Line 3", "red", new List<string> { "5", "50", "10", "33", "8", "12", "15" })
});
protected override void OnInitialized()
{
LineParams= new(formaterLabelPopup: GetSelectedPointLabelMarkup);
}
private string GetSelectedPointLabelMarkup(string value)
{
StringBuilder builder = new StringBuilder();
builder.Append("<div style='");
builder.Append("pointer-events: none;");
builder.Append("background-color: blue;");
builder.Append("box-shadow: 0 2px 6px rgba(0,0,0,0.2);");
builder.Append("padding: 6px 12px;");
builder.Append("border-radius: 6px;");
builder.Append("text-align: center;");
builder.Append("'>");
builder.Append($"<strong style='");
builder.Append("color: white;");
builder.Append("font-size: medium;");
builder.Append("font-weight: bold;");
builder.Append($"'>");
builder.Append($"{value}");
builder.Append($"</strong>");
builder.Append("</div>");
return builder.ToString();
}
}
- RotationAngleXLabel must be between 0 and 90 degress to keep good view. Paramter outside will generate an ArgumentException.
Ring Percentage
Example about Line Chart.
<RingPercentageComponent Percentage=69 />
Also you can set some parameters
public class RingParams
{
public int Width { get; init; }
public int Height { get; init; }
public double FontSizeRatio { get; init; }
public string LabelColor { get; init; }
public string FromColor { get; init; }
public string ToColor { get; init; }
public string CircunferenceColour { get; init; }
public int StrokeWidth { get; init; }
public RingParams(int width = 0, int height = 0, double fontPerspective = 3.5, string labelColor = "green",
string fromColor = "#FFD700", string toColor = "#B22222", string circunferenceColour = "#eee", int strokeWidth = 10)
{
Width = width;
Height = height;
FontSizeRatio = fontPerspective;
LabelColor = labelColor;
FromColor = fromColor;
ToColor = toColor;
CircunferenceColour = circunferenceColour;
StrokeWidth = strokeWidth;
}
}
Then you can do
<RingPercentageComponent Percentage=33 Parameters="new RingParams(width: 100)" />
Column with lines
Example about ColumnWithLine Chart.
<ColumnWithLineChartComponent Data=ChartData />
@code {
private ColumnWithLineChartData ChartData = new(new List<ColumnDataItem>
{
new("ENE",200000,184615) ,
new("",0,0) { Label = "FEB", PrimaryValue = 300000, SecondaryValue = 245454 },
new("",0,0) { Label = "MAR", PrimaryValue = 400000, SecondaryValue = 289655 },
new("",0,0) { Label = "ABR", PrimaryValue = 500000, SecondaryValue = 319672 },
new("",0,0) { Label = "MAY", PrimaryValue = 600000, SecondaryValue = 452830 },
new("",0,0) { Label = "JUN", PrimaryValue = 700000, SecondaryValue = 466666 },
})
{
PrimaryLegend = "Active Users",
SecondaryLegend = "Non Active Users",
Title = "Total users"
};
}
Also you can set some parameters
public class ColumnWithLineChartParams
{
public int Width { get; set; } = 800;
public int Height { get; set; } = 500;
public string BackgroundColor { get; set; } = "transparent";
public int BarWidth { get; set; } = 15;
public int MinBarHeight { get; set; } = 150;
public int Spacing { get; set; } = 15;
public string PrimaryColor { get; set; } = "#4e79a7";
public string SecondaryColor { get; set; } = "#f28e2b";
public string GrandTotalLineColor { get; set; } = "#e15759";
public string PrimaryPercentageLineColor { get; set; } = "#59a84b";
public string SecondaryPercentageLineColor { get; set; } = "#ed49ff";
public bool ShowTitle { get; set; } = true;
public bool ShowLegend { get; set; } = true;
public bool ShowGranTotal { get; set; } = true;
public bool ShowPrimaryValues { get; set; } = true;
public bool ShowSecondaryValues { get; set; } = false;
public Func<ColumnDataItem, string> BigTotalValueLabelFormatter { get; set; }
public Func<ColumnDataItem, string> PrimaryValueLabelFormatter { get; set; }
public Func<ColumnDataItem, string> SecondaryValueLabelFormatter { get; set; }
public Func<ColumnDataItem, string> BottomLabelFormatter { get; set; }
public Func<ColumnDataItem, string> TooltipFormatter { get; set; }
}
Then you can do
<ColumnWithLineChartComponent Data=ChartData Parameters=WithLineChartParams />
@code {
ColumnWithLineChartParams WithLineChartParams = new();
protected override void OnInitialized()
{
WithLineChartParams.PrimaryColor = "green";
WithLineChartParams.SecondaryColor = "blue";
}
private ColumnWithLineChartData ChartData = new(new List<ColumnDataItem>
{
new("ENE",200000,184615) ,
new("",0,0) { Label = "FEB", PrimaryValue = 300000, SecondaryValue = 245454 },
new("",0,0) { Label = "MAR", PrimaryValue = 400000, SecondaryValue = 289655 },
new("",0,0) { Label = "ABR", PrimaryValue = 500000, SecondaryValue = 319672 },
new("",0,0) { Label = "MAY", PrimaryValue = 600000, SecondaryValue = 452830 },
new("",0,0) { Label = "JUN", PrimaryValue = 700000, SecondaryValue = 466666 },
})
{
PrimaryLegend = "Active Users",
SecondaryLegend = "Non Active Users",
Title = "Total users"
};
}
Reacting to what the user clicks
Every chart made of parts tells you which one was clicked, so the page around it can react. The callback of each chart carries the type that chart works with, and nothing happens at all when no handler is given.
| Chart | Callback | What it carries | What is clickable |
|---|---|---|---|
PieChartComponent |
OnClick |
ChartSegment |
The slice and its entry in the legend |
ColumnChartComponent |
OnClick |
ChartSegment |
The column, the empty part of it and its label |
BarChartComponent |
OnClick |
ChartSegment |
The bar, the empty part of its row and its label |
StackedBarChartComponent |
OnClick |
ChartSegment |
Each segment and its label |
LineChartComponent |
OnPointClick |
LineChartPoint |
Every dot drawn, the highest and lowest ones included |
LineChartComponent |
OnLegendClick |
LineData |
Each series in the legend |
ColumnWithLineChartComponent |
OnItemClick |
ColumnDataItem |
The columns and the points of the lines |
ColumnWithLineChartComponent |
OnPointClick |
ColumnWithLinePoint |
The points of the lines, saying which line |
<BarChartComponent Topics=Totals OnClick=Selected />
<StackedBarChartComponent Topics=Totals OnClick=Selected />
<LineChartComponent Data=ChartData OnPointClick=PointSelected OnLegendClick=SeriesSelected />
@code {
void Selected(ChartSegment segment)
{
// segment.Name, segment.Value, segment.ChartColor ...
}
void PointSelected(LineChartPoint point)
{
// point.SeriesName, point.Index, point.Value, point.Label
}
void SeriesSelected(LineData series)
{
// series.Name and every value of that line
}
}
The empty part of a column or of a bar answers the click with the same value as the filled part, so a small value is as easy to hit as a big one.
The charts that select something of their own keep doing it: the line chart still opens its popup on a point and still isolates a series from the legend, and the callback is raised as well as that, not instead of it.
public class LineChartPoint
{
public string SeriesName { get; }
public string Colour { get; }
public int Index { get; } // position in the series, counting from zero
public string Value { get; } // the value as it was given, before being parsed
public string Label { get; } // the X axis label at that position, when there is one
}
A point of a ColumnWithLineChartComponent raises both of its callbacks, OnItemClick first and then OnPointClick; a column raises only the first. The points of the lines are drawn, and can therefore be clicked, only when ShowGranTotal, ShowPrimaryValues or ShowSecondaryValues are on, each one bringing its own line.
public class ColumnWithLinePoint
{
public ColumnDataItem Item { get; }
public int Index { get; } // position in the data, counting from zero
public ColumnWithLineSeries Series { get; } // GrandTotal, Primary or Secondary
public string Percentage { get; } // what the chart writes over that point
}
RingPercentageComponent has no callback: it is one whole ring, there are no parts to tell apart.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (git checkout -b feature/AmazingFeature)
- Commit your changes (git commit -m 'Add some AmazingFeature')
- Push to the branch (git push origin feature/AmazingFeature)
- Open a Pull Request
License
This project is licensed under the MIT License.
Acknowledgments
- Built with love for the Blazor community
- Inspired by the need for simple, effective dashboard components
- Thanks to all contributors and users
Made with love by DrUalcman
If you find this component useful, please consider giving it a star on GitHub!
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.AspNetCore.Components.Web (>= 10.0.11)
-
net8.0
- Microsoft.AspNetCore.Components.Web (>= 8.0.30)
-
net9.0
- Microsoft.AspNetCore.Components.Web (>= 9.0.19)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.3.19 | 208 | 9/1/2026 |
| 1.2.17 | 576 | 11/2/2025 |
| 1.2.16 | 246 | 10/22/2025 |
| 1.2.15 | 270 | 10/2/2025 |
| 1.2.14 | 276 | 9/23/2025 |
| 1.2.13 | 312 | 8/30/2025 |
| 1.2.12 | 449 | 7/21/2025 |
| 1.2.11 | 278 | 7/7/2025 |
| 1.1.10 | 437 | 6/11/2025 |
| 1.1.9 | 281 | 6/2/2025 |
| 1.1.8 | 281 | 4/2/2025 |
| 1.1.7 | 257 | 3/21/2025 |
| 1.1.6 | 252 | 3/14/2025 |
| 1.1.5 | 299 | 3/12/2025 |
| 1.1.4 | 294 | 11/18/2024 |
| 1.0.3 | 261 | 10/15/2024 |
| 1.0.2 | 254 | 10/13/2024 |
| 1.0.1 | 225 | 10/10/2024 |
| 1.0.0 | 225 | 10/10/2024 |
Click callbacks on the Column, Bar, StackedBar and Line charts, and on the points of the lines of the ColumnWithLine chart, carrying the value behind whatever was clicked. New StackedBarChartComponent, one single bar split into the share every value takes of the whole, in either orientation. Column and Bar charts take a ColumnFillReference to fill against the highest value or against the total, and a ColumnLabelPlacement to put the labels at the bottom, top, left or right. Column chart labels can be rotated, and their font size is configurable. Existing charts keep their previous look.