LiveCharts 在更改轴MinValue 和 MaxValue或添加新数据时重新渲染整个图

如何解决LiveCharts 在更改轴MinValue 和 MaxValue或添加新数据时重新渲染整个图

我创建了一个包含 5 个图表的 LineChart。每个有 250 分:每 1 分钟 1 分。我有一个移动 MinValueX 和 MaxValueX 的按钮。和一个事件 UserControl_MouseDown 将新数据添加到 1 个图表。但是当我调用它时,它需要 15-20 秒来移动或添加数据到图中。我认为 1250 点并不多。看起来它重新绘制了整个图形,而不是移动它或添加新数据。

我能否以某种方式将渲染行为更改为更优化?

这是我的 LineChart 控件:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using LiveCharts;
using LiveCharts.Defaults;
using LiveCharts.Wpf;

namespace Chart
{
    /// <summary>
    /// Interaction logic for LineChart2.xaml
    /// </summary>
    public partial class LineChart2 : UserControl,INotifyPropertyChanged
    {
        #region properties
        public SeriesCollection SeriesCollection { get; set; }
        private Dictionary<string,List<DateTimePoint>> SeriesFullCollection { get; set; }
        public Func<double,string> XFormatter { get; set; }
        public long Axisstep { get; set; }
        public double MinValueX { get; set; }
        public double MaxValueX { get; set; }

        private DateTime minValueXDate;
        public DateTime MinValueXDate
        {
            get { return minValueXDate; }
            set { minValueXDate = value;
                MinValueX = value.Ticks;
                OnPropertyChanged("MinValueX");
            }
        }
        private DateTime maxValueXDate;
        public DateTime MaxValueXDate
        {
            get { return maxValueXDate; }
            set
            {
                maxValueXDate = value;
                MaxValueX = value.Ticks;
                OnPropertyChanged("MaxValueX");
            }
        }
        public double MinValueY { get; set; }
        public double MaxValueY { get; set; }
        public int ChartButtonsId { get; set; }
        #endregion
        public LineChart2()
        {
            SeriesFullCollection = new Dictionary<string,List<DateTimePoint>>();
            SeriesCollection = new SeriesCollection();
            this.Loaded += ControlLoaded;                     
            DataContext = this;            
            InitializeComponent();       
        }

        private void ControlLoaded(object sender,RoutedEventArgs e)
        {
            MinValueXDate = DateTime.Now.AddHours(-3.5);
            MaxValueXDate = DateTime.Now.AddHours(0.5);
            Axisstep = TimeSpan.FromMinutes(15).Ticks;
            XFormatter = val => new DateTime((long)val).ToString("HH:mm");

            MinValueY = 0;            //Test
            MaxValueY = 20;            //Test
            //Test
            Text2Add("A");
            Text2Add("B");
            Text2Add("C");
            Text2Add("D");
            Text2Add("E");
            RefreshCollection();
        }

        #region Add/Update/Remove
        public void AddChart(string title,Dictionary<DateTime,double> data)
        {
            List<DateTimePoint> dateTimePoints = new List<DateTimePoint>();
            foreach (var item in data)
                dateTimePoints.Add(new DateTimePoint(item.Key,item.Value));

            SeriesFullCollection.Add(title,dateTimePoints);
            AddToCollection(title);
        }
        public void UpdateChart(string title,double> data)
        {
            var series = SeriesCollection.FirstOrDefault(x => x.Title == title);
            var seriesfull = SeriesFullCollection.FirstOrDefault(x => x.Key == title);
            if (series != null)
                foreach (var item in data)
                {
                    series.Values.Add(new DateTimePoint(item.Key,item.Value));
                    seriesfull.Value.Add(new DateTimePoint(item.Key,item.Value));
                }
        }
        public void RemoveChart(string title)
        {
            var series = SeriesCollection.FirstOrDefault(x => x.Title == title);
            var seriesfull = SeriesFullCollection.FirstOrDefault(x => x.Key == title);
            if (series != null)
            {
                SeriesCollection.Remove(series);
                SeriesFullCollection.Remove(seriesfull.Key);
            }
            RefreshCollection();
        }

