Skip to content

Commit 2ad4998

Browse files
committed
WIP:Axis fixes
1 parent 205f78f commit 2ad4998

14 files changed

Lines changed: 159 additions & 163 deletions

File tree

src/EPPlus.Export.ImageRenderer.Test/SvgPathTests.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,17 +511,39 @@ public void GenerateSvgForCharts()
511511
{
512512
var ws = p.Workbook.Worksheets[0];
513513
var renderer = new EPPlusImageRenderer.ImageRenderer();
514-
var ix = 2;
514+
//var ix = 5;
515+
//var c = ws.Drawings[ix];
516+
//var svg = renderer.RenderDrawingToSvg(c);
517+
//SaveTextFileToWorkbook($"svg\\ChartForSvg{ix++}.svg", svg);
518+
var ix = 1;
519+
foreach (ExcelChart c in ws.Drawings)
520+
{
521+
var svg = renderer.RenderDrawingToSvg(c);
522+
SaveTextFileToWorkbook($"svg\\ChartForSvg{ix++}.svg", svg);
523+
}
524+
}
525+
}
526+
[TestMethod]
527+
public void GenerateSvgForCharts_sheet2()
528+
{
529+
ExcelPackage.License.SetNonCommercialOrganization("EPPlus Project");
530+
using (var p = OpenTemplatePackage("ChartForSvg.xlsx"))
531+
{
532+
var ws = p.Workbook.Worksheets[1];
533+
var renderer = new EPPlusImageRenderer.ImageRenderer();
534+
var ix = 1;
515535
var c = ws.Drawings[ix];
516536
var svg = renderer.RenderDrawingToSvg(c);
517-
SaveTextFileToWorkbook($"svg\\ChartForSvg{ix++}.svg", svg);
537+
SaveTextFileToWorkbook($"svg\\ChartForSvg_sheet2_{ix++}.svg", svg);
538+
//var ix = 1;
518539
//foreach (ExcelChart c in ws.Drawings)
519540
//{
520541
// var svg = renderer.RenderDrawingToSvg(c);
521542
// SaveTextFileToWorkbook($"svg\\ChartForSvg{ix++}.svg", svg);
522543
//}
523544
}
524545
}
546+
525547
[TestMethod]
526548
public void CreateChartsWithDifferentSize()
527549
{

src/EPPlus.Export.ImageRenderer/DrawingBase.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Date Author Change
1212
*************************************************************************************************/
1313

1414
using EPPlus.Export.ImageRenderer;
15+
using EPPlus.Graphics;
1516
using EPPlusImageRenderer.RenderItems;
1617
using OfficeOpenXml;
1718
using OfficeOpenXml.Drawing;
@@ -22,11 +23,13 @@ Date Author Change
2223

2324
namespace EPPlusImageRenderer
2425
{
25-
internal abstract class DrawingBase : RenderItem
26+
internal abstract class DrawingBase
2627
{
2728
protected ExcelWorkbook _wb;
29+
protected ExcelDrawing _drawing;
30+
protected ExcelTheme _theme;
2831

29-
internal DrawingBase(ExcelDrawing drawing) : base(drawing)
32+
internal DrawingBase(ExcelDrawing drawing)
3033
{
3134
drawing.GetSizeInPixels(out int width, out int height);
3235
Drawing = drawing;
@@ -40,5 +43,6 @@ internal DrawingBase(ExcelDrawing drawing) : base(drawing)
4043
internal ITextMeasurer TextMeasurer { get; }
4144
public List<RenderItem> RenderItems { get; } = new List<RenderItem>();
4245
public DrawingSize Size { get; internal set; }
46+
internal BoundingBox Bounds = new BoundingBox();
4347
}
4448
}

src/EPPlus.Export.ImageRenderer/DrawingChart.cs

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Date Author Change
1313

1414
using EPPlusImageRenderer.RenderItems;
1515
using OfficeOpenXml.Drawing.Chart;
16+
using OfficeOpenXml.FormulaParsing.Excel.Functions.Finance;
1617
using OfficeOpenXml.FormulaParsing.Excel.Functions.MathFunctions;
1718
using OfficeOpenXml.Utils.TypeConversion;
1819
using System;
@@ -59,15 +60,16 @@ protected List<object> GetAxisValue(ExcelChartAxisStandard ax, RenderItem rect,
5960
max = d;
6061
}
6162
}
62-
GetAutoMinMaxValue(ax, isCount, ref min, ref max, out majorUnit);
63+
var maxMajorTickmarks = 10; //TODO: Calculate based on rect size
64+
GetAutoMinMaxValue(ax, maxMajorTickmarks, isCount, ref min, ref max, out majorUnit);
6365
for(var v=min; v<=max;v+=majorUnit)
6466
{
6567
l.Add(v);
6668
}
6769
return l;
6870
}
6971

