在WPF中使用Winform中自带的画图控件Chart,模拟动态更新数据
程序员文章站
2024-02-16 10:49:28
...
一、如何在WPF中使用Chart控件
1、添加引用
右键项目引用
-添加引用
,在程序集
中选择下图三个东东
2、添加命名空间
xmlns:Wchart="clr-namespace:System.Windows.Forms.DataVisualization.Charting;assembly=System.Windows.Forms.DataVisualization"
3、引用
注意要放在WindowsFormsHost
标签内部
<WindowsFormsHost Grid.Row="2">
<Wchart:Chart x:Name="ChartPlot"/>
</WindowsFormsHost>
二、代码
先上最终的效果图,如下图,可选择图中显示的点数,以及更新速度。
1、布局设计
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<RadioButton Name="rbtn_highspeed" Content="100ms" Style="{StaticResource rabtn}" Click="rbtn_highspeed_Click"/>
<RadioButton Name="rbtn_lowspeed" Content="500ms" IsChecked="True" Style="{StaticResource rabtn}" Click="rbtn_lowspeed_Click"/>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<RadioButton Name="rbtn_manypoint" Content="50点" IsChecked="True" Style="{StaticResource rabtn}" Click="rbtn_manypoint_Click"/>
<RadioButton Name="rbtn_littlepoint" Content="20点" Style="{StaticResource rabtn}" Click="rbtn_littlepoint_Click"/>
</StackPanel>
<Button Name="btn_start" Content="开始" Margin="10,1" Click="btn_start_Click"/>
</StackPanel>
<WindowsFormsHost Grid.Row="2">
<Wchart:Chart x:Name="ChartPlot"/>
</WindowsFormsHost>
</Grid>
rabtn
是自定义的一个RadioButton
样式资源文件,感兴趣的可以看看(不看也没影响)
<Style x:Key="rabtn" TargetType="RadioButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Border>
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Rectangle Name="rec" Grid.Column="0" Width="15" Height="15"
Stroke="Black" Fill="White"/>
<ContentPresenter Grid.Column="1" VerticalAlignment="Center" Margin="5,1"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="rec" Property="Fill" Value="RoyalBlue"/>
<Setter TargetName="rec" Property="Stroke" Value="Transparent"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
2、逻辑实现
public partial class MainWindow : Window
{
private ChartArea AREA = new ChartArea() { Name = "Line" }; // 画图区域
private Series SERIES = new Series(); // 一条折线
private Legend LEGEND = new Legend(); // 一个图例
private System.Timers.Timer timer = new System.Timers.Timer(); // 定时器
private int INTERVAL = 500; // 定时器时间
private int MAXPLOT = 100; // 图中最多点数
public MainWindow()
{
InitializeComponent();
// area样式设置
AREA.AxisX.Enabled = AxisEnabled.True; // 使X轴可用
AREA.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount; // X 轴标签数量,由显示的数据点数量自动调整
AREA.AxisY.Enabled = AxisEnabled.True;
AREA.AxisY.MajorTickMark.Enabled = false;
AREA.CursorX.IsUserSelectionEnabled = true; // 鼠标选择区域放大
// series设置
SERIES.ChartArea = "Line";
SERIES.ChartType = SeriesChartType.Line; // 折线图
SERIES.Name = "随机数";
SERIES.ToolTip = "数值:\n#VALY"; // 鼠标悬浮在点上面显示提示(不够灵敏)
// legend设置
LEGEND.Alignment = System.Drawing.StringAlignment.Near; // legend靠近显示,不然太占用地方了
LEGEND.Docking = Docking.Left; // 靠左显示
LEGEND.DockedToChartArea = "Line"; // 默认图例是显示在图的外面,占用地方
LEGEND.IsDockedInsideChartArea = true; // 将图例放在图里面
LEGEND.BackColor = System.Drawing.Color.Transparent; // 无背景色,不然会挡住折线
// 添加area series legend
ChartPlot.ChartAreas.Add(AREA);
ChartPlot.Series.Add(SERIES);
ChartPlot.Legends.Add(LEGEND);
// timer设置
timer.Enabled = false;
timer.Interval = INTERVAL;
timer.Elapsed += Timer_Elapsed;
}
/// <summary>
/// 定时更新图
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Application.Current.Dispatcher.Invoke(() =>
{
if (SERIES.Points.Count >= MAXPLOT)
{
for(int i = 0; i < SERIES.Points.Count - MAXPLOT - 1; i++)
{
SERIES.Points.RemoveAt(0);
}
}
SERIES.Points.AddXY(DateTime.Now.ToString("HH:mm:ss"), GetRandomNumber());
// 刷新图
AREA.RecalculateAxesScale();
});
}
/// <summary>
/// 开始、暂停 画图
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_start_Click(object sender, RoutedEventArgs e)
{
if (timer.Enabled)
{
timer.Enabled = false;
btn_start.Content = "开始";
}
else
{
timer.Enabled = true;
btn_start.Content = "暂停";
}
}
/// <summary>
/// 改变间隔时间
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void rbtn_highspeed_Click(object sender, RoutedEventArgs e)
{
timer.Interval = 100;
}
private void rbtn_lowspeed_Click(object sender, RoutedEventArgs e)
{
timer.Interval = 500;
}
/// <summary>
/// 改变图中最多点数
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void rbtn_manypoint_Click(object sender, RoutedEventArgs e)
{
MAXPLOT = 50;
}
private void rbtn_littlepoint_Click(object sender, RoutedEventArgs e)
{
MAXPLOT = 20;
}
/// <summary>
/// 产生随机数
/// </summary>
/// <returns></returns>
private int GetRandomNumber()
{
byte[] buffer = Guid.NewGuid().ToByteArray();
int iSeed = BitConverter.ToInt32(buffer, 0);
Random random = new Random(iSeed);
return random.Next(-100, 100);
}
}
3、最后
动态效果图来啦!!!!!!!!!
写在最后:最近做wpf一个项目,需要画图。可惜wpf没有自带的画图控件,而查询了很多了第三方控件(OxyPlot、Visifire、Dynamic Data Display)并尝试用了一下,唔,好难啊,主要是资料好少,还是winform的chart用的舒服。在此做个记录,以后用到的话也方便。
有问题欢迎交流。
上一篇: 浅谈IC卡数据分析