Reputation: 330
I'm currently creating Excel spreadsheets via EPPlus, the data is basically split into, section, questions, responses, with each being a subset of the other, I don't know how many questions each section might have, so everything needs to be done via loops.
What I want is for the document to contain a worksheet that shows a chart for each question giving a breakdown of the answers.
I'm extremely close to getting it working correctly but something in my code is causing issues and I can't work out what it is.
The data I'm currently working with holds 10 questions, all the charts are drawn but the very last one is positioned directly over the top of the first. I'm also having issues with getting the text results positioned correctly but since the code for that depends on that for the charts I'm hoping that sorting the charts will help me sort the results.
Here is my code:
Int32 chartPaddingX = 50;
Int32 chartPaddingY = 200;
Int32 chartW = 320;
Int32 chartH = 200;
Int32 chartXCount = 0;
Int32 chartYCount = 1;
Int32 marginTop = 0;
Int32 marginLeft = 0;
Int32 resultsControlVar = 0;
Int32 numCharts = 0;
Int32 rnStart = 14;
chartXCount = 0;
chartYCount = 0;
chartPaddingX = 50;
rowNum = y = 14;
colNum = 2;
String title = section.First().title.ToString();
ExcelWorksheet ws = pkg.Workbook.Worksheets.Add(title);
int idx = 0;
foreach (var question in results.questions.Where(q => q.section_guid == section.Key))
{
var chart = ws.Drawings.AddChart(question.question.ToString(), OfficeOpenXml.Drawing.Chart.eChartType.ColumnClustered);
chart.SetSize(chartW, chartH);
chart.Title.Text = question.question.ToString();
chart.Legend.Add();
marginLeft = (chartW + chartPaddingX) * chartXCount;
// SET CHART PLACEMENT
if (numCharts == 0)
{
marginTop = 50;
}
else if ((numCharts <= 3) && (numCharts != 0))
{
marginTop = 50;
}
else if (numCharts > 3)
{
marginTop = ((chartH + chartPaddingY) * chartYCount) + 50;
}
else
{
marginTop = (chartH + chartPaddingY) * chartYCount;
}
if (chartXCount >= 3)
{
chart.SetPosition(marginTop, 50);
chartYCount++;
chartXCount = 0;
resultsControlVar = 1;
}
else
{
chart.SetPosition(marginTop, marginLeft + 50);
}
chartXCount++;
numCharts++;
...... Add results data and chart series ......
if (resultsControlVar == 1)
{
rowNum = rnStart;
rowNum = rowNum + 20;
rnStart = rowNum;
colNum = 2;
resultsControlVar = 0;
}
else
{
rowNum = rnStart;
colNum = colNum + 6;
}
} // close foreach
Upvotes: 1
Views: 729
Reputation: 330
Accepted Ernie's answer as he got there before me and had some useful tips for debugging. Many thanks for your time Ernie.
I actually managed to solve the issue this morning before checking back here, this is what I came up with:
foreach (var question in results.questions.Where(q => q.section_guid == section.Key))
{
// SET CHART PLACEMENT
if (chartXCount != chartXMax)
{
if (numCharts == 0)
{
chartX = ((chartW + chartPaddingX) * chartXCount) + 50;
chartY = ((chartH + chartPaddingY) * chartYCount) + 50;
}
else
{
chartX = ((chartW + chartPaddingX) * chartXCount) + 50;
}
chart.SetPosition(chartY, chartX);
chartXCount++;
}
else
{
chartX = ((chartW + chartPaddingX) * chartXCount) + 50;
chart.SetPosition(chartY, chartX);
chartYCount++;
resultsControlVar = 1;
}
numCharts++;
... DOING SOME OTHER BITS N BOBS ...
// INCREMENT Y VALUE
if (resultsControlVar == 1) // INCREMENT THE YPOS VALUE OF THE CHART
{
rowNum = rnStart;
rowNum = rowNum + 20;
rnStart = rowNum;
colNum = 2;
chartY = ((chartH + chartPaddingY) * chartYCount) + 50;
resultsControlVar = 0;
chartXCount = 0;
}
else // RESETS THE ROWNUM FOR DATA VALUES
{
rowNum = rnStart;
colNum = colNum + 6;
}
}
Upvotes: 0
Reputation: 14250
Check your algo logic, it is not giving the left/top you might be expecting. If you strip it down to the bare minimum:
[TestMethod]
public void Check_Multi_Test()
{
Int32 chartPaddingX = 50;
Int32 chartPaddingY = 200;
Int32 chartW = 320;
Int32 chartH = 200;
Int32 chartXCount = 0;
Int32 chartYCount = 1;
Int32 marginTop = 0;
Int32 marginLeft = 0;
Int32 numCharts = 0;
chartXCount = 0;
chartYCount = 0;
//foreach (var question in results.questions.Where(q => q.section_guid == section.Key))
for (var i = 0; i < 10; i++)
{
marginLeft = (chartW + chartPaddingX)*chartXCount;
// SET CHART PLACEMENT
if (numCharts == 0)
{
marginTop = 50;
}
else if ((numCharts <= 3) && (numCharts != 0))
{
marginTop = 50;
}
else if (numCharts > 3)
{
marginTop = ((chartH + chartPaddingY)*chartYCount) + 50;
}
else
{
marginTop = (chartH + chartPaddingY)*chartYCount;
}
if (chartXCount >= 3)
{
//chart.SetPosition(marginTop, 50);
Console.WriteLine("{{i: {0}, numCharts: {1}, left: {2}, top: {3}}}", i, numCharts, 50, marginTop); //Console.Writeline will simulate chart placement
chartYCount++;
chartXCount = 0;
}
else
{
//chart.SetPosition(marginTop, marginLeft + 50);
Console.WriteLine("{{i: {0}, numCharts: {1}, left: {2}, top: {3}}}", i, numCharts, marginLeft + 50, marginTop); //Console.Writeline will simulate chart placement
}
chartXCount++;
numCharts++;
}
}
and output left/top to the console you can easily see the error starting with iteration 3:
{i: 0, numCharts: 0, left: 50, top: 50}
{i: 1, numCharts: 1, left: 420, top: 50}
{i: 2, numCharts: 2, left: 790, top: 50}
{i: 3, numCharts: 3, left: 50, top: 50}
{i: 4, numCharts: 4, left: 420, top: 450}
{i: 5, numCharts: 5, left: 790, top: 450}
{i: 6, numCharts: 6, left: 50, top: 450}
{i: 7, numCharts: 7, left: 420, top: 850}
{i: 8, numCharts: 8, left: 790, top: 850}
{i: 9, numCharts: 9, left: 50, top: 850}
It should not need to be so complex actually:
//foreach (var question in results.questions.Where(q => q.section_guid == section.Key))
for (var i = 0; i < 10; i++)
{
marginLeft = (chartW + chartPaddingX)*chartXCount + 50;
marginTop = (chartH + chartPaddingY)*chartYCount + 50;
//chart.SetPosition(marginTop, marginLeft); //Console.Writeline will simulate chart placement
Console.WriteLine("{{i: {0}, numCharts: {1}, left: {2}, top: {3}}}", i, numCharts, marginLeft, marginTop);
if (chartXCount >= 2)
{
chartYCount++;
chartXCount = 0;
}
else
chartXCount++;
numCharts++;
}
Gives you this:
{i: 0, numCharts: 0, left: 50, top: 50}
{i: 1, numCharts: 1, left: 420, top: 50}
{i: 2, numCharts: 2, left: 790, top: 50}
{i: 3, numCharts: 3, left: 50, top: 450}
{i: 4, numCharts: 4, left: 420, top: 450}
{i: 5, numCharts: 5, left: 790, top: 450}
{i: 6, numCharts: 6, left: 50, top: 850}
{i: 7, numCharts: 7, left: 420, top: 850}
{i: 8, numCharts: 8, left: 790, top: 850}
{i: 9, numCharts: 9, left: 50, top: 1250}
Upvotes: 1