From 71829c520235b733870563f30dceef9ef4dbbb98 Mon Sep 17 00:00:00 2001 From: xuri Date: Sun, 27 Dec 2020 00:18:54 +0800 Subject: [PATCH] AddChart support disable legend of the chart --- README.md | 3 +- README_zh.md | 3 +- chart.go | 148 +++++++++++++++++++++++++++++++++++++++++++++++--- chart_test.go | 16 +++--- drawing.go | 3 + 5 files changed, 156 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 7c67092c3e..b6c14332f0 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,8 @@ import ( func main() { categories := map[string]string{ - "A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"} + "A2": "Small", "A3": "Normal", "A4": "Large", + "B1": "Apple", "C1": "Orange", "D1": "Pear"} values := map[string]int{ "B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8} f := excelize.NewFile() diff --git a/README_zh.md b/README_zh.md index daafd1d89f..1118367dd4 100644 --- a/README_zh.md +++ b/README_zh.md @@ -112,7 +112,8 @@ import ( func main() { categories := map[string]string{ - "A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"} + "A2": "Small", "A3": "Normal", "A4": "Large", + "B1": "Apple", "C1": "Orange", "D1": "Pear"} values := map[string]int{ "B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8} f := excelize.NewFile() diff --git a/chart.go b/chart.go index bdb7f5b761..9d44c50e75 100644 --- a/chart.go +++ b/chart.go @@ -514,8 +514,11 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) { // ) // // func main() { -// categories := map[string]string{"A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"} -// values := map[string]int{"B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8} +// categories := map[string]string{ +// "A2": "Small", "A3": "Normal", "A4": "Large", +// "B1": "Apple", "C1": "Orange", "D1": "Pear"} +// values := map[string]int{ +// "B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8} // f := excelize.NewFile() // for k, v := range categories { // f.SetCellValue("Sheet1", k, v) @@ -523,7 +526,54 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) { // for k, v := range values { // f.SetCellValue("Sheet1", k, v) // } -// if err := f.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"}],"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}}`); err != nil { +// if err := f.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" +// }], +// "title": +// { +// "name": "Fruit 3D Clustered Column Chart" +// }, +// "legend": +// { +// "none": false, +// "position": "bottom", +// "show_legend_key": false +// }, +// "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 +// } +// }`); err != nil { // fmt.Println(err) // return // } @@ -627,10 +677,13 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) { // // Set properties of the chart legend. The options that can be set are: // +// none // position // show_legend_key // -// position: Set the position of the chart legend. The default legend position is right. The available positions are: +// none: Specified if show the legend without overlapping the chart. The default value is 'false'. +// +// position: Set the position of the chart legend. The default legend position is right. This parameter only takes effect when 'none' is false. The available positions are: // // top // bottom @@ -728,8 +781,11 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) { // ) // // func main() { -// categories := map[string]string{"A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"} -// values := map[string]int{"B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8} +// categories := map[string]string{ +// "A2": "Small", "A3": "Normal", "A4": "Large", +// "B1": "Apple", "C1": "Orange", "D1": "Pear"} +// values := map[string]int{ +// "B2": 2, "C2": 3, "D2": 3, "B3": 5, "C3": 2, "D3": 4, "B4": 6, "C4": 7, "D4": 8} // f := excelize.NewFile() // for k, v := range categories { // f.SetCellValue("Sheet1", k, v) @@ -737,7 +793,85 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) { // for k, v := range values { // f.SetCellValue("Sheet1", k, v) // } -// if err := f.AddChart("Sheet1", "E1", `{"type":"col","series":[{"name":"Sheet1!$A$2","categories":"","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"}],"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":"Clustered Column - 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}}`, `{"type":"line","series":[{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4","marker":{"symbol":"none","size":10}}],"format":{"x_scale":1,"y_scale":1,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true}}`); err != nil { +// if err := f.AddChart("Sheet1", "E1", `{ +// "type": "col", +// "series": [ +// { +// "name": "Sheet1!$A$2", +// "categories": "", +// "values": "Sheet1!$B$2:$D$2" +// }, +// { +// "name": "Sheet1!$A$3", +// "categories": "Sheet1!$B$1:$D$1", +// "values": "Sheet1!$B$3:$D$3" +// }], +// "format": +// { +// "x_scale": 1.0, +// "y_scale": 1.0, +// "x_offset": 15, +// "y_offset": 10, +// "print_obj": true, +// "lock_aspect_ratio": false, +// "locked": false +// }, +// "title": +// { +// "name": "Clustered Column - Line Chart" +// }, +// "legend": +// { +// "position": "left", +// "show_legend_key": false +// }, +// "plotarea": +// { +// "show_bubble_size": true, +// "show_cat_name": false, +// "show_leader_lines": false, +// "show_percent": true, +// "show_series_name": true, +// "show_val": true +// } +// }`, `{ +// "type": "line", +// "series": [ +// { +// "name": "Sheet1!$A$4", +// "categories": "Sheet1!$B$1:$D$1", +// "values": "Sheet1!$B$4:$D$4", +// "marker": +// { +// "symbol": "none", +// "size": 10 +// } +// }], +// "format": +// { +// "x_scale": 1, +// "y_scale": 1, +// "x_offset": 15, +// "y_offset": 10, +// "print_obj": true, +// "lock_aspect_ratio": false, +// "locked": false +// }, +// "legend": +// { +// "position": "right", +// "show_legend_key": false +// }, +// "plotarea": +// { +// "show_bubble_size": true, +// "show_cat_name": false, +// "show_leader_lines": false, +// "show_percent": true, +// "show_series_name": true, +// "show_val": true +// } +// }`); err != nil { // fmt.Println(err) // return // } diff --git a/chart_test.go b/chart_test.go index 4a7000ae1b..9bbc06d141 100644 --- a/chart_test.go +++ b/chart_test.go @@ -116,7 +116,7 @@ func TestAddChart(t *testing.T) { // Test add chart on not exists worksheet. assert.EqualError(t, f.AddChart("SheetN", "P1", "{}"), "sheet SheetN is not exist") - assert.NoError(t, f.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"},{"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 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"}`)) + assert.NoError(t, f.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"},{"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":{"none":true,"show_legend_key":true},"title":{"name":"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"}`)) 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"}`)) 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"}`)) 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"}`)) @@ -179,14 +179,14 @@ func TestAddChart(t *testing.T) { assert.NoError(t, f.AddChart("Sheet2", "BD64", `{"type":"barOfPie","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$A$30:$D$37","values":"Sheet1!$B$30:$B$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":"Bar of Pie 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":{"major_grid_lines":true},"y_axis":{"major_grid_lines":true}}`)) // combo chart f.NewSheet("Combo Charts") - clusteredColumnCombo := map[string][]string{ - "A1": {"line", "Clustered Column - Line Chart"}, - "I1": {"bubble", "Clustered Column - Bubble Chart"}, - "Q1": {"bubble3D", "Clustered Column - Bubble 3D Chart"}, - "Y1": {"doughnut", "Clustered Column - Doughnut Chart"}, + clusteredColumnCombo := [][]string{ + {"A1", "line", "Clustered Column - Line Chart"}, + {"I1", "bubble", "Clustered Column - Bubble Chart"}, + {"Q1", "bubble3D", "Clustered Column - Bubble 3D Chart"}, + {"Y1", "doughnut", "Clustered Column - Doughnut Chart"}, } - for axis, props := range clusteredColumnCombo { - assert.NoError(t, f.AddChart("Combo Charts", axis, fmt.Sprintf(`{"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"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"}],"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":"%s"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true}}`, props[1]), fmt.Sprintf(`{"type":"%s","series":[{"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},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true}}`, props[0]))) + for _, props := range clusteredColumnCombo { + assert.NoError(t, f.AddChart("Combo Charts", props[0], fmt.Sprintf(`{"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"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"}],"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":"%s"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true}}`, props[2]), fmt.Sprintf(`{"type":"%s","series":[{"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},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true}}`, props[1]))) } stackedAreaCombo := map[string][]string{ "A16": {"line", "Stacked Area - Line Chart"}, diff --git a/drawing.go b/drawing.go index 0db5d0e749..de9905e7d5 100644 --- a/drawing.go +++ b/drawing.go @@ -236,6 +236,9 @@ func (f *File) addChart(formatSet *formatChart, comboCharts []*formatChart) { Bubble: f.drawBaseChart, Bubble3D: f.drawBaseChart, } + if formatSet.Legend.None { + xlsxChartSpace.Chart.Legend = nil + } addChart := func(c, p *cPlotArea) { immutable, mutable := reflect.ValueOf(c).Elem(), reflect.ValueOf(p).Elem() for i := 0; i < mutable.NumField(); i++ {