浏览代码

- Update the function `AddChart()`: clustered, stacked and 100% stacked bar and column series charts supported, relate issue #190;
- go test and godoc has been updated

Ri Xu 7 年之前
父节点
当前提交
45c31c4764
共有 2 个文件被更改,包括 187 次插入50 次删除
  1. 169 40
      chart.go
  2. 18 10
      excelize_test.go

+ 169 - 40
chart.go

@@ -11,9 +11,17 @@ import (
 const (
 	Bar                 = "bar"
 	BarStacked          = "barStacked"
-	Bar3D               = "bar3D"
-	Bar3DColumn         = "bar3DColumn"
+	BarPercentStacked   = "barPercentStacked"
+	Bar3DClustered      = "bar3DClustered"
+	Bar3DStacked        = "bar3DStacked"
 	Bar3DPercentStacked = "bar3DPercentStacked"
+	Col                 = "col"
+	ColStacked          = "colStacked"
+	ColPercentStacked   = "colPercentStacked"
+	Col3DClustered      = "col3DClustered"
+	Col3D               = "col3D"
+	Col3DStacked        = "col3DStacked"
+	Col3DPercentStacked = "col3DPercentStacked"
 	Doughnut            = "doughnut"
 	Line                = "line"
 	Pie                 = "pie"
@@ -27,9 +35,17 @@ var (
 	chartView3DRotX = map[string]int{
 		Bar:                 0,
 		BarStacked:          0,
-		Bar3D:               15,
-		Bar3DColumn:         15,
+		BarPercentStacked:   0,
+		Bar3DClustered:      15,
+		Bar3DStacked:        15,
 		Bar3DPercentStacked: 15,
+		Col:                 0,
+		ColStacked:          0,
+		ColPercentStacked:   0,
+		Col3DClustered:      15,
+		Col3D:               15,
+		Col3DStacked:        15,
+		Col3DPercentStacked: 15,
 		Doughnut:            0,
 		Line:                0,
 		Pie:                 0,
@@ -40,9 +56,17 @@ var (
 	chartView3DRotY = map[string]int{
 		Bar:                 0,
 		BarStacked:          0,
-		Bar3D:               20,
-		Bar3DColumn:         20,
+		BarPercentStacked:   0,
+		Bar3DClustered:      20,
+		Bar3DStacked:        20,
 		Bar3DPercentStacked: 20,
+		Col:                 0,
+		ColStacked:          0,
+		ColPercentStacked:   0,
+		Col3DClustered:      20,
+		Col3D:               20,
+		Col3DStacked:        20,
+		Col3DPercentStacked: 20,
 		Doughnut:            0,
 		Line:                0,
 		Pie:                 0,
@@ -53,9 +77,17 @@ var (
 	chartView3DDepthPercent = map[string]int{
 		Bar:                 100,
 		BarStacked:          100,
-		Bar3D:               100,
-		Bar3DColumn:         100,
+		BarPercentStacked:   100,
+		Bar3DClustered:      100,
+		Bar3DStacked:        100,
 		Bar3DPercentStacked: 100,
+		Col:                 100,
+		ColStacked:          100,
+		ColPercentStacked:   100,
+		Col3DClustered:      100,
+		Col3D:               100,
+		Col3DStacked:        100,
+		Col3DPercentStacked: 100,
 		Doughnut:            100,
 		Line:                100,
 		Pie:                 100,
@@ -66,9 +98,17 @@ var (
 	chartView3DRAngAx = map[string]int{
 		Bar:                 0,
 		BarStacked:          0,
-		Bar3D:               1,
-		Bar3DColumn:         1,
+		BarPercentStacked:   0,
+		Bar3DClustered:      1,
+		Bar3DStacked:        1,
 		Bar3DPercentStacked: 1,
+		Col:                 0,
+		ColStacked:          0,
+		ColPercentStacked:   0,
+		Col3DClustered:      1,
+		Col3D:               1,
+		Col3DStacked:        1,
+		Col3DPercentStacked: 1,
 		Doughnut:            0,
 		Line:                0,
 		Pie:                 0,
@@ -86,9 +126,17 @@ var (
 	chartValAxNumFmtFormatCode = map[string]string{
 		Bar:                 "General",
 		BarStacked:          "General",
-		Bar3D:               "General",
-		Bar3DColumn:         "General",
+		BarPercentStacked:   "0%",
+		Bar3DClustered:      "General",
+		Bar3DStacked:        "General",
 		Bar3DPercentStacked: "0%",
+		Col:                 "General",
+		ColStacked:          "General",
+		ColPercentStacked:   "0%",
+		Col3DClustered:      "General",
+		Col3D:               "General",
+		Col3DStacked:        "General",
+		Col3DPercentStacked: "0%",
 		Doughnut:            "General",
 		Line:                "General",
 		Pie:                 "General",
@@ -99,9 +147,33 @@ var (
 	plotAreaChartGrouping = map[string]string{
 		Bar:                 "clustered",
 		BarStacked:          "stacked",
-		Bar3D:               "clustered",
-		Bar3DColumn:         "standard",
+		BarPercentStacked:   "percentStacked",
+		Bar3DClustered:      "clustered",
+		Bar3DStacked:        "stacked",
 		Bar3DPercentStacked: "percentStacked",
+		Col:                 "clustered",
+		ColStacked:          "stacked",
+		ColPercentStacked:   "percentStacked",
+		Col3DClustered:      "clustered",
+		Col3D:               "standard",
+		Col3DStacked:        "stacked",
+		Col3DPercentStacked: "percentStacked",
+		Line:                "standard",
+	}
+	plotAreaChartBarDir = map[string]string{
+		Bar:                 "bar",
+		BarStacked:          "bar",
+		BarPercentStacked:   "bar",
+		Bar3DClustered:      "bar",
+		Bar3DStacked:        "bar",
+		Bar3DPercentStacked: "bar",
+		Col:                 "col",
+		ColStacked:          "col",
+		ColPercentStacked:   "col",
+		Col3DClustered:      "col",
+		Col3D:               "col",
+		Col3DStacked:        "col",
+		Col3DPercentStacked: "col",
 		Line:                "standard",
 	}
 )
@@ -134,7 +206,7 @@ func parseFormatChartSet(formatSet string) *formatChart {
 
 // AddChart provides the method to add chart in a sheet by given chart format
 // set (such as offset, scale, aspect ratio setting and print settings) and
-// properties set. For example, create 3D bar chart with data
+// properties set. For example, create 3D clustered column chart with data
 // Sheet1!$A$29:$D$32:
 //
 //    package main
@@ -155,7 +227,7 @@ func parseFormatChartSet(formatSet string) *formatChart {
 //        for k, v := range values {
 //            xlsx.SetCellValue("Sheet1", k, v)
 //        }
-//        xlsx.AddChart("SHEET1", "F2", `{"type":"bar3D","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"}],"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":"Fruit Line 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"}`)
+//        xlsx.AddChart("Sheet1", "E1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"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":"Fruit 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"}`)
 //        // Save xlsx file by the given path.
 //        err := xlsx.SaveAs("./Workbook.xlsx")
 //        if err != nil {
@@ -166,12 +238,20 @@ func parseFormatChartSet(formatSet string) *formatChart {
 // The following shows the type of chart supported by excelize:
 //
 //     Type                | Chart
-//    ---------------------+---------------------------
-//     bar                 | bar chart
-//     barStacked          | stacked bar chart
-//     bar3D               | 3D bar chart
-//     bar3DColumn         | 3D column bar chart
+//    ---------------------+------------------------------
+//     bar                 | 2D clustered bar chart
+//     barStacked          | 2D stacked bar chart
+//     barPercentStacked   | 2D 100% stacked bar chart
+//     bar3DClustered      | 3D clustered bar chart
+//     bar3DStacked        | 3D stacked bar chart
 //     bar3DPercentStacked | 3D 100% stacked bar chart
+//     col                 | 2D clustered column chart
+//     colStacked          | 2D stacked column chart
+//     colPercentStacked   | 2D 100% stacked column chart
+//     col3DClustered      | 3D clustered column chart
+//     col3D               | 3D column column chart
+//     col3DStacked        | 3D stacked column chart
+//     col3DPercentStacked | 3D 100% stacked column chart
 //     doughnut            | doughnut chart
 //     line                | line chart
 //     pie                 | pie chart
@@ -423,11 +503,19 @@ func (f *File) addChart(formatSet *formatChart) {
 		},
 	}
 	plotAreaFunc := map[string]func(*formatChart) *cPlotArea{
-		Bar:                 f.drawBarChart,
-		BarStacked:          f.drawBarChart,
-		Bar3D:               f.drawBarChart,
-		Bar3DColumn:         f.drawBarChart,
-		Bar3DPercentStacked: f.drawBarChart,
+		Bar:                 f.drawBaseChart,
+		BarStacked:          f.drawBaseChart,
+		BarPercentStacked:   f.drawBaseChart,
+		Bar3DClustered:      f.drawBaseChart,
+		Bar3DStacked:        f.drawBaseChart,
+		Bar3DPercentStacked: f.drawBaseChart,
+		Col:                 f.drawBaseChart,
+		ColStacked:          f.drawBaseChart,
+		ColPercentStacked:   f.drawBaseChart,
+		Col3DClustered:      f.drawBaseChart,
+		Col3D:               f.drawBaseChart,
+		Col3DStacked:        f.drawBaseChart,
+		Col3DPercentStacked: f.drawBaseChart,
 		Doughnut:            f.drawDoughnutChart,
 		Line:                f.drawLineChart,
 		Pie3D:               f.drawPie3DChart,
@@ -442,9 +530,9 @@ func (f *File) addChart(formatSet *formatChart) {
 	f.saveFileList(media, string(chart))
 }
 
-// drawBarChart provides function to draw the c:plotArea element for bar, barStacked and
-// bar3D chart by given format sets.
-func (f *File) drawBarChart(formatSet *formatChart) *cPlotArea {
+// drawBaseChart provides function to draw the c:plotArea element for bar,
+// and column series charts by given format sets.
+func (f *File) drawBaseChart(formatSet *formatChart) *cPlotArea {
 	c := cCharts{
 		BarDir: &attrValString{
 			Val: "col",
@@ -462,8 +550,9 @@ func (f *File) drawBarChart(formatSet *formatChart) *cPlotArea {
 			{Val: 753999904},
 		},
 	}
+	c.BarDir.Val = plotAreaChartBarDir[formatSet.Type]
 	c.Grouping.Val = plotAreaChartGrouping[formatSet.Type]
-	if formatSet.Type == "barStacked" {
+	if formatSet.Type == "colStacked" || formatSet.Type == "barStacked" || formatSet.Type == "barPercentStacked" || formatSet.Type == "colPercentStacked" {
 		c.Overlap = &attrValInt{Val: 100}
 	}
 	catAx := f.drawPlotAreaCatAx(formatSet)
@@ -479,12 +568,17 @@ func (f *File) drawBarChart(formatSet *formatChart) *cPlotArea {
 			CatAx:    catAx,
 			ValAx:    valAx,
 		},
-		"bar3D": {
+		"barPercentStacked": {
+			BarChart: &c,
+			CatAx:    catAx,
+			ValAx:    valAx,
+		},
+		"bar3DClustered": {
 			Bar3DChart: &c,
 			CatAx:      catAx,
 			ValAx:      valAx,
 		},
-		"bar3DColumn": {
+		"bar3DStacked": {
 			Bar3DChart: &c,
 			CatAx:      catAx,
 			ValAx:      valAx,
@@ -494,6 +588,41 @@ func (f *File) drawBarChart(formatSet *formatChart) *cPlotArea {
 			CatAx:      catAx,
 			ValAx:      valAx,
 		},
+		"col": {
+			BarChart: &c,
+			CatAx:    catAx,
+			ValAx:    valAx,
+		},
+		"colStacked": {
+			BarChart: &c,
+			CatAx:    catAx,
+			ValAx:    valAx,
+		},
+		"colPercentStacked": {
+			BarChart: &c,
+			CatAx:    catAx,
+			ValAx:    valAx,
+		},
+		"col3DClustered": {
+			Bar3DChart: &c,
+			CatAx:      catAx,
+			ValAx:      valAx,
+		},
+		"col3D": {
+			Bar3DChart: &c,
+			CatAx:      catAx,
+			ValAx:      valAx,
+		},
+		"col3DStacked": {
+			Bar3DChart: &c,
+			CatAx:      catAx,
+			ValAx:      valAx,
+		},
+		"col3DPercentStacked": {
+			Bar3DChart: &c,
+			CatAx:      catAx,
+			ValAx:      valAx,
+		},
 	}
 	return charts[formatSet.Type]
 }
@@ -654,7 +783,7 @@ func (f *File) drawChartSeriesSpPr(i int, formatSet *formatChart) *cSpPr {
 			},
 		},
 	}
-	chartSeriesSpPr := map[string]*cSpPr{Bar: nil, BarStacked: nil, Bar3D: nil, Bar3DColumn: nil, Bar3DPercentStacked: nil, Doughnut: nil, Line: spPrLine, Pie: nil, Pie3D: nil, Radar: nil, Scatter: spPrScatter}
+	chartSeriesSpPr := map[string]*cSpPr{Bar: nil, BarStacked: nil, BarPercentStacked: nil, Bar3DClustered: nil, Bar3DStacked: nil, Bar3DPercentStacked: nil, Col: nil, ColStacked: nil, ColPercentStacked: nil, Col3DClustered: nil, Col3D: nil, Col3DStacked: nil, Col3DPercentStacked: nil, Doughnut: nil, Line: spPrLine, Pie: nil, Pie3D: nil, Radar: nil, Scatter: spPrScatter}
 	return chartSeriesSpPr[formatSet.Type]
 }
 
@@ -683,7 +812,7 @@ func (f *File) drawChartSeriesDPt(i int, formatSet *formatChart) []*cDPt {
 			},
 		},
 	}}
-	chartSeriesDPt := map[string][]*cDPt{Bar: nil, BarStacked: nil, Bar3D: nil, Bar3DColumn: nil, Bar3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: dpt, Pie3D: dpt, Radar: nil, Scatter: nil}
+	chartSeriesDPt := map[string][]*cDPt{Bar: nil, BarStacked: nil, BarPercentStacked: nil, Bar3DClustered: nil, Bar3DStacked: nil, Bar3DPercentStacked: nil, Col: nil, ColStacked: nil, ColPercentStacked: nil, Col3DClustered: nil, Col3D: nil, Col3DStacked: nil, Col3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: dpt, Pie3D: dpt, Radar: nil, Scatter: nil}
 	return chartSeriesDPt[formatSet.Type]
 }
 
@@ -695,7 +824,7 @@ func (f *File) drawChartSeriesCat(v formatChartSeries, formatSet *formatChart) *
 			F: v.Categories,
 		},
 	}
-	chartSeriesCat := map[string]*cCat{Bar: cat, BarStacked: cat, Bar3D: cat, Bar3DColumn: cat, Bar3DPercentStacked: cat, Doughnut: cat, Line: cat, Pie: cat, Pie3D: cat, Radar: cat, Scatter: nil}
+	chartSeriesCat := map[string]*cCat{Bar: cat, BarStacked: cat, BarPercentStacked: cat, Bar3DClustered: cat, Bar3DStacked: cat, Bar3DPercentStacked: cat, Col: cat, ColStacked: cat, ColPercentStacked: cat, Col3DClustered: cat, Col3D: cat, Col3DStacked: cat, Col3DPercentStacked: cat, Doughnut: cat, Line: cat, Pie: cat, Pie3D: cat, Radar: cat, Scatter: nil}
 	return chartSeriesCat[formatSet.Type]
 }
 
@@ -707,7 +836,7 @@ func (f *File) drawChartSeriesVal(v formatChartSeries, formatSet *formatChart) *
 			F: v.Values,
 		},
 	}
-	chartSeriesVal := map[string]*cVal{Bar: val, BarStacked: val, Bar3D: val, Bar3DColumn: val, Bar3DPercentStacked: val, Doughnut: val, Line: val, Pie: val, Pie3D: val, Radar: val, Scatter: nil}
+	chartSeriesVal := map[string]*cVal{Bar: val, BarStacked: val, BarPercentStacked: val, Bar3DClustered: val, Bar3DStacked: val, Bar3DPercentStacked: val, Col: val, ColStacked: val, ColPercentStacked: val, Col3DClustered: val, Col3D: val, Col3DStacked: val, Col3DPercentStacked: val, Doughnut: val, Line: val, Pie: val, Pie3D: val, Radar: val, Scatter: nil}
 	return chartSeriesVal[formatSet.Type]
 }
 
@@ -733,7 +862,7 @@ func (f *File) drawChartSeriesMarker(i int, formatSet *formatChart) *cMarker {
 			},
 		},
 	}
-	chartSeriesMarker := map[string]*cMarker{Bar: nil, BarStacked: nil, Bar3D: nil, Bar3DColumn: nil, Bar3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: marker}
+	chartSeriesMarker := map[string]*cMarker{Bar: nil, BarStacked: nil, BarPercentStacked: nil, Bar3DClustered: nil, Bar3DStacked: nil, Bar3DPercentStacked: nil, Col: nil, ColStacked: nil, ColPercentStacked: nil, Col3DClustered: nil, Col3D: nil, Col3DStacked: nil, Col3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: marker}
 	return chartSeriesMarker[formatSet.Type]
 }
 
@@ -745,7 +874,7 @@ func (f *File) drawChartSeriesXVal(v formatChartSeries, formatSet *formatChart)
 			F: v.Categories,
 		},
 	}
-	chartSeriesXVal := map[string]*cCat{Bar: nil, BarStacked: nil, Bar3D: nil, Bar3DColumn: nil, Bar3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: cat}
+	chartSeriesXVal := map[string]*cCat{Bar: nil, BarStacked: nil, BarPercentStacked: nil, Bar3DClustered: nil, Bar3DStacked: nil, Bar3DPercentStacked: nil, Col: nil, ColStacked: nil, ColPercentStacked: nil, Col3DClustered: nil, Col3D: nil, Col3DStacked: nil, Col3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: cat}
 	return chartSeriesXVal[formatSet.Type]
 }
 
@@ -757,7 +886,7 @@ func (f *File) drawChartSeriesYVal(v formatChartSeries, formatSet *formatChart)
 			F: v.Values,
 		},
 	}
