2011-05-25 26 views
6

Estoy usando la biblioteca de gráficos en .Net 4.0 para crear un gráfico de columnas apiladas con varias series. Mi objetivo es un histograma que muestra el número acumulado de acciones (completar informes) por día en varias series (profesores). A menudo faltan datos (no hay actividad ese día por un maestro en particular).El gráfico de columnas apiladas de Microsoft tiene huecos

me sale lagunas en los bares cuando hay datos que faltan en una serie:

Histogram with gaps in the columns

Mi código:

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

¿Cómo puedo eliminar el

Respuesta

9

que tienen una forma de hacer que esto funcione
Disculpe por la respuesta larga, pero encontré que la manera en la que intenta implementar esta respuesta afectará si funciona o no.

Debe ajustar el punto a cero manualmente a medida que agrega puntos. Nota: No pude hacer que esto funcione al agregar los puntos cero después del hecho.

Consulte el siguiente ejemplo y capturas de pantalla resultantes: 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); 

imagen de "before.png": enter image description here

Ahora quite los comentarios de la serie sin puntos de datos en un valor dado x:

(Tenga en cuenta que encontré no lo hace funciona si agregas los puntos en un valor de x dado para los valores en donde haces y = 0 al final - alias justo antes de guardar la imagen. El orden de los puntos en la serie parece importar para StackedColumn, nunca he trabajado con este tipo excepto para investigar cómo responder a esta pregunta para que sea de conocimiento común para los usuarios de este tipo)

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

imagen de "after.png": (? Aunque es posible que pueda para insertarlos) enter image description here

Por lo tanto, teniendo en cuenta que no puede agregar los puntos cero después de que el hecho de que tendrá que modificar el código para algo como esto:

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

lo siento por los bloques de código largo, pero el ejemplo era necesario demostrar cómo hacer que funcione, sin caer en la trampa de la suma de los puntos vacíos (donde y = 0) al final, ya que eso no funcionará.

Avíseme si necesita más ayuda.

+0

+1 gracias por los excelentes ejemplos de código –

5

se encontró con el mismo problema por mí mismo y quería compartir la solución correcta:

Uso DataManipulator para insertar los desaparecidos (x, y) obtenidos:

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

Works Perfect, thanks. Además, todavía no tengo idea de por qué sucede esto ... – Lambda

+0

Esto en realidad me ha fijado el ancho de las columnas, pero todavía hay vacíos. –

0

bucle a través de la serie no funciona para por alguna razón, pero la próxima solución funciona como un amuleto:

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