Skip to content

Commit add9357

Browse files
committed
WIP:Fixes for axis on bar charts
1 parent 97303d3 commit add9357

4 files changed

Lines changed: 70 additions & 32 deletions

File tree

src/EPPlus.Export.ImageRenderer.Test/Chart/LineChartToSvgTests.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,16 @@ public void GenerateSvgForCharts_SecondaryAxis_sheet2()
123123
{
124124
var ws = p.Workbook.Worksheets[1];
125125
var renderer = new EPPlusImageRenderer.ImageRenderer();
126-
//var ix = 0;
127-
//var c = ws.Drawings[ix];
128-
//var svg = renderer.RenderDrawingToSvg(c);
129-
//SaveTextFileToWorkbook($"svg\\ChartForSvg_sheet2_{ix++}.svg", svg);
130-
var ix = 1;
131-
foreach (ExcelChart c in ws.Drawings)
132-
{
133-
var svg = renderer.RenderDrawingToSvg(c);
134-
SaveTextFileToWorkbook($"svg\\ChartForSvg_Sheet2_SecAxis{ix++}.svg", svg);
135-
}
126+
var ix = 2;
127+
var c = ws.Drawings[ix];
128+
var svg = renderer.RenderDrawingToSvg(c);
129+
SaveTextFileToWorkbook($"svg\\ChartForSvg_sheet2_{ix++}.svg", svg);
130+
//var ix = 1;
131+
//foreach (ExcelChart c in ws.Drawings)
132+
//{
133+
// var svg = renderer.RenderDrawingToSvg(c);
134+
// SaveTextFileToWorkbook($"svg\\ChartForSvg_Sheet2_SecAxis{ix++}.svg", svg);
135+
//}
136136
}
137137
}
138138
[TestMethod]

src/EPPlus.Export.ImageRenderer/Svg/Chart/Axis/DateAxisScaleCalculator.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,5 +486,43 @@ private static bool FitAsVerticalDiagonalText(double min, double max, int interv
486486

487487
}
488488
}
489+
490+
internal static AxisScale CalculateByHeight(double min, double max, ITextMeasurer tm, AxisOptions options)
491+
{
492+
var ax = options.Axis;
493+
var plotAreaHeight = options.ChartSize.Bounds.Height;
494+
var mf = ax.Font.GetMeasureFont();
495+
int interval;
496+
eTimeUnit unit;
497+
var minString = DateTime.FromOADate(min).ToString(options.NumberFormat);
498+
var res = tm.MeasureText(minString, mf);
499+
if (options.LockedInterval.HasValue)
500+
{
501+
interval = (int)options.LockedInterval.Value;
502+
unit = options.LockedIntervalUnit ?? eTimeUnit.Days;
503+
}
504+
else
505+
{
506+
interval = 1;
507+
unit = eTimeUnit.Days;
508+
//Get interval for maximum width with vertical text.
509+
while(FitAsVerticalDiagonalText(min, max, interval, unit, res.Height, res.Height * 0.3, plotAreaHeight) == false)
510+
{
511+
AddIntervall(ref interval, ref unit);
512+
}
513+
}
514+
515+
return new AxisScale()
516+
{
517+
MajorInterval = interval,
518+
MinorInterval = 1,
519+
MinorDateUnit = unit,
520+
MajorDateUnit = unit,
521+
Min = min,
522+
Max = max,
523+
TextOrientation = eTextOrientation.Horizontal
524+
};
525+
526+
}
489527
}
490528
}

src/EPPlus.Export.ImageRenderer/Svg/Chart/ChartTypeDrawers/BarColumnChartTypeDrawer.cs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,8 @@ internal BarColumnChartTypeDrawer(SvgChart svgChart, ExcelBarChart chartType) :
6666

6767
var dataPoints = new List<BoundingBox>();
6868

69-
if (chartType.IsTypeColumn())
70-
{
71-
AddColumn(chartType, serie, catValues, valValues, dataPoints, count, i);
72-
}
73-
else
74-
{
75-
AddBar(chartType, serie, catValues, valValues, dataPoints, count, i);
76-
}
69+
//Add the bar or column.
70+
AddBar(chartType, serie, catValues, valValues, dataPoints, count, i);
7771

7872
dataPointsPerSerie.Add(dataPoints);
7973

