2011-05-25 121 views
6

我正在使用.Net 4.0中的圖表庫創建具有多個系列的堆積柱形圖。我的目標是顯示多個系列(教師)每天的累計行動次數(報告完成次數)的直方圖。經常缺少數據(特定教師當天沒有進行任何活動)。Microsoft圖表堆疊柱形圖有空白

我得到的酒吧的差距時,有一系列的缺失數據:

Histogram with gaps in the columns

我的代碼:

public ActionResult CompletionHistogram(int sid, int width, int height) 
    { 
     Site site = SiteRepository.Get(sid); 
     if (site == null) 
      return new HttpNotFoundResult(); 

     Chart chart = new Chart(); 
     chart.Height = height; 
     chart.Width = width; 
     ChartArea area = chart.ChartAreas.Add("Default"); 

     // Treat each teacher as a series 
     foreach (Teacher t in site.Teachers) 
     { 
      Series series = chart.Series.Add(t.FullName); 
      series.ChartType = SeriesChartType.StackedColumn; 
      series.Name = t.FullName; 

      // Group completions by day (filter out incomplete reports and null timestamps) 
      var groups = t.StudentReports 
       .Where<StudentReport>(rep => rep.IsComplete && rep.FirstSaveTimestamp.HasValue) 
       .GroupBy<StudentReport, DateTime>(rep => rep.FirstSaveTimestamp.Value.Date); 

      bool hasPoints = false; 
      foreach (var g in groups) 
      { 
       series.Points.AddXY(g.Key, g.Count()); 
       hasPoints = true; 
      } 

      series.IsValueShownAsLabel = true; 
      series.ToolTip = "#VALX"; 

      if (hasPoints) 
       chart.DataManipulator.InsertEmptyPoints(1, IntervalType.Days, series); 
     } 


     area.AxisX.LabelStyle.Format = "ddd M/d"; 
     return new ChartResult(chart); 
    } 

我如何刪除

回答

9

我有一個做這項工作的方法。
對不起,很長的回答,但我發現你試圖實現這個答案的方式會影響它的工作與否。

當您添加點時,您需要手動將點設置爲零。 注意:我無法通過事後添加零點來完成此項工作。

查看示例和生成的屏幕截圖旁邊: chart1.Series.Clear();圖表1.系列。添加(新系列());圖表1.系列。添加(新系列());圖表1.系列。添加(新系列());圖表1.系列。添加(新系列());

foreach (Series s in chart1.Series) 
{ 
    s.ChartType = SeriesChartType.StackedColumn; 
} 

//chart1.Series[0].Points.Add(new DataPoint(0, 0)); 
chart1.Series[0].Points.Add(new DataPoint(1, 3)); 
chart1.Series[0].Points.Add(new DataPoint(2, 3)); 
chart1.Series[0].Points.Add(new DataPoint(3, 3)); 

chart1.Series[1].Points.Add(new DataPoint(0, 3)); 
//chart1.Series[1].Points.Add(new DataPoint(1, 0)); 
chart1.Series[1].Points.Add(new DataPoint(2, 3)); 
chart1.Series[1].Points.Add(new DataPoint(3, 3)); 

chart1.Series[2].Points.Add(new DataPoint(0, 3)); 
chart1.Series[2].Points.Add(new DataPoint(1, 3)); 
//chart1.Series[2].Points.Add(new DataPoint(2, 0)); 
chart1.Series[2].Points.Add(new DataPoint(3, 3)); 

chart1.Series[3].Points.Add(new DataPoint(0, 3)); 
chart1.Series[3].Points.Add(new DataPoint(1, 3)); 
chart1.Series[3].Points.Add(new DataPoint(2, 3)); 
//chart1.Series[3].Points.Add(new DataPoint(3, 0)); 

chart1.SaveImage("C:\\Before.png", ChartImageFormat.Png); 

形象「before.png」: enter image description here

現在刪除評論的系列在給定的x值沒有數據點:

(請注意,我發現它不如果你在一個給定的x值上添加了點,那麼你在最後使y = 0的值上加上點 - 也就是說,在我保存圖像之前,系列中點的順序似乎對StackedColumn很重要,我從來沒有用過這種類型除了研究如何回答這個問題以便這種類型的用戶可能是常識)

