2011-05-25 122 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")