LiveCharts WPF渲染性能差

LiveCharts WPF渲染性能差,wpf,livecharts,Wpf,Livecharts,我正在构建一个WPF工具,用于可视化冷藏集装箱(冷却集装箱)的数据。传感器数据(温度、设定值、湿度)的简单绘图。 问题在于渲染性能。 数据通过RESTAPI以惊人的速度加载。将值重新格式化为DateTimePoints(需要1ms)后,它们将被设置为绑定序列集合上的齿轮值。设置值后,应用程序立即冻结10秒,不连贯地呈现图表,整个应用程序不再可用。 我做了所有的例子和演示,但我无法让LiveCharts以可用的方式运行,我不知道我在这里做错了什么 卡特西安查特 3x GStepLineSeries

我正在构建一个WPF工具,用于可视化冷藏集装箱(冷却集装箱)的数据。传感器数据(温度、设定值、湿度)的简单绘图。
问题在于渲染性能。 数据通过RESTAPI以惊人的速度加载。将值重新格式化为DateTimePoints(需要1ms)后,它们将被设置为绑定序列集合上的齿轮值。设置值后,应用程序立即冻结10秒,不连贯地呈现图表,整个应用程序不再可用。 我做了所有的例子和演示,但我无法让LiveCharts以可用的方式运行,我不知道我在这里做错了什么

卡特西安查特
3x GStepLineSeries,每个系列(在本例中)626个值
XaxiFormatter日期时间点

我不知道我做错了什么。1900齿轮值是否过高?LiveCharts有那么糟糕吗

公共GSTEPLINE系列电源温度
{
获取{return\u supplyTemperatures???(\u supplyTemperatures=new GStepLineSeries(){Title=“Supply”});}
设置
{
_供应温度=值;
RaisePropertyChanged();
}
}
公共GSTEPLINE系列返回温度
{
获取{return\u returnTemperatures???(\u returnTemperatures=new GStepLineSeries{Title=“return”});}
设置
{
_返回温度=值;
RaisePropertyChanged();
}
}
公共GSTEPLINE系列设定点
{
得到
{
返回设置点??(\u设置点=新的GSTEPLINESERIATES
{
Title=“设定点”,
填充=画笔。透明,
PointGeometry=null
});
}
设置
{
_设定点=数值;
RaisePropertyChanged();
}
}
公共系列收集ReeferDataTemperatureSeries
{
得到
{
如果(_reeferDataTemperatureSeries==null)
{
_reeferDataTemperatureSeries=
新的SeriesCollection(GetSeriesConfig()){供应温度、返回温度、设定点};
}
返回_reeferDataTemperatureSeries;
}
设置
{
_reeferDataTemperatureSeries=值;
RaisePropertyChanged();
}
}
私有CartesianMapper GetSeriesConfig()
{
返回Mappers.Xy()
.X(rdcv=>(双精度)rdcv.DateTime.Ticks)
.Y(rdcv=>rdcv.Value);
}
Xaml:


通过做一些更改,我能够在大约1.5秒内绘制出每个系列中包含1000个数据点的图形

  • 将图表上的“可悬停”设置为false
  • 使所有序列上的点几何图形为空

我的代码版本也使用了标准图表,而不是齿轮版本,因为我没有这方面的许可证,所以对您来说可能更快。

不幸的是,WPF的开源图表没有很好的性能。如果你想获得更高的点数和实时更新,那么你可能需要考虑一个商业图表。 我想推荐我自己的组件SciChart作为一个潜在的解决方案。是的,它是商业性的,我会透露我是它的所有者,但是它可以通过为您提供一个性能优异的框架(数百万点,毫秒更新)来真正解决WPF图表速度慢的问题。它还支持MVVM,并具有很多特性

如果你有时间,请看一看,网址是


具体的性能演示可以在页面上找到

我也有这个问题,对我有用的是:

SeriesCollection[0]。value=chartvalues.AsGearedValues()。具有质量(Quality.High)

质量当然是可选的。但即使有20万个点,我也不再有渲染问题了。在我的示例中,CAHRT值是
图表值

