WPF 绘制图表合集-LiveCharts

WPF 绘制图表 - LiveCharts 使用指南

LiveCharts 是一款功能强大且界面美观的 WPF 图表绘制类库,相比其他同类库,其 UI 风格更加多样、现代化,支持丰富的动画效果和交互功能。

以下是基于 LiveCharts 实现多种常用图表的详细示例。

准备工作

在使用 LiveCharts 前,需通过 NuGet 安装以下两个核心包:

bash 复制代码
Install-Package LiveCharts.Wpf
Install-Package LiveCharts

确保在 XAML 文件中添加命名空间引用:

xml 复制代码
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"

1、甘特图(Gantt Chart)

前台 View 代码

xml 复制代码
<lvc:CartesianChart Grid.Row="2" Zoom="None" Margin="0,40">
    <lvc:CartesianChart.AxisX>
        <lvc:Axis Style="{StaticResource FontChartAxis}"
                  LabelFormatter="{Binding Path=Formatter}"
                  MinValue="{Binding Path=From, Mode=TwoWay}" 
                  MaxValue="{Binding Path=To, Mode=TwoWay}">
            <lvc:Axis.Separator>
                <lvc:Separator Stroke="#33ffffff" StrokeDashArray="10"/>
            </lvc:Axis.Separator>
        </lvc:Axis>
    </lvc:CartesianChart.AxisX>
    <lvc:CartesianChart.AxisY>
        <lvc:Axis Style="{StaticResource FontChartAxis}"
                  Labels="{Binding Path=Labels}">
            <lvc:Axis.Separator>
                <lvc:Separator Stroke="#33ffffff" StrokeDashArray="10"/>
            </lvc:Axis.Separator>
        </lvc:Axis>
    </lvc:CartesianChart.AxisY>
    <lvc:CartesianChart.Series>
        <lvc:RowSeries Style="{StaticResource FontRowSeries}"
                       Fill="#008bd3" 
                       LabelsPosition="Parallel" 
                       DataLabels="True" 
                       Values="{Binding Path=Values}"/>
    </lvc:CartesianChart.Series>
</lvc:CartesianChart>

后台 ViewModel 代码

csharp 复制代码
private double _from;
private double _to;
private Func<double, string> _formatter;
private string[] _labels;
private ChartValues<GanttPoint> _values;

public double From { get => _from; set { _from = value; NotifyOfPropertyChange(() => From); } }
public double To { get => _to; set { _to = value; NotifyOfPropertyChange(() => To); } }
public Func<double, string> Formatter { get => _formatter; set { _formatter = value; NotifyOfPropertyChange(() => Formatter); } }
public string[] Labels { get => _labels; set { _labels = value; NotifyOfPropertyChange(() => Labels); } }
public ChartValues<GanttPoint> Values { get => _values; set { _values = value; NotifyOfPropertyChange(() => Values); } }

public void ShowGanttChart()
{
    var now = DateTime.Now;

    Values = new ChartValues<GanttPoint>
    {
        new GanttPoint(now.Ticks, now.AddSeconds(2).Ticks),
        new GanttPoint(now.AddSeconds(1).Ticks, now.AddSeconds(3).Ticks),
        new GanttPoint(now.AddSeconds(3).Ticks, now.AddSeconds(5).Ticks),
        new GanttPoint(now.AddSeconds(5).Ticks, now.AddSeconds(8).Ticks),
        new GanttPoint(now.AddSeconds(6).Ticks, now.AddSeconds(10).Ticks)
    };

    Formatter = value => new DateTime((long)value).ToString("MM-dd HH:mm:ss");

    Labels = new[]
    {
        "原材料出库", "智能装配", "个性化定制", "智能包装", "智能仓储"
    };

    From = Values.First().StartPoint;
    To = Values.Last().EndPoint;
}

说明GanttPoint 用于表示时间区间,X 轴为时间(以 Ticks 表示),Y 轴为任务名称。

2、进度环(Gauge Chart)

前台 View 代码