@@ -122,23 +116,21 @@ private void AddBar(ExcelBarChart chartType, ExcelBarChartSerie serie, List<List
122116
var slotWidth = yWidth / slotSize;
123117
var clusterWidth = slotWidth * 100 / (100 + chartType.GapWidth);
124118
var step = 1 - overlapPercent;
125-
double barWidth;
126-
barWidth = slotWidth / (1 + (seriesCount - 1) * step + gapPercent);
119+
var barWidth = slotWidth / (1 + (seriesCount - 1) * step + gapPercent);
127120
var halfGap = (barWidth * gapPercent) / 2;
128121

129122
double yAxisStart;
130-
131123
if (yAxis.Axis.Crosses == eCrosses.AutoZero)
132124
{
133-
yAxisStart = valAx.GetPositionInPlotarea(yAxis.Min <= 0 ? 0D : yAxis.Min, true);
125+
yAxisStart = valAx.GetPositionInPlotarea(valAx.Min <= 0 ? 0D : yAxis.Min, true);
134126
}
135127
else if (yAxis.Axis.Crosses == eCrosses.Min)
136128
{
137-
yAxisStart = valAx.GetPositionInPlotarea(yAxis.Min, true);
129+
yAxisStart = valAx.GetPositionInPlotarea(valAx.Min, true);
138130
}
139131
else
140132
{
141-
yAxisStart = valAx.GetPositionInPlotarea(yAxis.Max, true);
133+
yAxisStart = valAx.GetPositionInPlotarea(valAx.Max, true);
142134
}
143135

144136
var isStacked = chartType.IsTypeStacked();
@@ -224,7 +216,7 @@ private void AddBar(ExcelBarChart chartType, ExcelBarChartSerie serie, List<List
224216
{
225217
if (y < 0)
226218
{
227-
rect.Left = yAxisStart;
219+
rect.Left = yPos;
228220
rect.Width = yAxisStart - yPos;
229221
}
230222
else

src/EPPlus.Export.ImageRenderer/Svg/Chart/SvgChartAxis.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,14 @@ private List<SvgTextBox> GetAxisValueTextBoxes()
353353
if(Axis.IsVertical)
354354
{
355355
x = ticMarkX;
356-
y = ticMarkY - height / 2;
356+
if (SvgChart.Chart.IsTypeBar())
357+
{
358+
y = ticMarkY;
359+
}
360+
else
361+
{
362+
y = ticMarkY - height / 2;
363+
}
357364
}
358365
else
359366
{
@@ -415,7 +422,7 @@ private List<SvgTextBox> GetAxisValueTextBoxes()
415422

416423
var p = Axis.TextBody.Paragraphs.FirstOrDefault();
417424

418-
if (p.HorizontalAlignment != eTextAlignment.Center && (Axis.AxisPosition == eAxisPosition.Bottom || Axis.AxisPosition == eAxisPosition.Top))
425+
if (p.HorizontalAlignment != eTextAlignment.Center && Axis.AxisType!=eAxisType.Val && (Axis.AxisPosition == eAxisPosition.Bottom || Axis.AxisPosition == eAxisPosition.Top))
419426
{
420427
//Horizontal axises are always center aligned visually
421428
//Should be broken out as input to ImportParagraph instead of changing the base item
@@ -452,7 +459,7 @@ private List<SvgTextBox> GetAxisValueTextBoxes()
452459
}
453460
}
454461
}
455-
else if(LabelOrientation==eTextOrientation.Horizontal) //Only apples when labels are horizontally aligned
462+
else if(LabelOrientation==eTextOrientation.Horizontal && Axis.AxisType==eAxisType.Cat) //Only apples when labels are horizontally aligned
456463
{
457464
//Align the axis labels according to the label alignment setting. This is only relevant for horizontal axis, vertical axis are always right aligned.
458465
var lblAlignment = (Axis as ExcelChartAxisStandard)?.LabelAlignment??OfficeOpenXml.eAxisLabelAlignment.Center;
@@ -571,7 +578,7 @@ private double GetAxisItemTop(int i, OfficeOpenXml.Interfaces.Drawing.Text.TextM
571578
else
572579
{
573580
var majorHeight = Rectangle.Height / (AxisValues.Count);
574-
if (Axis.AxisType == eAxisType.Cat)
581+
if (Axis.AxisType == eAxisType.Cat || Axis.AxisType == eAxisType.Date)
575582
{
576583
return Rectangle.Top + majorHeight * (AxisValues.Count - i - 1) + (majorHeight / 2) - m.Height / 2;
577584
}
@@ -846,7 +853,7 @@ internal double GetPositionInPlotarea(double val, bool startValue=false)
846853
else
847854
{
848855
if (val < Min || val > Max) return double.NaN;
849-
var diff = Max - Min;
856+
var diff = Max - Min + 1;
850857
return (((Max-val) / diff * SvgChart.Plotarea.Rectangle.Height));
851858
}
852859
}
@@ -882,7 +889,7 @@ protected List<object> GetAxisValue(ExcelChartAxisStandard ax, RenderItem rect,
882889
LockedMax = ax.MaxValue,
883890
LockedInterval = ax.MajorUnit,
884891
LockedIntervalUnit = ax.MajorTimeUnit,
885-
AddPadding = ax.AxisType!=eAxisType.Cat,//(ax.AxisPosition == eAxisPosition.Left || ax.AxisPosition == eAxisPosition.Right),
892+
AddPadding = ax.AxisType==eAxisType.Val,//(ax.AxisPosition == eAxisPosition.Left || ax.AxisPosition == eAxisPosition.Right),
886893
Axis = ax,
887894
IsStacked100 = Chart.IsTypePercentStacked(),
888895
ChartSize = rect
@@ -951,7 +958,8 @@ protected List<object> GetAxisValue(ExcelChartAxisStandard ax, RenderItem rect,
951958
AxisScale res;
952959
if (ax.IsVertical)
953960
{
954-
res = DateAxisScaleCalculator.Calculate(min ?? 0, max ?? 0, length, options);
961+
//res = DateAxisScaleCalculator.Calculate(min ?? 0, max ?? 0, length, options);
962+
res = DateAxisScaleCalculator.CalculateByHeight(min ?? 0D, max ?? 0D, SvgChart.TextMeasurer, options);
955963
}
956964
else
957965
{

0 commit comments

Comments
 (0)