diff --git a/examples/Console/Charts/Program.cs b/examples/Console/Charts/Program.cs
index c44554b..229047f 100644
--- a/examples/Console/Charts/Program.cs
+++ b/examples/Console/Charts/Program.cs
@@ -19,10 +19,10 @@ namespace Charts
// Render a breakdown chart
AnsiConsole.WriteLine();
- Render("Languages", new BreakdownChart()
+ Render("Languages used", new BreakdownChart()
.FullSize()
.Width(60)
- .TagValueFormat("{0}%")
+ .ShowPercentage()
.AddItem("SCSS", 37, Color.Red)
.AddItem("HTML", 28.3, Color.Blue)
.AddItem("C#", 22.6, Color.Green)
diff --git a/src/Spectre.Console.Tests/Unit/BreakdownChartTests.cs b/src/Spectre.Console.Tests/Unit/BreakdownChartTests.cs
index 160b1af..b16991b 100644
--- a/src/Spectre.Console.Tests/Unit/BreakdownChartTests.cs
+++ b/src/Spectre.Console.Tests/Unit/BreakdownChartTests.cs
@@ -42,14 +42,14 @@ namespace Spectre.Console.Tests.Unit
[Fact]
[Expectation("TagFormat")]
- public async Task Should_Render_Correctly_With_Specific_Tag_Formatter()
+ public async Task Should_Render_Correctly_With_Specific_Value_Formatter()
{
// Given
var console = new FakeConsole(width: 80);
var chart = Fixture.GetChart()
.Width(60)
.Culture("sv-SE")
- .TagValueFormat("{0}%");
+ .UseValueFormatter((v, c) => string.Format(c, "{0}%", v));
// When
console.Render(chart);
diff --git a/src/Spectre.Console/Extensions/BreakdownChartExtensions.cs b/src/Spectre.Console/Extensions/BreakdownChartExtensions.cs
index 5c7a2e1..e19bb43 100644
--- a/src/Spectre.Console/Extensions/BreakdownChartExtensions.cs
+++ b/src/Spectre.Console/Extensions/BreakdownChartExtensions.cs
@@ -141,16 +141,53 @@ namespace Spectre.Console
/// Tags will be shown.
///
/// The breakdown chart.
- /// The tag value format.
+ /// The value formatter to use.
/// The same instance so that multiple calls can be chained.
- public static BreakdownChart TagValueFormat(this BreakdownChart chart, string? format)
+ public static BreakdownChart UseValueFormatter(this BreakdownChart chart, Func? func)
{
if (chart is null)
{
throw new ArgumentNullException(nameof(chart));
}
- chart.TagValueFormat = format;
+ chart.ValueFormatter = func;
+ return chart;
+ }
+
+ ///
+ /// Tags will be shown.
+ ///
+ /// The breakdown chart.
+ /// The value formatter to use.
+ /// The same instance so that multiple calls can be chained.
+ public static BreakdownChart UseValueFormatter(this BreakdownChart chart, Func? func)
+ {
+ if (chart is null)
+ {
+ throw new ArgumentNullException(nameof(chart));
+ }
+
+ chart.ValueFormatter = func != null
+ ? (value, _) => func(value)
+ : null;
+
+ return chart;
+ }
+
+ ///
+ /// Tags will be shown.
+ ///
+ /// The breakdown chart.
+ /// The same instance so that multiple calls can be chained.
+ public static BreakdownChart ShowPercentage(this BreakdownChart chart)
+ {
+ if (chart is null)
+ {
+ throw new ArgumentNullException(nameof(chart));
+ }
+
+ chart.ValueFormatter = (value, culture) => string.Format(culture, "{0}%", value);
+
return chart;
}
diff --git a/src/Spectre.Console/Widgets/Charts/BreakdownChart.cs b/src/Spectre.Console/Widgets/Charts/BreakdownChart.cs
index 74f972f..b7b6708 100644
--- a/src/Spectre.Console/Widgets/Charts/BreakdownChart.cs
+++ b/src/Spectre.Console/Widgets/Charts/BreakdownChart.cs
@@ -31,9 +31,9 @@ namespace Spectre.Console
public bool ShowTagValues { get; set; } = true;
///
- /// Gets or sets the tag value format.
+ /// Gets or sets the tag value formatter.
///
- public string? TagValueFormat { get; set; }
+ public Func? ValueFormatter { get; set; }
///
/// Gets or sets a value indicating whether or not the
@@ -91,7 +91,7 @@ namespace Spectre.Console
Width = width,
Culture = Culture,
ShowTagValues = ShowTagValues,
- TagValueFormat = TagValueFormat,
+ ValueFormatter = ValueFormatter,
});
}
diff --git a/src/Spectre.Console/Widgets/Charts/BreakdownTags.cs b/src/Spectre.Console/Widgets/Charts/BreakdownTags.cs
index cec47f9..9fc5fcd 100644
--- a/src/Spectre.Console/Widgets/Charts/BreakdownTags.cs
+++ b/src/Spectre.Console/Widgets/Charts/BreakdownTags.cs
@@ -12,7 +12,7 @@ namespace Spectre.Console
public int? Width { get; set; }
public CultureInfo? Culture { get; set; }
public bool ShowTagValues { get; set; } = true;
- public string? TagValueFormat { get; set; }
+ public Func? ValueFormatter { get; set; }
public BreakdownTags(List data)
{
@@ -56,16 +56,21 @@ namespace Spectre.Console
private string FormatValue(IBreakdownChartItem item, CultureInfo culture)
{
- var formatter = TagValueFormat ?? "{0}";
+ var formatter = ValueFormatter ?? DefaultFormatter;
if (ShowTagValues)
{
return string.Format(culture, "{0} [grey]{1}[/]",
item.Label.EscapeMarkup(),
- string.Format(culture, formatter, item.Value));
+ formatter(item.Value, culture));
}
return item.Label.EscapeMarkup();
}
+
+ private static string DefaultFormatter(double value, CultureInfo culture)
+ {
+ return value.ToString(culture);
+ }
}
}
diff --git a/src/Spectre.Console/Widgets/ProgressBar.cs b/src/Spectre.Console/Widgets/ProgressBar.cs
index f54cb2a..0021b1b 100644
--- a/src/Spectre.Console/Widgets/ProgressBar.cs
+++ b/src/Spectre.Console/Widgets/ProgressBar.cs
@@ -44,6 +44,11 @@ namespace Spectre.Console
bars = Math.Max(0, bars);
}
+ if (bars < 0)
+ {
+ yield break;
+ }
+
yield return new Segment(new string(token, bars), style);
if (ShowValue)