2015-05-09 40 views
1

基本上我有一個圖表綁定從一個DataTable哪個來源是從DataGridView。我在圖上有可縮放的函數,我需要它使用X Axis SelectionStart和SelectionEnd來計算所選數據塊。從可縮放圖C#的計算#

所以我有一些最小值最大值和平均值放在另一個選項卡上的richtextbox。如代碼如下所示:在圖像中

//To show the Data from file into the TextBox               
     richTextBox1.AppendText("\n" + "Heart Average : " + HRM.Active.DataRows.Average(r => r.HeartRate) + "\n"); 
     richTextBox1.AppendText("\n" + "Heart Minimum : " + HRM.Active.DataRows.Min(r => r.HeartRate) + "\n"); 
     richTextBox1.AppendText("\n" + "Heart Maximum : " + HRM.Active.DataRows.Max(r => r.HeartRate) + "\n"); 
     richTextBox1.AppendText("\n" + "Average Speed (KM/H): " + HRM.Active.DataRows.Average(r => r.Speed) + "\n"); 
     richTextBox1.AppendText("\n" + "Maximum Speed : " + HRM.Active.DataRows.Max(r => r.Speed) + "\n"); 
     richTextBox1.AppendText(Environment.NewLine + " - (MPH): " + ""); 
     richTextBox1.AppendText("\n" + "Average Power: " + HRM.Active.DataRows.Average(r => r.Power) + "\n"); 
     richTextBox1.AppendText("\n" + "Maximum Power : " + HRM.Active.DataRows.Max(r => r.Power) + "\n"); 
     richTextBox1.AppendText("\n" + "Average Altitude (KM/H): " + HRM.Active.DataRows.Average(r => r.Altitude) + "\n"); 
     richTextBox1.AppendText("\n" + "Maximum Altitude : " + HRM.Active.DataRows.Max(r => r.Altitude) + "\n"); 
     richTextBox1.AppendText("\n" + "Cadence Average : " + HRM.Active.DataRows.Average(r => r.Cadence) + "\n"); 
     richTextBox1.AppendText("\n" + "Cadence Maximum : " + HRM.Active.DataRows.Max(r => r.Cadence) + "\n"); 
     richTextBox1.AppendText("\n" + "Pressure Average : " + HRM.Active.DataRows.Average(r => r.Pressure) + "\n"); 
     richTextBox1.AppendText("\n" + "Pressure Maximum : " + HRM.Active.DataRows.Max(r => r.Pressure) + "\n"); 

現在下面你可以看到圖,它顯示在那裏的數據的圖像,這裏是結合所述數據表的曲線圖的代碼。

protected void drawChart() 
    { 
     DataTable dt = new DataTable(); 
     dt.Clear(); 
     foreach (DataGridViewColumn col in dataGridView1.Columns) 
     { 
      dt.Columns.Add(col.HeaderText); 
     } 
     foreach (DataGridViewRow row in dataGridView1.Rows) 
     { 
      DataRow dRow = dt.NewRow(); 
      foreach (DataGridViewCell cell in row.Cells) 
      { 
       dRow[cell.ColumnIndex] = cell.Value; 
      } 
      dt.Rows.Add(dRow); 
     } 

現在我需要做的是每次我放大時間附近的另一圖形和文本框和灰塊出來它顯示我所選擇的塊中的最小值maximiums和均線!然後,當我縮小它重置爲原來的。

如果你不明白我的意思只是給我發消息,我會提供更多信息。 enter image description here

+0

確實有在[此帖]一個llok(http://stackoverflow.com我們可以在我們的系列做的統計,也許這樣的/問題/ 30055627/MSChart的選-A-部分數據的-和 - 更新圖表/ 30061259#30061259)。這裏解決了一個非常類似的問題。至少如何從選定/可見點計算出像平均值這樣的東西。 - 在Chart內顯示它們是另一回事;您可以添加自定義圖例來顯示實時統計數據。 – TaW

+0

除了在這裏尋求更多幫助外,是否還有其他方式可以與您聯繫?更快,因爲我還沒有聊天功能。 – mvoase

+0

您可以通過在左上方的stackExchnge下拉列表中選擇聊天或重新進入[舊房間](http://chat.stackoverflow.com/rooms/77095/discussion-on-回答逐TAW-圖表-放大到顯示-更精確的數據) – TaW

回答

1

縮放滾動後更新基於可視Points統計計算,你需要知道兩件事情:你應該這樣做,並指向可見。

要使用的事件是AxisViewChanged,那很容易。你已經迷上它後,你可以調用一個函數來更新你的統計:

private void chart1_AxisViewChanged(object sender, ViewEventArgs e) 
{ 
    updateStats(); 
} 

困難的部分是要知道哪些Points收集部分可見。

乍一看你可能認爲ViewEventArgs帕爾姆有幫助;畢竟它有如下有前途的數據:NewPositionNewSize

但仔細看,你會發現兩者都是雙打的,所以除非你的XValues已經從0開始計數爲1,它們將不會索引到Points集合中。

相反,我們必須對這些值進行一些搜索,從左到右和最右側。這裏有一個功能可以這樣做:

int getVisiblePoint(Chart chart, Series series, bool first) 
{ 
    Series S = series; 
    ChartArea CA = chart.ChartAreas[S.ChartArea]; 
    DataPoint pt = null; 
    if (first) pt = S.Points.Select(x => x) 
           .Where(x => x.XValue >= CA.AxisX.ScaleView.ViewMinimum) 
           .DefaultIfEmpty(S.Points.First()).First(); 
    else pt = S.Points.Select(x => x) 
         .Where(x => x.XValue <= CA.AxisX.ScaleView.ViewMaximum) 
         .DefaultIfEmpty(S.Points.Last()).Last(); 

    return S.Points.IndexOf(pt); 
} 

從這裏開始事情變得容易多了;使用簡單的功能做數學

void updateStats() 
{ 
    int firstPt = getVisiblePoint(chart1, chart1.Series[0], true); 
    int lastPt = getVisiblePoint(chart1, chart1.Series[0], false); 
    int sCount = chart1.Series.Count; 
    double[] avg = new double[sCount]; 
    double[] min = new double[sCount]; 
    double[] max = new double[sCount]; 

    for (int i = 0; i < sCount; i++) 
    { 
     Series S = chart1.Series[i]; 
     avg[i] = getAverage(S, firstPt, lastPt); 
     min[i] = getMixMax(S, firstPt, lastPt, true); 
     max[i] = getMixMax(S, firstPt, lastPt, false); 
    } 
    // insert code to display the data here! 
} 

double getAverage(Series series, int first, int last) 
{ 
    double sum = 0; 
    for (int i = first; i < last; i++) sum += series.Points[i].YValues[0]; 
    return sum/(last - first + 1); 
} 

double getMixMax(Series series, int first, int last, bool min) 
{ 
    double val = 0; 

    for (int i = first; i < last; i++) 
    { 
     double v = series.Points[i].YValues[0]; 
     if ((min && val > v) || (!min && val >= v)) val = v; 
    } 
    return val; 
}