WPF中輕鬆生成動態圖表:例項詳解(MVVM模式)

架构师老卢發表於2024-04-30
WPF中輕鬆生成動態圖表:例項詳解(MVVM模式)

概述:本文程式碼示例演示瞭如何在WPF中使用LiveCharts庫建立動態條形圖。透過建立資料模型、ViewModel和在XAML中使用`CartesianChart`控制元件,你可以輕鬆實現圖表的資料繫結和動態更新。我將透過清晰的步驟指南包括詳細的中文註釋,幫助你快速理解並應用這一功能。

先上效果:

WPF中輕鬆生成動態圖表:例項詳解(MVVM模式)

在WPF中使用LiveCharts生成動態的條形圖表需要以下步驟。以下是詳細的例項原始碼:

步驟 1: 引用LiveCharts庫

首先,在專案中引用LiveCharts庫。你可以透過NuGet包管理器來安裝LiveCharts.Wpf:

Install-Package LiveCharts.Wpf

步驟 2: 建立WPF專案

建立一個新的WPF專案,確保已經在XAML檔案中引用了LiveCharts的名稱空間:

xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"

步驟 3: 建立資料模型

建立一個資料模型,用於儲存條形圖的資料:

// BarChartData.cs
public class BarChartData
{
    public string Category { get; set; }
    public double Value { get; set; }
}

步驟 4: 建立ViewModel

建立一個ViewModel類,用於處理圖表的資料和邏輯。在這個類中,你將生成資料並將其繫結到圖表控制元件:

public partial class ViewModel : ViewModelBase
{
    private readonly Random _r = new();
    private static readonly (string, double)[] s_initialData =
    {
        ("上海", 500),
        ("北京", 450),
        ("深圳", 520),
        ("廣州", 550),
        ("重慶", 660),
        ("天津", 920),
        ("成都", 1000)
    };

    [ObservableProperty]
    private ISeries[] _series =
        s_initialData
            .Select(x => new RowSeries<ObservableValue>
            {
                Values = new[] { new ObservableValue(x.Item2) },
                Name = x.Item1,
                Stroke = null,
                MaxBarWidth = 25,
                DataLabelsPaint = new SolidColorPaint(new SKColor(245, 245, 245)),
                DataLabelsPosition = DataLabelsPosition.End,
                DataLabelsTranslate = new LvcPoint(-1, 0),
                DataLabelsFormatter = point => $"{point.Context.Series.Name} {point.PrimaryValue}"
            })
            .OrderByDescending(x => ((ObservableValue[])x.Values!)[0].Value)
            .ToArray();

    [ObservableProperty]
    private Axis[] _xAxes = { new Axis { SeparatorsPaint = new SolidColorPaint(new SKColor(220, 220, 220)) } };

    [ObservableProperty]
    private Axis[] _yAxes = { new Axis { IsVisible = false } };

    /// <summary>
    /// 動態修改資料,實際專案中讀取真實資料
    /// </summary>
    public void RandomIncrement()
    {
        foreach (var item in Series)
        {
            if (item.Values is null) continue;

            var i = ((ObservableValue[])item.Values)[0];
            i.Value += _r.Next(0, 100);
        }
        //對新資料重新排序
        Series = Series.OrderByDescending(x => ((ObservableValue[])x.Values!)[0].Value).ToArray();
    }
}

步驟 5: 在XAML中使用圖表控制元件

在XAML中使用LiveCharts的 CartesianChart 控制元件來顯示條形圖:

<!-- MainWindow.xaml -->
<Window x:Class="Sample_Charts_Bars.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
        xmlns:local="clr-namespace:Sample_Charts_Bars"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <lvc:CartesianChart Title="{Binding Title}" 
            Series="{Binding Series}"
            XAxes="{Binding XAxes}"
            YAxes="{Binding YAxes}"
            TooltipPosition="Hidden">
        </lvc:CartesianChart>
    </Grid>
</Window>

步驟 6: 在MainWindow中設定DataContext

在MainWindow.xaml.cs中設定ViewModel的DataContext,以便資料繫結:

// MainWindow.xaml.cs
using System.Windows;

namespace YourNamespace
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Update();
        }

        public async void Update()
        {
            var vm = (ViewModel)DataContext;
            while (true)
            {
                //更新資料
                Application.Current.Dispatcher.Invoke(vm.RandomIncrement);
                await Task.Delay(100);
            }
        }
    }
}

需要檢視更多例項請關注我,後面將逐個釋出。

原始碼獲取:https://pan.baidu.com/s/1EtHg5dvB7ZEQDI9Y3VICpw?pwd=6666

相關文章