只要我错过了asgearedvalues的东西,它就不起作用了,尽管显示它是GearedCollection,应该没问题。

免费的LiveCharts性能非常差。如果您想显示几十个数据点,可能是几百个,也可以。如果要显示大量数据,则需要高性能,齿轮传动就是答案。我从免费版本开始,但在大约1000点之后,UI停止更新,CPU使用率达到40%,即使动画被禁用,鼠标悬停和工具提示也被关闭。唯一有帮助的是将
PointGeometry
设置为
null
。这解决了性能问题,但也删除了点的圆圈,这是不可接受的


然后我尝试了齿轮传动,即使有数千个点,悬停,工具提示启用和默认点几何,速度和性能都非常好(只有1%的CPU使用率)。我一直禁用动画,并将质量设置为低。Geared速度快、重量轻、美观且功能丰富,令人惊叹。只需99美元,它什么都不花。尤其是与SciChart相比,后者的成本高出10倍。我对LiveCharts和Geared唯一关心的是缺乏积极的开发。上一次更新都是在2018年,而Beto似乎刚刚消失。Geared太棒了,如果这个项目被放弃的话,那将是非常悲哀的。再说一次,99美元对于这样一个库来说算不了什么。

你有没有尝试过评测你的应用程序?哪些方法消耗了最多的CPU时间?相关:SciChart一定很好,我们也有这个选项,这很好。然而,Geared还具有出色的性能、许多功能、非常易于使用、MVVM友好、超快速和轻量级。而所有这些都只需支付SciChat价格的一小部分!在图表上花费超过1000美元
 public GStepLineSeries SupplyTemperatures
    {
        get { return _supplyTemperatures ?? (_supplyTemperatures = new GStepLineSeries() { Title = "Supply" }); }
        set
        {
            _supplyTemperatures = value;
            RaisePropertyChanged();
        }
    }

    public GStepLineSeries ReturnTemperatures
    {
        get { return _returnTemperatures ?? (_returnTemperatures = new GStepLineSeries { Title = "Return" }); }
        set
        {
            _returnTemperatures = value;
            RaisePropertyChanged();
        }
    }

    public GStepLineSeries Setpoints
    {
        get
        {
            return _setpoints ?? (_setpoints = new GStepLineSeries
            {
                Title = "Setpoint",
                Fill = Brushes.Transparent,
                PointGeometry = null
            });
        }
        set
        {
            _setpoints = value;
            RaisePropertyChanged();
        }
    }

    public SeriesCollection ReeferDataTemperatureSeries
    {
        get
        {
            if (_reeferDataTemperatureSeries == null)
            {
                _reeferDataTemperatureSeries =
                    new SeriesCollection(GetSeriesConfig()) { SupplyTemperatures, ReturnTemperatures, Setpoints };

            }

            return _reeferDataTemperatureSeries;
        }
        set
        {
            _reeferDataTemperatureSeries = value;
            RaisePropertyChanged();
        }
    }

    private CartesianMapper<DateTimePoint> GetSeriesConfig()
    {
        return Mappers.Xy<DateTimePoint>()
            .X(rdcv => (double)rdcv.DateTime.Ticks)
            .Y(rdcv => rdcv.Value);
    }
     <lvc:CartesianChart
                                Height="800"
                                DisableAnimations="True"
                                IsManipulationEnabled="False"
                                LegendLocation="Top"
                                Series="{Binding ReeferDataTemperatureSeries}">

                                <lvc:CartesianChart.AxisX>
                                    <lvc:Axis
                                        Title="Time"
                                        LabelFormatter="{Binding ReeferDataFormatter}"
                                        RangeChanged="Axis_OnRangeChanged"
                                        Separator="{x:Static lvc:DefaultAxes.CleanSeparator}" />
                                </lvc:CartesianChart.AxisX>
                                <lvc:CartesianChart.AxisY>
                                    <lvc:Axis Title="Temperature" />
                                </lvc:CartesianChart.AxisY>
                            </lvc:CartesianChart>