70-
private void GetAutoMinMaxValue(ExcelChartAxisStandard ax, bool isCount, ref double? min, ref double? max, out double? majorUnit)
72+
private void GetAutoMinMaxValue(ExcelChartAxisStandard ax, int maxMajorTickmarks, bool isCount, ref double? min, ref double? max, out double? majorUnit)
7173
{
7274
if(ax.MinValue.HasValue)
7375
{
@@ -88,55 +90,92 @@ private void GetAutoMinMaxValue(ExcelChartAxisStandard ax, bool isCount, ref dou
8890
}
8991
}
9092
}
91-
if(ax.MaxValue.HasValue)
93+
94+
if(isCount)
9295
{
93-
max = ax.MaxValue;
94-
majorUnit = ax.MajorUnit ?? GetAutoUnit(min.Value, max.Value);
96+
majorUnit = 1;
9597
}
9698
else
9799
{
98-
majorUnit = ax.MajorUnit ?? GetAutoUnit(min.Value, max.Value);
99-
if (isCount==false)
100+
if (ax.MaxValue.HasValue)
101+
{
102+
max = ax.MaxValue;
103+
majorUnit = ax.MajorUnit ?? GetAutoUnit(min.Value, max.Value);
104+
if (ax.MinValue.HasValue == false)
105+
{
106+
var newMin = max - majorUnit;
107+
while (newMin > min)
108+
{
109+
newMin -= majorUnit.Value;
110+
}
111+
min = newMin;
112+
}
113+
}
114+
else
100115
{
101-
var diff = max.Value - min.Value;
102-
var newMax = max.Value + majorUnit;
103-
while ((newMax - min) < (diff * 1.05))
116+
majorUnit = ax.MajorUnit ?? GetAutoUnit(min.Value, max.Value);
117+
if (isCount == false)
118+
{
119+
var diff = max.Value - min.Value;
120+
var newMax = min.Value + majorUnit;
121+
while ((newMax - min) < (diff * 1.05))
122+
{
123+
newMax += majorUnit.Value;
124+
}
125+
max = newMax;
126+
}
127+
if(min != 0 && max-min<9)
104128
{
105-
newMax += majorUnit.Value;
129+
min -= 2;
106130
}
107-
max = newMax;
131+
}
132+
var newUnit = majorUnit;
133+
while (newUnit >= 2 && (max - min) / newUnit > maxMajorTickmarks)
134+
{
135+
newUnit /= 2;
108136
}
109137
}
110138
}
111139

112140
private double GetAutoUnit(double min, double max)
113141
{
114142
var diff = max - min;
115-
var pow = 0;
116-
while (diff < 10)
117-
{
118-
diff *= 10;
119-
pow++;
120-
}
121-
var unit = diff / 10D;
122-
var rest = unit % 10d;
123-
if (rest < 5)
143+
if (diff < 8)
124144
{
125-
unit -= rest;
145+
return 1;
126146
}
127147
else
128148
{
129-
unit += 10 - rest;
130-
}
131-
if(pow>0)
132-
{
133-
unit /= Math.Pow(10, pow);
134-
}
135-
if (unit == 0)
136-
{
137-
return 1;
149+
var rawMajorUnit = diff;
150+
var exponent = Math.Floor(Math.Log10(rawMajorUnit));
151+
var fraction = rawMajorUnit / (Math.Pow(10, exponent));
152+
double unit;
153+
if (fraction <= 1)
154+
{
155+
unit = 1D;
156+
}
157+
else if (fraction <= 2)
158+
{
159+
unit = 2;
160+
}
161+
else if (fraction <= 2.5)
162+
{
163+
unit = 2.5;
164+
}
165+
else if (fraction <= 5)
166+
{
167+
unit = 5;
168+
}
169+
else
170+
{
171+
unit = 10;
172+
}
173+
174+
var axMax = unit * Math.Pow(10, exponent);
175+
var axMin = Math.Floor(min / axMax) * axMax;
176+
axMax = Math.Ceiling(max / axMax) * axMax;
177+
return axMax / 10;
138178
}
139-
return unit;
140179
}
141180
}
142181
}

src/EPPlus.Export.ImageRenderer/RenderItems/RenderItem.cs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -212,23 +212,6 @@ private string GetFillColor(ExcelDrawingFillBasic fill, ExcelDrawingColorManager
212212

213213
internal BoundingBox Bounds = new BoundingBox();
214214
internal abstract void GetBounds(out double il, out double it, out double ir, out double ib);
215-
216-
internal string RenderSvgElement(SvgElement element)
217-
{
218-
string retStr = string.Empty;
219-
220-
using (var ms = EPPlusMemoryManager.GetStream())
221-
{
222-
SvgWriter writer = new SvgWriter(ms, Encoding.UTF8);
223-
writer.RenderSvgElement(element, true);
224-
ms.Position = 0;
225-
using (var sr = new StreamReader(ms))
226-
{
227-
retStr = sr.ReadToEnd();
228-
return retStr;
229-
}
230-
}
231-
}
232215
}
233216
/// <summary>
234217
/// Base class for any item rendered.
@@ -237,6 +220,5 @@ internal abstract class RenderItemBase
237220
{
238221
public abstract RenderItemType Type { get; }
239222
public abstract void Render(StringBuilder sb);
240-
241223
}
242224
}

