livechart应用笔记

前端部分:

<UserControl x:Class="MvvmProjectFrame.Views.RealTimeView"
             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:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MvvmProjectFrame.Views" d:DataContext="{d:DesignInstance Type=local:RealTimeView}"
             mc:Ignorable="d" 
             d:DesignHeight="930" d:DesignWidth="1770">
    <UserControl.Resources>
        <Style x:Key="buttonStyle" TargetType="Button">
            <Setter Property="Width" Value="80"/>
            <Setter Property="Margin" Value="10,0"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="LightGray"/>
            <Setter Property="FontSize" Value="14"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border BorderThickness="0,0,0,2" BorderBrush="{TemplateBinding  BorderBrush}" Background="{TemplateBinding  Background}">
                            <ContentPresenter Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="FontSize" Value="16"/>
                                <Setter Property="Background" Value="#FFE6EDEB"/>
                            </Trigger>
                            <Trigger Property="IsFocused" Value="True">
                                <Setter Property="FontSize" Value="16"/>
                                <Setter Property="Background" Value="#ffD1E5FB"/>
                                <Setter Property="BorderBrush" Value="#B6BC0B"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
            <TextBlock Text="选择显示曲线:" FontSize="14" VerticalAlignment="Center" Margin="5,0"/>
            <ComboBox  x:Name="comboBoxName1" Margin="10,0"  FontSize="14" Width="150" Height="25"/>
            <Button Content="开始"  Click="Button_Click" Style="{StaticResource buttonStyle}"/>
            <Button Content="停止"  Click="Button_Click_1" Style="{StaticResource buttonStyle}"/>
            <Button Content="实时曲线"  Click="Button_Click_2" Style="{StaticResource buttonStyle}"/>
            <Button Content="历史曲线"  Click="Button_Click_3" Style="{StaticResource buttonStyle}"/>
            <Button Content="查询"  Click="Button_Click_4" Style="{StaticResource buttonStyle}"/>
            <TextBox x:Name="dateTimeBox3" Text="2023-04-06 15:18:30" VerticalAlignment="Center" Margin="5,0,0,0" Width="180" Background="White"/>
            <TextBox Text="至" VerticalAlignment="Center"  HorizontalAlignment="Center" Margin="10,5,5,5" Background="Transparent" Foreground="Black" BorderBrush="White" BorderThickness="0"/>
            <TextBox x:Name="dateTimeBox4" Text="2023-04-06 15:19:30" VerticalAlignment="Center" Margin="5,0,10,0" Width="180" Background="White"/>
            <TextBlock Text="当前曲线名称:" FontSize="14" VerticalAlignment="Center"/>
            <TextBlock x:Name="liveChartName" Text="{Binding ElementName=comboBoxName1, Path=Text}" Margin="10,0,0,0" Width="100" FontSize="14" VerticalAlignment="Center"/>
        </StackPanel>

        <lvc:CartesianChart Grid.Row="1" AnimationsSpeed="0:0:0.5" Zoom="{Binding iZoom}" Pan="{Binding iPan}">
            <lvc:CartesianChart.Series>
                <lvc:LineSeries Values="{Binding ChartValues}"
                                PointGeometry="{x:Null}"
                                Fill="Transparent"
                                StrokeThickness="2"
                                Stroke="Red"
                                LineSmoothness="1"/>
            </lvc:CartesianChart.Series>

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

            <lvc:CartesianChart.AxisY>
                <lvc:Axis MinValue="0" MaxValue="{Binding Ymax}" Foreground="Black">
                    <lvc:Axis.Separator>
                        <lvc:Separator Step="{Binding YStep}" />
                    </lvc:Axis.Separator>
                </lvc:Axis>
            </lvc:CartesianChart.AxisY>
        </lvc:CartesianChart>
    </Grid>
</UserControl>

 

 

 后端部分:

