diff --git a/chart_test.go b/chart_test.go index 1f265a3f..accfc590 100644 --- a/chart_test.go +++ b/chart_test.go @@ -220,12 +220,12 @@ func TestAddChart(t *testing.T) { {sheetName: "Sheet1", cell: "AV30", opts: &Chart{Type: "col3DCylinderPercentStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cylinder Percent Stacked Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "AV45", opts: &Chart{Type: "col3DCylinder", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cylinder Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "P45", opts: &Chart{Type: "col3D", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, - {sheetName: "Sheet2", cell: "P1", opts: &Chart{Type: "line3D", Series: series2, Format: format, Legend: ChartLegend{Position: "top", ShowLegendKey: false}, Title: ChartTitle{Name: "3D Line Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, TickLabelSkip: 1}, YAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, MajorUnit: 1}}}, + {sheetName: "Sheet2", cell: "P1", opts: &Chart{Type: "line3D", Series: series2, Format: format, Legend: ChartLegend{Position: "top", ShowLegendKey: false}, Title: ChartTitle{Name: "3D Line Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, TickLabelSkip: 1, NumFmt: ChartNumFmt{CustomNumFmt: "General"}}, YAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, MajorUnit: 1, NumFmt: ChartNumFmt{CustomNumFmt: "General"}}}}, {sheetName: "Sheet2", cell: "X1", opts: &Chart{Type: "scatter", Series: series, Format: format, Legend: ChartLegend{Position: "bottom", ShowLegendKey: false}, Title: ChartTitle{Name: "Scatter Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet2", cell: "P16", opts: &Chart{Type: "doughnut", Series: series3, Format: format, Legend: ChartLegend{Position: "right", ShowLegendKey: false}, Title: ChartTitle{Name: "Doughnut Chart"}, PlotArea: ChartPlotArea{ShowBubbleSize: false, ShowCatName: false, ShowLeaderLines: false, ShowPercent: true, ShowSerName: false, ShowVal: false}, ShowBlanksAs: "zero", HoleSize: 30}}, {sheetName: "Sheet2", cell: "X16", opts: &Chart{Type: "line", Series: series2, Format: format, Legend: ChartLegend{Position: "top", ShowLegendKey: false}, Title: ChartTitle{Name: "Line Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, TickLabelSkip: 1}, YAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, MajorUnit: 1}}}, {sheetName: "Sheet2", cell: "P32", opts: &Chart{Type: "pie3D", Series: series3, Format: format, Legend: ChartLegend{Position: "bottom", ShowLegendKey: false}, Title: ChartTitle{Name: "3D Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, - {sheetName: "Sheet2", cell: "X32", opts: &Chart{Type: "pie", Series: series3, Format: format, Legend: ChartLegend{Position: "bottom", ShowLegendKey: false}, Title: ChartTitle{Name: "Pie Chart"}, PlotArea: ChartPlotArea{ShowBubbleSize: true, ShowCatName: false, ShowLeaderLines: false, ShowPercent: true, ShowSerName: false, ShowVal: false}, ShowBlanksAs: "gap"}}, + {sheetName: "Sheet2", cell: "X32", opts: &Chart{Type: "pie", Series: series3, Format: format, Legend: ChartLegend{Position: "bottom", ShowLegendKey: false}, Title: ChartTitle{Name: "Pie Chart"}, PlotArea: ChartPlotArea{ShowBubbleSize: true, ShowCatName: false, ShowLeaderLines: false, ShowPercent: true, ShowSerName: false, ShowVal: false, NumFmt: ChartNumFmt{CustomNumFmt: "0.00%;0;;"}}, ShowBlanksAs: "gap"}}, // bar series chart {sheetName: "Sheet2", cell: "P48", opts: &Chart{Type: "bar", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Clustered Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet2", cell: "X48", opts: &Chart{Type: "barStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Stacked Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, diff --git a/drawing.go b/drawing.go index 93684a3f..f035d50a 100644 --- a/drawing.go +++ b/drawing.go @@ -995,10 +995,24 @@ func (f *File) drawCharSeriesBubble3D(opts *Chart) *attrValBool { return &attrValBool{Val: boolPtr(true)} } +// drawChartNumFmt provides a function to draw the c:numFmt element by given +// data labels format sets. +func (f *File) drawChartNumFmt(labels ChartNumFmt) *cNumFmt { + var numFmt *cNumFmt + if labels.CustomNumFmt != "" || labels.SourceLinked { + numFmt = &cNumFmt{ + FormatCode: labels.CustomNumFmt, + SourceLinked: labels.SourceLinked, + } + } + return numFmt +} + // drawChartDLbls provides a function to draw the c:dLbls element by given // format sets. func (f *File) drawChartDLbls(opts *Chart) *cDLbls { return &cDLbls{ + NumFmt: f.drawChartNumFmt(opts.PlotArea.NumFmt), ShowLegendKey: &attrValBool{Val: boolPtr(opts.Legend.ShowLegendKey)}, ShowVal: &attrValBool{Val: boolPtr(opts.PlotArea.ShowVal)}, ShowCatName: &attrValBool{Val: boolPtr(opts.PlotArea.ShowCatName)}, @@ -1040,12 +1054,9 @@ func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs { Max: max, Min: min, }, - Delete: &attrValBool{Val: boolPtr(opts.XAxis.None)}, - AxPos: &attrValString{Val: stringPtr(catAxPos[opts.XAxis.ReverseOrder])}, - NumFmt: &cNumFmt{ - FormatCode: "General", - SourceLinked: true, - }, + Delete: &attrValBool{Val: boolPtr(opts.XAxis.None)}, + AxPos: &attrValString{Val: stringPtr(catAxPos[opts.XAxis.ReverseOrder])}, + NumFmt: &cNumFmt{FormatCode: "General"}, MajorTickMark: &attrValString{Val: stringPtr("none")}, MinorTickMark: &attrValString{Val: stringPtr("none")}, TickLblPos: &attrValString{Val: stringPtr("nextTo")}, @@ -1059,6 +1070,9 @@ func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs { NoMultiLvlLbl: &attrValBool{Val: boolPtr(false)}, }, } + if numFmt := f.drawChartNumFmt(opts.XAxis.NumFmt); numFmt != nil { + axs[0].NumFmt = numFmt + } if opts.XAxis.MajorGridLines { axs[0].MajorGridlines = &cChartLines{SpPr: f.drawPlotAreaSpPr()} } @@ -1097,8 +1111,7 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs { Delete: &attrValBool{Val: boolPtr(opts.YAxis.None)}, AxPos: &attrValString{Val: stringPtr(valAxPos[opts.YAxis.ReverseOrder])}, NumFmt: &cNumFmt{ - FormatCode: chartValAxNumFmtFormatCode[opts.Type], - SourceLinked: true, + FormatCode: chartValAxNumFmtFormatCode[opts.Type], }, MajorTickMark: &attrValString{Val: stringPtr("none")}, MinorTickMark: &attrValString{Val: stringPtr("none")}, @@ -1110,6 +1123,9 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs { CrossBetween: &attrValString{Val: stringPtr(chartValAxCrossBetween[opts.Type])}, }, } + if numFmt := f.drawChartNumFmt(opts.YAxis.NumFmt); numFmt != nil { + axs[0].NumFmt = numFmt + } if opts.YAxis.MajorGridLines { axs[0].MajorGridlines = &cChartLines{SpPr: f.drawPlotAreaSpPr()} } diff --git a/xmlChart.go b/xmlChart.go index 6c17ab87..56049af6 100644 --- a/xmlChart.go +++ b/xmlChart.go @@ -481,6 +481,7 @@ type cNumCache struct { // entire series or the entire chart. It contains child elements that specify // the specific formatting and positioning settings. type cDLbls struct { + NumFmt *cNumFmt `xml:"numFmt"` ShowLegendKey *attrValBool `xml:"showLegendKey"` ShowVal *attrValBool `xml:"showVal"` ShowCatName *attrValBool `xml:"showCatName"` @@ -519,6 +520,12 @@ type cPageMargins struct { T float64 `xml:"t,attr"` } +// ChartNumFmt directly maps the number format settings of the chart. +type ChartNumFmt struct { + CustomNumFmt string + SourceLinked bool +} + // ChartAxis directly maps the format settings of the chart axis. type ChartAxis struct { None bool @@ -531,6 +538,7 @@ type ChartAxis struct { Minimum *float64 Font Font LogBase float64 + NumFmt ChartNumFmt } // ChartDimension directly maps the dimension of the chart. @@ -548,6 +556,7 @@ type ChartPlotArea struct { ShowPercent bool ShowSerName bool ShowVal bool + NumFmt ChartNumFmt } // Chart directly maps the format settings of the chart.