WPF實現(xiàn)曲線數(shù)據(jù)展示
wpf實現(xiàn)曲線數(shù)據(jù)展示,函數(shù)曲線展示,實例:震動數(shù)據(jù)分析為例。
如上圖所示,如果你想實現(xiàn)上圖中的效果,請詳細(xì)參考我的內(nèi)容。
一共有兩種方式來實現(xiàn),一種是使用第三方的框架來實現(xiàn),另外一種是自己通過原創(chuàng)代碼來一步步實現(xiàn),本文主要介紹這兩種曲線的實現(xiàn)方式。
1.首先我創(chuàng)建一個wpf的解決方案項目。
2.在NuGet中添加 DynamicDataDisplay 項目支持
為了展示我們的UI界面,我們還添加了一個第三方的樣式框架 Panuon.UI.Silver
3.我們在MainWindow.xaml文件中添加如下代碼
<d3:ChartPlotter x:Name="plotter"> <d3:Header x:Name="HeaderTitle" Visibility="Visible" Content="這是曲線的標(biāo)題" FontSize="14" HorizontalAlignment="Center" /> <d3:VerticalAxisTitle Content="Value" FontSize="14" Visibility="Collapsed"/> <d3:HorizontalAxisTitle Content="時間" FontSize="14" Visibility="Collapsed"/> </d3:ChartPlotter>
4.接下來我們就開始實現(xiàn)后臺代碼部分
MainWindow.xaml
<Window x:Class="WpfApp11.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:pu="clr-namespace:Panuon.UI.Silver;assembly=Panuon.UI.Silver" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp11" xmlns:d3="http://research.microsoft.com/DynamicDataDisplay/1.0" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <StackPanel Panel.ZIndex="1" Margin="50,40,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Orientation="Vertical"> <CheckBox x:Name="XCheckBox" IsChecked="True" pu:CheckBoxHelper.CheckBoxStyle="Standard" pu:CheckBoxHelper.BoxHeight="20" pu:CheckBoxHelper.BoxWidth="20" pu:CheckBoxHelper.CornerRadius="15" pu:CheckBoxHelper.CheckedBackground="{Binding ColorX}"> <CheckBox.Content> <DockPanel> <TextBlock VerticalAlignment="Center" FontSize="14" FontWeight="Bold" Text="X:" Foreground="{Binding ColorX}"/> <TextBlock x:Name="txtFhr1" Text="{Binding ValueX}" FontSize="32" FontWeight="Bold" Foreground="{Binding ColorX}"/> </DockPanel> </CheckBox.Content> </CheckBox> <CheckBox x:Name="YCheckBox" IsChecked="True" pu:CheckBoxHelper.CheckedBackground="{Binding ColorY}" pu:CheckBoxHelper.CheckBoxStyle="Standard" pu:CheckBoxHelper.BoxHeight="20" pu:CheckBoxHelper.BoxWidth="20" pu:CheckBoxHelper.CornerRadius="15"> <CheckBox.Content> <DockPanel> <TextBlock VerticalAlignment="Center" FontSize="14" FontWeight="Bold" Text="Y:" Foreground="{Binding ColorY}"/> <TextBlock x:Name="txtFhr2" Text="{Binding ValueY}" FontSize="32" FontWeight="Bold" Foreground="{Binding ColorY}" /> </DockPanel> </CheckBox.Content> </CheckBox> <CheckBox x:Name="ZCheckBox" IsChecked="True" pu:CheckBoxHelper.CheckedBackground="{Binding ColorZ}" pu:CheckBoxHelper.CheckBoxStyle="Standard" pu:CheckBoxHelper.BoxHeight="20" pu:CheckBoxHelper.BoxWidth="20" pu:CheckBoxHelper.CornerRadius="15"> <CheckBox.Content> <DockPanel> <TextBlock VerticalAlignment="Center" FontSize="14" FontWeight="Bold" Text="Z:" Foreground="{Binding ColorZ}"/> <TextBlock x:Name="txtFhr3" Text="{Binding ValueZ}" FontSize="32" FontWeight="Bold" Foreground="{Binding ColorZ}"/> </DockPanel> </CheckBox.Content> </CheckBox> <TextBlock VerticalAlignment="Center" FontSize="14" Text="單位:1g≈9.80 m/s2" Margin="0,10"/> </StackPanel> <d3:ChartPlotter x:Name="plotter" MouseMove="Plotter_MouseMove" Panel.ZIndex="0"> <d3:Header x:Name="HeaderTitle" Visibility="Visible" Content="這是曲線的標(biāo)題" FontSize="14" HorizontalAlignment="Center" /> <d3:VerticalAxisTitle Content="Value" FontSize="14" Visibility="Collapsed"/> <d3:HorizontalAxisTitle Content="時間" FontSize="14" Visibility="Collapsed"/> </d3:ChartPlotter> </Grid> </Window>
MainWindow.cs
using Microsoft.Research.DynamicDataDisplay.DataSources; using Microsoft.Research.DynamicDataDisplay; using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Threading; using Microsoft.Research.DynamicDataDisplay.Charts; using System.Windows.Input; using Panuon.UI.Silver; namespace WpfApp11 { /// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : Window { private readonly DispatcherTimer dispatcherTimer = new DispatcherTimer(); private readonly LineGraph lineGraphX = new LineGraph(); private readonly LineGraph lineGraphY = new LineGraph(); private readonly LineGraph lineGraphZ = new LineGraph(); private readonly ObservableDataSource<Point> xPoint = new ObservableDataSource<Point>(); private readonly ObservableDataSource<Point> yPoint = new ObservableDataSource<Point>(); private readonly ObservableDataSource<Point> zPoint = new ObservableDataSource<Point>(); private readonly FontView fontView = new FontView(); public MainWindow() { InitializeComponent(); lineGraphX = plotter.AddLineGraph(xPoint, Colors.Red, 1.2, "X"); //#FFFF0000 lineGraphY = plotter.AddLineGraph(yPoint, Colors.Green, 1.2, "Y"); //FF008000 lineGraphZ = plotter.AddLineGraph(zPoint, Colors.Blue, 1.2, "Z");//FF0000FF //LineLegendItem.xaml標(biāo)簽 HorizontalDateTimeAxis horizontalAxis = new HorizontalDateTimeAxis(); horizontalAxis.ShowMinorTicks = false; horizontalAxis.LabelProvider = new DateTimeAxisControl().LabelProvider; horizontalAxis.IsDefaultAxis = true; horizontalAxis.ShowMayorLabels = false; horizontalAxis.LabelProvider.SetCustomView((info, uiElement) => { (uiElement as TextBlock).Text = info.Tick.ToString("HH:mm:ss"); //時間軸日期格式 }); plotter.ContextMenu = PopulateContextMenu(plotter); plotter.HorizontalAxis.Remove(); //去除默認(rèn) plotter.Children.Add(horizontalAxis); //加入新的 Loaded += MainWindow_Loaded; this.XCheckBox.DataContext = fontView; this.YCheckBox.DataContext = fontView; this.ZCheckBox.DataContext = fontView; this.XCheckBox.Checked += XCheckBox_Checked; this.XCheckBox.Unchecked += XCheckBox_Checked; this.YCheckBox.Checked += YCheckBox_Checked; this.YCheckBox.Unchecked += YCheckBox_Checked; this.ZCheckBox.Checked += ZCheckBox_Checked; this.ZCheckBox.Unchecked += ZCheckBox_Checked; } #region CheckedEvent private void XCheckBox_Checked(object sender, RoutedEventArgs e) { CheckBox checkBox = sender as CheckBox; if (checkBox != null) { if ((bool)checkBox.IsChecked) { fontView.ColorX = fontView.IsColorX; } else { fontView.ColorX = fontView.UnColor; } } if (lineGraphX.Visibility == Visibility.Hidden) { lineGraphX.Visibility = Visibility.Visible; } else { lineGraphX.Visibility = Visibility.Hidden; } } private void YCheckBox_Checked(object sender, RoutedEventArgs e) { CheckBox checkBox = sender as CheckBox; if (checkBox != null) { if ((bool)checkBox.IsChecked) { fontView.ColorY = fontView.IsColorY; } else { fontView.ColorY = fontView.UnColor; } } if (lineGraphY.Visibility == Visibility.Hidden) { lineGraphY.Visibility = Visibility.Visible; } else { lineGraphY.Visibility = Visibility.Hidden; } } private void ZCheckBox_Checked(object sender, RoutedEventArgs e) { CheckBox checkBox = sender as CheckBox; if (checkBox != null) { if ((bool)checkBox.IsChecked) { fontView.ColorZ = fontView.IsColorZ; } else { fontView.ColorZ = fontView.UnColor; } } if (lineGraphZ.Visibility == Visibility.Hidden) { lineGraphZ.Visibility = Visibility.Visible; } else { lineGraphZ.Visibility = Visibility.Hidden; } } #endregion /// <summary> /// 重寫右鍵菜單 /// </summary> /// <param name="plotter"></param> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> private ContextMenu PopulateContextMenu(IInputElement target) { ContextMenu result = new ContextMenu(); StateIcon homeIcon = new StateIcon() { Icon = (char)Convert.ToInt32("f015", 16) + string.Empty }; StateIcon saveIcon = new StateIcon() { Icon = (char)Convert.ToInt32("f2d2", 16) + string.Empty }; StateIcon copyIcon = new StateIcon() { Icon = (char)Convert.ToInt32("f01a", 16) + string.Empty }; StateIcon queryIcon = new StateIcon() { Icon = (char)Convert.ToInt32("f022", 16) + string.Empty }; StateIcon logIcon = new StateIcon() { Icon = (char)Convert.ToInt32("f07c", 16) + string.Empty }; MenuItem fitToViewMenuItem = new MenuItem { Header = "主圖", ToolTip = "初始化顯示,顯示主圖中心位置", Icon = homeIcon, Command = ChartCommands.FitToView, CommandTarget = target }; MenuItem savePictureMenuItem = new MenuItem { Header = "保存", ToolTip = "保存曲線圖", Icon = saveIcon, Command = ChartCommands.SaveScreenshot, CommandTarget = target }; MenuItem copyPictureMenuItem = new MenuItem { Header = "拷貝", ToolTip = "拷貝,復(fù)制", Icon = copyIcon, Command = ChartCommands.CopyScreenshot, CommandTarget = target }; result.Items.Add(fitToViewMenuItem); result.Items.Add(copyPictureMenuItem); result.Items.Add(savePictureMenuItem); return result; } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { dispatcherTimer.Interval = TimeSpan.FromMilliseconds(100); dispatcherTimer.Tick += (sender1, e1) => Timer_Tick(sender1, e1); dispatcherTimer.IsEnabled = true; } /// <summary> /// 定時器刷新界面數(shù)據(jù) /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Timer_Tick(object sender, EventArgs e) { var axis = new HorizontalDateTimeAxis(); DateTime dateTime = DateTime.Now; Random random = new Random(); double a, b, c; do { a = random.NextDouble() * 10; b = random.NextDouble() * 10; c = random.NextDouble() * 10; } while (a == b || b == c || a == c); Point x = new Point(axis.ConvertToDouble(dateTime), a); xPoint.AppendAsync(this.Dispatcher, x); Point y = new Point(axis.ConvertToDouble(dateTime), b); yPoint.AppendAsync(this.Dispatcher, y); Point z = new Point(axis.ConvertToDouble(dateTime), c); zPoint.AppendAsync(this.Dispatcher, z); } /// <summary> /// 鼠標(biāo)選中時,X軸和Y軸的值 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Plotter_MouseMove(object sender, MouseEventArgs e) { try { DateTime dateTime = DateTime.Now; var axis = new HorizontalDateTimeAxis(); axis.ConvertToDouble(dateTime); ChartPlotter chart = sender as ChartPlotter; Point point = e.GetPosition(this).ScreenToData(chart.Transform); TimeSpan ts = TimeSpan.FromMilliseconds(Math.Floor(point.X * 1000000)); DateTime formattedDate = DateTime.MinValue.Add(ts); this.HeaderTitle.Content = $"速度:{point.Y.ToString("N5")} 時間:{formattedDate:HH:mm:ss,fff}"; // 目標(biāo)時間 DateTime targetTime = formattedDate; //var select = this.Data.OrderBy(v => Math.Abs((v.DateTime - targetTime).TotalMilliseconds)).First(); // 獲取與目標(biāo)時間最接近的 Entity // 顯示選中 Entity //this.SelectedEntity.Content = select.ToString(); } catch (Exception) { } } } }
FontView.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WpfApp11 { internal class FontView : INotifyPropertyChanged { /// <summary> /// 曲線顏色 /// </summary> public string UnColor => "#DCDCDC"; public string IsColorX => "#FFFF0000"; //"#009C26"; public string IsColorY => "#FF008000"; //"#8080C0"; public string IsColorZ => "#FF0000FF"; //"#000000"; public FontView() { _colorX = this.IsColorX; _colorY = this.IsColorY; _colorZ = this.IsColorZ; } private string _colorX = string.Empty; private string _colorY = string.Empty; private string _colorZ = string.Empty; public string ColorX { get { return this._colorX; } set { if (this._colorX != value) { this._colorX = value; OnPropertyChanged(nameof(ColorX)); } } } public string ColorY { get { return this._colorY; } set { if (this._colorY != value) { this._colorY = value; OnPropertyChanged(nameof(ColorY)); } } } public string ColorZ { get { return this._colorZ; } set { if (this._colorZ != value) { this._colorZ = value; OnPropertyChanged(nameof(ColorZ)); } } } private string x = "0.000"; private string y = "0.000"; private string z = "0.000"; public string ValueX { get { return this.x; } set { if (this.x != value) { this.x = value; OnPropertyChanged(nameof(ValueX)); } } } public string ValueY { get { return this.y; } set { if (this.y != value) { this.y = value; OnPropertyChanged(nameof(ValueY)); } } } public string ValueZ { get { return this.z; } set { if (this.z != value) { this.z = value; OnPropertyChanged(nameof(ValueZ)); } } } private string node = "000000"; private string time = "00:00:00,000"; public string Node { get { return this.node; } set { if (this.node != value) { this.node = value; OnPropertyChanged(nameof(Node)); } } } public string Time { get { return this.time; } set { if (this.time != value) { this.time = value; OnPropertyChanged(nameof(Time)); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }
到此這篇關(guān)于WPF實現(xiàn)曲線數(shù)據(jù)展示的文章就介紹到這了,更多相關(guān)WPF曲線數(shù)據(jù)展示內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# byte數(shù)組與Image相互轉(zhuǎn)換的方法
這篇文章介紹了C# byte數(shù)組與Image相互轉(zhuǎn)換的方法,有需要的朋友可以參考一下2013-10-10C# 中的GroupBy的動態(tài)拼接問題及GroupBy<>用法介紹
這篇文章主要介紹了C# 中的GroupBy的動態(tài)拼接問題,在文章給大家提到了C# List泛型集合中的GroupBy<>用法詳解,需要的朋友可以參考下2017-12-12C#利用ScriptControl動態(tài)執(zhí)行JS和VBS腳本
C#中利用ScriptControl動態(tài)執(zhí)行JS和VBS腳本的實現(xiàn)方法,需要的朋友可以參考下2013-04-04sqlserver備份還原數(shù)據(jù)庫功能封裝分享
這篇文章主要介紹了sqlserver備份還原數(shù)據(jù)庫功能封裝示例,需要的朋友可以參考下2014-03-03