2017-05-01 8 views
0

さて、基本的には、このグラフをDateTimeに置き換え、ストップウォッチに基づいてX軸をプロットしたいと考えています。次に、シリアルポートからのデータをY軸にプロットする必要があります。これは、ボタンを押すだけですべて生き生きとしなければならない。時間とシリアルポートからの読み取り値に基づいて点をプロットするためのライブチャートの定数変更例を使用しますか?

https://lvcharts.net/App/examples/v1/wpf/Constant%20Changes

それに伴う問題、それはある種のストップウォッチではなく、システム時刻を使用していることである。ここでは

は私が続く例です。私はWPFを使用しており、このグラフの能力を拡張したいと考えています。

誰かがこれを手伝ってくれたら、スカイプなどで助けてください。私にお知らせください!

最終的に、グラフからすべてのデータを取り出してどこかに保存したいと考えています。だから私は後のポイントと比較することができます。

ありがとうございます!

Mainwindow.cs.xaml

<Window x:Class="TestChartProject.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:local="clr-namespace:TestChartProject" 
    xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"></RowDefinition> 
     <RowDefinition Height="*"></RowDefinition> 
    </Grid.RowDefinitions> 
    <Button Grid.Row="0" Click="InjectStopOnClick"> 
     Inject/Stop Data 
    </Button> 
    <!--Here we disable tooltips and hovering to get a better performance--> 
    <lvc:CartesianChart Grid.Row="1" AnimationsSpeed="0:0:1" Hoverable="True" DataTooltip="{x:Null}"> 
     <lvc:CartesianChart.Series> 
      <lvc:LineSeries Values="{Binding ChartValues}" 
          PointGeometry="{x:Null}" 
          LineSmoothness="1" 
          StrokeThickness="6" 
          Stroke="#F34336" 
          Fill="Transparent"/> 
     </lvc:CartesianChart.Series> 



     <lvc:CartesianChart.AxisX> 


      <lvc:Axis LabelFormatter="{Binding DateTimeFormatter}" 
         MaxValue="{Binding AxisMax}" 
         MinValue="{Binding AxisMin}" 
         Unit="{Binding AxisUnit}"> 
       <lvc:Axis.Separator> 
        <lvc:Separator Step="{Binding AxisStep}" /> 
       </lvc:Axis.Separator> 
      </lvc:Axis> 




     </lvc:CartesianChart.AxisX> 



    </lvc:CartesianChart> 
</Grid> 

MainWindow.cs

private double _axisMax; 
    private double _axisMin; 
    private double _trend; 

    public MainWindow() 
    { 
     InitializeComponent(); 

     //To handle live data easily, in this case we built a specialized type 
     //the MeasureModel class, it only contains 2 properties 
     //DateTime and Value 
     //We need to configure LiveCharts to handle MeasureModel class 
     //The next code configures MeasureModel globally, this means 
     //that LiveCharts learns to plot MeasureModel and will use this config every time 
     //a IChartValues instance uses this type. 
     //this code ideally should only run once 
     //you can configure series in many ways, learn more at 
     //http://lvcharts.net/App/examples/v1/wpf/Types%20and%20Configuration 

     var mapper = Mappers.Xy<MeasureModel>() 
      .X(model => model.Session.Ticks) //use DateTime.Ticks as X 
      .Y(model => model.Value);   //use the value property as Y 

     //lets save the mapper globally. 
     Charting.For<MeasureModel>(mapper); 

     //the values property will store our values array 
     ChartValues = new ChartValues<MeasureModel>(); 

     //lets set how to display the X Labels 
     DateTimeFormatter = value => new DateTime((long)value).ToString("mm:ss"); 

     //AxisStep forces the distance between each separator in the X axis 
     AxisStep = TimeSpan.FromSeconds(1).Ticks; 
     //AxisUnit forces lets the axis know that we are plotting seconds 
     //this is not always necessary, but it can prevent wrong labeling 
     AxisUnit = TimeSpan.TicksPerSecond; 

     SetAxisLimits(DateTime.Now); 

     //The next code simulates data changes every 300 ms 

     IsReading = false; 

     DataContext = this; 
    } 

    public ChartValues<MeasureModel> ChartValues { get; set; } 
    public Func<double, string> DateTimeFormatter { get; set; } 
    public double AxisStep { get; set; } 
    public double AxisUnit { get; set; } 

    public double AxisMax 
    { 
     get { return _axisMax; } 
     set 
     { 
      _axisMax = value; 
      OnPropertyChanged("AxisMax"); 
     } 
    } 
    public double AxisMin 
    { 
     get { return _axisMin; } 
     set 
     { 
      _axisMin = value; 
      OnPropertyChanged("AxisMin"); 
     } 
    } 

    public bool IsReading { get; set; } 

    private void Read() 
    { 
     var r = new Random(); 

     while (IsReading) 
     { 
      Thread.Sleep(1); 
      var now = DateTime.Now; 


      _trend = r.Next(100); 

      ChartValues.Add(new MeasureModel 
      { 
       Session = now, 
       Value = _trend 
      }); 

      SetAxisLimits(now); 

      //lets only use the last 150 values 
      if (ChartValues.Count > 10) ChartValues.RemoveAt(0); 
     } 
    } 

    private void SetAxisLimits(DateTime now) 
    { 
     AxisMax = now.Ticks + TimeSpan.FromSeconds(1).Ticks; // lets force the axis to be 1 second ahead 
     AxisMin = now.Ticks - TimeSpan.FromSeconds(8).Ticks; // and 8 seconds behind 
    } 

    private void InjectStopOnClick(object sender, RoutedEventArgs e) 
    { 
     IsReading = !IsReading; 
     if (IsReading) Task.Factory.StartNew(Read); 
    } 

    #region INotifyPropertyChanged implementation 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName = null) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    #endregion 
} 

MeasureModel私はあなたが必要だと思うものに基づい

public class MeasureModel 
{ 
    public DateTime Session { get; set; } 
    public double Value { get; set; } 
} 

答えて

0

が、多分これはあなたを助けます:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     //used to generate random values 
     var r = new Random(); 
     var t = 0d; 

     //lets instead plot elapsed milliseconds and value 
     var mapper = Mappers.Xy<MeasureModel>() 
      .X(x => x.ElapsedMilliseconds) 
      .Y(x => x.Value); 

     //save the mapper globally   
     Charting.For<MeasureModel>(mapper); 

     Values = new ChartValues<MeasureModel>(); 
     var sw = new Stopwatch(); 
     sw.Start(); 

     Task.Run(() => 
     { 
      while (true) 
      { 
       Thread.Sleep(500); 

       //we add the lecture based on our StopWatch instance 
       Values.Add(new MeasureModel 
       { 
        ElapsedMilliseconds = sw.ElapsedMilliseconds, 
        Value = t += r.Next(0,10) 
       }); 
      } 
     }); 

     DataContext = this; 
    } 

    public ChartValues<MeasureModel> Values { get; set; } 
} 

public class MeasureModel 
{ 
    public double ElapsedMilliseconds { get; set; } 
    public double Value { get; set; } 
} 

XAML:

<lvc:CartesianChart> 
     <lvc:CartesianChart.Series> 
      <lvc:LineSeries Values="{Binding Values}" /> 
     </lvc:CartesianChart.Series> 
    </lvc:CartesianChart> 
+0

すごいです!私が持っている唯一の質問は、X軸上にあり、フォーマットではなく乱数の束を私に与えます。私はこのようにすることを好むでしょう: "分:秒"。ありがとう! – Hypergyzed

関連する問題