This closes #1983, support create combo chart with same types

- Add new exported ChartLineUnset enumeration
- Fix set line type of line chart does not work
- Support set line type of scatter chart
This commit is contained in:
xuri 2024-09-05 21:38:19 +08:00
parent aca04ecf57
commit 8c0ef7f90d
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
3 changed files with 208 additions and 180 deletions

View File

@ -85,7 +85,8 @@ type ChartLineType byte
// This section defines the currently supported chart line types enumeration. // This section defines the currently supported chart line types enumeration.
const ( const (
ChartLineSolid ChartLineType = iota ChartLineUnset ChartLineType = iota
ChartLineSolid
ChartLineNone ChartLineNone
ChartLineAutomatic ChartLineAutomatic
) )

View File

@ -176,7 +176,12 @@ func (f *File) addChart(opts *Chart, comboCharts []*Chart) {
if field.IsNil() { if field.IsNil() {
continue continue
} }
immutable.FieldByName(mutable.Type().Field(i).Name).Set(field) fld := immutable.FieldByName(mutable.Type().Field(i).Name)
if field.Kind() == reflect.Slice && i < 16 { // All []*cCharts type fields
fld.Set(reflect.Append(fld, field.Index(0)))
continue
}
fld.Set(field)
} }
} }
addChart(xlsxChartSpace.Chart.PlotArea, plotAreaFunc[opts.Type](xlsxChartSpace.Chart.PlotArea, opts)) addChart(xlsxChartSpace.Chart.PlotArea, plotAreaFunc[opts.Type](xlsxChartSpace.Chart.PlotArea, opts))
@ -194,7 +199,8 @@ func (f *File) addChart(opts *Chart, comboCharts []*Chart) {
// drawBaseChart provides a function to draw the c:plotArea element for bar, // drawBaseChart provides a function to draw the c:plotArea element for bar,
// and column series charts by given format sets. // and column series charts by given format sets.
func (f *File) drawBaseChart(pa *cPlotArea, opts *Chart) *cPlotArea { func (f *File) drawBaseChart(pa *cPlotArea, opts *Chart) *cPlotArea {
c := cCharts{ c := []*cCharts{
{
BarDir: &attrValString{ BarDir: &attrValString{
Val: stringPtr("col"), Val: stringPtr("col"),
}, },
@ -209,224 +215,225 @@ func (f *File) drawBaseChart(pa *cPlotArea, opts *Chart) *cPlotArea {
DLbls: f.drawChartDLbls(opts), DLbls: f.drawChartDLbls(opts),
AxID: f.genAxID(opts), AxID: f.genAxID(opts),
Overlap: &attrValInt{Val: intPtr(100)}, Overlap: &attrValInt{Val: intPtr(100)},
},
} }
var ok bool var ok bool
if *c.BarDir.Val, ok = plotAreaChartBarDir[opts.Type]; !ok { if *c[0].BarDir.Val, ok = plotAreaChartBarDir[opts.Type]; !ok {
c.BarDir = nil c[0].BarDir = nil
} }
if *c.Overlap.Val, ok = plotAreaChartOverlap[opts.Type]; !ok { if *c[0].Overlap.Val, ok = plotAreaChartOverlap[opts.Type]; !ok {
c.Overlap = nil c[0].Overlap = nil
} }
catAx := f.drawPlotAreaCatAx(pa, opts) catAx := f.drawPlotAreaCatAx(pa, opts)
valAx := f.drawPlotAreaValAx(pa, opts) valAx := f.drawPlotAreaValAx(pa, opts)
charts := map[ChartType]*cPlotArea{ charts := map[ChartType]*cPlotArea{
Area: { Area: {
AreaChart: &c, AreaChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
AreaStacked: { AreaStacked: {
AreaChart: &c, AreaChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
AreaPercentStacked: { AreaPercentStacked: {
AreaChart: &c, AreaChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Area3D: { Area3D: {
Area3DChart: &c, Area3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Area3DStacked: { Area3DStacked: {
Area3DChart: &c, Area3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Area3DPercentStacked: { Area3DPercentStacked: {
Area3DChart: &c, Area3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar: { Bar: {
BarChart: &c, BarChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
BarStacked: { BarStacked: {
BarChart: &c, BarChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
BarPercentStacked: { BarPercentStacked: {
BarChart: &c, BarChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DClustered: { Bar3DClustered: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DStacked: { Bar3DStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DPercentStacked: { Bar3DPercentStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DConeClustered: { Bar3DConeClustered: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DConeStacked: { Bar3DConeStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DConePercentStacked: { Bar3DConePercentStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DPyramidClustered: { Bar3DPyramidClustered: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DPyramidStacked: { Bar3DPyramidStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DPyramidPercentStacked: { Bar3DPyramidPercentStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DCylinderClustered: { Bar3DCylinderClustered: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DCylinderStacked: { Bar3DCylinderStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bar3DCylinderPercentStacked: { Bar3DCylinderPercentStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col: { Col: {
BarChart: &c, BarChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
ColStacked: { ColStacked: {
BarChart: &c, BarChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
ColPercentStacked: { ColPercentStacked: {
BarChart: &c, BarChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3D: { Col3D: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DClustered: { Col3DClustered: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DStacked: { Col3DStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DPercentStacked: { Col3DPercentStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DCone: { Col3DCone: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DConeClustered: { Col3DConeClustered: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DConeStacked: { Col3DConeStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DConePercentStacked: { Col3DConePercentStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DPyramid: { Col3DPyramid: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DPyramidClustered: { Col3DPyramidClustered: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DPyramidStacked: { Col3DPyramidStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DPyramidPercentStacked: { Col3DPyramidPercentStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DCylinder: { Col3DCylinder: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DCylinderClustered: { Col3DCylinderClustered: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DCylinderStacked: { Col3DCylinderStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Col3DCylinderPercentStacked: { Col3DCylinderPercentStacked: {
Bar3DChart: &c, Bar3DChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bubble: { Bubble: {
BubbleChart: &c, BubbleChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
Bubble3D: { Bubble3D: {
BubbleChart: &c, BubbleChart: c,
CatAx: catAx, CatAx: catAx,
ValAx: valAx, ValAx: valAx,
}, },
@ -443,13 +450,15 @@ func (f *File) drawDoughnutChart(pa *cPlotArea, opts *Chart) *cPlotArea {
} }
return &cPlotArea{ return &cPlotArea{
DoughnutChart: &cCharts{ DoughnutChart: []*cCharts{
{
VaryColors: &attrValBool{ VaryColors: &attrValBool{
Val: opts.VaryColors, Val: opts.VaryColors,
}, },
Ser: f.drawChartSeries(opts), Ser: f.drawChartSeries(opts),
HoleSize: &attrValInt{Val: intPtr(holeSize)}, HoleSize: &attrValInt{Val: intPtr(holeSize)},
}, },
},
} }
} }
@ -457,7 +466,8 @@ func (f *File) drawDoughnutChart(pa *cPlotArea, opts *Chart) *cPlotArea {
// chart by given format sets. // chart by given format sets.
func (f *File) drawLineChart(pa *cPlotArea, opts *Chart) *cPlotArea { func (f *File) drawLineChart(pa *cPlotArea, opts *Chart) *cPlotArea {
return &cPlotArea{ return &cPlotArea{
LineChart: &cCharts{ LineChart: []*cCharts{
{
Grouping: &attrValString{ Grouping: &attrValString{
Val: stringPtr(plotAreaChartGrouping[opts.Type]), Val: stringPtr(plotAreaChartGrouping[opts.Type]),
}, },
@ -468,6 +478,7 @@ func (f *File) drawLineChart(pa *cPlotArea, opts *Chart) *cPlotArea {
DLbls: f.drawChartDLbls(opts), DLbls: f.drawChartDLbls(opts),
AxID: f.genAxID(opts), AxID: f.genAxID(opts),
}, },
},
CatAx: f.drawPlotAreaCatAx(pa, opts), CatAx: f.drawPlotAreaCatAx(pa, opts),
ValAx: f.drawPlotAreaValAx(pa, opts), ValAx: f.drawPlotAreaValAx(pa, opts),
} }
@ -477,7 +488,8 @@ func (f *File) drawLineChart(pa *cPlotArea, opts *Chart) *cPlotArea {
// chart by given format sets. // chart by given format sets.
func (f *File) drawLine3DChart(pa *cPlotArea, opts *Chart) *cPlotArea { func (f *File) drawLine3DChart(pa *cPlotArea, opts *Chart) *cPlotArea {
return &cPlotArea{ return &cPlotArea{
Line3DChart: &cCharts{ Line3DChart: []*cCharts{
{
Grouping: &attrValString{ Grouping: &attrValString{
Val: stringPtr(plotAreaChartGrouping[opts.Type]), Val: stringPtr(plotAreaChartGrouping[opts.Type]),
}, },
@ -488,6 +500,7 @@ func (f *File) drawLine3DChart(pa *cPlotArea, opts *Chart) *cPlotArea {
DLbls: f.drawChartDLbls(opts), DLbls: f.drawChartDLbls(opts),
AxID: f.genAxID(opts), AxID: f.genAxID(opts),
}, },
},
CatAx: f.drawPlotAreaCatAx(pa, opts), CatAx: f.drawPlotAreaCatAx(pa, opts),
ValAx: f.drawPlotAreaValAx(pa, opts), ValAx: f.drawPlotAreaValAx(pa, opts),
} }
@ -497,12 +510,14 @@ func (f *File) drawLine3DChart(pa *cPlotArea, opts *Chart) *cPlotArea {
// chart by given format sets. // chart by given format sets.
func (f *File) drawPieChart(pa *cPlotArea, opts *Chart) *cPlotArea { func (f *File) drawPieChart(pa *cPlotArea, opts *Chart) *cPlotArea {
return &cPlotArea{ return &cPlotArea{
PieChart: &cCharts{ PieChart: []*cCharts{
{
VaryColors: &attrValBool{ VaryColors: &attrValBool{
Val: opts.VaryColors, Val: opts.VaryColors,
}, },
Ser: f.drawChartSeries(opts), Ser: f.drawChartSeries(opts),
}, },
},
} }
} }
@ -510,12 +525,14 @@ func (f *File) drawPieChart(pa *cPlotArea, opts *Chart) *cPlotArea {
// pie chart by given format sets. // pie chart by given format sets.
func (f *File) drawPie3DChart(pa *cPlotArea, opts *Chart) *cPlotArea { func (f *File) drawPie3DChart(pa *cPlotArea, opts *Chart) *cPlotArea {
return &cPlotArea{ return &cPlotArea{
Pie3DChart: &cCharts{ Pie3DChart: []*cCharts{
{
VaryColors: &attrValBool{ VaryColors: &attrValBool{
Val: opts.VaryColors, Val: opts.VaryColors,
}, },
Ser: f.drawChartSeries(opts), Ser: f.drawChartSeries(opts),
}, },
},
} }
} }
@ -527,7 +544,8 @@ func (f *File) drawPieOfPieChart(pa *cPlotArea, opts *Chart) *cPlotArea {
splitPos = &attrValInt{Val: intPtr(opts.PlotArea.SecondPlotValues)} splitPos = &attrValInt{Val: intPtr(opts.PlotArea.SecondPlotValues)}
} }
return &cPlotArea{ return &cPlotArea{
OfPieChart: &cCharts{ OfPieChart: []*cCharts{
{
OfPieType: &attrValString{ OfPieType: &attrValString{
Val: stringPtr("pie"), Val: stringPtr("pie"),
}, },
@ -538,6 +556,7 @@ func (f *File) drawPieOfPieChart(pa *cPlotArea, opts *Chart) *cPlotArea {
SplitPos: splitPos, SplitPos: splitPos,
SerLines: &attrValString{}, SerLines: &attrValString{},
}, },
},
} }
} }
@ -549,7 +568,8 @@ func (f *File) drawBarOfPieChart(pa *cPlotArea, opts *Chart) *cPlotArea {
splitPos = &attrValInt{Val: intPtr(opts.PlotArea.SecondPlotValues)} splitPos = &attrValInt{Val: intPtr(opts.PlotArea.SecondPlotValues)}
} }
return &cPlotArea{ return &cPlotArea{
OfPieChart: &cCharts{ OfPieChart: []*cCharts{
{
OfPieType: &attrValString{ OfPieType: &attrValString{
Val: stringPtr("bar"), Val: stringPtr("bar"),
}, },
@ -560,6 +580,7 @@ func (f *File) drawBarOfPieChart(pa *cPlotArea, opts *Chart) *cPlotArea {
Ser: f.drawChartSeries(opts), Ser: f.drawChartSeries(opts),
SerLines: &attrValString{}, SerLines: &attrValString{},
}, },
},
} }
} }
@ -567,7 +588,8 @@ func (f *File) drawBarOfPieChart(pa *cPlotArea, opts *Chart) *cPlotArea {
// chart by given format sets. // chart by given format sets.
func (f *File) drawRadarChart(pa *cPlotArea, opts *Chart) *cPlotArea { func (f *File) drawRadarChart(pa *cPlotArea, opts *Chart) *cPlotArea {
return &cPlotArea{ return &cPlotArea{
RadarChart: &cCharts{ RadarChart: []*cCharts{
{
RadarStyle: &attrValString{ RadarStyle: &attrValString{
Val: stringPtr("marker"), Val: stringPtr("marker"),
}, },
@ -578,6 +600,7 @@ func (f *File) drawRadarChart(pa *cPlotArea, opts *Chart) *cPlotArea {
DLbls: f.drawChartDLbls(opts), DLbls: f.drawChartDLbls(opts),
AxID: f.genAxID(opts), AxID: f.genAxID(opts),
}, },
},
CatAx: f.drawPlotAreaCatAx(pa, opts), CatAx: f.drawPlotAreaCatAx(pa, opts),
ValAx: f.drawPlotAreaValAx(pa, opts), ValAx: f.drawPlotAreaValAx(pa, opts),
} }
@ -587,7 +610,8 @@ func (f *File) drawRadarChart(pa *cPlotArea, opts *Chart) *cPlotArea {
// scatter chart by given format sets. // scatter chart by given format sets.
func (f *File) drawScatterChart(pa *cPlotArea, opts *Chart) *cPlotArea { func (f *File) drawScatterChart(pa *cPlotArea, opts *Chart) *cPlotArea {
return &cPlotArea{ return &cPlotArea{
ScatterChart: &cCharts{ ScatterChart: []*cCharts{
{
ScatterStyle: &attrValString{ ScatterStyle: &attrValString{
Val: stringPtr("smoothMarker"), // line,lineMarker,marker,none,smooth,smoothMarker Val: stringPtr("smoothMarker"), // line,lineMarker,marker,none,smooth,smoothMarker
}, },
@ -598,6 +622,7 @@ func (f *File) drawScatterChart(pa *cPlotArea, opts *Chart) *cPlotArea {
DLbls: f.drawChartDLbls(opts), DLbls: f.drawChartDLbls(opts),
AxID: f.genAxID(opts), AxID: f.genAxID(opts),
}, },
},
ValAx: append(f.drawPlotAreaCatAx(pa, opts), f.drawPlotAreaValAx(pa, opts)...), ValAx: append(f.drawPlotAreaCatAx(pa, opts), f.drawPlotAreaValAx(pa, opts)...),
} }
} }
@ -606,7 +631,8 @@ func (f *File) drawScatterChart(pa *cPlotArea, opts *Chart) *cPlotArea {
// given format sets. // given format sets.
func (f *File) drawSurface3DChart(pa *cPlotArea, opts *Chart) *cPlotArea { func (f *File) drawSurface3DChart(pa *cPlotArea, opts *Chart) *cPlotArea {
plotArea := &cPlotArea{ plotArea := &cPlotArea{
Surface3DChart: &cCharts{ Surface3DChart: []*cCharts{
{
Ser: f.drawChartSeries(opts), Ser: f.drawChartSeries(opts),
AxID: []*attrValInt{ AxID: []*attrValInt{
{Val: intPtr(100000000)}, {Val: intPtr(100000000)},
@ -614,12 +640,13 @@ func (f *File) drawSurface3DChart(pa *cPlotArea, opts *Chart) *cPlotArea {
{Val: intPtr(100000005)}, {Val: intPtr(100000005)},
}, },
}, },
},
CatAx: f.drawPlotAreaCatAx(pa, opts), CatAx: f.drawPlotAreaCatAx(pa, opts),
ValAx: f.drawPlotAreaValAx(pa, opts), ValAx: f.drawPlotAreaValAx(pa, opts),
SerAx: f.drawPlotAreaSerAx(opts), SerAx: f.drawPlotAreaSerAx(opts),
} }
if opts.Type == WireframeSurface3D { if opts.Type == WireframeSurface3D {
plotArea.Surface3DChart.Wireframe = &attrValBool{Val: boolPtr(true)} plotArea.Surface3DChart[0].Wireframe = &attrValBool{Val: boolPtr(true)}
} }
return plotArea return plotArea
} }
@ -628,7 +655,8 @@ func (f *File) drawSurface3DChart(pa *cPlotArea, opts *Chart) *cPlotArea {
// given format sets. // given format sets.
func (f *File) drawSurfaceChart(pa *cPlotArea, opts *Chart) *cPlotArea { func (f *File) drawSurfaceChart(pa *cPlotArea, opts *Chart) *cPlotArea {
plotArea := &cPlotArea{ plotArea := &cPlotArea{
SurfaceChart: &cCharts{ SurfaceChart: []*cCharts{
{
Ser: f.drawChartSeries(opts), Ser: f.drawChartSeries(opts),
AxID: []*attrValInt{ AxID: []*attrValInt{
{Val: intPtr(100000000)}, {Val: intPtr(100000000)},
@ -636,12 +664,13 @@ func (f *File) drawSurfaceChart(pa *cPlotArea, opts *Chart) *cPlotArea {
{Val: intPtr(100000005)}, {Val: intPtr(100000005)},
}, },
}, },
},
CatAx: f.drawPlotAreaCatAx(pa, opts), CatAx: f.drawPlotAreaCatAx(pa, opts),
ValAx: f.drawPlotAreaValAx(pa, opts), ValAx: f.drawPlotAreaValAx(pa, opts),
SerAx: f.drawPlotAreaSerAx(opts), SerAx: f.drawPlotAreaSerAx(opts),
} }
if opts.Type == WireframeContour { if opts.Type == WireframeContour {
plotArea.SurfaceChart.Wireframe = &attrValBool{Val: boolPtr(true)} plotArea.SurfaceChart[0].Wireframe = &attrValBool{Val: boolPtr(true)}
} }
return plotArea return plotArea
} }
@ -650,7 +679,8 @@ func (f *File) drawSurfaceChart(pa *cPlotArea, opts *Chart) *cPlotArea {
// given format sets. // given format sets.
func (f *File) drawBubbleChart(pa *cPlotArea, opts *Chart) *cPlotArea { func (f *File) drawBubbleChart(pa *cPlotArea, opts *Chart) *cPlotArea {
plotArea := &cPlotArea{ plotArea := &cPlotArea{
BubbleChart: &cCharts{ BubbleChart: []*cCharts{
{
VaryColors: &attrValBool{ VaryColors: &attrValBool{
Val: opts.VaryColors, Val: opts.VaryColors,
}, },
@ -658,10 +688,11 @@ func (f *File) drawBubbleChart(pa *cPlotArea, opts *Chart) *cPlotArea {
DLbls: f.drawChartDLbls(opts), DLbls: f.drawChartDLbls(opts),
AxID: f.genAxID(opts), AxID: f.genAxID(opts),
}, },
},
ValAx: append(f.drawPlotAreaCatAx(pa, opts), f.drawPlotAreaValAx(pa, opts)...), ValAx: append(f.drawPlotAreaCatAx(pa, opts), f.drawPlotAreaValAx(pa, opts)...),
} }
if opts.BubbleSize > 0 && opts.BubbleSize <= 300 { if opts.BubbleSize > 0 && opts.BubbleSize <= 300 {
plotArea.BubbleChart.BubbleScale = &attrValFloat{Val: float64Ptr(float64(opts.BubbleSize))} plotArea.BubbleChart[0].BubbleScale = &attrValFloat{Val: float64Ptr(float64(opts.BubbleSize))}
} }
return plotArea return plotArea
} }
@ -750,23 +781,19 @@ func (f *File) drawShapeFill(fill Fill, spPr *cSpPr) *cSpPr {
func (f *File) drawChartSeriesSpPr(i int, opts *Chart) *cSpPr { func (f *File) drawChartSeriesSpPr(i int, opts *Chart) *cSpPr {
spPr := &cSpPr{SolidFill: &aSolidFill{SchemeClr: &aSchemeClr{Val: "accent" + strconv.Itoa((opts.order+i)%6+1)}}} spPr := &cSpPr{SolidFill: &aSolidFill{SchemeClr: &aSchemeClr{Val: "accent" + strconv.Itoa((opts.order+i)%6+1)}}}
spPr = f.drawShapeFill(opts.Series[i].Fill, spPr) spPr = f.drawShapeFill(opts.Series[i].Fill, spPr)
spPrScatter := &cSpPr{ solid := &cSpPr{
Ln: &aLn{
W: 25400,
NoFill: &attrValString{},
},
}
spPrLine := &cSpPr{
Ln: &aLn{ Ln: &aLn{
W: f.ptToEMUs(opts.Series[i].Line.Width), W: f.ptToEMUs(opts.Series[i].Line.Width),
Cap: "rnd", // rnd, sq, flat Cap: "rnd", // rnd, sq, flat
SolidFill: spPr.SolidFill, SolidFill: spPr.SolidFill,
}, },
} }
if chartSeriesSpPr, ok := map[ChartType]*cSpPr{ noLn := &cSpPr{Ln: &aLn{NoFill: &attrValString{}}}
Line: spPrLine, Scatter: spPrScatter, if chartSeriesSpPr, ok := map[ChartType]map[ChartLineType]*cSpPr{
Line: {ChartLineUnset: solid, ChartLineSolid: solid, ChartLineNone: noLn, ChartLineAutomatic: solid},
Scatter: {ChartLineUnset: noLn, ChartLineSolid: solid, ChartLineNone: noLn, ChartLineAutomatic: noLn},
}[opts.Type]; ok { }[opts.Type]; ok {
return chartSeriesSpPr return chartSeriesSpPr[opts.Series[i].Line.Type]
} }
if spPr.SolidFill.SrgbClr != nil { if spPr.SolidFill.SrgbClr != nil {
return spPr return spPr

View File

@ -301,21 +301,21 @@ type cView3D struct {
// plot area of the chart. // plot area of the chart.
type cPlotArea struct { type cPlotArea struct {
Layout *string `xml:"layout"` Layout *string `xml:"layout"`
AreaChart *cCharts `xml:"areaChart"` AreaChart []*cCharts `xml:"areaChart"`
Area3DChart *cCharts `xml:"area3DChart"` Area3DChart []*cCharts `xml:"area3DChart"`
BarChart *cCharts `xml:"barChart"` BarChart []*cCharts `xml:"barChart"`
Bar3DChart *cCharts `xml:"bar3DChart"` Bar3DChart []*cCharts `xml:"bar3DChart"`
BubbleChart *cCharts `xml:"bubbleChart"` BubbleChart []*cCharts `xml:"bubbleChart"`
DoughnutChart *cCharts `xml:"doughnutChart"` DoughnutChart []*cCharts `xml:"doughnutChart"`
LineChart *cCharts `xml:"lineChart"` LineChart []*cCharts `xml:"lineChart"`
Line3DChart *cCharts `xml:"line3DChart"` Line3DChart []*cCharts `xml:"line3DChart"`
PieChart *cCharts `xml:"pieChart"` PieChart []*cCharts `xml:"pieChart"`
Pie3DChart *cCharts `xml:"pie3DChart"` Pie3DChart []*cCharts `xml:"pie3DChart"`
OfPieChart *cCharts `xml:"ofPieChart"` OfPieChart []*cCharts `xml:"ofPieChart"`
RadarChart *cCharts `xml:"radarChart"` RadarChart []*cCharts `xml:"radarChart"`
ScatterChart *cCharts `xml:"scatterChart"` ScatterChart []*cCharts `xml:"scatterChart"`
Surface3DChart *cCharts `xml:"surface3DChart"` Surface3DChart []*cCharts `xml:"surface3DChart"`
SurfaceChart *cCharts `xml:"surfaceChart"` SurfaceChart []*cCharts `xml:"surfaceChart"`
CatAx []*cAxs `xml:"catAx"` CatAx []*cAxs `xml:"catAx"`
ValAx []*cAxs `xml:"valAx"` ValAx []*cAxs `xml:"valAx"`
SerAx []*cAxs `xml:"serAx"` SerAx []*cAxs `xml:"serAx"`