using LiveCharts;
using LiveCharts.Configurations;
using MvvmProjectFrame.Models;
using Prism.Mvvm;
using System;
using System.ComponentModel;
using System.Data.SQLite;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace MvvmProjectFrame.Views
{
    /// <summary>
    /// RealTimeView.xaml 的交互逻辑
    /// </summary>
    public partial class RealTimeView : UserControl,INotifyPropertyChanged
    {
        public ChartValues<MeasureModel> ChartValues { get; set; }
        public Func<double, string> DateTimeFormatter { get; set; }

        SqliteConnection sqlite = new SqliteConnection();

        //实现接口通知
        public event PropertyChangedEventHandler PropertyChanged;
        public void Changed(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        //X轴显示数据最小个数和最大个数
        private double _axisMax;
        public double AxisMax
        {
            get { return _axisMax; }
            set { _axisMax = value; Changed("AxisMax"); }
        }

        private double _axisMin;
        public double AxisMin
        {
            get { return _axisMin; }
            set { _axisMin = value; Changed("AxisMin"); }
        }

        //轴步骤单元
        public double AxisStep { get; set; }
        public double AxisUnit { get; set; }

        //Y轴显示数据最大数和间隔
        private double _yMax;
        public double Ymax
        {
            get { return _yMax; }
            set { _yMax = value; Changed("Ymax"); }
        }
        private double _yStep;

        public double YStep
        {
            get { return _yStep; }
            set { _yStep = value; Changed("YStep"); }
        }

        //曲线数值
        public double curveValue { get; set; }

        //曲线启停控制
        public bool liveChartStart { get; set; }

        //存储时间
        public DateTime dateTimeData { get; set; }

        //实时曲线和历史曲线切换
        public bool curveMode { get; set; } = false;

        //表名称
        public string _chartName { get; set; } = "实时曲线";

        //放大平移功能
        private string _izoom = "None";
        public string iZoom
        {
            get { return _izoom; }
            set { _izoom = value; Changed("iZoom"); }
        }

        private string _ipan = "None";
        public string iPan
        {
            get { return _ipan; }
            set { _ipan = value; Changed("iPan"); }
        }

        public RealTimeView()
        {
            InitializeComponent();
            try
            {
                //使用DateTime.Ticks作为X,将value属性用作Y
                var mapper = Mappers.Xy<MeasureModel>()
                    .X(model => model.DateTime.Ticks)
                    .Y(model => model.Value);

                //全局保存映射器。
                Charting.For<MeasureModel>(mapper);

                //values属性将存储我们的值数组
                ChartValues = new ChartValues<MeasureModel>();

                //设置如何显示X标签
                DateTimeFormatter = value => new DateTime((long)value).ToString("HH:mm:ss");

                //AxisStep强制X轴上每个分隔符之间的距离
                AxisStep = TimeSpan.FromSeconds(1).Ticks;
                //AxisUnit力让轴知道我们正在绘制秒
                //这并不总是必要的,但它可以防止错误的标签
                AxisUnit = TimeSpan.TicksPerSecond;
            }
            catch (Exception)
            {
                return;
            }

            this.comboBoxName1.Items.Add("一次供水温度");
            this.comboBoxName1.Items.Add("一次回水温度");
            this.comboBoxName1.Items.Add("二次供水温度");
            this.comboBoxName1.Items.Add("二次回水温度");
            this.comboBoxName1.Items.Add("一次供水压力");
            this.comboBoxName1.Items.Add("一次回水压力");
            this.comboBoxName1.Items.Add("二次供水压力");
            this.comboBoxName1.Items.Add("二次回水压力");
            this.comboBoxName1.SelectedIndex = 0;

            liveChartStart = true;
            try
            {
                //绑定数据上下文
                DataContext = this;
                Task.Run(async () =>
                {
                    await Read();
                });
            }
            catch (Exception)
            {
                return;
            }
        }

       

        

        //开始
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            liveChartStart = true;
        }

        //停止
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            liveChartStart = false;
        }

        //实时曲线
        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            curveMode = false;
            liveChartStart = true;
            _chartName = "实时曲线";
            ChartValues.Clear();
            liveYmax(this.comboBoxName1);
            //iZoom = "None";
            //iPan = "None";
        }

        //历史曲线
        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            curveMode = true;
            liveChartStart = false;
            ChartValues.Clear();
            _chartName = "历史曲线";
            //iZoom = "X";
            //iPan = "Unset";
        }

        //查询
        private void Button_Click_4(object sender, RoutedEventArgs e)
        {
            if (_chartName == "历史曲线")
            {
                SqliteData(sqlite, "./data.db", "datatask", dateTimeBox3.Text, dateTimeBox4.Text, this.comboBoxName1.Text);
            }
        }

        /// <summary>
        /// 连接数据库对应显示曲线
        /// </summary>
        /// <param name="dbpath">数据库地址</param>
        /// <param name="tableName">表名称</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="lineName">曲线名称</param>
        private void SqliteData(SqliteConnection sqlite, string dbpath, string tableName, string startTime, string endTime, string lineName)
        {
            try
            {
                //建立数据块连接
                sqlite.SqliteConnOpen(dbpath);
                //全部查询数据,返回一个数据流
                SQLiteDataReader reader = sqlite.QueryCriteria(tableName, "Time", startTime, endTime);
                //判断曲线名称,reader循环执行下一条返回true,直至没有下一条返回false;
                switch (lineName)
                {
                    case "一次供水温度":
                        if (reader != null)
                        {
                            while (reader.Read())
                            {
                                SetAddData(reader, "Temp1", "DateTime");
                            }
                            //获取当前时间,设置X轴长度限制
                            SetAxisProperties(dateTimeData, 30, 0, 150, 25);
                        }
                        break;
                    case "一次回水温度":
                        if (reader != null)
                        {
                            while (reader.Read())
                            {
                                SetAddData(reader, "Temp2", "DateTime");
                            }
                            //获取当前时间,设置X轴长度限制
                            SetAxisProperties(dateTimeData, 30, 0, 150, 25);
                        }
                        break;
                    case "二次供水温度":
                        if (reader != null)
                        {
                            while (reader.Read())
                            {
                                SetAddData(reader, "Temp3", "DateTime");
                            }
                            //获取当前时间,设置X轴长度限制
                            SetAxisProperties(dateTimeData, 30, 0, 150, 25);
                        }
                        break;
                    case "二次回水温度":
                        if (reader != null)
                        {
                            while (reader.Read())
                            {
                                SetAddData(reader, "Temp4", "DateTime");
                            }
                            //获取当前时间,设置X轴长度限制
                            SetAxisProperties(dateTimeData, 30, 0, 150, 25);
                        }
                        break;
                    case "一次供水压力":
                        if (reader != null)
                        {
                            while (reader.Read())
                            {
                                SetAddData(reader, "Pressure1", "DateTime");
                            }
                            //获取当前时间,设置X轴长度限制
                            SetAxisProperties(dateTimeData, 30, 0, 16, 2);
                        }
                        break;
                    case "一次回水压力":
                        if (reader != null)
                        {
                            while (reader.Read())
                            {
                                SetAddData(reader, "Pressure2", "DateTime");
                            }
                            //获取当前时间,设置X轴长度限制
                            SetAxisProperties(dateTimeData, 30, 0, 16, 2);
                        }
                        break;
                    case "二次供水压力":
                        if (reader != null)
                        {
                            while (reader.Read())
                            {
                                SetAddData(reader, "Pressure3", "DateTime");
                            }
                            //获取当前时间,设置X轴长度限制
                            SetAxisProperties(dateTimeData, 30, 0, 16, 2);
                        }
                        break;
                    case "二次回水压力":
                        if (reader != null)
                        {
                            while (reader.Read())
                            {
                                SetAddData(reader, "Pressure4", "DateTime");
                            }
                            //获取当前时间,设置X轴长度限制
                            SetAxisProperties(dateTimeData, 30, 0, 16, 2);
                        }
                        break;
                }
                sqlite.SqliteConnClose();
            }
            catch (Exception)
            {
                return;
            }
        }

        private async Task Read()
        {
            while (true)
            {
                if (liveChartStart)
                {
                    await Task.Delay(250);
                    this.Dispatcher.Invoke(() =>
                    {
                        if (curveMode == false)
                        {
                            liveYmax(this.comboBoxName1);
                            ChartValues.Add(new MeasureModel
                            {
                                DateTime = DateTime.Now,
                                Value = curveValue
                            });
                            //只使用最后150个值
                            if (ChartValues.Count > 150) ChartValues.RemoveAt(0);
                        }
                    });
                }
            }
        }

        /// <summary>
        /// 根据不同曲线名称,设置Y轴最大值、间距,随机数范围
        /// </summary>
        /// <param name="comboBox"></param>
        public void liveYmax(ComboBox comboBox)
        {
            try
            {
                switch (comboBox.Text)
                {
                    case "一次供水温度":
                    case "一次回水温度":
                    case "二次供水温度":
                    case "二次回水温度":
                        SetAxisProperties(DateTime.Now, 1, 8, 150, 25);
                        curveValue = MeasureModel.TempValue;
                        break;
                    case "一次供水压力":
                    case "一次回水压力":
                    case "二次供水压力":
                    case "二次回水压力":
                        SetAxisProperties(DateTime.Now, 1, 8, 32, 2);
                        curveValue = MeasureModel.TempValue;
                        break;
                }
            }
            catch (Exception)
            {
                return;
            }

        }

        /// <summary>
        /// 设置X/Y轴属性
        /// </summary>
        /// <param name="now">当前时间</param>
        /// <param name="minSeconds">x轴最小秒数</param>
        /// <param name="maxSeconds">x轴最大秒数</param>
        /// <param name="ymax">y轴最大值</param>
        /// <param name="ystep">y轴间距</param>
        private void SetAxisProperties(DateTime now, int minSeconds, int maxSeconds, double ymax, double ystep)
        {
            try
            {
                //让我们强制轴 落后8秒
                AxisMax = now.Ticks + TimeSpan.FromSeconds(minSeconds).Ticks; // lets force the axis to be 1 second ahead
                AxisMin = now.Ticks - TimeSpan.FromSeconds(maxSeconds).Ticks; // and 8 seconds behind
                Ymax = ymax;
                YStep = ystep;
            }
            catch (Exception)
            {
                return;
            }
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="reader">数据流</param>
        /// <param name="name">数据库里的名称</param>
        /// <param name="dateTime">数据库里的时间</param>
        private void SetAddData(SQLiteDataReader reader, string name, string dateTime)
        {
            curveValue = Convert.ToDouble(reader[name]);
            dateTimeData = Convert.ToDateTime(reader[dateTime]);
            this.Dispatcher.Invoke(() =>
            {
                ChartValues.Add(new MeasureModel
                {
                    DateTime = dateTimeData,
                    Value = curveValue
                });
            });
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: datalabelsformatter是一个用于格式化数据标签的函数。它可以被用于各种图表类型,包括livechart。livechart是一种可动态更新的图表,可以实时展现数据的变化。在livechart中,datalabelsformatter可以将数据标签格式化为特定的文本,使得这些标签更加易于理解和读取。例如,在一个实时的股票价格图表中,datalabelsformatter可以将数据标签格式化为如“$10.00”这样的形式,以便用户可以更加清晰地读取价格信息。另外,在一个实时天气预报图表中,datalabelsformatter可以将数据标签格式化为如“25°C”这样的形式,以便用户可以更加方便地理解当前天气情况。总之,datalabelsformatter是一个非常有用的工具,在livechart等图表中可以帮助用户更好地理解和使用数据。 ### 回答2: datalabelsformatter是一个用于格式化数据标签的函数,在livechart中经常会用到。livechart是一种实时更新数据的图表类型,通过动态的数据展示方式,可以使数据分析更加直观。 在livechart中,datalabelsformatter可以用来自定义数据标签的显示方式,包括数字格式、数值单位、小数位数等等。通过设置datalabelsformatter,可以使livechart中的数据标签更加符合我们的需求,从而更好地展示数据。 举个例子,比如我们希望在一个柱状图中展示每个柱子的百分比,并且保留一位小数。我们可以使用以下代码来设置datalabelsformatter: ``` datalabelsformatter: function() { return (this.y * 100).toFixed(1) + '%'; }, ``` 通过这段代码,我们让每个数据标签显示了柱子高度的百分比,并且保留了一位小数。这样,在livechart中展示数据的同时,也让数据更加易读易懂。 总之,datalabelsformatter是一个非常实用的函数,在livechart中的应用非常广泛。通过自定义数据标签的显示方式,我们可以更好地展示数据,并且提高数据分析的效率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值