xml 复制代码
<lvc:Gauge Grid.Row="0" 
           GaugeBackground="#11ffffff" 
           HighFontSize="24"
           Uses360Mode="False" 
           From="0" To="100" 
           InnerRadius="35" 
           Value="{Binding OrderProgress}">
    <!-- 调整起始角度为顶部(0°),方向为逆时针 -->
    <lvc:Gauge.GaugeRenderTransform>
        <TransformGroup>
            <RotateTransform Angle="90"/>
            <ScaleTransform ScaleX="-1"/>
        </TransformGroup>
    </lvc:Gauge.GaugeRenderTransform>
    <!-- 设置渐变色填充 -->
    <lvc:Gauge.GaugeActiveFill>
        <LinearGradientBrush>
            <GradientStop Color="#539fff" Offset="0.0" />
            <GradientStop Color="#00eaff" Offset="0.5" />
            <GradientStop Color="#6af0ff" Offset="1.0" /> 
        </LinearGradientBrush>
    </lvc:Gauge.GaugeActiveFill>
</lvc:Gauge>

后台 ViewModel 代码

csharp 复制代码
private double _orderProgress;
public double OrderProgress 
{ 
    get => _orderProgress; 
    set { _orderProgress = value; NotifyOfPropertyChange(() => OrderProgress); } 
}

private void ShowGauge()
{
    OrderProgress = 90; // 设置进度为 90%
}

用途:常用于展示完成率、健康度、设备状态等指标。

3、柱状堆积图(Stacked Column Chart)

前台 View 代码

xml 复制代码
<lvc:CartesianChart Grid.Column="1" LegendLocation="Right" Margin="20,0">
    <lvc:CartesianChart.AxisX>
        <lvc:Axis Style="{StaticResource FontChartAxis}" 
                  Labels="{Binding Labels}" 
                  Title="时间">
            <lvc:Axis.Separator>
                <lvc:Separator Step="5" Stroke="#33ffffff" StrokeDashArray="10"/>
            </lvc:Axis.Separator>
        </lvc:Axis>
    </lvc:CartesianChart.AxisX>
    <lvc:CartesianChart.AxisY>
        <lvc:Axis Style="{StaticResource FontChartAxis}" Title="数量">
            <lvc:Axis.Separator>
                <lvc:Separator Stroke="#33ffffff" StrokeDashArray="10"/>
            </lvc:Axis.Separator>
        </lvc:Axis>
    </lvc:CartesianChart.AxisY>
    <lvc:CartesianChart.Series>
        <lvc:StackedColumnSeries Style="{StaticResource FontStackedColumnSeries}"
                                 Fill="#222222" 
                                 LabelsPosition="Merged" 
                                 MaxColumnWidth="20" 
                                 DataLabels="True"
                                 Values="{Binding V1}" 
                                 Title="黑色U盘"/>
        <lvc:StackedColumnSeries Style="{StaticResource FontStackedColumnSeries}"
                                 Fill="#26def2" 
                                 LabelsPosition="Merged" 
                                 MaxColumnWidth="20" 
                                 DataLabels="True"
                                 Values="{Binding V2}" 
                                 Title="蓝色U盘"/>
        <lvc:StackedColumnSeries Style="{StaticResource FontStackedColumnSeries}"
                                 Fill="#ee6363" 
                                 LabelsPosition="Merged" 
                                 MaxColumnWidth="20" 
                                 DataLabels="True"
                                 Values="{Binding V3}" 
                                 Title="红色U盘"/>
    </lvc:CartesianChart.Series>
    <lvc:CartesianChart.ChartLegend>
        <lvc:DefaultLegend BulletSize="12" Style="{StaticResource FontChartLegend}"/>
    </lvc:CartesianChart.ChartLegend>
</lvc:CartesianChart>

后台 ViewModel 代码

csharp 复制代码
private string[] _labels;
private IChartValues _v1, _v2, _v3;

