2011-03-19 78 views
10

我一直在尋找網絡一段時間,但仍然沒有找到任何好的解決方案,我的問題。我想讓MS Chart在滾動時自動重新調整Y軸,以確保所有數據點都可見。這裏的扭曲是我需要有能力排除某些系列被用於自動縮放。到目前爲止,我只找到提供在AxisViewChanged事件上遍歷整個點集合的解決方案,當您有大量點集合和一些系列迭代時,這種方法效果不佳。我想知道是否有任何方法通過獲取當前可見的最小和最大X值之間的數據點來縮小搜索範圍。任何幫助,將不勝感激。圖表控制Y軸自動縮放滾動

編輯繼承人的形象。正如你所看到的,中間的燭臺並不完全可見。 enter image description here

+1

Mmh不清楚我...您想在滾動X軸的同時重新調整Y軸,對嗎?否則對我來說沒有意義。順便說一句,你可以舉一個你需要什麼的視覺例子嗎? – digEmAll 2011-03-19 16:25:37

+0

@digEmAll是的,這是正確的 – 2011-03-19 16:53:01

回答

6

你可以試試這個代碼

 DateTime date = DateTime.Now; 
     chart1.ChartAreas[0].AxisX.Minimum = 0; 
     chart1.ChartAreas[0].AxisX.Maximum = 20; 
     Random r = new Random((int)date.Ticks); 

     chart1.Series[0].ChartType = SeriesChartType.Candlestick; 
     chart1.Series[0].Color = Color.Green; 
     chart1.Series[0].XValueType = ChartValueType.Time; 
     chart1.Series[0].IsXValueIndexed = true; 
     chart1.Series[0].YValuesPerPoint = 4; 
     chart1.Series[0].CustomProperties = "MaxPixelPointWidth=10"; 
     for (int i = 0; i < 100; i++) 
     { 
      DataPoint point = new DataPoint(date.AddHours(i).ToOADate(), new double[] { r.Next(10, 20), r.Next(30, 40), r.Next(20, 30), r.Next(20, 30) }); 
      chart1.Series[0].Points.Add(point); 
     } 

     int min = (int)chart1.ChartAreas[0].AxisX.Minimum; 
     int max = (int)chart1.ChartAreas[0].AxisX.Maximum; 

     if (max > chart1.Series[0].Points.Count) 
      max = chart1.Series[0].Points.Count; 

     var points = chart1.Series[0].Points.Skip(min).Take(max - min); 

     var minValue = points.Min(x => x.YValues[0]); 
     var maxValue = points.Max(x => x.YValues[1]); 

     chart1.ChartAreas[0].AxisY.Minimum = minValue; 
     chart1.ChartAreas[0].AxisY.Maximum = maxValue; 

enter image description here

+0

@Stecya。我有DateTime作爲X值,使最大值的方式低於最小值,所以點變成了一個空的集合。 – 2011-03-19 17:07:15

+0

您可以使用'chart1.Series [0] .IsXValueIndexed = true;'然後x值將是整數,並且lables仍然是DateTime – Stecya 2011-03-19 17:11:20

+0

@Stecya。但是這會消除X軸上的所有空缺,不是嗎? – 2011-03-19 17:18:49

5

使用查詢來找出你要使用的代碼中發現y最小和y哪個系列。

private void chart1_AxisViewChanged(object sender, ViewEventArgs e) 
    { 
     if (e.Axis.AxisName == AxisName.X) 
     { 
      int start = (int)e.Axis.ScaleView.ViewMinimum; 
      int end = (int)e.Axis.ScaleView.ViewMaximum; 

      // Series ss = chart1.Series.FindByName("SeriesName"); 
      // use ss instead of chart1.Series[0] 

      double[] temp = chart1.Series[0].Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[0]).ToArray(); 
      double ymin = temp.Min(); 
      double ymax = temp.Max(); 

      chart1.ChartAreas[0].AxisY.ScaleView.Position = ymin; 
      chart1.ChartAreas[0].AxisY.ScaleView.Size = ymax - ymin; 
     } 
    } 
3

這是從Shivaram Kr的優良提交一個小的改進,以防止打開,關閉和低脫落的最低點底部與四個Y值金融圖表:高,低,打開關閉。

// The following line goes in your form constructor 
this.chart1.AxisViewChanged += new EventHandler<ViewEventArgs> (this.chart1_AxisViewChanged); 


private void chart1_AxisViewChanged(object sender, ViewEventArgs e) 
{ 
    if (e.Axis.AxisName == AxisName.X) 
    { 
     int start = (int)e.Axis.ScaleView.ViewMinimum; 
     int end = (int)e.Axis.ScaleView.ViewMaximum; 
     // Use two separate arrays, one for highs (same as temp was in Shavram's original) 
     // and a new one for lows which is used to set the Y axis min. 
     double[] tempHighs = chart1.Series[0].Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[0]).ToArray(); 
     double[] tempLows = chart1.Series[0].Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[1]).ToArray(); 
     double ymin = tempLows.Min(); 
     double ymax = tempHighs.Max(); 

     chart1.ChartAreas[0].AxisY.ScaleView.Position = ymin; 
     chart1.ChartAreas[0].AxisY.ScaleView.Size = ymax - ymin; 
    } 
} 
0

基於以前的答案

private void chart1_AxisViewChanged(object sender, ViewEventArgs e) 
    { 
     if(e.Axis.AxisName == AxisName.X) 
     { 
      int start = (int)e.Axis.ScaleView.ViewMinimum; 
      int end = (int)e.Axis.ScaleView.ViewMaximum; 

      List<double> allNumbers = new List<double>(); 

      foreach(Series item in chart1.Series) 
       allNumbers.AddRange(item.Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[0]).ToList()); 

      double ymin = allNumbers.Min(); 
      double ymax = allNumbers.Max(); 

      chart1.ChartAreas[0].AxisY.ScaleView.Position = ymin; 
      chart1.ChartAreas[0].AxisY.ScaleView.Size = ymax - ymin; 
     } 
    } 

這可能是你在chartarea更多的系列。在這種情況下,您可以選擇該區域所有系列的高位和低位,而不是一個。

問候,

Matthijs

0

以上回答對我來說非常有幫助。但是,我有一個包含多個圖表區域的圖表。我已調整代碼以擴大到所有圖表區域:

foreach (ChartArea area in chart1.ChartAreas) 
    { 
     List<double> allNumbers = new List<double>(); 

     foreach (Series item in chart1.Series) 
     if (item.ChartArea == area.Name) 
      allNumbers.AddRange(item.Points.Where((x, i) => i >= start && i <= end).Select(x => x.YValues[0]).ToList()); 

     double ymin = allNumbers.Min(); 
     double ymax = allNumbers.Max(); 

     if (ymax > ymin) 
     { 
     double offset = 0.02 * (ymax - ymin); 
     area.AxisY.Maximum = ymax + offset; 
     area.AxisY.Minimum = ymin - offset; 
     } 
    } 
相關問題