From dcbde4b8311b5cb48731fbaf23eee58d994dac61 Mon Sep 17 00:00:00 2001 From: Ri Xu Date: Thu, 29 Mar 2018 20:17:07 +0800 Subject: [PATCH] - Add categories or values on reverse order (orientation of the chart) support, and set auto or fixed maximum, minimum of the axis, relate issue #202; - go test and godoc has been updated --- chart.go | 52 +++++++++++++++++++++++++++++++++++++++++++----- excelize_test.go | 4 ++-- xmlChart.go | 25 +++++++++++++---------- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/chart.go b/chart.go index 756ef615..5c5ac1d0 100644 --- a/chart.go +++ b/chart.go @@ -176,6 +176,18 @@ var ( Col3DPercentStacked: "col", Line: "standard", } + orientation = map[bool]string{ + true: "maxMin", + false: "minMax", + } + catAxPos = map[bool]string{ + true: "t", + false: "b", + } + valAxPos = map[bool]string{ + true: "r", + false: "l", + } ) // parseFormatChartSet provides function to parse the format settings of the @@ -227,7 +239,7 @@ func parseFormatChartSet(formatSet string) *formatChart { // for k, v := range values { // xlsx.SetCellValue("Sheet1", k, v) // } -// 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"}`) +// 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","x_axis":{"reverse_order":true},"y_axis":{"maximum":7.5,"minimum":0.5}}`) // // Save xlsx file by the given path. // err := xlsx.SaveAs("./Book1.xlsx") // if err != nil { @@ -329,6 +341,16 @@ func parseFormatChartSet(formatSet string) *formatChart { // // show_val: Specifies that the value shall be shown in a data label. The show_val property is optional. The default value is false. // +// Set the primary horizontal and vertical axis options by x_axis and y_axis. The properties that can be set are: +// +// reverse_order +// maximum +// minimum +// +// reverse_order: Specifies that the categories or values on reverse order (orientation of the chart). The reverse_order property is optional. The default value is false. +// maximum: Specifies that the fixed maximum, 0 is auto. The maximum property is optional. The default value is auto. +// minimum: Specifies that the fixed minimum, 0 is auto. The minimum property is optional. The default value is auto. +// func (f *File) AddChart(sheet, cell, format string) { formatSet := parseFormatChartSet(format) // Read sheet data. @@ -914,14 +936,24 @@ func (f *File) drawChartSeriesDLbls(formatSet *formatChart) *cDLbls { // drawPlotAreaCatAx provides function to draw the c:catAx element. func (f *File) drawPlotAreaCatAx(formatSet *formatChart) []*cAxs { + min := &attrValFloat{Val: formatSet.XAxis.Minimum} + max := &attrValFloat{Val: formatSet.XAxis.Maximum} + if formatSet.XAxis.Minimum == 0 { + min = nil + } + if formatSet.XAxis.Maximum == 0 { + max = nil + } return []*cAxs{ { AxID: &attrValInt{Val: 754001152}, Scaling: &cScaling{ - Orientation: &attrValString{Val: "minMax"}, + Orientation: &attrValString{Val: orientation[formatSet.XAxis.ReverseOrder]}, + Max: max, + Min: min, }, Delete: &attrValBool{Val: false}, - AxPos: &attrValString{Val: "b"}, + AxPos: &attrValString{Val: catAxPos[formatSet.XAxis.ReverseOrder]}, NumFmt: &cNumFmt{ FormatCode: "General", SourceLinked: true, @@ -943,14 +975,24 @@ func (f *File) drawPlotAreaCatAx(formatSet *formatChart) []*cAxs { // drawPlotAreaValAx provides function to draw the c:valAx element. func (f *File) drawPlotAreaValAx(formatSet *formatChart) []*cAxs { + min := &attrValFloat{Val: formatSet.YAxis.Minimum} + max := &attrValFloat{Val: formatSet.YAxis.Maximum} + if formatSet.YAxis.Minimum == 0 { + min = nil + } + if formatSet.YAxis.Maximum == 0 { + max = nil + } return []*cAxs{ { AxID: &attrValInt{Val: 753999904}, Scaling: &cScaling{ - Orientation: &attrValString{Val: "minMax"}, + Orientation: &attrValString{Val: orientation[formatSet.YAxis.ReverseOrder]}, + Max: max, + Min: min, }, Delete: &attrValBool{Val: false}, - AxPos: &attrValString{Val: "l"}, + AxPos: &attrValString{Val: valAxPos[formatSet.YAxis.ReverseOrder]}, NumFmt: &cNumFmt{ FormatCode: chartValAxNumFmtFormatCode[formatSet.Type], SourceLinked: true, diff --git a/excelize_test.go b/excelize_test.go index b98400ce..f266250a 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -861,8 +861,8 @@ func TestAddChart(t *testing.T) { 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"}`) + 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","y_axis":{"maximum":7.5,"minimum":0.5}}`) + 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","x_axis":{"reverse_order":true,"maximum":0,"minimum":0},"y_axis":{"reverse_order":true,"maximum":0,"minimum":0}}`) // Save xlsx file by the given path. err = xlsx.SaveAs("./test/Book_addchart.xlsx") if err != nil { diff --git a/xmlChart.go b/xmlChart.go index 229760e2..252a8969 100644 --- a/xmlChart.go +++ b/xmlChart.go @@ -345,6 +345,8 @@ type cAxs struct { // additional axis settings. type cScaling struct { Orientation *attrValString `xml:"c:orientation"` + Max *attrValFloat `xml:"c:max"` + Min *attrValFloat `xml:"c:min"` } // cNumFmt (Numbering Format) directly maps the c:numFmt element. This element @@ -482,16 +484,19 @@ type cPageMargins struct { // formatChartAxis directly maps the format settings of the chart axis. type formatChartAxis struct { - Crossing string `json:"crossing"` - MajorTickMark string `json:"major_tick_mark"` - MinorTickMark string `json:"minor_tick_mark"` - MinorUnitType string `json:"minor_unit_type"` - MajorUnit int `json:"major_unit"` - MajorUnitType string `json:"major_unit_type"` - DisplayUnits string `json:"display_units"` - DisplayUnitsVisible bool `json:"display_units_visible"` - DateAxis bool `json:"date_axis"` - NumFormat string `json:"num_format"` + Crossing string `json:"crossing"` + MajorTickMark string `json:"major_tick_mark"` + MinorTickMark string `json:"minor_tick_mark"` + MinorUnitType string `json:"minor_unit_type"` + MajorUnit int `json:"major_unit"` + MajorUnitType string `json:"major_unit_type"` + DisplayUnits string `json:"display_units"` + DisplayUnitsVisible bool `json:"display_units_visible"` + DateAxis bool `json:"date_axis"` + ReverseOrder bool `json:"reverse_order"` + Maximum float64 `json:"maximum"` + Minimum float64 `json:"minimum"` + NumFormat string `json:"num_format"` NumFont struct { Color string `json:"color"` Bold bool `json:"bold"`