public string[] Labels { get => _labels; set { _labels = value; NotifyOfPropertyChange(() => Labels); } }
public IChartValues V1 { get => _v1; set { _v1 = value; NotifyOfPropertyChange(() => V1); } }
public IChartValues V2 { get => _v2; set { _v2 = value; NotifyOfPropertyChange(() => V2); } }
public IChartValues V3 { get => _v3; set { _v3 = value; NotifyOfPropertyChange(() => V3); } }

private void ShowStackedColumn()
{
    V1 = new ChartValues<ObservableValue> { 5, 8, 2, 4, 6, 2, 9, 4, 6, 2, 9, 3 };
    V2 = new ChartValues<ObservableValue> { 5, 8, 2, 4, 6, 2, 9, 4, 6, 2, 9, 3 };
    V3 = new ChartValues<ObservableValue> { 5, 8, 2, 4, 6, 2, 9, 4, 6, 2, 9, 3 };

    Labels = new[] { "1月", "2月", "3月", "4月", "5月", "6月", 
                     "7月", "8月", "9月", "10月", "11月", "12月" };
}

特点:适用于展示多类别在不同时间段的总量构成。

4、饼状图(Pie Chart)

方式一:静态定义 Series

xml 复制代码
<lvc:PieChart Grid.Column="0" Margin="80,25" LegendLocation="Right" InnerRadius="35">
    <lvc:PieChart.Series>
        <lvc:PieSeries Style="{StaticResource FontPieSeries}" Fill="#222222" DataLabels="True" Values="4" Title="黑色U盘"/>
        <lvc:PieSeries Style="{StaticResource FontPieSeries}" Fill="#26def2" DataLabels="True" Values="5" Title="蓝色U盘"/>
        <lvc:PieSeries Style="{StaticResource FontPieSeries}" Fill="#ee6363" DataLabels="True" Values="6" Title="红色U盘"/>
    </lvc:PieChart.Series>
    <lvc:PieChart.ChartLegend>
        <lvc:DefaultLegend BulletSize="12" Style="{StaticResource FontChartLegend}"/>
    </lvc:PieChart.ChartLegend>
</lvc:PieChart>

方式二:动态绑定 Series(推荐)

前台代码
xml 复制代码
<lvc:PieChart Name="Chart" 
              Grid.Row="1" 
              Grid.Column="3" 
              Grid.ColumnSpan="4"
              Series="{Binding OrderCountSeries}" 
              Margin="0,0,35,0" 
              LegendLocation="Right" 
              InnerRadius="25">
    <lvc:PieChart.ChartLegend>
        <lvc:DefaultLegend BulletSize="18" Style="{StaticResource FontDefaultStyle}"/>
    </lvc:PieChart.ChartLegend>
</lvc:PieChart>
后台代码
csharp 复制代码
private SeriesCollection _orderCountSeries;
public SeriesCollection OrderCountSeries 
{ 
    get => _orderCountSeries; 
    set { _orderCountSeries = value; NotifyOfPropertyChange(() => OrderCountSeries); } 
}

public ObservableValue OrangeOrderCount { get; set; } = new ObservableValue();
public ObservableValue AppleOrderCount { get; set; } = new ObservableValue();
public ObservableValue PearOrderCount { get; set; } = new ObservableValue();

private void InitializeChartSeries()
{
    OrderCountSeries = new SeriesCollection
    {
        new PieSeries
        {
            Title = "橙    汁    Orange",
            Values = new ChartValues<ObservableValue> { new ObservableValue() },
            DataLabels = true,
            FontSize = 28
        },
        new PieSeries
        {
            Title = "苹果汁    Apple",
            Values = new ChartValues<ObservableValue> { new ObservableValue() },
            DataLabels = true,
            FontSize = 28
        },
        new PieSeries
        {
            Title = "梨    汁    Pear",
            Values = new ChartValues<ObservableValue> { new ObservableValue() },
            DataLabels = true,
            FontSize = 28
        }
    };
}