-	chartSeriesYVal := map[string]*cVal{Bar: nil, BarStacked: nil, Bar3D: nil, Bar3DColumn: nil, Bar3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: val}
+	chartSeriesYVal := map[string]*cVal{Bar: nil, BarStacked: nil, BarPercentStacked: nil, Bar3DClustered: nil, Bar3DStacked: nil, Bar3DPercentStacked: nil, Col: nil, ColStacked: nil, ColPercentStacked: nil, Col3DClustered: nil, Col3D: nil, Col3DStacked: nil, Col3DPercentStacked: nil, Doughnut: nil, Line: nil, Pie: nil, Pie3D: nil, Radar: nil, Scatter: val}
 	return chartSeriesYVal[formatSet.Type]
 }
 
@@ -779,7 +908,7 @@ func (f *File) drawChartDLbls(formatSet *formatChart) *cDLbls {
 // format sets.
 func (f *File) drawChartSeriesDLbls(formatSet *formatChart) *cDLbls {
 	dLbls := f.drawChartDLbls(formatSet)
-	chartSeriesDLbls := map[string]*cDLbls{Bar: dLbls, BarStacked: dLbls, Bar3D: dLbls, Bar3DColumn: dLbls, Bar3DPercentStacked: dLbls, Doughnut: dLbls, Line: dLbls, Pie: dLbls, Pie3D: dLbls, Radar: dLbls, Scatter: nil}
+	chartSeriesDLbls := map[string]*cDLbls{Bar: dLbls, BarStacked: dLbls, BarPercentStacked: dLbls, Bar3DClustered: dLbls, Bar3DStacked: dLbls, Bar3DPercentStacked: dLbls, Col: dLbls, ColStacked: dLbls, ColPercentStacked: dLbls, Col3DClustered: dLbls, Col3D: dLbls, Col3DStacked: dLbls, Col3DPercentStacked: dLbls, Doughnut: dLbls, Line: dLbls, Pie: dLbls, Pie3D: dLbls, Radar: dLbls, Scatter: nil}
 	return chartSeriesDLbls[formatSet.Type]
 }
 

+ 18 - 10
excelize_test.go

@@ -826,17 +826,25 @@ func TestAddChart(t *testing.T) {
 	for k, v := range values {
 		xlsx.SetCellValue("Sheet1", k, v)
 	}
-	xlsx.AddChart("Sheet1", "P1", `{"type":"bar3D","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"}],"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":"Fruit 3D 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"}`)
-	xlsx.AddChart("Sheet1", "X1", `{"type":"bar","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"}],"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":"Fruit 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"}`)
-	xlsx.AddChart("Sheet1", "P16", `{"type":"doughnut","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"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":"right","show_legend_key":false},"title":{"name":"Fruit Doughnut Chart"},"plotarea":{"show_bubble_size":false,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`)
-	xlsx.AddChart("Sheet1", "X16", `{"type":"line","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"}],"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":"top","show_legend_key":false},"title":{"name":"Fruit Line 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"}`)
-	xlsx.AddChart("Sheet1", "P30", `{"type":"pie3D","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"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":"Fruit 3D Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`)
-	xlsx.AddChart("Sheet1", "X30", `{"type":"pie","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"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":"Fruit Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"gap"}`)
+	xlsx.AddChart("Sheet1", "P1", `{"type":"col","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"}],"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":"Fruit 2D 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"}`)
+	xlsx.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"}],"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":"Fruit 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"}`)
+	xlsx.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"}],"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":"Fruit 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"}`)
+	xlsx.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"}],"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":"Fruit 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"}`)
+	xlsx.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"}],"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":"Fruit 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"}`)
+	xlsx.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"}],"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":"Fruit 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"}`)
+	xlsx.AddChart("Sheet1", "P45", `{"type":"col3D","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"}],"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":"Fruit 3D 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"}`)
 	xlsx.AddChart("Sheet2", "P1", `{"type":"radar","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"}],"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":"top_right","show_legend_key":false},"title":{"name":"Fruit Radar 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":"span"}`)
 	xlsx.AddChart("Sheet2", "X1", `{"type":"scatter","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"}],"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":"Fruit Scatter 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"}`)
-	xlsx.AddChart("Sheet2", "P16", `{"type":"barStacked","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"}],"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":"Fruit 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"}`)
-	xlsx.AddChart("Sheet2", "X17", `{"type":"bar3DColumn","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"}],"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":"Fruit 3D 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"}`)
-	xlsx.AddChart("Sheet2", "P32", `{"type":"bar3DPercentStacked","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"}],"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":"Fruit 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"}`)
+	xlsx.AddChart("Sheet2", "P16", `{"type":"doughnut","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"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":"right","show_legend_key":false},"title":{"name":"Fruit Doughnut Chart"},"plotarea":{"show_bubble_size":false,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`)
+	xlsx.AddChart("Sheet2", "X16", `{"type":"line","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"}],"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":"top","show_legend_key":false},"title":{"name":"Fruit Line 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"}`)
+	xlsx.AddChart("Sheet2", "P32", `{"type":"pie3D","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"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":"Fruit 3D Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`)
+	xlsx.AddChart("Sheet2", "X32", `{"type":"pie","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"}],"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":"Fruit Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"gap"}`)
+	xlsx.AddChart("Sheet2", "P48", `{"type":"bar","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"}],"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":"Fruit 2D Clustered 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"}`)
+	xlsx.AddChart("Sheet2", "X48", `{"type":"barStacked","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"}],"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":"Fruit 2D 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"}`)
+	xlsx.AddChart("Sheet2", "P64", `{"type":"barPercentStacked","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"}],"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":"Fruit 2D 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"}`)
+	xlsx.AddChart("Sheet2", "X64", `{"type":"bar3DClustered","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"}],"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":"Fruit 3D Clustered 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"}`)
+	xlsx.AddChart("Sheet2", "P80", `{"type":"bar3DStacked","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"}],"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":"Fruit 3D 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"}`)
+	xlsx.AddChart("Sheet2", "X80", `{"type":"bar3DPercentStacked","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"}],"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":"Fruit 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"}`)
 	// Save xlsx file by the given path.
 	err = xlsx.SaveAs("./test/Workbook_addchart.xlsx")
 	if err != nil {
@@ -1013,7 +1021,7 @@ func TestTitleToNumber(t *testing.T) {
 func TestSharedStrings(t *testing.T) {
 	xlsx, err := OpenFile("./test/SharedStrings.xlsx")
 	if err != nil {
-		fmt.Println(err)
+		t.Error(err)
 		return
 	}
 	xlsx.GetRows("Sheet1")