2017-09-26 172 views
0

我需要绘制包含一系列随时间推移的值的图表。值之间的时间段不规则(几秒钟)。为此,我使用库LiveChart.Wpf,继Date Time tutorial和来自GitHub的日期轴示例(DateAxisExample.xamlDateAxisExample.xaml.cs)。在X轴中使用带有DateAxis和DateModel的CartesianChart

这是XAML:

<UserControl x:Class="Wpf.Charts.SensorChart" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Grid> 
     <lvc:CartesianChart Series="{Binding SeriesCollection}" LegendLocation="Left"> 
      <lvc:CartesianChart.AxisX> 
       <lvc:DateAxis Title="Time" 
           InitialDateTime="{Binding InitialDateTime}" 
           Period="{Binding Period}" 
           SelectedWindow="{Binding SelectedWindow}" 
           LabelFormatter="{Binding Formatter}"> 
       </lvc:DateAxis> 
      </lvc:CartesianChart.AxisX> 
     </lvc:CartesianChart> 
    </Grid> 
</UserControl> 

这我的身后代码:

using LiveCharts; 
using LiveCharts.Configurations; 
using LiveCharts.Helpers; 
using LiveCharts.Wpf; 
using System; 
using System.Windows.Controls; 

namespace Wpf.Charts 
{ 
    public partial class SensorChart : UserControl 
    { 
     public SeriesCollection SeriesCollection { get; set; } 
     public DateTime InitialDateTime { get; set; } 
     public PeriodUnits Period { get; set; } 
     public IAxisWindow SelectedWindow { get; set; } 
     private Func<double, string> Formatter { get; set; } 

     public SensorChart() 
     { 
      InitializeComponent(); 
      this.SetChartModelValues(); 
      this.DataContext = this; 
     } 

     private void SetChartModelValues() 
     { 
      var dayConfig = Mappers.Xy<ChartModel>() 
        .X(dayModel => (double)dayModel.DateTime.Ticks/TimeSpan.FromSeconds(1).Ticks) 
        .Y(dayModel => dayModel.Value); 

      DateTime now = DateTime.Now; 
      now = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second); 

      this.SeriesCollection = new SeriesCollection(dayConfig) 
      { 
       new LineSeries() 
       { 
        Values = new ChartValues<ChartModel>() 
        { 
         new ChartModel(now.AddSeconds(5), 3), 
         new ChartModel(now.AddSeconds(10), 6), 
         new ChartModel(now.AddSeconds(15), 8), 
         new ChartModel(now.AddSeconds(20), 4), 
         new ChartModel(now.AddSeconds(55), 7), 
         new ChartModel(now.AddSeconds(60), 2), 
         new ChartModel(now.AddSeconds(65), 6), 
         new ChartModel(now.AddSeconds(70), 8), 
         new ChartModel(now.AddSeconds(75), 4), 
         new ChartModel(now.AddSeconds(80), 7), 
         new ChartModel(now.AddSeconds(105), 3), 
         new ChartModel(now.AddSeconds(110), 6), 
         new ChartModel(now.AddSeconds(115), 8), 
         new ChartModel(now.AddSeconds(120), 4), 
         new ChartModel(now.AddSeconds(155), 7), 
         new ChartModel(now.AddSeconds(160), 2), 
         new ChartModel(now.AddSeconds(165), 6), 
         new ChartModel(now.AddSeconds(170), 8), 
         new ChartModel(now.AddSeconds(175), 4), 
         new ChartModel(now.AddSeconds(180), 7), 
        } 
       } 
      }; 
      //foreach() 

      this.InitialDateTime = now; 
      this.Period = PeriodUnits.Seconds; 
      this.SelectedWindow = new DateAxisWindows.FifteenSecondsAxisWindow(); 
      this.Formatter = this.DateLabelFormater; 
     } 