private void UpdateChartSeries()
{
    OrangeOrderCount.Value = TodaysFinishedOrderList?.FindAll(o => o.PRODUCT_CODE == (int)ItemType.Orange).Count ?? 0;
    AppleOrderCount.Value = TodaysFinishedOrderList?.FindAll(o => o.PRODUCT_CODE == (int)ItemType.Apple).Count ?? 0;
    PearOrderCount.Value = TodaysFinishedOrderList?.FindAll(o => o.PRODUCT_CODE == (int)ItemType.Pear).Count ?? 0;

    OrderCountSeries[0].Values[0] = OrangeOrderCount;
    OrderCountSeries[1].Values[0] = AppleOrderCount;
    OrderCountSeries[2].Values[0] = PearOrderCount;
}

优势:可动态更新数据,适合实时监控场景。

5、柱状图(Column Chart)

前台代码

xml 复制代码
<lvc:CartesianChart Margin="20,75,20,15">
    <lvc:CartesianChart.AxisX>
        <lvc:Axis Style="{StaticResource FontChartAxis}" 
                  FontSize="12" 
                  Labels="{Binding Path=StorageLabels}" 
                  Title="库位" 
                  LabelsRotation="20">
            <lvc:Axis.Separator>
                <lvc:Separator Step="1" IsEnabled="False"/>
            </lvc:Axis.Separator>
        </lvc:Axis>
    </lvc:CartesianChart.AxisX>
    <lvc:CartesianChart.AxisY>
        <lvc:Axis Style="{StaticResource FontChartAxis}" 
                  FontSize="12" 
                  Title="百分比" 
                  LabelFormatter="{Binding Path=AxisPercentage}">
            <lvc:Axis.Separator>
                <lvc:Separator Stroke="#33ffffff" StrokeDashArray="10"/>
            </lvc:Axis.Separator>
        </lvc:Axis>
    </lvc:CartesianChart.AxisY>
    <lvc:CartesianChart.Series>
        <lvc:ColumnSeries Style="{StaticResource FontColumnSeries}" 
                          Values="{Binding Path=StoragePercentages}"
                          DataLabels="True" 
                          LabelsPosition="Top"/>
    </lvc:CartesianChart.Series>
    <lvc:CartesianChart.ChartLegend>
        <lvc:DefaultLegend BulletSize="12" Style="{StaticResource FontChartLegend}"/>
    </lvc:CartesianChart.ChartLegend>
</lvc:CartesianChart>

后台代码

csharp 复制代码
private Func<double, string> _axisPercentage;
private string[] _storageLabels;
private IChartValues _storagePercentages;

public Func<double, string> AxisPercentage { get => _axisPercentage; set { _axisPercentage = value; NotifyOfPropertyChange(() => AxisPercentage); } }
public string[] StorageLabels { get => _storageLabels; set { _storageLabels = value; NotifyOfPropertyChange(() => StorageLabels); } }
public IChartValues StoragePercentages { get => _storagePercentages; set { _storagePercentages = value; NotifyOfPropertyChange(() => StoragePercentages); } }

private void ShowStoragePercentageColumnChart()
{
    StorageLabels = new[]
    {
        "单元一原料","单元一成品","单元二原料","单元二半成品",
        "单元三原料","单元三半成品","单元四原料","单元四半成品"
    };

    AxisPercentage = val => val.ToString("P"); // 百分比格式化
    StoragePercentages = new ChartValues<double> { 0.2, 0.5, 0.44, 0.88, 0.22, 0.6, 0.14, 0.09 };
}

6、折线图(Line Chart)

前台代码

