WPF編程,Live Charts使用說明(48)——時間處理

要在LiveCharts中處理日期時間,您必須爲圖表創建自定義比例,這並不難,但是請在閱讀本文之前確定是否有必要,是否只需要簡單的標籤(例如“一月,二月,三月”,以及所有它們之間有規律的間隔,然後僅使用 Axis.Labels就足夠了

在這裏插入圖片描述

XAML

<lvc:CartesianChart Series="{Binding Series}">
  <lvc:CartesianChart.AxisX>
    <lvc:Axis LabelFormatter="{Binding Formatter}"></lvc:Axis>
  </lvc:CartesianChart.AxisX>
</lvc:CartesianChart>

.CS數據類

using System;
 
namespace Wpf.CartesianChart.Using_DateTime
{
    public class DateModel
    {
        public System.DateTime DateTime { get; set; }
        public double Value { get; set; }
    }
}

後臺:

using System;
using System.Windows.Controls;
using System.Windows.Media;
using LiveCharts;
using LiveCharts.Configurations;
using LiveCharts.Wpf;
 
namespace Wpf.CartesianChart.Using_DateTime
{
    public partial class DateTime : UserControl
    {
        public DateTime()
        {
            InitializeComponent();
 
            var dayConfig = Mappers.Xy<DateModel>()
                .X(dayModel => (double) dayModel.DateTime.Ticks/TimeSpan.FromHours(1).Ticks)
                .Y(dayModel => dayModel.Value);
 
            //Notice you can also configure this type globally, so you don't need to configure every
            //SeriesCollection instance using the type.
            //more info at http://lvcharts.net/App/Index#/examples/v1/wpf/Types%20and%20Configuration
 
            Series = new SeriesCollection(dayConfig)
            {
                new LineSeries
                {
                    Values = new ChartValues<DateModel>
                    {
                        new DateModel
                        {
                            DateTime = System.DateTime.Now,
                            Value = 5
                        },
                        new DateModel
                        {
                            DateTime = System.DateTime.Now.AddHours(2),
                            Value = 9
                        }
                    },
                    Fill = Brushes.Transparent
                },
                new ColumnSeries
                {
                    Values = new ChartValues<DateModel>
                    {
                        new DateModel
                        {
                            DateTime = System.DateTime.Now,
                            Value = 4
                        },
                        new DateModel
                        {
                            DateTime = System.DateTime.Now.AddHours(1),
                            Value = 6
                        },
                        new DateModel
                        {
                            DateTime = System.DateTime.Now.AddHours(2),
                            Value = 8
                        }
                    }
                }
            };
 
            Formatter = value => new System.DateTime((long) (value*TimeSpan.FromHours(1).Ticks)).ToString("t");
            
            DataContext = this;
        }
 
        public Func<double, string> Formatter { get; set; }
        public SeriesCollection Series { get; set; }
    }
}

前臺:

<UserControl x:Class="Wpf.CartesianChart.Using_DateTime.DateTime"
             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 Series}">
            <lvc:CartesianChart.AxisX>
                <lvc:Axis LabelFormatter="{Binding Formatter}"></lvc:Axis>
            </lvc:CartesianChart.AxisX>
        </lvc:CartesianChart>
    </Grid>
</UserControl>
現在,一切都很簡單,此方法只是一個問題,當您需要任何條形圖系列時,條形圖的寬度爲單一(1),請注意我們使用DateTime.Ticks作爲X,因此條形圖的寬度爲1個刻度和1個滴答是1毫秒,請注意我們的點之間相隔2個小時,繪製的條形圖系列寬度爲1毫秒,間隔2小時不可見1毫秒,那麼如何使條形圖可見?

我們需要更改圖表的單位,使用小時數

var dayConfig = Mappers.Xy<DateModel>()
  .X(dateModel => dateModel.DateTime.Ticks/TimeSpan.FromHours(1).Ticks)
  .Y(dateModel => dateModel.Value);
//and the formatter
Formatter = value => new DateTime((long) (value*TimeSpan.FromHours(1).Ticks)).ToString("t");

下一組示例顯示瞭如何在許多時間間隔內配置圖表的比例

//Every 15 minutes
var dayConfig = Mappers.Xy<DateModel>()
  .X(dateModel => dateModel.DateTime.Ticks/TimeSpan.FromMinutes(15).Ticks)
  .Y(dateModel => dateModel.Value);
//and the formatter
Formatter = value => new DateTime((long) (value*TimeSpan.FromMinutes(15).Ticks)).ToString("t");
 
//Days
var dayConfig = Mappers.Xy<DateModel>()
  .X(dateModel => dateModel.DateTime.Ticks/TimeSpan.FromDays(1).Ticks)
  .Y(dateModel => dateModel.Value);
//and the formatter
Formatter = value => new DateTime((long) (value*TimeSpan.FromDays(1).Ticks)).ToString("d");
 
//Months
//30.44 is the average days in a solar year
var dayConfig = Mappers.Xy<DateModel>()
  .X(dateModel => dateModel.DateTime.Ticks/(TimeSpan.FromDays(1).Ticks*30.44))
  .Y(dateModel => dateModel.Value);
//and the formatter
Formatter = value => new DateTime((long) (value*TimeSpan.FromDays(1).Ticks*30.44)).ToString("M");
 
//Years
//365.2425 is the days in a solar year
var dayConfig = Mappers.Xy<DateModel>()
  .X(dateModel => dateModel.DateTime.Ticks/(TimeSpan.FromDays(1).Ticks*365.2425))
  .Y(dateModel => dateModel.Value);
//and the formatter
Formatter = value => new DateTime((long) (value*TimeSpan.FromDays(1).Ticks*365.2425)).ToString("yyyy");
注意:由於並非所有的月份和年份都具有相同的天數,所以每個條形的寬度可能會在幾個月內變化:+-(1 / 30.44),而在幾年中變化:+ /-(1 / 365.2425),則外觀很小且可折舊錯誤。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章