src/EPPlus.Export.ImageRenderer/RenderItems/Shared/DrawingBaseItem.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,6 @@ internal void ImportEpplusDrawing(ExcelShapeBase drawing)
2222
Bounds.Top = drawing.GetPixelTop();
2323
Bounds.Width = drawing.GetPixelWidth();
2424
Bounds.Height = drawing.GetPixelHeight();
25-
26-
SetDrawingPropertiesFill(drawing.Fill, null);
27-
SetDrawingPropertiesBorder(drawing.Border, null, drawing.Border != null);
28-
}
29-
30-
public override RenderItemType Type => RenderItemType.Group;
31-
32-
internal override void GetBounds(out double il, out double it, out double ir, out double ib)
33-
{
34-
il = Bounds.Left; it = Bounds.Top; ir = Bounds.Right; ib = Bounds.Bottom;
3525
}
3626
}
3727
}

src/EPPlus.Export.ImageRenderer/RenderItems/Shared/ShapeItem.cs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ internal ShapeItem(ExcelShape shape) : base(shape)
4040
shapeDef.Calculate(shape);
4141

4242
//RenderItems.Add(new SvgRenderPathItem(shape));
43-
RenderItems.Add(new SvgGroupItem(shapeDef.GetTransform(shape.Rotation)));
43+
RenderItems.Add(new SvgGroupItem(shape.Rotation, shape.GetPixelWidth()/2, shape.GetPixelHeight()/2));
4444

4545
//Draw Filled path's
4646
foreach (var path in shapeDef.ShapePaths)
@@ -194,8 +194,6 @@ public string ViewBox
194194
}
195195
}
196196

197-
public override RenderItemType Type => throw new NotImplementedException();
198-
199197
private string GetFontColor()
200198
{
201199
string color;
@@ -214,19 +212,6 @@ private string GetFontColor()
214212
return color;
215213
}
216214

217-
TextBox GetTextBox()
218-
{
219-
//if (_renderTextBox != null)
220-
//{
221-
// return new TextBox(_shape.TextBody, _renderTextBox);
222-
//}
223-
//else
224-
//{
225-
GetShapeInnerBound(out double x, out double y, out double width, out double height);
226-
return new TextBox(x, y, width, height);
227-
//}
228-
}
229-
230215
private void GetFontNameAndSize(ExcelFont nsFont, out string fontName, out double fontSize)
231216
{
232217
fontName = string.IsNullOrEmpty(_shape.Font.LatinFont) ? _shape.Font.ComplexFont : _shape.Font.LatinFont;

src/EPPlus.Export.ImageRenderer/RenderItems/SvgRenderRectItem.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,18 @@ public SvgRenderRectItem(ExcelDrawing drawing) : base(drawing)
3434

3535
public double X { get { return Bounds.Left; } set { Bounds.Left = value; } }
3636
public double Y { get { return Bounds.Top; } set { Bounds.Top = value; } }
37+
public double Left { get { return Bounds.Left; } set { Bounds.Left = value; } }
38+
public double Top { get { return Bounds.Top; } set { Bounds.Top = value; } }
3739
public double Width { get { return Bounds.Width; } set { Bounds.Width = value; } }
3840
public double Height { get { return Bounds.Height; } set { Bounds.Height = value; } }
41+
public double Right { get { return Bounds.Left + Width; } }
42+
public double Bottom { get { return Bounds.Top + Height; } }
3943

4044
public override RenderItemType Type => RenderItemType.Rect;
4145

4246
public override void Render(StringBuilder sb)
4347
{
44-
var groupItem = new SvgGroupItem("");
48+
var groupItem = new SvgGroupItem();
4549
groupItem.Render(sb);
4650

4751
RenderRect(sb);

src/EPPlus.Export.ImageRenderer/Svg/SvgChart.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,6 @@ private void SetAxisPositionsFromPlotarea(SvgChart sc)
131131
internal SvgChartTitle HorizontalAxisTitle { get; set; }
132132
internal SvgChartTitle SecondVerticalAxisTitle { get; set; }
133133

134-
public override RenderItemType Type => throw new System.NotImplementedException();
135-
136134
private void SetChartArea()
137135
{
138136
var item = new SvgRenderRectItem(Chart);

0 commit comments

Comments
 (0)