Skip to content

Commit eb520ae

Browse files
committed
Improve compatibility for charts
1 parent 475fbf3 commit eb520ae

File tree

6 files changed

+29
-75
lines changed

6 files changed

+29
-75
lines changed

chart.go

+17-66
Original file line numberDiff line numberDiff line change
@@ -179,59 +179,11 @@ var (
179179
Contour: 0,
180180
WireframeContour: 0,
181181
}
182-
chartView3DDepthPercent = map[string]int{
183-
Area: 100,
184-
AreaStacked: 100,
185-
AreaPercentStacked: 100,
186-
Area3D: 100,
187-
Area3DStacked: 100,
188-
Area3DPercentStacked: 100,
189-
Bar: 100,
190-
BarStacked: 100,
191-
BarPercentStacked: 100,
192-
Bar3DClustered: 100,
193-
Bar3DStacked: 100,
194-
Bar3DPercentStacked: 100,
195-
Bar3DConeClustered: 100,
196-
Bar3DConeStacked: 100,
197-
Bar3DConePercentStacked: 100,
198-
Bar3DPyramidClustered: 100,
199-
Bar3DPyramidStacked: 100,
200-
Bar3DPyramidPercentStacked: 100,
201-
Bar3DCylinderClustered: 100,
202-
Bar3DCylinderStacked: 100,
203-
Bar3DCylinderPercentStacked: 100,
204-
Col: 100,
205-
ColStacked: 100,
206-
ColPercentStacked: 100,
207-
Col3D: 100,
208-
Col3DClustered: 100,
209-
Col3DStacked: 100,
210-
Col3DPercentStacked: 100,
211-
Col3DCone: 100,
212-
Col3DConeClustered: 100,
213-
Col3DConeStacked: 100,
214-
Col3DConePercentStacked: 100,
215-
Col3DPyramid: 100,
216-
Col3DPyramidClustered: 100,
217-
Col3DPyramidStacked: 100,
218-
Col3DPyramidPercentStacked: 100,
219-
Col3DCylinder: 100,
220-
Col3DCylinderClustered: 100,
221-
Col3DCylinderStacked: 100,
222-
Col3DCylinderPercentStacked: 100,
223-
Doughnut: 100,
224-
Line: 100,
225-
Pie: 100,
226-
Pie3D: 100,
227-
Radar: 100,
228-
Scatter: 100,
229-
Surface3D: 100,
230-
WireframeSurface3D: 100,
231-
Contour: 100,
232-
WireframeContour: 100,
233-
Bubble: 100,
234-
Bubble3D: 100,
182+
plotAreaChartOverlap = map[string]int{
183+
BarStacked: 100,
184+
BarPercentStacked: 100,
185+
ColStacked: 100,
186+
ColPercentStacked: 100,
235187
}
236188
chartView3DPerspective = map[string]int{
237189
Contour: 0,
@@ -842,11 +794,10 @@ func (f *File) addChart(formatSet *formatChart) {
842794
},
843795
},
844796
View3D: &cView3D{
845-
RotX: &attrValInt{Val: chartView3DRotX[formatSet.Type]},
846-
RotY: &attrValInt{Val: chartView3DRotY[formatSet.Type]},
847-
DepthPercent: &attrValInt{Val: chartView3DDepthPercent[formatSet.Type]},
848-
Perspective: &attrValInt{Val: chartView3DPerspective[formatSet.Type]},
849-
RAngAx: &attrValInt{Val: chartView3DRAngAx[formatSet.Type]},
797+
RotX: &attrValInt{Val: chartView3DRotX[formatSet.Type]},
798+
RotY: &attrValInt{Val: chartView3DRotY[formatSet.Type]},
799+
Perspective: &attrValInt{Val: chartView3DPerspective[formatSet.Type]},
800+
RAngAx: &attrValInt{Val: chartView3DRAngAx[formatSet.Type]},
850801
},
851802
Floor: &cThicknessSpPr{
852803
Thickness: &attrValInt{Val: 0},
@@ -980,6 +931,7 @@ func (f *File) drawBaseChart(formatSet *formatChart) *cPlotArea {
980931
{Val: 754001152},
981932
{Val: 753999904},
982933
},
934+
Overlap: &attrValInt{Val: 100},
983935
}
984936
var ok bool
985937
if c.BarDir.Val, ok = plotAreaChartBarDir[formatSet.Type]; !ok {
@@ -988,8 +940,8 @@ func (f *File) drawBaseChart(formatSet *formatChart) *cPlotArea {
988940
if c.Grouping.Val, ok = plotAreaChartGrouping[formatSet.Type]; !ok {
989941
c.Grouping = nil
990942
}
991-
if strings.HasSuffix(formatSet.Type, "Stacked") {
992-
c.Overlap = &attrValInt{Val: 100}
943+
if c.Overlap.Val, ok = plotAreaChartOverlap[formatSet.Type]; !ok {
944+
c.Overlap = nil
993945
}
994946
catAx := f.drawPlotAreaCatAx(formatSet)
995947
valAx := f.drawPlotAreaValAx(formatSet)
@@ -1485,7 +1437,7 @@ func (f *File) drawChartSeriesCat(v formatChartSeries, formatSet *formatChart) *
14851437
F: v.Categories,
14861438
},
14871439
}
1488-
chartSeriesCat := map[string]*cCat{Scatter: nil}
1440+
chartSeriesCat := map[string]*cCat{Scatter: nil, Bubble: nil, Bubble3D: nil}
14891441
if _, ok := chartSeriesCat[formatSet.Type]; ok {
14901442
return nil
14911443
}
@@ -1500,7 +1452,7 @@ func (f *File) drawChartSeriesVal(v formatChartSeries, formatSet *formatChart) *
15001452
F: v.Values,
15011453
},
15021454
}
1503-
chartSeriesVal := map[string]*cVal{Scatter: nil}
1455+
chartSeriesVal := map[string]*cVal{Scatter: nil, Bubble: nil, Bubble3D: nil}
15041456
if _, ok := chartSeriesVal[formatSet.Type]; ok {
15051457
return nil
15061458
}
@@ -1783,7 +1735,6 @@ func (f *File) drawPlotAreaTxPr() *cTxPr {
17831735
// deserialization, two different structures: decodeWsDr and encodeWsDr are
17841736
// defined.
17851737
func (f *File) drawingParser(path string) (*xlsxWsDr, int) {
1786-
cNvPrID := 1
17871738
if f.Drawings[path] == nil {
17881739
content := xlsxWsDr{}
17891740
content.A = NameSpaceDrawingML
@@ -1793,7 +1744,6 @@ func (f *File) drawingParser(path string) (*xlsxWsDr, int) {
17931744
decodeWsDr := decodeWsDr{}
17941745
_ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(path)), &decodeWsDr)
17951746
content.R = decodeWsDr.R
1796-
cNvPrID = len(decodeWsDr.OneCellAnchor) + len(decodeWsDr.TwoCellAnchor) + 1
17971747
for _, v := range decodeWsDr.OneCellAnchor {
17981748
content.OneCellAnchor = append(content.OneCellAnchor, &xdrCellAnchor{
17991749
EditAs: v.EditAs,
@@ -1809,7 +1759,8 @@ func (f *File) drawingParser(path string) (*xlsxWsDr, int) {
18091759
}
18101760
f.Drawings[path] = &content
18111761
}
1812-
return f.Drawings[path], cNvPrID
1762+
wsDr := f.Drawings[path]
1763+
return wsDr, len(wsDr.OneCellAnchor) + len(wsDr.TwoCellAnchor) + 2
18131764
}
18141765

18151766
// addDrawingChart provides a function to add chart graphic frame by given
@@ -1845,7 +1796,7 @@ func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rI
18451796
graphicFrame := xlsxGraphicFrame{
18461797
NvGraphicFramePr: xlsxNvGraphicFramePr{
18471798
CNvPr: &xlsxCNvPr{
1848-
ID: len(content.OneCellAnchor) + len(content.TwoCellAnchor) + 2,
1799+
ID: cNvPrID,
18491800
Name: "Chart " + strconv.Itoa(cNvPrID),
18501801
},
18511802
},

chart_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func TestAddChart(t *testing.T) {
126126
assert.NoError(t, f.AddChart("Sheet1", "X1", `{"type":"colStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"2D Stacked Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
127127
assert.NoError(t, f.AddChart("Sheet1", "P16", `{"type":"colPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"100% Stacked Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
128128
assert.NoError(t, f.AddChart("Sheet1", "X16", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"3D Clustered Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
129-
assert.NoError(t, f.AddChart("Sheet1", "P30", `{"type":"col3DStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"3D 100% Stacked Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
129+
assert.NoError(t, f.AddChart("Sheet1", "P30", `{"type":"col3DStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"3D Stacked Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
130130
assert.NoError(t, f.AddChart("Sheet1", "X30", `{"type":"col3DPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"3D 100% Stacked Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
131131
assert.NoError(t, f.AddChart("Sheet1", "AF1", `{"type":"col3DConeStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"3D Column Cone Stacked Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
132132
assert.NoError(t, f.AddChart("Sheet1", "AF16", `{"type":"col3DConeClustered","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"3D Column Cone Clustered Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))

col.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ func (f *File) GetColOutlineLevel(sheet, col string) (uint8, error) {
113113
for c := range xlsx.Cols.Col {
114114
colData := &xlsx.Cols.Col[c]
115115
if colData.Min <= colNum && colNum <= colData.Max {
116-
level = colData.OutlineLevel + 1
116+
level = colData.OutlineLevel
117117
}
118118
}
119119
return level, err

picture.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
272272
twoCellAnchor.To = &to
273273
pic := xlsxPic{}
274274
pic.NvPicPr.CNvPicPr.PicLocks.NoChangeAspect = formatSet.NoChangeAspect
275-
pic.NvPicPr.CNvPr.ID = len(content.OneCellAnchor) + len(content.TwoCellAnchor) + 2
275+
pic.NvPicPr.CNvPr.ID = cNvPrID
276276
pic.NvPicPr.CNvPr.Descr = file
277277
pic.NvPicPr.CNvPr.Name = "Picture " + strconv.Itoa(cNvPrID)
278278
if hyperlinkRID != 0 {

shape.go

+8-5
Original file line numberDiff line numberDiff line change
@@ -411,18 +411,21 @@ func (f *File) addDrawingShape(sheet, drawingXML, cell string, formatSet *format
411411
U: u,
412412
Sz: p.Font.Size * 100,
413413
Latin: &aLatin{Typeface: p.Font.Family},
414-
SolidFill: &aSolidFill{
415-
SrgbClr: &attrValString{
416-
Val: strings.Replace(strings.ToUpper(p.Font.Color), "#", "", -1),
417-
},
418-
},
419414
},
420415
T: text,
421416
},
422417
EndParaRPr: &aEndParaRPr{
423418
Lang: "en-US",
424419
},
425420
}
421+
srgbClr := strings.Replace(strings.ToUpper(p.Font.Color), "#", "", -1)
422+
if len(srgbClr) == 6 {
423+
paragraph.R.RPr.SolidFill = &aSolidFill{
424+
SrgbClr: &attrValString{
425+
Val: srgbClr,
426+
},
427+
}
428+
}
426429
shape.TxBody.P = append(shape.TxBody.P, paragraph)
427430
}
428431
twoCellAnchor.Sp = &shape

xmlChart.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,8 @@ type cCharts struct {
332332
VaryColors *attrValBool `xml:"varyColors"`
333333
Wireframe *attrValBool `xml:"wireframe"`
334334
Ser *[]cSer `xml:"ser"`
335-
Shape *attrValString `xml:"shape"`
336335
DLbls *cDLbls `xml:"dLbls"`
336+
Shape *attrValString `xml:"shape"`
337337
HoleSize *attrValInt `xml:"holeSize"`
338338
Smooth *attrValBool `xml:"smooth"`
339339
Overlap *attrValInt `xml:"overlap"`

0 commit comments

Comments
 (0)