0

我需要将大量数据处理成一个List<ChartData>用于自定义控件的数据。在达到列表计数 80,00,000 后,大约 300 万点它工作正常它会引发内存不足错误。List 有计数限制吗?是意味着我应该使用任何其他集合而不是列表。

有没有更好的技术将大量数据加载到内存中?问题出在以下函数中。如果 ChartIndexedDataPoint.Count 达到 30,00,000 以上

 protected override void CalculateSegments(ChartSeries series, ChartIndexedDataPoint[] points)
    {
        double[] yCoef={0};
        IChartDataPoint startPoint = null;
        IChartDataPoint endPoint = null;
        ChartPoint startControlPoint = null;
        ChartPoint endControlPoint = null;
        if (points.Length >= 2)
        {
            NaturalSpline(points, out yCoef);
            if (series.ShowEmptyPoints == false && series.Area.EnableLazyLoading == true)
            {
                allpoints = new List<IChartDataPoint>();
                if (series.ActualYAxis.IsAutoSetRange == true || series.ActualXAxis.IsAutoSetRange == true)
                {
                    series.Segments.Clear();
                    series.Adornments.Clear();

                    for (int i = 0, count = points.Length; i < count - 1; i++)
                    {
                        startPoint = points[i].DataPoint;
                        endPoint = points[i + 1].DataPoint;
                        GetBezierControlPoints(startPoint, endPoint, yCoef[i], yCoef[i + 1], out startControlPoint, out endControlPoint);
                        allpoints.Add(startPoint);
                        allpoints.Add(startControlPoint);
                        allpoints.Add(endControlPoint);
                        allpoints.Add(endPoint);
                    }
                    series.Segments.Add(new ChartFastSplineSegment(allpoints, points, series)); 
                    return;
                }
                if (series.Segments.Count != 0)
                {
                    ChartFastSplineSegment segment = ((ChartFastSplineSegment)series.Segments[0]);

                    if (segment.Points != null && segment.Points.Count < points.Length)
                    {
                        segment.GetSegmet(points[points.Length - 1].DataPoint, series);
                    }
                    else if (segment.Points == null || segment.Points.Count > points.Length)
                    {                           
                        for (int i = 0, count = points.Length; i < count - 1; i++)
                        {
                            startPoint = points[i].DataPoint;
                            endPoint = points[i + 1].DataPoint;
                            GetBezierControlPoints(startPoint, endPoint, yCoef[i], yCoef[i + 1], out startControlPoint, out endControlPoint);
                            allpoints.Add(startPoint);
                            allpoints.Add(startControlPoint);
                            allpoints.Add(endControlPoint);
                            allpoints.Add(endPoint);
                        }
                        segment.UpdateSegment(allpoints, series);
                        segment.refresh = true;
                    }
                }
                else
                {                        
                    for (int i = 0, count = points.Length; i < count - 1; i++)
                    {
                        startPoint = points[i].DataPoint;
                        endPoint = points[i + 1].DataPoint;
                        GetBezierControlPoints(startPoint, endPoint, yCoef[i], yCoef[i + 1], out startControlPoint, out endControlPoint);
                        allpoints.Add(startPoint);
                        allpoints.Add(startControlPoint);
                        allpoints.Add(endControlPoint);
                        allpoints.Add(endPoint);
                    }
                    series.Segments.Add(new ChartFastSplineSegment(allpoints, points, series)); 
                }
            }
            else if (series.Segments.Count == 0 || series.internaldata_modified || allpoints.Count > points.Length)
            {
                allpoints = new List<IChartDataPoint>();
                series.Segments.Clear();
                series.Adornments.Clear();
                ChartIndexedDataPoint[] pts = points;
                List<ChartIndexedDataPoint> tempPointArray = new List<ChartIndexedDataPoint>();                    
                for (int i = 0; i < pts.Length-1; i++)
                {
                    switch (pts[i].DataPoint.EmptyPoint)
                    {
                        case false:
                            {
                                startPoint = points[i].DataPoint;
                                endPoint = points[i + 1].DataPoint;
                                GetBezierControlPoints(startPoint, endPoint, yCoef[i], yCoef[i + 1], out startControlPoint, out endControlPoint);
                                allpoints.Add(startPoint);
                                allpoints.Add(startControlPoint);
                                allpoints.Add(endControlPoint);
                                allpoints.Add(endPoint);
                                tempPointArray.Add(pts[i]);
                                break;
                            }
                        case true:
                            {
                                if (allpoints.Count > 0)
                                {
                                    if (i < points.Length)
                                    {
                                        startPoint = points[i].DataPoint;
                                        endPoint = points[i + 1].DataPoint;
                                        GetBezierControlPoints(startPoint, endPoint, yCoef[i], yCoef[i + 1], out startControlPoint, out endControlPoint);
                                        allpoints.Add(startPoint);
                                        allpoints.Add(startControlPoint);
                                        allpoints.Add(endControlPoint);
                                        allpoints.Add(endPoint);
                                    }
                                    tempPointArray.Add(points[i]);

                                }
                                break;
                            }
                    }
                }
                if (tempPointArray.Count != 0 && allpoints.Count != 0)
                {
                    series.Segments.Add(new ChartFastSplineSegment(allpoints, tempPointArray.ToArray(), series));
                }
            }
            if (series.Segments.Count > 0)
            {
                List<ChartIndexedDataPoint> tempPointArray = new List<ChartIndexedDataPoint>();
                List<ChartIndexedDataPoint> pts = points.ToList();

                if (!series.Contains_emptypt)
                {
                    int cnt = (allpoints.Count+4)/4;
                    while ((allpoints.Count + 4) / 4 != points.Length && (allpoints.Count + 4) / 4 < points.Length)
                    {
                        startPoint = points[cnt-1].DataPoint;
                        endPoint = points[cnt].DataPoint;
                        GetBezierControlPoints(startPoint, endPoint, yCoef[cnt-1], yCoef[cnt], out startControlPoint, out endControlPoint);
                        allpoints.Add(startPoint);
                        allpoints.Add(startControlPoint);
                        allpoints.Add(endControlPoint);
                        allpoints.Add(endPoint);
                        cnt++;
                    }
                }
                (series.Segments[0] as ChartFastSplineSegment).m_points = allpoints;
                if (series.ActualXAxis.IsAutoSetRange || series.Zoomactionenabled)
                {                        
                    double X_MAX = allpoints.Max(x => x.X);
                    double X_MIN = allpoints.Min(x => x.X);
                    (series.Segments[0] as ChartFastSplineSegment).xRange = new DoubleRange(X_MIN, X_MAX);//xRange + cdpt.X;
                    if (series.ActualXAxis.RangeCalculationMode == RangeCalculationMode.AdjustAcrossChartTypes)
                    {
                        (series.Segments[0] as ChartFastSplineSegment).xRange += (series.Segments[0] as ChartFastSplineSegment).xRange.Start - 0.5;
                        (series.Segments[0] as ChartFastSplineSegment).xRange += (series.Segments[0] as ChartFastSplineSegment).xRange.End + 0.5;
                    }
                    (series.Segments[0] as ChartFastSplineSegment).SetRange(series);

                }
                if (series.ActualYAxis.IsAutoSetRange || series.Zoomactionenabled)
                {                        
                    double Y_MAX = allpoints.Max(y => y.Y);
                    double Y_MIN = allpoints.Min(y => y.Y);

                    (series.Segments[0] as ChartFastSplineSegment).yRange = new DoubleRange(Y_MIN, Y_MAX);//yRange + cdpt.Y;

                    if (series.ActualXAxis.RangeCalculationMode == RangeCalculationMode.AdjustAcrossChartTypes)
                    {
                        (series.Segments[0] as ChartFastSplineSegment).xRange += (series.Segments[0] as ChartFastSplineSegment).xRange.Start - 0.5;
                        (series.Segments[0] as ChartFastSplineSegment).xRange += (series.Segments[0] as ChartFastSplineSegment).xRange.End + 0.5;
                    }

                    (series.Segments[0] as ChartFastSplineSegment).SetRange(series);
                    if (series.Zoomactionenabled)
                    {
                        series.Zoomactionenabled = false;
                    }
                }
            }
        }     
    }
4

3 回答 3

2

您的应用程序可以利用数据虚拟化吗?http://www.codeproject.com/Articles/34405/WPF-Data-Virtualization

于 2012-11-28T17:23:15.360 回答
2

即使没有记忆问题,也没有有意义的方式来一次呈现所有这些信息而不以某种方式对其进行总结。您拥有的数据点比 1920x1080 屏幕中的像素多。您需要想办法减少对您的用例有意义的点数。

于 2012-11-28T17:41:19.100 回答
0

最后我解决了这个问题。

allpoints.Add(startPoint);
allpoints.Add(startControlPoint);
allpoints.Add(endControlPoint);
allpoints.Add(endPoint);

allpoints 到 4 个列表中

startPoints<IChartDataPoint>
endControlPointS<IChartDataPoint>
endControlPointS<IChartDataPoint>
endPointS<IChartDataPoint>
于 2012-11-29T16:51:28.273 回答