     private string DateLabelFormater(double value) 
     { 
      DateTime dateTime = new DateTime((long)(value * TimeSpan.FromSeconds(1).Ticks)); 
      return dateTime.ToString("HH:mm:ss"); 
     } 
    } 

    public class ChartModel 
    { 
     public DateTime DateTime { get; set; } 
     public double Value { get; set; } 

     public ChartModel(DateTime dateTime, double value) 
     { 
      this.DateTime = dateTime; 
      this.Value = value; 
     } 
    } 
} 

但是当我运行该应用程序会显示在今年4036的日期。你知道发生了什么吗?

回答

3

试试这个,如果你想显示的实际值:

public partial class SensorChart : UserControl 
{ 
    public SeriesCollection SeriesCollection { get; set; } 
    public DateTime InitialDateTime { get; set; } 
    public Func<double, string> Formatter { get; set; } 

    public SensorChart() 
    { 
     InitializeComponent(); 
     this.SetChartModelValues(); 
     this.DataContext = this; 
    } 

    private void SetChartModelValues() 
    { 
     var dayConfig = Mappers.Xy<ChartModel>() 
          .X(dayModel => dayModel.DateTime.Ticks) 
          .Y(dayModel => dayModel.Value); 


     DateTime now = DateTime.Now; 

     this.SeriesCollection = new SeriesCollection(dayConfig) 
     { 
      new LineSeries() 
      { 
       Values = new ChartValues<ChartModel>() 
       { 
        new ChartModel(now.AddSeconds(5), 3), 
        new ChartModel(now.AddSeconds(10), 6), 
        new ChartModel(now.AddSeconds(15), 8), 
        new ChartModel(now.AddSeconds(20), 4), 
        new ChartModel(now.AddSeconds(55), 7), 
        new ChartModel(now.AddSeconds(60), 2), 
        new ChartModel(now.AddSeconds(65), 6), 
        new ChartModel(now.AddSeconds(70), 8), 
        new ChartModel(now.AddSeconds(75), 4), 
        new ChartModel(now.AddSeconds(80), 7), 
        new ChartModel(now.AddSeconds(105), 3), 
        new ChartModel(now.AddSeconds(110), 6), 
        new ChartModel(now.AddSeconds(115), 8), 
        new ChartModel(now.AddSeconds(120), 4), 
        new ChartModel(now.AddSeconds(155), 7), 
        new ChartModel(now.AddSeconds(160), 2), 
        new ChartModel(now.AddSeconds(165), 6), 
        new ChartModel(now.AddSeconds(170), 8), 
        new ChartModel(now.AddSeconds(175), 4), 
        new ChartModel(now.AddSeconds(180), 7), 
       } 
      } 
     }; 

     this.InitialDateTime = now; 
     this.Formatter = value => new DateTime((long)value).ToString("yyyy-MM:dd HH:mm:ss"); 
    } 
} 

XAML:

<lvc:CartesianChart Series="{Binding SeriesCollection}" LegendLocation="Left"> 
    <lvc:CartesianChart.AxisX> 
     <lvc:Axis LabelFormatter="{Binding Formatter}" 
        MinValue="{Binding InitialDateTime.Ticks}"> 
     </lvc:Axis> 
    </lvc:CartesianChart.AxisX> 
</lvc:CartesianChart> 

enter image description here

+0

谢谢您的回答。我不知道为什么,但是如果我复制并粘贴您的XAML和C#代码,图表会显示日期Ticks值。我的意思是,我看到一个这样的数字:** 6.36421203383936E + 17 **。看来LabelFormatter没有正确设置。但是不使用绑定,如果我直接在代码后面设置格式化程序,它可以正常工作。 (datetime)((long)value).ToString(){this.axisX.LabelFormatter = value => new DateTime((long)value).ToString() “yyyy-MM:dd HH:mm:ss”);' 你知道它为什么可以吗? – Jon

+1

确保Formatter属性是公共的。在你的示例代码中,它是私有的。 – mm8

+0

哦!这是我的错......再次感谢你! – Jon