【问题标题】:Microsoft chart stacked column chart has gaps微软图表堆积柱形图有差距
【发布时间】:2011-05-25 23:09:16
【问题描述】:

我正在使用 .Net 4.0 中的图表库来创建包含多个系列的堆积柱形图。我的目标是一个直方图,显示多个系列(教师)每天的累积行动(报告完成)数量。经常缺少数据(特定教师当天没有活动)。

当系列中缺少数据时,我会在条形中出现空白:

我的代码:

    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);
    }

如何删除

【问题讨论】:

    标签: .net-4.0 mschart


    【解决方案1】:

    我有办法完成这项工作。
    抱歉,答案很长,但我发现您尝试实施此答案的方式会影响它是否有效。

    您需要在添加点时手动将点设置为零。 注意:我无法通过事后添加零点来完成这项工作。

    查看示例旁边的示例和生成的屏幕截图: 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));
    
    chart1.SaveImage("C:\\Before.png", ChartImageFormat.Png);
    

    “之前.png”的图像:

    现在删除在给定 x 值处没有数据点的系列的 cmets:

    (注意!我发现如果你在给定的 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”的图像:

    因此,鉴于您不能在事后添加零点(尽管您可以插入它们?)您需要将您的代码修改为以下内容:

    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)的陷阱,因为那将不起作用。

    如果您需要更多帮助,请告诉我。

    【讨论】:

      【解决方案2】:

      自己也遇到了同样的问题,想分享一下正确的解决方案:

      使用 DataManipulator 插入缺失的 (x,y) 值:

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

      【讨论】:

      • 这实际上为我固定了列宽,但差距仍然存在。
      【解决方案3】:

      由于某种原因,循环通过系列对我不起作用,但下一个解决方案就像一个魅力:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多