Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xuri
excelize
提交
f8aa3adf
excelize
项目概览
xuri
/
excelize
通知
13
Star
2
Fork
4
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
excelize
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
已验证
提交
f8aa3adf
编写于
6月 18, 2023
作者:
xurime
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
This closes #1553, the `AddChart` function support set primary titles
- Update unit tests and documentation - Lint issues fixed
上级
9bc3fd7e
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
92 addition
and
43 deletion
+92
-43
chart.go
chart.go
+16
-2
chart_test.go
chart_test.go
+1
-1
drawing.go
drawing.go
+63
-30
numfmt.go
numfmt.go
+8
-8
numfmt_test.go
numfmt_test.go
+1
-1
xmlChart.go
xmlChart.go
+3
-1
未找到文件。
chart.go
浏览文件 @
f8aa3adf
...
...
@@ -794,6 +794,8 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// Maximum
// Minimum
// Font
// NumFmt
// Title
//
// The properties of 'YAxis' that can be set are:
//
...
...
@@ -805,6 +807,9 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// Maximum
// Minimum
// Font
// LogBase
// NumFmt
// Title
//
// None: Disable axes.
//
...
...
@@ -813,14 +818,14 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// MinorGridLines: Specifies minor grid lines.
//
// MajorUnit: Specifies the distance between major ticks. Shall contain a
// positive floating-point number. The
MajorUnit
property is optional. The
// positive floating-point number. The
'MajorUnit'
property is optional. The
// default value is auto.
//
// TickLabelSkip: Specifies how many tick labels to skip between label that is
// drawn. The 'TickLabelSkip' property is optional. The default value is auto.
//
// ReverseOrder: Specifies that the categories or values on reverse order
// (orientation of the chart). The
ReverseOrder
property is optional. The
// (orientation of the chart). The
'ReverseOrder'
property is optional. The
// default value is false.
//
// Maximum: Specifies that the fixed maximum, 0 is auto. The 'Maximum' property
...
...
@@ -841,6 +846,15 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// Color
// VertAlign
//
// LogBase: Specifies logarithmic scale for the YAxis.
//
// NumFmt: Specifies that if linked to source and set custom number format code
// for axis. The 'NumFmt' property is optional. The default format code is
// 'General'.
//
// Title: Specifies that the primary horizontal or vertical axis title. The
// 'Title' property is optional.
//
// Set chart size by 'Dimension' property. The 'Dimension' property is optional.
// The default width is 480, and height is 290.
//
...
...
chart_test.go
浏览文件 @
f8aa3adf
...
...
@@ -206,7 +206,7 @@ func TestAddChart(t *testing.T) {
sheetName
,
cell
string
opts
*
Chart
}{
{
sheetName
:
"Sheet1"
,
cell
:
"P1"
,
opts
:
&
Chart
{
Type
:
Col
,
Series
:
series
,
Format
:
format
,
Legend
:
ChartLegend
{
Position
:
"none"
,
ShowLegendKey
:
true
},
Title
:
ChartTitle
{
Name
:
"2D Column Chart"
},
PlotArea
:
plotArea
,
ShowBlanksAs
:
"zero"
,
XAxis
:
ChartAxis
{
Font
:
Font
{
Bold
:
true
,
Italic
:
true
,
Underline
:
"dbl"
,
Color
:
"000000"
}
},
YAxis
:
ChartAxis
{
Font
:
Font
{
Bold
:
false
,
Italic
:
false
,
Underline
:
"sng"
,
Color
:
"777777"
}}}},
{
sheetName
:
"Sheet1"
,
cell
:
"P1"
,
opts
:
&
Chart
{
Type
:
Col
,
Series
:
series
,
Format
:
format
,
Legend
:
ChartLegend
{
Position
:
"none"
,
ShowLegendKey
:
true
},
Title
:
ChartTitle
{
Name
:
"2D Column Chart"
},
PlotArea
:
plotArea
,
ShowBlanksAs
:
"zero"
,
XAxis
:
ChartAxis
{
Font
:
Font
{
Bold
:
true
,
Italic
:
true
,
Underline
:
"dbl"
,
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
:
ChartTitle
{
Name
:
"2D Stacked Column Chart"
},
PlotArea
:
plotArea
,
ShowBlanksAs
:
"zero"
}},
{
sheetName
:
"Sheet1"
,
cell
:
"P16"
,
opts
:
&
Chart
{
Type
:
ColPercentStacked
,
Series
:
series
,
Format
:
format
,
Legend
:
legend
,
Title
:
ChartTitle
{
Name
:
"100% Stacked Column Chart"
},
PlotArea
:
plotArea
,
ShowBlanksAs
:
"zero"
}},
{
sheetName
:
"Sheet1"
,
cell
:
"X16"
,
opts
:
&
Chart
{
Type
:
Col3DClustered
,
Series
:
series
,
Format
:
format
,
Legend
:
ChartLegend
{
Position
:
"bottom"
,
ShowLegendKey
:
false
},
Title
:
ChartTitle
{
Name
:
"3D Clustered Column Chart"
},
PlotArea
:
plotArea
,
ShowBlanksAs
:
"zero"
}},
...
...
drawing.go
浏览文件 @
f8aa3adf
...
...
@@ -66,41 +66,43 @@ func (f *File) addChart(opts *Chart, comboCharts []*Chart) {
Title
:
&
cTitle
{
Tx
:
cTx
{
Rich
:
&
cRich
{
P
:
aP
{
PPr
:
&
aPPr
{
DefRPr
:
aRPr
{
Kern
:
1200
,
Strike
:
"noStrike"
,
U
:
"none"
,
Sz
:
1400
,
SolidFill
:
&
aSolidFill
{
SchemeClr
:
&
aSchemeClr
{
Val
:
"tx1"
,
LumMod
:
&
attrValInt
{
Val
:
intPtr
(
65000
),
},
LumOff
:
&
attrValInt
{
Val
:
intPtr
(
35000
),
P
:
[]
aP
{
{
PPr
:
&
aPPr
{
DefRPr
:
aRPr
{
Kern
:
1200
,
Strike
:
"noStrike"
,
U
:
"none"
,
Sz
:
1400
,
SolidFill
:
&
aSolidFill
{
SchemeClr
:
&
aSchemeClr
{
Val
:
"tx1"
,
LumMod
:
&
attrValInt
{
Val
:
intPtr
(
65000
),
},
LumOff
:
&
attrValInt
{
Val
:
intPtr
(
35000
),
},
},
},
},
Ea
:
&
aEa
{
Typeface
:
"+mn-ea"
,
},
Cs
:
&
aCs
{
Typeface
:
"+mn-cs"
,
},
Latin
:
&
xlsxCTTextFont
{
Typeface
:
"+mn-lt"
,
Ea
:
&
aEa
{
Typeface
:
"+mn-ea"
,
}
,
Cs
:
&
aCs
{
Typeface
:
"+mn-cs"
,
}
,
Latin
:
&
xlsxCTTextFont
{
Typeface
:
"+mn-lt"
,
}
,
},
},
},
R
:
&
aR
{
RPr
:
aRPr
{
Lang
:
"en-US"
,
AltLang
:
"en-US"
,
R
:
&
aR
{
RPr
:
aRPr
{
Lang
:
"en-US"
,
AltLang
:
"en-US"
,
},
T
:
opts
.
Title
.
Name
,
},
T
:
opts
.
Title
.
Name
,
},
},
},
...
...
@@ -1059,6 +1061,7 @@ func (f *File) drawPlotAreaCatAx(opts *Chart) []*cAxs {
NumFmt
:
&
cNumFmt
{
FormatCode
:
"General"
},
MajorTickMark
:
&
attrValString
{
Val
:
stringPtr
(
"none"
)},
MinorTickMark
:
&
attrValString
{
Val
:
stringPtr
(
"none"
)},
Title
:
f
.
drawPlotAreaTitles
(
opts
.
XAxis
.
Title
,
""
),
TickLblPos
:
&
attrValString
{
Val
:
stringPtr
(
"nextTo"
)},
SpPr
:
f
.
drawPlotAreaSpPr
(),
TxPr
:
f
.
drawPlotAreaTxPr
(
&
opts
.
YAxis
),
...
...
@@ -1110,6 +1113,7 @@ func (f *File) drawPlotAreaValAx(opts *Chart) []*cAxs {
},
Delete
:
&
attrValBool
{
Val
:
boolPtr
(
opts
.
YAxis
.
None
)},
AxPos
:
&
attrValString
{
Val
:
stringPtr
(
valAxPos
[
opts
.
YAxis
.
ReverseOrder
])},
Title
:
f
.
drawPlotAreaTitles
(
opts
.
YAxis
.
Title
,
"horz"
),
NumFmt
:
&
cNumFmt
{
FormatCode
:
chartValAxNumFmtFormatCode
[
opts
.
Type
],
},
...
...
@@ -1169,6 +1173,35 @@ func (f *File) drawPlotAreaSerAx(opts *Chart) []*cAxs {
}
}
// drawPlotAreaTitles provides a function to draw the c:title element.
func
(
f
*
File
)
drawPlotAreaTitles
(
runs
[]
RichTextRun
,
vert
string
)
*
cTitle
{
if
len
(
runs
)
==
0
{
return
nil
}
title
:=
&
cTitle
{
Tx
:
cTx
{
Rich
:
&
cRich
{}},
Overlay
:
&
attrValBool
{
Val
:
boolPtr
(
false
)}}
for
_
,
run
:=
range
runs
{
r
:=
&
aR
{
T
:
run
.
Text
}
if
run
.
Font
!=
nil
{
r
.
RPr
.
B
,
r
.
RPr
.
I
=
run
.
Font
.
Bold
,
run
.
Font
.
Italic
if
run
.
Font
.
Color
!=
""
{
r
.
RPr
.
SolidFill
=
&
aSolidFill
{
SrgbClr
:
&
attrValString
{
Val
:
stringPtr
(
run
.
Font
.
Color
)}}
}
if
run
.
Font
.
Size
>
0
{
r
.
RPr
.
Sz
=
run
.
Font
.
Size
*
100
}
}
title
.
Tx
.
Rich
.
P
=
append
(
title
.
Tx
.
Rich
.
P
,
aP
{
PPr
:
&
aPPr
{
DefRPr
:
aRPr
{}},
R
:
r
,
EndParaRPr
:
&
aEndParaRPr
{
Lang
:
"en-US"
,
AltLang
:
"en-US"
},
})
}
if
vert
==
"horz"
{
title
.
Tx
.
Rich
.
BodyPr
=
aBodyPr
{
Rot
:
-
5400000
,
Vert
:
vert
}
}
return
title
}
// drawPlotAreaSpPr provides a function to draw the c:spPr element.
func
(
f
*
File
)
drawPlotAreaSpPr
()
*
cSpPr
{
return
&
cSpPr
{
...
...
numfmt.go
浏览文件 @
f8aa3adf
...
...
@@ -1190,7 +1190,7 @@ func (nf *numberFormat) printNumberLiteral(text string) string {
}
for
_
,
token
:=
range
nf
.
section
[
nf
.
sectionIdx
]
.
Items
{
if
token
.
TType
==
nfp
.
TokenTypeCurrencyLanguage
{
if
err
,
changeNumFmtCode
:=
nf
.
currencyLanguageHandler
(
token
);
err
!=
nil
||
changeNumFmtCode
{
if
changeNumFmtCode
,
err
:=
nf
.
currencyLanguageHandler
(
token
);
err
!=
nil
||
changeNumFmtCode
{
return
nf
.
value
}
result
+=
nf
.
currencyString
...
...
@@ -1326,7 +1326,7 @@ func (nf *numberFormat) dateTimeHandler() string {
nf
.
t
,
nf
.
hours
,
nf
.
seconds
=
timeFromExcelTime
(
nf
.
number
,
nf
.
date1904
),
false
,
false
for
i
,
token
:=
range
nf
.
section
[
nf
.
sectionIdx
]
.
Items
{
if
token
.
TType
==
nfp
.
TokenTypeCurrencyLanguage
{
if
err
,
changeNumFmtCode
:=
nf
.
currencyLanguageHandler
(
token
);
err
!=
nil
||
changeNumFmtCode
{
if
changeNumFmtCode
,
err
:=
nf
.
currencyLanguageHandler
(
token
);
err
!=
nil
||
changeNumFmtCode
{
return
nf
.
value
}
nf
.
result
+=
nf
.
currencyString
...
...
@@ -1397,28 +1397,28 @@ func (nf *numberFormat) positiveHandler() string {
// currencyLanguageHandler will be handling currency and language types tokens
// for a number format expression.
func
(
nf
*
numberFormat
)
currencyLanguageHandler
(
token
nfp
.
Token
)
(
error
,
bool
)
{
func
(
nf
*
numberFormat
)
currencyLanguageHandler
(
token
nfp
.
Token
)
(
bool
,
error
)
{
for
_
,
part
:=
range
token
.
Parts
{
if
inStrSlice
(
supportedTokenTypes
,
part
.
Token
.
TType
,
true
)
==
-
1
{
return
ErrUnsupportedNumberFormat
,
false
return
false
,
ErrUnsupportedNumberFormat
}
if
part
.
Token
.
TType
==
nfp
.
TokenSubTypeLanguageInfo
{
if
strings
.
EqualFold
(
part
.
Token
.
TValue
,
"F800"
)
{
// [$-x-sysdate]
if
nf
.
opts
!=
nil
&&
nf
.
opts
.
LongDatePattern
!=
""
{
nf
.
value
=
format
(
nf
.
value
,
nf
.
opts
.
LongDatePattern
,
nf
.
date1904
,
nf
.
cellType
,
nf
.
opts
)
return
nil
,
true
return
true
,
nil
}
part
.
Token
.
TValue
=
"409"
}
if
strings
.
EqualFold
(
part
.
Token
.
TValue
,
"F400"
)
{
// [$-x-systime]
if
nf
.
opts
!=
nil
&&
nf
.
opts
.
LongTimePattern
!=
""
{
nf
.
value
=
format
(
nf
.
value
,
nf
.
opts
.
LongTimePattern
,
nf
.
date1904
,
nf
.
cellType
,
nf
.
opts
)
return
nil
,
true
return
true
,
nil
}
part
.
Token
.
TValue
=
"409"
}
if
_
,
ok
:=
supportedLanguageInfo
[
strings
.
ToUpper
(
part
.
Token
.
TValue
)];
!
ok
{
return
ErrUnsupportedNumberFormat
,
false
return
false
,
ErrUnsupportedNumberFormat
}
nf
.
localCode
=
strings
.
ToUpper
(
part
.
Token
.
TValue
)
}
...
...
@@ -1426,7 +1426,7 @@ func (nf *numberFormat) currencyLanguageHandler(token nfp.Token) (error, bool) {
nf
.
currencyString
=
part
.
Token
.
TValue
}
}
return
nil
,
false
return
false
,
nil
}
// localAmPm return AM/PM name by supported language ID.
...
...
numfmt_test.go
浏览文件 @
f8aa3adf
...
...
@@ -1093,7 +1093,7 @@ func TestNumFmt(t *testing.T) {
}
}
nf
:=
numberFormat
{}
err
,
changeNumFmtCode
:=
nf
.
currencyLanguageHandler
(
nfp
.
Token
{
Parts
:
[]
nfp
.
Part
{{}}})
changeNumFmtCode
,
err
:=
nf
.
currencyLanguageHandler
(
nfp
.
Token
{
Parts
:
[]
nfp
.
Part
{{}}})
assert
.
Equal
(
t
,
ErrUnsupportedNumberFormat
,
err
)
assert
.
False
(
t
,
changeNumFmtCode
)
}
xmlChart.go
浏览文件 @
f8aa3adf
...
...
@@ -74,7 +74,7 @@ type cTx struct {
type
cRich
struct
{
BodyPr
aBodyPr
`xml:"a:bodyPr,omitempty"`
LstStyle
string
`xml:"a:lstStyle,omitempty"`
P
aP
`xml:"a:p"`
P
[]
aP
`xml:"a:p"`
}
// aBodyPr (Body Properties) directly maps the a:bodyPr element. This element
...
...
@@ -351,6 +351,7 @@ type cAxs struct {
AxPos
*
attrValString
`xml:"axPos"`
MajorGridlines
*
cChartLines
`xml:"majorGridlines"`
MinorGridlines
*
cChartLines
`xml:"minorGridlines"`
Title
*
cTitle
`xml:"title"`
NumFmt
*
cNumFmt
`xml:"numFmt"`
MajorTickMark
*
attrValString
`xml:"majorTickMark"`
MinorTickMark
*
attrValString
`xml:"minorTickMark"`
...
...
@@ -539,6 +540,7 @@ type ChartAxis struct {
Font
Font
LogBase
float64
NumFmt
ChartNumFmt
Title
[]
RichTextRun
}
// ChartDimension directly maps the dimension of the chart.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录