WPF實(shí)現(xiàn)曲線數(shù)據(jù)展示
wpf實(shí)現(xiàn)曲線數(shù)據(jù)展示,函數(shù)曲線展示,實(shí)例:震動(dòng)數(shù)據(jù)分析為例。

如上圖所示,如果你想實(shí)現(xiàn)上圖中的效果,請(qǐng)?jiān)敿?xì)參考我的內(nèi)容。
一共有兩種方式來(lái)實(shí)現(xiàn),一種是使用第三方的框架來(lái)實(shí)現(xiàn),另外一種是自己通過(guò)原創(chuàng)代碼來(lái)一步步實(shí)現(xiàn),本文主要介紹這兩種曲線的實(shí)現(xiàn)方式。
1.首先我創(chuàng)建一個(gè)wpf的解決方案項(xiàng)目。

2.在NuGet中添加 DynamicDataDisplay 項(xiàng)目支持

為了展示我們的UI界面,我們還添加了一個(gè)第三方的樣式框架 Panuon.UI.Silver

3.我們?cè)贛ainWindow.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="時(shí)間" FontSize="14" Visibility="Collapsed"/>
</d3:ChartPlotter>
4.接下來(lái)我們就開(kāi)始實(shí)現(xiàn)后臺(tái)代碼部分
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="時(shí)間" 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"); //時(shí)間軸日期格式
});
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>
/// 重寫(xiě)右鍵菜單
/// </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í)器刷新界面數(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)選中時(shí),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")} 時(shí)間:{formattedDate:HH:mm:ss,fff}";
// 目標(biāo)時(shí)間
DateTime targetTime = formattedDate;
//var select = this.Data.OrderBy(v => Math.Abs((v.DateTime - targetTime).TotalMilliseconds)).First(); // 獲取與目標(biāo)時(shí)間最接近的 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實(shí)現(xiàn)曲線數(shù)據(jù)展示的文章就介紹到這了,更多相關(guān)WPF曲線數(shù)據(jù)展示內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# byte數(shù)組與Image相互轉(zhuǎn)換的方法
這篇文章介紹了C# byte數(shù)組與Image相互轉(zhuǎn)換的方法,有需要的朋友可以參考一下2013-10-10
C# 中的GroupBy的動(dòng)態(tài)拼接問(wèn)題及GroupBy<>用法介紹
這篇文章主要介紹了C# 中的GroupBy的動(dòng)態(tài)拼接問(wèn)題,在文章給大家提到了C# List泛型集合中的GroupBy<>用法詳解,需要的朋友可以參考下2017-12-12
Unity3D實(shí)現(xiàn)簡(jiǎn)易五子棋源碼
這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)簡(jiǎn)易五子棋源碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
C#利用ScriptControl動(dòng)態(tài)執(zhí)行JS和VBS腳本
C#中利用ScriptControl動(dòng)態(tài)執(zhí)行JS和VBS腳本的實(shí)現(xiàn)方法,需要的朋友可以參考下2013-04-04
sqlserver備份還原數(shù)據(jù)庫(kù)功能封裝分享
這篇文章主要介紹了sqlserver備份還原數(shù)據(jù)庫(kù)功能封裝示例,需要的朋友可以參考下2014-03-03

