Skip to content

Commit

Permalink
This closes #2033, support set gap width and overlap for column and b…
Browse files Browse the repository at this point in the history
…ar chart

- Add new fields GapWidth and Overlap in the Chart data type
- Update unit tests
- Update dependencies modules
  • Loading branch information
xuri committed Dec 8, 2024
1 parent c936188 commit 3ca60f8
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 23 deletions.
46 changes: 45 additions & 1 deletion chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,42 @@ var (
Line: "standard",
Line3D: "standard",
}
barColChartTypes = []ChartType{
Bar,
BarStacked,
BarPercentStacked,
Bar3DClustered,
Bar3DStacked,
Bar3DPercentStacked,
Bar3DConeClustered,
Bar3DConeStacked,
Bar3DConePercentStacked,
Bar3DPyramidClustered,
Bar3DPyramidStacked,
Bar3DPyramidPercentStacked,
Bar3DCylinderClustered,
Bar3DCylinderStacked,
Bar3DCylinderPercentStacked,
Col,
ColStacked,
ColPercentStacked,
Col3D,
Col3DClustered,
Col3DStacked,
Col3DPercentStacked,
Col3DCone,
Col3DConeStacked,
Col3DConeClustered,
Col3DConePercentStacked,
Col3DPyramid,
Col3DPyramidClustered,
Col3DPyramidStacked,
Col3DPyramidPercentStacked,
Col3DCylinder,
Col3DCylinderClustered,
Col3DCylinderStacked,
Col3DCylinderPercentStacked,
}
orientation = map[bool]string{
true: "maxMin",
false: "minMax",
Expand Down Expand Up @@ -904,7 +940,7 @@ func (opts *Chart) parseTitle() {
// TextRotation
// Vertical
//
// The value of 'TextRotation' that can be set from -90 to 90:
// The value of 'TextRotation' that can be set from -90 to 90.
//
// The value of 'Vertical' that can be set are:
//
Expand Down Expand Up @@ -949,6 +985,14 @@ func (opts *Chart) parseTitle() {
// 'HoleSize' property. The 'HoleSize' property is optional. The default width
// is 75, and the value should be great than 0 and less or equal than 90.
//
// Set the gap with of the column and bar series chart by 'GapWidth' property.
// The 'GapWidth' property is optional. The default width is 150, and the value
// should be great or equal than 0 and less or equal than 500.
//
// Set series overlap of the column and bar series chart by 'Overlap' property.
// The 'Overlap' property is optional. The default width is 0, and the value
// should be great or equal than -100 and less or equal than 100.
//
// combo: Specifies the create a chart that combines two or more chart types in
// a single chart. For example, create a clustered column - line chart with
// data Sheet1!$E$1:$L$15:
Expand Down
2 changes: 1 addition & 1 deletion chart_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func TestAddChart(t *testing.T) {
opts *Chart
}{
{sheetName: "Sheet1", cell: "P1", opts: &Chart{Type: Col, Series: series, Format: format, Legend: ChartLegend{Position: "none", ShowLegendKey: true}, Title: []RichTextRun{{Text: "2D Column Chart"}}, PlotArea: plotArea, Border: ChartLine{Type: ChartLineNone}, ShowBlanksAs: "zero", XAxis: ChartAxis{Font: Font{Bold: true, Italic: true, Underline: "dbl", Family: "Times New Roman", Size: 15, Strike: true, Color: "000000"}, Title: []RichTextRun{{Text: "Primary Horizontal Axis Title"}}}, YAxis: ChartAxis{Font: Font{Bold: false, Italic: false, Underline: "sng", Color: "777777"}, Title: []RichTextRun{{Text: "Primary Vertical Axis Title", Font: &Font{Color: "777777", Bold: true, Italic: true, Size: 12}}}}}},
{sheetName: "Sheet1", cell: "X1", opts: &Chart{Type: ColStacked, Series: series, Format: format, Legend: legend, Title: []RichTextRun{{Text: "2D Stacked Column Chart"}}, PlotArea: plotArea, Fill: Fill{Type: "pattern", Pattern: 1}, Border: ChartLine{Type: ChartLineAutomatic}, ShowBlanksAs: "zero"}},
{sheetName: "Sheet1", cell: "X1", opts: &Chart{Type: ColStacked, Series: series, Format: format, Legend: legend, Title: []RichTextRun{{Text: "2D Stacked Column Chart"}}, PlotArea: plotArea, Fill: Fill{Type: "pattern", Pattern: 1}, Border: ChartLine{Type: ChartLineAutomatic}, ShowBlanksAs: "zero", GapWidth: uintPtr(10), Overlap: intPtr(100)}},
{sheetName: "Sheet1", cell: "P16", opts: &Chart{Type: ColPercentStacked, Series: series, Format: format, Legend: legend, Title: []RichTextRun{{Text: "100% Stacked Column Chart"}}, PlotArea: plotArea, Fill: Fill{Type: "pattern", Color: []string{"EEEEEE"}, Pattern: 1}, Border: ChartLine{Type: ChartLineSolid, Width: 2}, ShowBlanksAs: "zero", XAxis: ChartAxis{Alignment: Alignment{Vertical: "wordArtVertRtl", TextRotation: 0}}}},
{sheetName: "Sheet1", cell: "X16", opts: &Chart{Type: Col3DClustered, Series: series, Format: format, Legend: ChartLegend{Position: "bottom", ShowLegendKey: false}, Title: []RichTextRun{{Text: "3D Clustered Column Chart"}}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet1", cell: "P30", opts: &Chart{Type: Col3DStacked, Series: series, Format: format, Legend: legend, Title: []RichTextRun{{Text: "3D Stacked Column Chart"}}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{Alignment: Alignment{Vertical: "vert", TextRotation: 0}}}},
Expand Down
43 changes: 35 additions & 8 deletions drawing.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,20 +210,18 @@ func (f *File) drawBaseChart(pa *cPlotArea, opts *Chart) *cPlotArea {
VaryColors: &attrValBool{
Val: opts.VaryColors,
},
Ser: f.drawChartSeries(opts),
Shape: f.drawChartShape(opts),
DLbls: f.drawChartDLbls(opts),
AxID: f.genAxID(opts),
Overlap: &attrValInt{Val: intPtr(100)},
Ser: f.drawChartSeries(opts),
Shape: f.drawChartShape(opts),
DLbls: f.drawChartDLbls(opts),
GapWidth: f.drawChartGapWidth(opts),
AxID: f.genAxID(opts),
Overlap: f.drawChartOverlap(opts),
},
}
var ok bool
if *c[0].BarDir.Val, ok = plotAreaChartBarDir[opts.Type]; !ok {
c[0].BarDir = nil
}
if *c[0].Overlap.Val, ok = plotAreaChartOverlap[opts.Type]; !ok {
c[0].Overlap = nil
}
catAx := f.drawPlotAreaCatAx(pa, opts)
valAx := f.drawPlotAreaValAx(pa, opts)
charts := map[ChartType]*cPlotArea{
Expand Down Expand Up @@ -697,6 +695,35 @@ func (f *File) drawBubbleChart(pa *cPlotArea, opts *Chart) *cPlotArea {
return plotArea
}

// drawChartGapWidth provides a function to draw the c:gapWidth element by given
// format sets.
func (f *File) drawChartGapWidth(opts *Chart) *attrValInt {
for _, t := range barColChartTypes {
if t == opts.Type && opts.GapWidth != nil && *opts.GapWidth != 150 && *opts.GapWidth <= 500 {
return &attrValInt{intPtr(int(*opts.GapWidth))}
}
}
return nil
}

// drawChartOverlap provides a function to draw the c:overlap element by given
// format sets.
func (f *File) drawChartOverlap(opts *Chart) *attrValInt {
var val *attrValInt
if _, ok := plotAreaChartOverlap[opts.Type]; ok {
val = &attrValInt{intPtr(100)}
}
if opts.Overlap != nil && -100 <= *opts.Overlap && *opts.Overlap <= 100 {
val = &attrValInt{intPtr(*opts.Overlap)}
}
for _, t := range barColChartTypes {
if t == opts.Type {
return val
}
}
return nil
}

// drawChartShape provides a function to draw the c:shape element by given
// format sets.
func (f *File) drawChartShape(opts *Chart) *attrValString {
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ go 1.18
require (
github.com/richardlehane/mscfb v1.0.4
github.com/stretchr/testify v1.9.0
github.com/tiendc/go-deepcopy v1.1.0
github.com/tiendc/go-deepcopy v1.2.0
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7
golang.org/x/crypto v0.29.0
golang.org/x/crypto v0.30.0
golang.org/x/image v0.18.0
golang.org/x/net v0.31.0
golang.org/x/text v0.20.0
golang.org/x/net v0.32.0
golang.org/x/text v0.21.0
)

require (
Expand Down
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ github.com/richardlehane/msoleps v1.0.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM
github.com/richardlehane/msoleps v1.0.4/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tiendc/go-deepcopy v1.1.0 h1:rBHhm5vg7WYnGLwktbQouodWjBXDoStOL4S7v/K8S4A=
github.com/tiendc/go-deepcopy v1.1.0/go.mod h1:toXoeQoUqXOOS/X4sKuiAoSk6elIdqc0pN7MTgOOo2I=
github.com/tiendc/go-deepcopy v1.2.0 h1:6vCCs+qdLQHzFqY1fcPirsAWOmrLbuccilfp8UzD1Qo=
github.com/tiendc/go-deepcopy v1.2.0/go.mod h1:toXoeQoUqXOOS/X4sKuiAoSk6elIdqc0pN7MTgOOo2I=
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY=
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A=
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
3 changes: 3 additions & 0 deletions xmlChart.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ type cCharts struct {
SplitPos *attrValInt `xml:"splitPos"`
SerLines *attrValString `xml:"serLines"`
DLbls *cDLbls `xml:"dLbls"`
GapWidth *attrValInt `xml:"gapWidth"`
Shape *attrValString `xml:"shape"`
HoleSize *attrValInt `xml:"holeSize"`
Smooth *attrValBool `xml:"smooth"`
Expand Down Expand Up @@ -584,6 +585,8 @@ type Chart struct {
ShowBlanksAs string
BubbleSize int
HoleSize int
GapWidth *uint
Overlap *int
order int
}

Expand Down
2 changes: 1 addition & 1 deletion xmlWorksheet.go
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ type PageLayoutOptions struct {
// BlackAndWhite specified print black and white.
BlackAndWhite *bool
// PageOrder specifies the ordering of multiple pages. Values
// accepted: overThenDown, downThenOver
// accepted: overThenDown and downThenOver
PageOrder *string
}

Expand Down

0 comments on commit 3ca60f8

Please sign in to comment.