☰
LiveCharts2 仪表盘(Gauge)实战指南:用 PieChart 与 GaugeGenerator 构建实心/角度仪表
2026/10/12 1:44:54 网站建设 项目流程
  • 数据可视化
  • 图表库
  • 跨平台

【免费下载链接】LiveCharts2

Beautiful, interactive charts, maps, and gauges. One API for every .NET UI framework.

项目地址:https://gitcode.com/gh_mirrors/li/LiveCharts2
点击查看免费下载

LiveCharts2 没有单独的仪表盘控件,而是让PieChart同时承载饼图、环形图与仪表盘三种形态,其中仪表盘由GaugeGenerator辅助类基于GaugeItem自动生成PieSeries<ObservableValue>系列集合。本文将以 docs/piechart/gauges.md 为骨架,结合仓库源码与示例,讲解GaugeItem的 value/builder 两个核心参数、GaugeItem.Background背景系列机制、BuildSolidGauge与BuildAngularGaugeSections两种构建方式,以及InitialRotation、MaxAngle、MinValue/MaxValue等配套属性。读完本文,你将能够在任意 .NET UI 框架(WPF、Avalonia、WinForms、MAUI、Blazor、Uno 等)中用同一套代码快速搭建实心仪表、多段仪表、动态仪表和带指针刻度的角度仪表。

仪表盘的定位:PieChart 的第三种形态

在 LiveCharts2 中,仪表盘并非独立图表类型,而是PieChart控件在特定配置下的渲染结果。其架构可概括为三层:

  1. 控件层:PieChart提供InitialRotation、MaxAngle、MinValue、MaxValue、LegendPosition等图表级属性;
  2. 辅助层:GaugeGenerator静态类根据传入的GaugeItem列表,生成一组带仪表盘语义的PieSeries<ObservableValue>;
  3. 系列层:每个GaugeItem对应一个扇形/环形分段,最终由PieChartEngine统一完成测量与绘制。

文档明确指出"you can also create gauges with thePieChartcontrol",从源码看,GaugeGenerator生成的就是可被普通饼图画布直接渲染的饼图系列(见 GaugeGenerator.cs),它"reuses all the power and functionality of thePieChartEngineclass",因此仪表盘天然继承了饼图的动画、主题、数据标签、图例与悬停等全部能力。

GaugeItem:仪表盘的构建单元

GaugeItem是描述仪表盘中一个元素的载体,位于 GaugeItem.cs,继承自泛型基类BaseGaugeItem<PieSeries<ObservableValue>>。其构造函数接收两个参数:

参数类型说明
valuedouble(或ObservableValue)该分段在仪表盘上的数值
builderAction<PieSeries<ObservableValue>>?委托,用于配置该数值对应的系列,可设置颜色、数据标签大小,以及普通饼图系列(pieseries.md)支持的一切属性

value参数有两种重载:直接传double,或传ObservableValue。后者的价值在于动态更新——ObservableValue实现了值变更通知,修改其Value后图表会自动重绘并播放过渡动画(详见下文的 Gauge5 示例)。

builder参数是可选的(默认为null),但它是仪表盘定制的核心入口。在委托内你可以像操作普通PieSeries<ObservableValue>一样设置Fill(颜色)、Stroke、DataLabelsSize、DataLabelsPosition、DataLabelsFormatter、InnerRadius、RelativeInnerRadius、RelativeOuterRadius、MaxRadialColumnWidth、Name(图例名称)等属性。

实心仪表盘:BuildSolidGauge

GaugeGenerator.BuildSolidGauge(params GaugeItem[] items)是构建实心仪表盘(Solid Gauge,即环形/半环形仪表)的入口,源码见 GaugeGenerator.cs。

单值仪表:最小示例

最简单的情形是只传入一个GaugeItem。仓库示例 Gauge1/View.cs 展示了完整用法:

