forked from p30928647/excelize
This closes #518, support creating chart with a secondary series axis
This commit is contained in:
parent
fb72e56667
commit
f5fe6d3fc9
5
chart.go
5
chart.go
|
@ -803,6 +803,7 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
|
||||||
// MajorGridLines
|
// MajorGridLines
|
||||||
// MinorGridLines
|
// MinorGridLines
|
||||||
// MajorUnit
|
// MajorUnit
|
||||||
|
// Secondary
|
||||||
// ReverseOrder
|
// ReverseOrder
|
||||||
// Maximum
|
// Maximum
|
||||||
// Minimum
|
// Minimum
|
||||||
|
@ -821,6 +822,10 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
|
||||||
// positive floating-point number. The 'MajorUnit' property is optional. The
|
// positive floating-point number. The 'MajorUnit' property is optional. The
|
||||||
// default value is auto.
|
// default value is auto.
|
||||||
//
|
//
|
||||||
|
// Secondary: Specifies the current series vertical axis as the secondary axis,
|
||||||
|
// this only works for the second and later chart in the combo chart. The
|
||||||
|
// default value is false.
|
||||||
|
//
|
||||||
// TickLabelSkip: Specifies how many tick labels to skip between label that is
|
// TickLabelSkip: Specifies how many tick labels to skip between label that is
|
||||||
// drawn. The 'TickLabelSkip' property is optional. The default value is auto.
|
// drawn. The 'TickLabelSkip' property is optional. The default value is auto.
|
||||||
//
|
//
|
||||||
|
|
|
@ -238,7 +238,7 @@ func TestAddChart(t *testing.T) {
|
||||||
{sheetName: "Sheet2", cell: "P64", opts: &Chart{Type: BarPercentStacked, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Stacked 100% Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
|
{sheetName: "Sheet2", cell: "P64", opts: &Chart{Type: BarPercentStacked, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Stacked 100% Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
|
||||||
{sheetName: "Sheet2", cell: "X64", opts: &Chart{Type: Bar3DClustered, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Clustered Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
|
{sheetName: "Sheet2", cell: "X64", opts: &Chart{Type: Bar3DClustered, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Clustered Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
|
||||||
{sheetName: "Sheet2", cell: "P80", opts: &Chart{Type: Bar3DStacked, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Stacked Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", YAxis: ChartAxis{Maximum: &maximum, Minimum: &minimum}}},
|
{sheetName: "Sheet2", cell: "P80", opts: &Chart{Type: Bar3DStacked, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Stacked Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", YAxis: ChartAxis{Maximum: &maximum, Minimum: &minimum}}},
|
||||||
{sheetName: "Sheet2", cell: "X80", opts: &Chart{Type: Bar3DPercentStacked, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D 100% Stacked Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{ReverseOrder: true, Minimum: &zero}, YAxis: ChartAxis{ReverseOrder: true, Minimum: &zero}}},
|
{sheetName: "Sheet2", cell: "X80", opts: &Chart{Type: Bar3DPercentStacked, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D 100% Stacked Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{ReverseOrder: true, Secondary: true, Minimum: &zero}, YAxis: ChartAxis{ReverseOrder: true, Minimum: &zero}}},
|
||||||
// area series chart
|
// area series chart
|
||||||
{sheetName: "Sheet2", cell: "AF1", opts: &Chart{Type: Area, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Area Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
|
{sheetName: "Sheet2", cell: "AF1", opts: &Chart{Type: Area, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Area Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
|
||||||
{sheetName: "Sheet2", cell: "AN1", opts: &Chart{Type: AreaStacked, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Stacked Area Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
|
{sheetName: "Sheet2", cell: "AN1", opts: &Chart{Type: AreaStacked, Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Stacked Area Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
|
||||||
|
@ -280,7 +280,7 @@ func TestAddChart(t *testing.T) {
|
||||||
{"I1", Doughnut, "Clustered Column - Doughnut Chart"},
|
{"I1", Doughnut, "Clustered Column - Doughnut Chart"},
|
||||||
}
|
}
|
||||||
for _, props := range clusteredColumnCombo {
|
for _, props := range clusteredColumnCombo {
|
||||||
assert.NoError(t, f.AddChart("Combo Charts", props[0].(string), &Chart{Type: Col, Series: series[:4], Format: format, Legend: legend, Title: ChartTitle{Name: props[2].(string)}, PlotArea: ChartPlotArea{ShowBubbleSize: true, ShowCatName: false, ShowLeaderLines: false, ShowPercent: true, ShowSerName: true, ShowVal: true}}, &Chart{Type: props[1].(ChartType), Series: series[4:], Format: format, Legend: legend, PlotArea: ChartPlotArea{ShowBubbleSize: true, ShowCatName: false, ShowLeaderLines: false, ShowPercent: true, ShowSerName: true, ShowVal: true}}))
|
assert.NoError(t, f.AddChart("Combo Charts", props[0].(string), &Chart{Type: Col, Series: series[:4], Format: format, Legend: legend, Title: ChartTitle{Name: props[2].(string)}, PlotArea: ChartPlotArea{ShowBubbleSize: true, ShowCatName: false, ShowLeaderLines: false, ShowPercent: true, ShowSerName: true, ShowVal: true}}, &Chart{Type: props[1].(ChartType), Series: series[4:], Format: format, Legend: legend, PlotArea: ChartPlotArea{ShowBubbleSize: true, ShowCatName: false, ShowLeaderLines: false, ShowPercent: true, ShowSerName: true, ShowVal: true}, YAxis: ChartAxis{Secondary: true}}))
|
||||||
}
|
}
|
||||||
stackedAreaCombo := map[string][]interface{}{
|
stackedAreaCombo := map[string][]interface{}{
|
||||||
"A16": {Line, "Stacked Area - Line Chart"},
|
"A16": {Line, "Stacked Area - Line Chart"},
|
||||||
|
|
112
drawing.go
112
drawing.go
|
@ -277,13 +277,10 @@ func (f *File) drawBaseChart(opts *Chart) *cPlotArea {
|
||||||
VaryColors: &attrValBool{
|
VaryColors: &attrValBool{
|
||||||
Val: opts.VaryColors,
|
Val: opts.VaryColors,
|
||||||
},
|
},
|
||||||
Ser: f.drawChartSeries(opts),
|
Ser: f.drawChartSeries(opts),
|
||||||
Shape: f.drawChartShape(opts),
|
Shape: f.drawChartShape(opts),
|
||||||
DLbls: f.drawChartDLbls(opts),
|
DLbls: f.drawChartDLbls(opts),
|
||||||
AxID: []*attrValInt{
|
AxID: f.genAxID(opts),
|
||||||
{Val: intPtr(754001152)},
|
|
||||||
{Val: intPtr(753999904)},
|
|
||||||
},
|
|
||||||
Overlap: &attrValInt{Val: intPtr(100)},
|
Overlap: &attrValInt{Val: intPtr(100)},
|
||||||
}
|
}
|
||||||
var ok bool
|
var ok bool
|
||||||
|
@ -542,10 +539,7 @@ func (f *File) drawLineChart(opts *Chart) *cPlotArea {
|
||||||
},
|
},
|
||||||
Ser: f.drawChartSeries(opts),
|
Ser: f.drawChartSeries(opts),
|
||||||
DLbls: f.drawChartDLbls(opts),
|
DLbls: f.drawChartDLbls(opts),
|
||||||
AxID: []*attrValInt{
|
AxID: f.genAxID(opts),
|
||||||
{Val: intPtr(754001152)},
|
|
||||||
{Val: intPtr(753999904)},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
CatAx: f.drawPlotAreaCatAx(opts),
|
CatAx: f.drawPlotAreaCatAx(opts),
|
||||||
ValAx: f.drawPlotAreaValAx(opts),
|
ValAx: f.drawPlotAreaValAx(opts),
|
||||||
|
@ -565,10 +559,7 @@ func (f *File) drawLine3DChart(opts *Chart) *cPlotArea {
|
||||||
},
|
},
|
||||||
Ser: f.drawChartSeries(opts),
|
Ser: f.drawChartSeries(opts),
|
||||||
DLbls: f.drawChartDLbls(opts),
|
DLbls: f.drawChartDLbls(opts),
|
||||||
AxID: []*attrValInt{
|
AxID: f.genAxID(opts),
|
||||||
{Val: intPtr(754001152)},
|
|
||||||
{Val: intPtr(753999904)},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
CatAx: f.drawPlotAreaCatAx(opts),
|
CatAx: f.drawPlotAreaCatAx(opts),
|
||||||
ValAx: f.drawPlotAreaValAx(opts),
|
ValAx: f.drawPlotAreaValAx(opts),
|
||||||
|
@ -658,10 +649,7 @@ func (f *File) drawRadarChart(opts *Chart) *cPlotArea {
|
||||||
},
|
},
|
||||||
Ser: f.drawChartSeries(opts),
|
Ser: f.drawChartSeries(opts),
|
||||||
DLbls: f.drawChartDLbls(opts),
|
DLbls: f.drawChartDLbls(opts),
|
||||||
AxID: []*attrValInt{
|
AxID: f.genAxID(opts),
|
||||||
{Val: intPtr(754001152)},
|
|
||||||
{Val: intPtr(753999904)},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
CatAx: f.drawPlotAreaCatAx(opts),
|
CatAx: f.drawPlotAreaCatAx(opts),
|
||||||
ValAx: f.drawPlotAreaValAx(opts),
|
ValAx: f.drawPlotAreaValAx(opts),
|
||||||
|
@ -681,10 +669,7 @@ func (f *File) drawScatterChart(opts *Chart) *cPlotArea {
|
||||||
},
|
},
|
||||||
Ser: f.drawChartSeries(opts),
|
Ser: f.drawChartSeries(opts),
|
||||||
DLbls: f.drawChartDLbls(opts),
|
DLbls: f.drawChartDLbls(opts),
|
||||||
AxID: []*attrValInt{
|
AxID: f.genAxID(opts),
|
||||||
{Val: intPtr(754001152)},
|
|
||||||
{Val: intPtr(753999904)},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
CatAx: f.drawPlotAreaCatAx(opts),
|
CatAx: f.drawPlotAreaCatAx(opts),
|
||||||
ValAx: f.drawPlotAreaValAx(opts),
|
ValAx: f.drawPlotAreaValAx(opts),
|
||||||
|
@ -698,9 +683,9 @@ func (f *File) drawSurface3DChart(opts *Chart) *cPlotArea {
|
||||||
Surface3DChart: &cCharts{
|
Surface3DChart: &cCharts{
|
||||||
Ser: f.drawChartSeries(opts),
|
Ser: f.drawChartSeries(opts),
|
||||||
AxID: []*attrValInt{
|
AxID: []*attrValInt{
|
||||||
{Val: intPtr(754001152)},
|
{Val: intPtr(100000000)},
|
||||||
{Val: intPtr(753999904)},
|
{Val: intPtr(100000001)},
|
||||||
{Val: intPtr(832256642)},
|
{Val: intPtr(100000005)},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CatAx: f.drawPlotAreaCatAx(opts),
|
CatAx: f.drawPlotAreaCatAx(opts),
|
||||||
|
@ -720,9 +705,9 @@ func (f *File) drawSurfaceChart(opts *Chart) *cPlotArea {
|
||||||
SurfaceChart: &cCharts{
|
SurfaceChart: &cCharts{
|
||||||
Ser: f.drawChartSeries(opts),
|
Ser: f.drawChartSeries(opts),
|
||||||
AxID: []*attrValInt{
|
AxID: []*attrValInt{
|
||||||
{Val: intPtr(754001152)},
|
{Val: intPtr(100000000)},
|
||||||
{Val: intPtr(753999904)},
|
{Val: intPtr(100000001)},
|
||||||
{Val: intPtr(832256642)},
|
{Val: intPtr(100000005)},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CatAx: f.drawPlotAreaCatAx(opts),
|
CatAx: f.drawPlotAreaCatAx(opts),
|
||||||
|
@ -745,10 +730,7 @@ func (f *File) drawBubbleChart(opts *Chart) *cPlotArea {
|
||||||
},
|
},
|
||||||
Ser: f.drawChartSeries(opts),
|
Ser: f.drawChartSeries(opts),
|
||||||
DLbls: f.drawChartDLbls(opts),
|
DLbls: f.drawChartDLbls(opts),
|
||||||
AxID: []*attrValInt{
|
AxID: f.genAxID(opts),
|
||||||
{Val: intPtr(754001152)},
|
|
||||||
{Val: intPtr(753999904)},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
ValAx: []*cAxs{f.drawPlotAreaCatAx(opts)[0], f.drawPlotAreaValAx(opts)[0]},
|
ValAx: []*cAxs{f.drawPlotAreaCatAx(opts)[0], f.drawPlotAreaValAx(opts)[0]},
|
||||||
}
|
}
|
||||||
|
@ -1050,7 +1032,7 @@ func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs {
|
||||||
}
|
}
|
||||||
axs := []*cAxs{
|
axs := []*cAxs{
|
||||||
{
|
{
|
||||||
AxID: &attrValInt{Val: intPtr(754001152)},
|
AxID: &attrValInt{Val: intPtr(100000000)},
|
||||||
Scaling: &cScaling{
|
Scaling: &cScaling{
|
||||||
Orientation: &attrValString{Val: stringPtr(orientation[opts.XAxis.ReverseOrder])},
|
Orientation: &attrValString{Val: stringPtr(orientation[opts.XAxis.ReverseOrder])},
|
||||||
Max: max,
|
Max: max,
|
||||||
|
@ -1065,7 +1047,7 @@ func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs {
|
||||||
TickLblPos: &attrValString{Val: stringPtr("nextTo")},
|
TickLblPos: &attrValString{Val: stringPtr("nextTo")},
|
||||||
SpPr: f.drawPlotAreaSpPr(),
|
SpPr: f.drawPlotAreaSpPr(),
|
||||||
TxPr: f.drawPlotAreaTxPr(&opts.YAxis),
|
TxPr: f.drawPlotAreaTxPr(&opts.YAxis),
|
||||||
CrossAx: &attrValInt{Val: intPtr(753999904)},
|
CrossAx: &attrValInt{Val: intPtr(100000001)},
|
||||||
Crosses: &attrValString{Val: stringPtr("autoZero")},
|
Crosses: &attrValString{Val: stringPtr("autoZero")},
|
||||||
Auto: &attrValBool{Val: boolPtr(true)},
|
Auto: &attrValBool{Val: boolPtr(true)},
|
||||||
LblAlgn: &attrValString{Val: stringPtr("ctr")},
|
LblAlgn: &attrValString{Val: stringPtr("ctr")},
|
||||||
|
@ -1085,6 +1067,28 @@ func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs {
|
||||||
if opts.XAxis.TickLabelSkip != 0 {
|
if opts.XAxis.TickLabelSkip != 0 {
|
||||||
axs[0].TickLblSkip = &attrValInt{Val: intPtr(opts.XAxis.TickLabelSkip)}
|
axs[0].TickLblSkip = &attrValInt{Val: intPtr(opts.XAxis.TickLabelSkip)}
|
||||||
}
|
}
|
||||||
|
if opts.order > 0 && opts.YAxis.Secondary {
|
||||||
|
axs = append(axs, &cAxs{
|
||||||
|
AxID: &attrValInt{Val: intPtr(opts.XAxis.axID)},
|
||||||
|
Scaling: &cScaling{
|
||||||
|
Orientation: &attrValString{Val: stringPtr(orientation[opts.XAxis.ReverseOrder])},
|
||||||
|
Max: max,
|
||||||
|
Min: min,
|
||||||
|
},
|
||||||
|
Delete: &attrValBool{Val: boolPtr(true)},
|
||||||
|
AxPos: &attrValString{Val: stringPtr("b")},
|
||||||
|
MajorTickMark: &attrValString{Val: stringPtr("none")},
|
||||||
|
MinorTickMark: &attrValString{Val: stringPtr("none")},
|
||||||
|
TickLblPos: &attrValString{Val: stringPtr("nextTo")},
|
||||||
|
SpPr: f.drawPlotAreaSpPr(),
|
||||||
|
TxPr: f.drawPlotAreaTxPr(&opts.YAxis),
|
||||||
|
CrossAx: &attrValInt{Val: intPtr(opts.YAxis.axID)},
|
||||||
|
Auto: &attrValBool{Val: boolPtr(true)},
|
||||||
|
LblAlgn: &attrValString{Val: stringPtr("ctr")},
|
||||||
|
LblOffset: &attrValInt{Val: intPtr(100)},
|
||||||
|
NoMultiLvlLbl: &attrValBool{Val: boolPtr(false)},
|
||||||
|
})
|
||||||
|
}
|
||||||
return axs
|
return axs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1104,7 +1108,7 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs {
|
||||||
}
|
}
|
||||||
axs := []*cAxs{
|
axs := []*cAxs{
|
||||||
{
|
{
|
||||||
AxID: &attrValInt{Val: intPtr(753999904)},
|
AxID: &attrValInt{Val: intPtr(100000001)},
|
||||||
Scaling: &cScaling{
|
Scaling: &cScaling{
|
||||||
LogBase: logBase,
|
LogBase: logBase,
|
||||||
Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])},
|
Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])},
|
||||||
|
@ -1122,7 +1126,7 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs {
|
||||||
TickLblPos: &attrValString{Val: stringPtr("nextTo")},
|
TickLblPos: &attrValString{Val: stringPtr("nextTo")},
|
||||||
SpPr: f.drawPlotAreaSpPr(),
|
SpPr: f.drawPlotAreaSpPr(),
|
||||||
TxPr: f.drawPlotAreaTxPr(&opts.XAxis),
|
TxPr: f.drawPlotAreaTxPr(&opts.XAxis),
|
||||||
CrossAx: &attrValInt{Val: intPtr(754001152)},
|
CrossAx: &attrValInt{Val: intPtr(100000000)},
|
||||||
Crosses: &attrValString{Val: stringPtr("autoZero")},
|
Crosses: &attrValString{Val: stringPtr("autoZero")},
|
||||||
CrossBetween: &attrValString{Val: stringPtr(chartValAxCrossBetween[opts.Type])},
|
CrossBetween: &attrValString{Val: stringPtr(chartValAxCrossBetween[opts.Type])},
|
||||||
},
|
},
|
||||||
|
@ -1142,6 +1146,26 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs {
|
||||||
if opts.YAxis.MajorUnit != 0 {
|
if opts.YAxis.MajorUnit != 0 {
|
||||||
axs[0].MajorUnit = &attrValFloat{Val: float64Ptr(opts.YAxis.MajorUnit)}
|
axs[0].MajorUnit = &attrValFloat{Val: float64Ptr(opts.YAxis.MajorUnit)}
|
||||||
}
|
}
|
||||||
|
if opts.order > 0 && opts.YAxis.Secondary {
|
||||||
|
axs = append(axs, &cAxs{
|
||||||
|
AxID: &attrValInt{Val: intPtr(opts.YAxis.axID)},
|
||||||
|
Scaling: &cScaling{
|
||||||
|
Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])},
|
||||||
|
Max: max,
|
||||||
|
Min: min,
|
||||||
|
},
|
||||||
|
Delete: &attrValBool{Val: boolPtr(false)},
|
||||||
|
AxPos: &attrValString{Val: stringPtr("r")},
|
||||||
|
MajorTickMark: &attrValString{Val: stringPtr("none")},
|
||||||
|
MinorTickMark: &attrValString{Val: stringPtr("none")},
|
||||||
|
TickLblPos: &attrValString{Val: stringPtr("nextTo")},
|
||||||
|
SpPr: f.drawPlotAreaSpPr(),
|
||||||
|
TxPr: f.drawPlotAreaTxPr(&opts.XAxis),
|
||||||
|
CrossAx: &attrValInt{Val: intPtr(opts.XAxis.axID)},
|
||||||
|
Crosses: &attrValString{Val: stringPtr("max")},
|
||||||
|
CrossBetween: &attrValString{Val: stringPtr(chartValAxCrossBetween[opts.Type])},
|
||||||
|
})
|
||||||
|
}
|
||||||
return axs
|
return axs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1157,7 +1181,7 @@ func (f *File) drawPlotAreaSerAx(opts *Chart) []*cAxs {
|
||||||
}
|
}
|
||||||
return []*cAxs{
|
return []*cAxs{
|
||||||
{
|
{
|
||||||
AxID: &attrValInt{Val: intPtr(832256642)},
|
AxID: &attrValInt{Val: intPtr(100000005)},
|
||||||
Scaling: &cScaling{
|
Scaling: &cScaling{
|
||||||
Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])},
|
Orientation: &attrValString{Val: stringPtr(orientation[opts.YAxis.ReverseOrder])},
|
||||||
Max: max,
|
Max: max,
|
||||||
|
@ -1168,7 +1192,7 @@ func (f *File) drawPlotAreaSerAx(opts *Chart) []*cAxs {
|
||||||
TickLblPos: &attrValString{Val: stringPtr("nextTo")},
|
TickLblPos: &attrValString{Val: stringPtr("nextTo")},
|
||||||
SpPr: f.drawPlotAreaSpPr(),
|
SpPr: f.drawPlotAreaSpPr(),
|
||||||
TxPr: f.drawPlotAreaTxPr(nil),
|
TxPr: f.drawPlotAreaTxPr(nil),
|
||||||
CrossAx: &attrValInt{Val: intPtr(753999904)},
|
CrossAx: &attrValInt{Val: intPtr(100000001)},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1467,3 +1491,13 @@ func (f *File) deleteDrawing(col, row int, drawingXML, drawingType string) error
|
||||||
f.Drawings.Store(drawingXML, wsDr)
|
f.Drawings.Store(drawingXML, wsDr)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// genAxID provides a function to generate ID for primary and secondary
|
||||||
|
// horizontal or vertical axis.
|
||||||
|
func (f *File) genAxID(opts *Chart) []*attrValInt {
|
||||||
|
opts.XAxis.axID, opts.YAxis.axID = 100000000, 100000001
|
||||||
|
if opts.order > 0 && opts.YAxis.Secondary {
|
||||||
|
opts.XAxis.axID, opts.YAxis.axID = 100000003, 100000004
|
||||||
|
}
|
||||||
|
return []*attrValInt{{Val: intPtr(opts.XAxis.axID)}, {Val: intPtr(opts.YAxis.axID)}}
|
||||||
|
}
|
||||||
|
|
|
@ -535,12 +535,14 @@ type ChartAxis struct {
|
||||||
MajorUnit float64
|
MajorUnit float64
|
||||||
TickLabelSkip int
|
TickLabelSkip int
|
||||||
ReverseOrder bool
|
ReverseOrder bool
|
||||||
|
Secondary bool
|
||||||
Maximum *float64
|
Maximum *float64
|
||||||
Minimum *float64
|
Minimum *float64
|
||||||
Font Font
|
Font Font
|
||||||
LogBase float64
|
LogBase float64
|
||||||
NumFmt ChartNumFmt
|
NumFmt ChartNumFmt
|
||||||
Title []RichTextRun
|
Title []RichTextRun
|
||||||
|
axID int
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChartDimension directly maps the dimension of the chart.
|
// ChartDimension directly maps the dimension of the chart.
|
||||||
|
|
Loading…
Reference in New Issue