        private void AddToCollection(string title)
        {
            var seriesfull = SeriesFullCollection.FirstOrDefault(x => x.Key == title);
            var l = new Lineseries();
            l.Title = seriesfull.Key;
            l.Values = new ChartValues<DateTimePoint>();
            l.PointGeometrySize = 2;
            l.Values.AddRange(seriesfull.Value.Where(x => x.DateTime >= MinValueXDate && x.DateTime <= MaxValueXDate));
            SeriesCollection.Add(l);
        }
        #endregion
        #region EventsMethod
        public void MoveNext()
        {
            MinValueXDate = MinValueXDate.AddTicks(Axisstep * 2);
            MaxValueXDate = MaxValueXDate.AddTicks(Axisstep * 2);
            //RefreshCollection();
        }
        public void MovePrevIoUs()
        {
            MinValueXDate = MinValueXDate.AddTicks(-Axisstep * 2);
            MaxValueXDate = MaxValueXDate.AddTicks(-Axisstep * 2);
            //RefreshCollection();
        }
        public void ZoomIn()
        {
            MinValueXDate = MinValueXDate.AddTicks(Axisstep);
            MaxValueXDate = MaxValueXDate.AddTicks(-Axisstep);
            //RefreshCollection();
        }
        public void ZoomOut()
        {
            MinValueXDate = MinValueXDate.AddTicks(-Axisstep);
            MaxValueXDate = MaxValueXDate.AddTicks(Axisstep);
            //RefreshCollection();
        }
        public void ChangeDate()
        {

        }
        #endregion
        private void RefreshCollection()
        {
            SeriesCollection.Clear();
            foreach (var item in SeriesFullCollection)
            {
                var l = new Lineseries();
                l.Title = item.Key;
                l.Values = new ChartValues<DateTimePoint>();
                l.PointGeometrySize = 2;
                l.Values.AddRange(item.Value.Where(x => x.DateTime >= MinValueXDate && x.DateTime <= MaxValueXDate));
                SeriesCollection.Add(l);
            }
        }
        #region Test
        private void Text2Add(string name)
        {
            var d = new Dictionary<DateTime,double>();
            int last = 0;
            Random r = new Random();
            for (int i = 0; i < 250; i++)
            {
                var next = r.Next(last == 0 ? 0 : last - 1,last == 20 ? 20 : last + 2);
                last = next;
                d.Add(DateTime.Now.AddMinutes(-250+ i),next);
            }
            AddChart(name,d);
        }
        private int aaaa = 0;

        public event PropertyChangedEventHandler PropertyChanged;

        private void UserControl_MouseDown(object sender,MouseButtonEventArgs e)
        {
            var d = new Dictionary<DateTime,double>();
            int last = 0;
            Random r = new Random();
            for (int i = 0; i < 10; i++)
            {
                var next = r.Next(last == 0 ? 0 : last - 1,last == 20 ? 20 : last + 2);
                last = next;
                d.Add(DateTime.Now.AddMinutes(aaaa + i),next);
            }
            aaaa += 10;
            UpdateChart("A",d);
        }
        #endregion
        protected void OnPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(name));
        }

        private void Button_Click(object sender,RoutedEventArgs e)
        {
            MinValueXDate = MinValueXDate.AddTicks(Axisstep * 2);
            MaxValueXDate = MaxValueXDate.AddTicks(Axisstep * 2);
        }
    }
}

和 Xaml:

<UserControl x:Class="Chart.LineChart2"
         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"
         xmlns:local="clr-namespace:Chart"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="800" MouseDown="UserControl_MouseDown">
    <Grid Background="White">
        <lvc:CartesianChart Series="{Binding SeriesCollection}" LegendLocation="Right" >
            <lvc:CartesianChart.AxisY>
                <lvc:Axis Title="Value" MinValue="{Binding MinValueY}" MaxValue="{Binding MaxValueY}"></lvc:Axis>
            </lvc:CartesianChart.AxisY>
            <lvc:CartesianChart.AxisX>
                <lvc:Axis LabelFormatter="{Binding XFormatter}" MinValue="{Binding MinValueX}" MaxValue="{Binding MaxValueX}">
                    <lvc:Axis.Separator>
                        <lvc:Separator Step="{Binding Axisstep}" />
                    </lvc:Axis.Separator>
                </lvc:Axis>
            </lvc:CartesianChart.AxisX>
        </lvc:CartesianChart>
        <Button Height="20" Width="50" Click="Button_Click" Margin="740,10,270"/>
    </Grid>
</UserControl>

解决方法

有一个指向带有 peformance tips 的页面的链接。

提高性能的建议可能性是:

  • 禁用动画
  • 减少图表中的形状数量
  • 尽可能地冻结
  • 避免多次调用 .Add()

所以在你的情况下,我至少会尝试第一个和最后一个建议。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?