chart1.Series.Clear(); 
chart1.Series.Add(new Series()); 
chart1.Series.Add(new Series()); 
chart1.Series.Add(new Series()); 
chart1.Series.Add(new Series()); 

foreach (Series s in chart1.Series) 
{ 
    s.ChartType = SeriesChartType.StackedColumn; 
} 

chart1.Series[0].Points.Add(new DataPoint(0, 0)); 
chart1.Series[0].Points.Add(new DataPoint(1, 3)); 
chart1.Series[0].Points.Add(new DataPoint(2, 3)); 
chart1.Series[0].Points.Add(new DataPoint(3, 3)); 

chart1.Series[1].Points.Add(new DataPoint(0, 3)); 
chart1.Series[1].Points.Add(new DataPoint(1, 0)); 
chart1.Series[1].Points.Add(new DataPoint(2, 3)); 
chart1.Series[1].Points.Add(new DataPoint(3, 3)); 

chart1.Series[2].Points.Add(new DataPoint(0, 3)); 
chart1.Series[2].Points.Add(new DataPoint(1, 3)); 
chart1.Series[2].Points.Add(new DataPoint(2, 0)); 
chart1.Series[2].Points.Add(new DataPoint(3, 3)); 

chart1.Series[3].Points.Add(new DataPoint(0, 3)); 
chart1.Series[3].Points.Add(new DataPoint(1, 3)); 
chart1.Series[3].Points.Add(new DataPoint(2, 3)); 
chart1.Series[3].Points.Add(new DataPoint(3, 0)); 

// If you add the empty points here, it does not seem to work. 
// Empty points are as follows, and are already added above in the 'after' example. 
// chart1.Series[0].Points.Add(new DataPoint(0, 0)); 
// chart1.Series[1].Points.Add(new DataPoint(1, 0)); 
// chart1.Series[2].Points.Add(new DataPoint(2, 0)); 
// chart1.Series[3].Points.Add(new DataPoint(3, 0)); 

chart1.SaveImage("C:\\After.png", ChartImageFormat.Png); 

形象「after.png」:(?雖然你可以將它們插入) enter image description here

所以,因爲你不能在事後添加零點,您需要修改代碼以這樣的事:

var allPossibleGroups = t.StudentReports; 

var groups = t.StudentReports 
      .Where<StudentReport>(rep => rep.IsComplete && rep.FirstSaveTimestamp.HasValue) 
      .GroupBy<StudentReport, DateTime>(rep => rep.FirstSaveTimestamp.Value.Date); 

     bool hasPoints = false; 
     foreach (var g in allPossibleGroups) 
     { 
      if(groups.ContainsKey(g)) 
      { 
       series.Points.AddXY(g.Key, g.Count()); 
       hasPoints = true; 
      } 
      else 
      { 
       series.Points.AddXY(g.Key, 0); 
      } 
     } 

對不起,長的代碼塊,但例如有必要演示如何使它發揮作用,而不會進入加空點(y = 0的陷阱)在最後,因爲這是行不通的。

讓我知道你是否需要更多幫助。

+0

+1感謝偉大的代碼示例 – 2011-09-06 03:38:54

5

遇到同樣的問題,我和想分享正確的解決方案:

使用DataManipulator插入缺失(X,Y)值:

foreach (Series s in chart.Series) 
{ 
    chart.DataManipulator.Sort(PointSortOrder.Ascending, "X", s); 
    chart.DataManipulator.InsertEmptyPoints(1, IntervalType.Number, s); 
} 
+0

作品完美,謝謝。也不知道爲什麼會發生這種情況... – Lambda 2014-02-14 10:29:45

+0

這實際上是固定列寬,但差距仍然存在。 – 2014-05-20 10:02:33

0

循環通系列不起作用我出於某種原因,但下一個解決方案像一個魅力工作:

Chart1.DataManipulator.InsertEmptyPoints(1, IntervalType.Number, "Series1, Series2, Series3, Series4")