Диаграмма с накоплением в диаграмме Microsoft имеет пробелы - PullRequest
6 голосов
/ 26 мая 2011

Я использую библиотеку диаграмм в .Net 4.0 для создания столбчатой ​​диаграммы с несколькими рядами. Моя цель - гистограмма, которая показывает совокупное количество действий (завершений отчетов) в течение нескольких серий (учителей). Часто отсутствуют данные (в этот день не было активности конкретного учителя).

Я получаю пробелы в барах, когда в серии отсутствуют данные:

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

Как я могу удалить

Ответы [ 3 ]

9 голосов
/ 02 августа 2011

У меня есть способ сделать эту работу.
Извините за длинный ответ, но я обнаружил, что способ, которым вы пытаетесь реализовать этот ответ, повлияет на его работу.

Вам нужноустановить точку на ноль вручную при добавлении точек.Примечание. Мне не удалось выполнить эту работу, добавив нулевые точки после факта.

См. Примеры рядом с полученными скриншотами: 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);

Изображение "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) вконец, так как это не сработает.

Дайте мне знать, если вам нужна дополнительная помощь.

5 голосов
/ 22 октября 2013

Я столкнулся с той же самой проблемой и хотел поделиться правильным решением:

Используйте DataManipulator, чтобы вставить недостающие (x, y) значения:

foreach (Series s in chart.Series)
{
    chart.DataManipulator.Sort(PointSortOrder.Ascending, "X", s);
    chart.DataManipulator.InsertEmptyPoints(1, IntervalType.Number, s);
}
0 голосов
/ 20 мая 2014

Зацикливание серии не работает для меня по некоторым причинам, но следующее решение работает как шарм:

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