在WPF中使用Winform中自带的画图控件Chart,模拟动态更新数据

13 篇文章 2 订阅
一、如何在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用的舒服。在此做个记录,以后用到的话也方便。

有问题欢迎交流。

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值