我需要为我的自定义控件将大量数据处理为单个List<ChartData>
。
达到列表计数80,00,000后,它可以正常工作大约300万点它会引发内存不足错误。列表是否有任何计数限制?是的意思是我应该使用任何其他集合而不是列表。
是否有更好的技术将大量数据加载到内存中? proplem在以下函数中。如果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;
}
}
}
}
}
答案 0 :(得分:2)
您的应用程序可以使用数据虚拟化吗? http://www.codeproject.com/Articles/34405/WPF-Data-Virtualization
答案 1 :(得分:2)
即使没有内存问题,也没有任何有意义的方法可以一次性呈现所有这些信息,而无需以某种方式对其进行总结。您拥有的数据点数多于1920x1080屏幕中的像素数。您需要考虑减少对您的用例有意义的点数的方法。
答案 2 :(得分:0)
最后我解决了这个问题。
allpoints.Add(startPoint);
allpoints.Add(startControlPoint);
allpoints.Add(endControlPoint);
allpoints.Add(endPoint);
allpoints分为4个列表
startPoints<IChartDataPoint>
endControlPointS<IChartDataPoint>
endControlPointS<IChartDataPoint>
endPointS<IChartDataPoint>