public void Apply(IChartSpace chartSpace) { using (ISpreadsheetDocument spreadsheet = chartSpace.OpenSpreadsheetDocument()) { IWorksheet seriesSheet = spreadsheet.Workbook.AppendWorksheet("Series"); IWorksheet connectorSheet = spreadsheet.Workbook.AppendWorksheet("Connector"); double total = this.categories.Sum(c => c.CustomOffset.HasValue ? c.CustomOffset.Value : c.Values.Sum(s => s.Value)); seriesSheet.Cells[0, 1].SetValue("Offset"); uint column = 1; uint seriesRow = 2; uint connectorRow = 0; if (this.total != null) { // set name of total category seriesSheet.Cells[column, 0].SetValue(this.total); connectorSheet.Cells[column, 0].SetValue(this.total); seriesSheet.Cells[0, seriesRow].SetValue("Total"); seriesSheet.Cells[column, 1].SetValue(0); seriesSheet.Cells[column, seriesRow].SetValue(total); ++seriesRow; ++column; ++connectorRow; } double offset = total; foreach (BurndownChartCategoryConfig category in this.categories) { // set name of category seriesSheet.Cells[column, 0].SetValue(category.Name); connectorSheet.Cells[column, 0].SetValue(category.Name); // set connector of category if (column > 1) { connectorSheet.Cells[column - 1, connectorRow].SetValue(offset); connectorSheet.Cells[column, connectorRow].SetValue(offset); } // set offset of category seriesSheet.Cells[column, 1].SetValue(offset - category.Values.Sum(s => s.Value)); if (category.CustomOffset.HasValue) { offset -= category.CustomOffset.Value; } else { offset -= category.Values.Sum(s => s.Value); } uint seriesIdx = 0; uint seriesCount = (uint)category.Values.Count; foreach (BurndownChartValueConfig value in category.Values) { // set name of series seriesSheet.Cells[0, seriesRow + seriesCount - seriesIdx - 1].SetValue(value.Name); // set value of series seriesSheet.Cells[column, seriesRow + seriesCount - seriesIdx - 1].SetValue(Math.Abs(value.Value)); ++seriesIdx; } seriesRow += (uint)category.Values.Count; ++connectorRow; ++column; } CartesianAxes axes = chartSpace.AppendCartesianAxes(); ILineChart lineChart = chartSpace.InsertLineChart(axes) .InitializeFromRange(connectorSheet.GetRange(0, 1, 0, connectorRow - 1), connectorSheet.GetRange(1, 0, column - 1, 0)); IBarChart barChart = chartSpace.InsertBarChart(axes) .InitializeFromRange(seriesSheet.GetRange(0, 1, 0, seriesRow - 1), seriesSheet.GetRange(1, 0, column - 1, 0)) .SetDirection(BarChartDirection.Column) .SetGrouping(BarChartGrouping.Stacked) .SetOverlap(1.0); // hide offset series barChart.Series[0].Style.SetNoFill(); if (this.total != null && this.totalStyle != null) { this.totalStyle(barChart.Series[1].Values[1]); } if (this.connectorStyle != null) { foreach (ILineChartValue value in lineChart.Series.SelectMany(s => s.Values)) { this.connectorStyle(value); } } int valueIndex = 0; int seriesIndex = 1; if (this.total != null) { ++valueIndex; ++seriesIndex; } foreach (BurndownChartCategoryConfig category in this.categories) { int seriesIdx = 0; foreach (BurndownChartValueConfig value in category.Values) { if (value.Style != null) { IBarChartSeries s = barChart.Series[seriesIndex + category.Values.Count - seriesIdx - 1]; value.Style(s.Values[valueIndex]); } ++seriesIdx; } seriesIndex += category.Values.Count; ++valueIndex; } axes.CategoryAxis .Text.SetFontSize(6) .MajorGridlines.Remove(); axes.ValueAxis .SetVisibility(false) .MajorGridlines.Remove(); } }
public static BurndownChartWizard BuildBurndownChart(IChartSpace chartSpace, BurndownChartData data) { using (ISpreadsheetDocument spreadsheet = chartSpace.OpenSpreadsheetDocument()) { IWorksheet seriesSheet = spreadsheet.Workbook.AppendWorksheet("Series"); IWorksheet connectorSheet = spreadsheet.Workbook.AppendWorksheet("Connector"); double total = data.Categories.Sum(c => c.Series.Sum(s => s.Value)); seriesSheet.Cells[0, 1].SetValue("Offset"); seriesSheet.Cells[0, 2].SetValue("Total"); seriesSheet.Cells[1, 0].SetValue("Total"); connectorSheet.Cells[1, 0].SetValue("Total"); seriesSheet.Cells[1, 1].SetValue(0); seriesSheet.Cells[1, 2].SetValue(total); double offset = total; uint column = 2; uint seriesRow = 3; uint connectorRow = 1; foreach (BurndownChartCategory category in data.Categories) { // set name of category seriesSheet.Cells[column, 0].SetValue(category.Name); connectorSheet.Cells[column, 0].SetValue(category.Name); // set connector of category connectorSheet.Cells[column - 1, connectorRow].SetValue(offset); connectorSheet.Cells[column, connectorRow].SetValue(offset); // set offset of category offset -= category.Series.Sum(s => s.Value); seriesSheet.Cells[column, 1].SetValue(offset); uint seriesIdx = 0; uint seriesCount = (uint)category.Series.Length; foreach (BurndownChartSeries series in category.Series) { // set name of series seriesSheet.Cells[0, seriesRow + seriesCount - seriesIdx - 1].SetValue(series.Name); // set value of series seriesSheet.Cells[column, seriesRow + seriesCount - seriesIdx - 1].SetValue(Math.Abs(series.Value)); ++seriesIdx; } seriesRow += (uint)category.Series.Length; ++connectorRow; ++column; } CartesianAxes axes = chartSpace.AppendCartesianAxes(); ILineChart lineChart = chartSpace.InsertLineChart(axes) .InitializeFromRange(connectorSheet.GetRange(0, 1, 0, connectorRow - 1), connectorSheet.GetRange(1, 0, column - 1, 0)); IBarChart barChart = chartSpace.InsertBarChart(axes) .InitializeFromRange(seriesSheet.GetRange(0, 1, 0, seriesRow - 1), seriesSheet.GetRange(1, 0, column - 1, 0)) .SetDirection(BarChartDirection.Column) .SetGrouping(BarChartGrouping.Stacked) .SetOverlap(1.0); // hide offset series barChart.Series[0].Style.SetNoFill(); if (data.TotalCallback != null) { data.TotalCallback(barChart.Series[1].Values[1]); } int valueIndex = 1; int seriesIndex = 2; foreach (BurndownChartCategory category in data.Categories) { int seriesIdx = 0; foreach (BurndownChartSeries series in category.Series) { if (series.Callback != null) { IBarChartSeries s = barChart.Series[seriesIndex + category.Series.Length - seriesIdx - 1]; series.Callback(s.Values[valueIndex]); } ++seriesIdx; } seriesIndex += category.Series.Length; ++valueIndex; } axes.CategoryAxis .Text.SetFontSize(6) .MajorGridlines.Remove(); axes.ValueAxis .SetVisibility(false) .MajorGridlines.Remove(); return(new BurndownChartWizard(chartSpace, data, axes, barChart, lineChart)); } }