xml 复制代码
<lvc:CartesianChart Grid.Column="2" LegendLocation="Right" Margin="15,0">
    <lvc:CartesianChart.AxisX>
        <lvc:Axis Style="{StaticResource FontChartAxis}" 
                  FontSize="12" 
                  Labels="{Binding Path=XTimeLabels}" 
                  Title="时间" 
                  LabelsRotation="40">
            <lvc:Axis.Separator>
                <lvc:Separator Step="1" IsEnabled="False"/>
            </lvc:Axis.Separator>
        </lvc:Axis>
    </lvc:CartesianChart.AxisX>
    <lvc:CartesianChart.AxisY>
        <lvc:Axis Style="{StaticResource FontChartAxis}" 
                  FontSize="12" 
                  Title="百分比" 
                  LabelFormatter="{Binding Path=YPercentageFormat}">
            <lvc:Axis.Separator>
                <lvc:Separator Stroke="#33ffffff" StrokeDashArray="10"/>
            </lvc:Axis.Separator>
        </lvc:Axis>
    </lvc:CartesianChart.AxisY>
    <lvc:CartesianChart.Series>
        <lvc:LineSeries Values="{Binding OccupancyRatesCell1}" 
                        PointGeometrySize="2" 
                        Stroke="#00f5ff" 
                        Fill="#1100f5ff" 
                        LineSmoothness="0" 
                        Title="一单元"/>
        <lvc:LineSeries Values="{Binding OccupancyRatesCell2}" 
                        PointGeometrySize="2" 
                        Stroke="#ccffcc" 
                        Fill="#11ccffcc" 
                        LineSmoothness="0" 
                        Title="二单元"/>
        <lvc:LineSeries Values="{Binding OccupancyRatesCell3}" 
                        PointGeometrySize="2" 
                        Stroke="#333399" 
                        Fill="#11333399" 
                        LineSmoothness="0" 
                        Title="三单元"/>
        <lvc:LineSeries Values="{Binding OccupancyRatesCell4}" 
                        PointGeometrySize="2" 
                        Stroke="#9966cc" 
                        Fill="#119966cc" 
                        LineSmoothness="0" 
                        Title="四单元"/>
    </lvc:CartesianChart.Series>
    <lvc:CartesianChart.ChartLegend>
        <lvc:DefaultLegend BulletSize="12" Style="{StaticResource FontChartLegend}"/>
    </lvc:CartesianChart.ChartLegend>
</lvc:CartesianChart>

后台代码

csharp 复制代码
private string[] _xTimeLabels;
private Func<double, string> _yPercentageFormat;
private ChartValues<double> _occupancyRatesCell1, _occupancyRatesCell2, 
                           _occupancyRatesCell3, _occupancyRatesCell4;

public string[] XTimeLabels { get => _xTimeLabels; set { _xTimeLabels = value; NotifyOfPropertyChange(() => XTimeLabels); } }
public Func<double, string> YPercentageFormat { get => _yPercentageFormat; set { _yPercentageFormat = value; NotifyOfPropertyChange(() => YPercentageFormat); } }
public ChartValues<double> OccupancyRatesCell1 { get => _occupancyRatesCell1; set { _occupancyRatesCell1 = value; NotifyOfPropertyChange(() => OccupancyRatesCell1); } }
public ChartValues<double> OccupancyRatesCell2 { get => _occupancyRatesCell2; set { _occupancyRatesCell2 = value; NotifyOfPropertyChange(() => OccupancyRatesCell2); } }
public ChartValues<double> OccupancyRatesCell3 { get => _occupancyRatesCell3; set { _occupancyRatesCell3 = value; NotifyOfPropertyChange(() => OccupancyRatesCell3); } }
public ChartValues<double> OccupancyRatesCell4 { get => _occupancyRatesCell4; set { _occupancyRatesCell4 = value; NotifyOfPropertyChange(() => OccupancyRatesCell4); } }

private void InitOccupancyRate()
{
    YPercentageFormat = value => value.ToString("P0"); // 整数百分比
    XTimeLabels = new[] { "08:00", "09:00", "10:00", "11:00", "12:00", 
                          "13:00", "14:00", "15:00", "16:00", "17:00" };

    OccupancyRatesCell1 = new ChartValues<double> { 0.75, 0.87, 0.82, 0.69, 0.73, 
                                                    0.71, 0.80, 0.85, 0.88, 0.79 };
    OccupancyRatesCell2 = new ChartValues<double> { 0.84, 0.77, 0.66, 0.74, 0.83, 
                                                    0.79, 0.75, 0.79, 0.84, 0.86 };
    OccupancyRatesCell3 = new ChartValues<double> { 0.87, 0.85, 0.77, 0.88, 0.69, 
                                                    0.82, 0.77, 0.78, 0.73, 0.84 };
    OccupancyRatesCell4 = new ChartValues<double> { 0.81, 0.76, 0.78, 0.80, 0.64, 
                                                    0.85, 0.83, 0.68, 0.78, 0.82 };
}