pieChart = new PieChart { Series = GaugeGenerator.BuildSolidGauge( new GaugeItem( 30, // the gauge value series => // the series style { series.MaxRadialColumnWidth = 50; series.DataLabelsSize = 50; })), InitialRotation = -90, MinValue = 0, MaxValue = 100, ... };

这里value = 30表示当前读数,MinValue = 0、MaxValue = 100划定量程;InitialRotation = -90让仪表从顶部(12 点方向)开始绘制;MaxRadialColumnWidth = 50限制环的径向厚度,DataLabelsSize = 50放大中心读数。WPF/XAML 场景下有对应的XamlGaugeSeries声明式写法(见 Gauge1/View.xaml)。

多值仪表:堆叠分段

传入多个GaugeItem时,各分段会在同一环上按值占比依次排布,形成"分段式"仪表。例如 Gauge4/View.cs 用三个数值 50 / 80 / 95 构建了三段仪表,并分别为每段命名:

Series = GaugeGenerator.BuildSolidGauge( new GaugeItem(50, series => SetStyle("Vanessa", series)), new GaugeItem(80, series => SetStyle("Charles", series)), new GaugeItem(95, series => SetStyle("Ana", series)), new GaugeItem(GaugeItem.Background, series => series.Fill = null)), InitialRotation = -90, MaxAngle = 350, MinValue = 0, MaxValue = 100, public static void SetStyle(string name, PieSeries<ObservableValue> series) { series.Name = name; series.DataLabelsSize = 20; series.DataLabelsPosition = PolarLabelsPosition.End; series.DataLabelsFormatter = point => point.Coordinate.PrimaryValue.ToString(); series.InnerRadius = 20; series.MaxRadialColumnWidth = 5; }

注意这里每个分段的InnerRadius = 20、MaxRadialColumnWidth = 5保持径向厚度一致,多段叠加后自然形成并列的同心环带;DataLabelsPosition = PolarLabelsPosition.End把数值标签放在环带末端。MaxAngle = 350则让仪表留出 10° 的缺口而非画满整圈。多值仪表盘效果可参考 gauge4/result.png。

动态仪表:ObservableValue 驱动

如果希望仪表读数实时变化,应使用ObservableValue重载并持有其引用,之后修改值即可触发自动重绘。示例 Gauge5/View.cs 的核心逻辑:

var observableValue1 = new ObservableValue { Value = 50 }; var observableValue2 = new ObservableValue { Value = 80 }; pieChart = new PieChart { Series = GaugeGenerator.BuildSolidGauge( new GaugeItem(observableValue1, series => { series.Name = "North"; series.DataLabelsPosition = PolarLabelsPosition.Start; }), new GaugeItem(observableValue2, series => { series.Name = "South"; series.DataLabelsPosition = PolarLabelsPosition.Start; })), InitialRotation = -90, MaxAngle = 270, MinValue = 0, MaxValue = 100, LegendPosition = LegendPosition.Bottom }; // 点击按钮后更新读数,图表自动动画过渡 observableValue1.Value = _random.Next(0, 100); observableValue2.Value = _random.Next(0, 100);

这段代码还展示了仪表盘与图例的配合:为每个GaugeItem设置series.Name后,LegendPosition = LegendPosition.Bottom即可显示图例。

背景系列:GaugeItem.Background 的机制

仪表盘通常需要一段"底色"来衬托当前读数。文档指出,将GaugeItem.Background作为value传入GaugeItem,会生成一个位于所有仪表分段之后的系列,充当图表的背景。

从源码看,GaugeItem.Background是定义在 BaseGaugeItem.cs 上的常量double.MaxValue;构造函数检测到该值时会把IsFillSeriesBuilder置为true,从而在GaugeGenerator.Build中被路由到背景系列(GaugeGenerator.cs)。生成的背景系列具有这些特征:

  • ZIndex = -1:始终垫底;
  • IsFillSeries = true:标记为填充系列;
  • IsVisibleAtLegend = false:不出现在图例中;
  • Values填充items.Length - 1个零值,用于撑起完整的背景环。

示例 Gauge2/View.cs 演示了背景系列的标准用法:

Series = GaugeGenerator.BuildSolidGauge( new GaugeItem(30, series => { series.Fill = new SolidColorPaint(SKColors.YellowGreen); series.DataLabelsSize = 50; series.DataLabelsPaint = new SolidColorPaint(SKColors.Red); series.DataLabelsPosition = PolarLabelsPosition.ChartCenter; series.InnerRadius = 75; }), new GaugeItem(GaugeItem.Background, series => { series.InnerRadius = 75; series.Fill = new SolidColorPaint(new SKColor(100, 181, 246, 90)); // 半透明蓝 })), InitialRotation = -225, MaxAngle = 270, MinValue = 0, MaxValue = 100,

这里前景段与背景段都设置InnerRadius = 75,保证两者径向对齐;背景用带透明度的SKColor(100, 181, 246, 90)填充,形成浅色轨道。若不需要背景(如 Gauge4 中令series.Fill = null),也能得到纯环效果。完整效果见 gauge2/result.png。

另一个细节:GaugeGenerator.BuildSolidGauge在入参中没有显式传入背景项时会自动补一个默认背景(GaugeGenerator.cs),这与文档中"there is a special value to customize the background series"的表述一致——不传GaugeItem.Background也能渲染仪表,但传入后才能自定义背景样式。

角度仪表盘:BuildAngularGaugeSections

除实心仪表外,GaugeGenerator还提供BuildAngularGaugeSections(params GaugeItem[] items),用于构建角度仪表(Angular Gauge,即扇形刻度仪表),源码见 GaugeGenerator.cs。

角度仪表与实心仪表在系列构造上的差异体现在PieChartExtensions.AsSeries内部(PieChartExtensions.cs):

  • Solid 模式:每个系列的Values中填充count - 1个占位(null/default)元素,再把真实值插入到与分段序号一致的位置,从而让多个分段共享同一圆环;
  • Angular 模式:每个系列只含自身一个值,且额外设置HoverPushout = 0、IsHoverable = false、DataLabelsPaint = null、AnimationsSpeed = 0,并开启IsRelativeToMinValue = true——分段从MinValue起算而不是从 0 起算,这是角度仪表刻度语义的关键。

角度仪表通常还要叠加指针(Needle)与刻度(Ticks)两个视觉元素。示例 AngularGauge/View.cs 与对应的 Blazor 版本 View.razor 完整演示了这套组合:

var sectionsOuter = 130; var sectionsWidth = 20; var needle = new NeedleVisual { Value = 45 }; pieChart = new PieChart { Series = GaugeGenerator.BuildAngularGaugeSections( new GaugeItem(60, s => SetStyle(sectionsOuter, sectionsWidth, s)), new GaugeItem(30, s => SetStyle(sectionsOuter, sectionsWidth, s)), new GaugeItem(10, s => SetStyle(sectionsOuter, sectionsWidth, s))), VisualElements = [ new AngularTicksVisual { Labeler = value => value.ToString("N1"), LabelsSize = 16, LabelsOuterOffset = 15, OuterOffset = 65, TicksLength = 20 }, needle ], InitialRotation = -225, MaxAngle = 270, MinValue = 0, MaxValue = 100 }; private static void SetStyle( double sectionsOuter, double sectionsWidth, PieSeries<ObservableValue> series) { series.OuterRadiusOffset = sectionsOuter; series.MaxRadialColumnWidth = sectionsWidth; series.CornerRadius = 0; }
  • 三个GaugeItem(60 / 30 / 10)定义三段刻度区段,OuterRadiusOffset = 130控制区段离外缘的距离,MaxRadialColumnWidth = 20控制区段厚度,CornerRadius = 0关闭圆角以获得规整的刻度条;
  • AngularTicksVisual负责刻度线与刻度标签,Labeler可自定义标签格式(如"N1"保留一位小数),TicksLength控制主刻度线长度;
  • NeedleVisual是指针,修改其Value即可驱动指针旋转,例如点击按钮后needle.Value = _random.Next(0, 100)。

动态效果可参考 angularGauge/result.gif。

配套属性:InitialRotation、MaxAngle 与量程

仪表盘的形态控制依赖PieChart的三个图表级属性,其语义在 docs/piechart/overview.md 中有详细图解:

属性默认值作用仪表盘常用值
InitialRotation0第一段绘制的起始角度(度)-90(顶部起始)、-225(左下起始)、45等
MaxAngle360整个图表覆盖的角度(度)270(四分之三圆)、350(留缺口)
MinValue/MaxValue—量程下限 / 上限仪表场景通常设为0/100

例如InitialRotation = -225+MaxAngle = 270组合出左下开口的标准 270° 仪表(Gauge2、AngularGauge 示例);InitialRotation = 45+MaxAngle = 270则生成右下开口的形态(Gauge3/View.cs)。这些属性变更会被 LiveCharts2 的动画系统自动补间过渡。此外GaugeItem的RelativeInnerRadius/RelativeOuterRadius(相对半径,随控件尺寸缩放)与InnerRadius(像素半径)配合,可让分段在环带上"错落分层",例如 Gauge/ViewModel.cs 中的多段仪表。

源码级验证:测试与 XAML 等价实现

仓库为仪表盘提供了可验证的实现证据:

  • 快照测试:tests/SnapshotTests/AngularGaugeTests.cs 用BuildAngularGaugeSections+AngularTicksVisual+NeedleVisual构建 600×600 的SKPieChart,断言渲染结果与基线快照一致,其中AngularGaugeAtMinValue用例还专门验证了MinValue边界下刻度透明度规则;
  • XAML 声明式等价物:在 XAML 框架(WPF/Avalonia/WinUI 等)中,GaugeGenerator的产物对应XamlGaugeSeries、XamlGaugeBackgroundSeries、XamlAngularGaugeSeries三个封装类(src/skiasharp/_Shared.Xaml/Series.cs)。其中XamlGaugeSeries通过GaugeValue依赖属性绑定到内部ObservableValue,值变更经OnGaugeValueChanged自动同步;背景系列复用同一套SetupBackgroundGaugeSeries逻辑。因此 Gauge1/View.xaml 可以用纯 XAML 等价实现:
<lvc:PieChart InitialRotation="-90" MinValue="0" MaxValue="100"> <lvc:PieChart.Series> <lvc:SeriesCollection> <lvc:XamlGaugeSeries GaugeValue="{Binding Value}" DataLabelsSize="50" MaxRadialColumnWidth="50"/> <!-- The background series is used to style the gauge background. --> <lvc:XamlGaugeBackgroundSeries/> </lvc:SeriesCollection> </lvc:PieChart.Series> </lvc:PieChart>

小结

LiveCharts2 的仪表盘能力可归纳为一条主线:GaugeGenerator(构建)→GaugeItem(元素定义)→PieSeries<ObservableValue>(渲染)。BuildSolidGauge负责环形分段式实心仪表,BuildAngularGaugeSections负责带指针/刻度的角度仪表,二者都可通过GaugeItem.Background定制背景轨道,通过 value/builder 双参数完成数值绑定与样式定制;ObservableValue重载则让仪表支持运行时动态更新。所有能力复用了PieChartEngine的渲染管线,因此动画、主题、图例与跨框架一致性均由 LiveCharts2 统一保证。

  • 数据可视化
  • 图表库
  • 跨平台

【免费下载链接】LiveCharts2

Beautiful, interactive charts, maps, and gauges. One API for every .NET UI framework.

项目地址:https://gitcode.com/gh_mirrors/li/LiveCharts2
点击查看免费下载

相关推荐

上一篇:Claude Coder 成功案例分享:从咖啡店网站到企业级应用的完整实现
下一篇:10个@alifd/next常见问题解决方案:开发中的坑与填坑指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询