Using CartesianChart with DateAxis and DateModel in X axis

允我心安 提交于 2019-12-08 07:19:12

问题


I need to draw a chart with a series of values that extend over time. The time period between values is irregular (a few seconds). For this I am using the library LiveChart.Wpf, following Date Time tutorial and date axis example from GitHub (DateAxisExample.xaml and DateAxisExample.xaml.cs).

This is 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>

And this my code behind:

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;
        }
    }
}

But when I run the application it displays dates of the year 4036. Do you know what is happening?


回答1:


Try this if you want to display the actual values:

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>



来源:https://stackoverflow.com/questions/46427721/using-cartesianchart-with-dateaxis-and-datemodel-in-x-axis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!