2013-06-20 3 views
2

나는 모든 노드가 이중 목록을 나타내는 treeViewelement을가집니다.Microsoft 차트 컨트롤 - 실패 후 차트 다시 그리기 (적색 십자가)

list에 값을 표시하려면 DataVisualization.Charting 컨트롤을 사용하고 있습니다.

일부 목록에 대해서는 예외가 발생합니다. RecalculateAxesScale(System.OverflowException: Value was either too large or too small for a Decimal). 이 오류를 무시하고 차트에 큰 적색 십자가가 표시됩니다.

이제 다른 노드를 클릭하면 유효하지만이 차트의 차트를 표시하려고하지만 차트가 다시 그려지지 않습니다. 그것은 항상 빨간색 X를 표시

내 코드 : dblList의

private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) 
{ 

//Refresh chart: 
chart1.Series.Clear(); 
chart1.ResetAutoValues(); 
chart1.ResetText(); 

//plot new doublelist 
var series = new Series 
{ 
    Name = "name", 
    Color = color, 
    ChartType = SeriesChartType.Line, 
    ChartArea = "chartName" 
}; 

this.chart1.Series.Add(series); 
    series.Points.DataBindY(doubleList); 
    var chartArea = chart1.ChartAreas["chartName"]; 
    chartArea.RecalculateAxesScale(); 
    chartArea.AxisX.Minimum = 1; 
    chartArea.AxisX.Maximum = doubleList.Count; 
    chartArea.CursorX.AutoScroll = true; 
    chartArea.CursorY.AutoScroll = true; 

    // Allow user to select area for zooming 
    chartArea.CursorX.IsUserEnabled = true; 
    chartArea.CursorX.IsUserSelectionEnabled = true; 

    // Set automatic zooming`<br> 
    chartArea.AxisX.ScaleView.Zoomable = true; 
    chartArea.AxisY.ScaleView.Zoomable = true; 
    chartArea.AxisX.ScrollBar.IsPositionedInside = true; 

    //reset zoom 
    chartArea.AxisX.ScaleView.ZoomReset(); 
    chart1.Invalidate(); 
} 

[편집]

유형 : 예외의

List<double> doubleList= (from s in myData select s.value).ToList(); 

전체 스택 :

{System.OverflowException: Value was either too large or too small for a Decimal. 
at System.Decimal.FCallMultiply(Decimal& d1, Decimal& d2) 
at System.Decimal.op_Multiply(Decimal d1, Decimal d2) 
at System.Windows.Forms.DataVisualization.Charting.Axis.RoundedValues(Double inter, Boolean shouldStartFromZero, Boolean autoMax, Boolean autoMin, Double& min, Double& max) 
at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateNumberAxis(Double& minimumValue, Double& maximumValue, Boolean shouldStartFromZero, Int32 preferredNumberOfIntervals, Boolean autoMaximum, Boolean autoMinimum) 
at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateAxis(Double& minimumValue, Double& maximumValue, Boolean autoMaximum, Boolean autoMinimum) 
at System.Windows.Forms.DataVisualization.Charting.Axis.EstimateAxis() 
at System.Windows.Forms.DataVisualization.Charting.ChartArea.SetDefaultAxesValues() 
at System.Windows.Forms.DataVisualization.Charting.ChartArea.SetData(Boolean initializeAxes, Boolean checkIndexedAligned) 

at System.Windows.Forms.DataVisualization.Charting.ChartArea.RecalculateAxesScale() 
,

[EDIT 2

예에서 :

List<double> dblList = new List<double>(); 
    dblList.Add(0.0); 
    dblList.Add(-7.4876421623346545E-36); 
    dblList.Add(1.0); 
    dblList.Add(-26697097281536.0); 
    dblList.Add(-6.8163553952838136E+28); //problem!!!!! 

마지막 값 (예외없이 적십자사) 문제를 생성한다. 그래서 목록을 변환하기위한 최소값과 최대 값이 적절하지 않은 것 같습니다. 그것에 대한 아이디어가 있습니까?

double min = (double)Decimal.MinValue; //min = -7.9228162514264338E+28 
double max = (double)Decimal.MaxValue; //max = 7.9228162514264338E+28 
+0

내 대답은 쓸모 없으므로 여기로 이동하십시오. 값 자체는 괜찮지 만 System.Decimal은 언더 플로/오버플로에 대한 산술 연산을 위해 throw됩니다. 그리고 체크/체크되지 않은 요구 사항을 무시합니다 ... –

+0

문제가 무엇인지 알 수 있습니까? 어떻게 처리 할 수 ​​있습니까? 너무 높거나 낮은 값을 일종의 표준 값으로 대체해야합니까? – purbsel

+0

예, 솔루션 일 수도 있지만 줌을 처리해야합니다 (축이 다시 계산 될 수 있으므로). –

답변

2

RecalculateAxesScale의 오류 (System.OverflowException이 : 값이 너무 크거나 진수 너무 작은 중 하나였다) 때문에 라이브러리의 버그, 던져졌다. 차트 함수 구현 (특히 축 재 계산/확대/축소)에서 십진수 값을 사용하므로 문제가 발생합니다.

그냥 그 값이

double min = (double)Decimal.MinValue; 
double max = (double)Decimal.MaxValue; 

보다 큰 경우 모든 차트 지점을 확인하고 문제가 해결되지 않은이 값으로 교체하십시오.

위의 값 대신 경계로 -/+7.92E+27을 선택했습니다. 이제 모든 것이 정상적으로 작동합니다.

1

그래서 지금까지 제시된 해결책은 거의 정확하지 않지만 정확합니다. 오픈 소스라면 문제를 직접 해결할 수 있지만 실제로 나는 실제 구현에 대해서만 추측해야합니다. 차트 라이브러리는 Decimal로 변환 된 것으로 나타나며 double에서 변환하는 동안 값 범위를 초과하면 예외를 throw합니다. 모든 범위를 벗어나는 값을 확인하고 Decimal.MinValue 및 Decimal.MaxValue로 설정하는 명백한 해결 방법은 동일한 예외와 함께 실패합니다. 사실 차트 엔진이 허용하는 실제 최대 값과 최소값은 약간의 실험을 통해 나 자신에 의해 대략적으로 더 작은 순서로 발견되었습니다.

때때로 논의가 두드러지는 이중 값을 가진 TVQ 차트의 작업 소스 코드입니다. 최대 및 최소 차트 값은 효율성을 위해 미리 계산됩니다.AddXY에 대한 모든 호출을 SafeChartDouble로 바꾸십시오. 응용 프로그램에 필요한대로 AxisX 데이터 유형을 변경하십시오.

private static readonly double SCALE_FACTOR = 10; 
    private static readonly double MIN_CHART_VALUE 
     = Convert.ToDouble(Decimal.MinValue)/SCALE_FACTOR; 
    private static readonly double MAX_CHART_VALUE 
     = Convert.ToDouble(Decimal.MaxValue)/SCALE_FACTOR; 

    private void SafeChartDouble(Series cs, DateTime ts, double dv) 
    { 
     // microsoft chart component breaks on very large/small values 
     double chartv; 
     if (dv < MIN_CHART_VALUE) 
     { 
      chartv = MIN_CHART_VALUE; 
     } 
     else if (dv > MAX_CHART_VALUE) 
     { 
      chartv = MAX_CHART_VALUE; 
     } 
     else 
     { 
      chartv = dv; 
     } 
     cs.Points.AddXY(ts, chartv); 
    } 
관련 문제