7、样式定义(Styles.xaml)

统一图表字体、颜色等视觉风格:

xml 复制代码
<!-- LiveCharts 文字样式 -->
<Style x:Key="FontChartAxis" TargetType="{x:Type lvc:Axis}">
    <Setter Property="HorizontalAlignment" Value="Center"/>
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="FontFamily" Value="Microsoft Yahei"/>
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="Foreground" Value="White"/>
</Style>

<Style x:Key="FontStackedColumnSeries" TargetType="{x:Type lvc:StackedColumnSeries}">
    <Setter Property="FontFamily" Value="Microsoft Yahei"/>
    <Setter Property="FontSize" Value="10"/>
    <Setter Property="Foreground" Value="White"/>
</Style>

<Style x:Key="FontColumnSeries" TargetType="{x:Type lvc:ColumnSeries}">
    <Setter Property="FontFamily" Value="Microsoft Yahei"/>
    <Setter Property="FontSize" Value="10"/>
    <Setter Property="Foreground" Value="White"/>
</Style>

<Style x:Key="FontChartLegend" TargetType="{x:Type lvc:DefaultLegend}">
    <Setter Property="FontFamily" Value="Microsoft Yahei"/>
    <Setter Property="FontSize" Value="12"/>
    <Setter Property="Foreground" Value="White"/>
</Style>

<Style x:Key="FontRowSeries" TargetType="{x:Type lvc:RowSeries}">
    <Setter Property="FontFamily" Value="Microsoft Yahei"/>
    <Setter Property="FontSize" Value="9"/>
    <Setter Property="Foreground" Value="White"/>
</Style>

<Style x:Key="FontPieSeries" TargetType="{x:Type lvc:PieSeries}">
    <Setter Property="FontFamily" Value="Microsoft Yahei"/>
    <Setter Property="FontSize" Value="24"/>
    <Setter Property="Foreground" Value="White"/>
</Style>

将此资源字典合并到 App.xaml 或用户控件中以全局使用。

总结

LiveCharts 提供了简洁的 API 和强大的数据绑定能力,结合 MVVM 模式可轻松实现动态、响应式的数据可视化。以上示例涵盖了工业、仓储、订单统计等常见业务场景,开发者可根据需求灵活调整样式与数据逻辑。

提示

  • 使用 ObservableValue 可实现数据变更自动刷新图表。

  • 支持鼠标悬停提示、动画过渡、缩放等功能。

  • 推荐使用深色背景搭配高对比度颜色提升可读性。

如需更多高级功能(如实时数据流、自定义几何图形),可查阅 LiveCharts 官方文档

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

来源:cnblogs.com/gnielee/archive/2010/08/02/wpf-cpu-usage.html

相关推荐
qq_124987075321 小时前
基于springboot的疾病预防系统的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·毕业设计
q***2511 天前
Spring Boot 集成 Kettle
java·spring boot·后端
时光追逐者1 天前
C#/.NET/.NET Core技术前沿周刊 | 第 62 期(2025年11.17-11.23)
c#·.net·.netcore
司铭鸿1 天前
祖先关系的数学重构:从家谱到算法的思维跃迁
开发语言·数据结构·人工智能·算法·重构·c#·哈希算法
码事漫谈1 天前
阿里《灵光》生成的视频下载不带水印的极简方法
后端
舒一笑1 天前
信息的建筑学:MyBatis Log Panda 如何重构开发者的认知地图
后端·sql·intellij idea
码事漫谈1 天前
WPF入门指南:解析默认项目结构
后端
iOS开发上架哦1 天前
7种常见的源代码混淆技术详解:网络安全中的重要防线
后端
回家路上绕了弯1 天前
单体架构拆微服务:从评估到落地的全流程指南
后端·微服务
疯狂的程序猴1 天前
手游频繁崩溃闪退原因分析与iOS崩溃日志解析方法
后端