sparkline.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. // Copyright 2016 - 2021 The excelize Authors. All rights reserved. Use of
  2. // this source code is governed by a BSD-style license that can be found in
  3. // the LICENSE file.
  4. //
  5. // Package excelize providing a set of functions that allow you to write to
  6. // and read from XLSX / XLSM / XLTM files. Supports reading and writing
  7. // spreadsheet documents generated by Microsoft Excel™ 2007 and later. Supports
  8. // complex components by high compatibility, and provided streaming API for
  9. // generating or reading data from a worksheet with huge amounts of data. This
  10. // library needs Go version 1.15 or later.
  11. package excelize
  12. import (
  13. "encoding/xml"
  14. "errors"
  15. "io"
  16. "strings"
  17. )
  18. // addSparklineGroupByStyle provides a function to create x14:sparklineGroups
  19. // element by given sparkline style ID.
  20. func (f *File) addSparklineGroupByStyle(ID int) *xlsxX14SparklineGroup {
  21. groups := []*xlsxX14SparklineGroup{
  22. {
  23. ColorSeries: &xlsxTabColor{Theme: 4, Tint: -0.499984740745262},
  24. ColorNegative: &xlsxTabColor{Theme: 5},
  25. ColorMarkers: &xlsxTabColor{Theme: 4, Tint: -0.499984740745262},
  26. ColorFirst: &xlsxTabColor{Theme: 4, Tint: 0.39997558519241921},
  27. ColorLast: &xlsxTabColor{Theme: 4, Tint: 0.39997558519241921},
  28. ColorHigh: &xlsxTabColor{Theme: 4},
  29. ColorLow: &xlsxTabColor{Theme: 4},
  30. }, // 0
  31. {
  32. ColorSeries: &xlsxTabColor{Theme: 4, Tint: -0.499984740745262},
  33. ColorNegative: &xlsxTabColor{Theme: 5},
  34. ColorMarkers: &xlsxTabColor{Theme: 4, Tint: -0.499984740745262},
  35. ColorFirst: &xlsxTabColor{Theme: 4, Tint: 0.39997558519241921},
  36. ColorLast: &xlsxTabColor{Theme: 4, Tint: 0.39997558519241921},
  37. ColorHigh: &xlsxTabColor{Theme: 4},
  38. ColorLow: &xlsxTabColor{Theme: 4},
  39. }, // 1
  40. {
  41. ColorSeries: &xlsxTabColor{Theme: 5, Tint: -0.499984740745262},
  42. ColorNegative: &xlsxTabColor{Theme: 6},
  43. ColorMarkers: &xlsxTabColor{Theme: 5, Tint: -0.499984740745262},
  44. ColorFirst: &xlsxTabColor{Theme: 5, Tint: 0.39997558519241921},
  45. ColorLast: &xlsxTabColor{Theme: 5, Tint: 0.39997558519241921},
  46. ColorHigh: &xlsxTabColor{Theme: 5},
  47. ColorLow: &xlsxTabColor{Theme: 5},
  48. }, // 2
  49. {
  50. ColorSeries: &xlsxTabColor{Theme: 6, Tint: -0.499984740745262},
  51. ColorNegative: &xlsxTabColor{Theme: 7},
  52. ColorMarkers: &xlsxTabColor{Theme: 6, Tint: -0.499984740745262},
  53. ColorFirst: &xlsxTabColor{Theme: 6, Tint: 0.39997558519241921},
  54. ColorLast: &xlsxTabColor{Theme: 6, Tint: 0.39997558519241921},
  55. ColorHigh: &xlsxTabColor{Theme: 6},
  56. ColorLow: &xlsxTabColor{Theme: 6},
  57. }, // 3
  58. {
  59. ColorSeries: &xlsxTabColor{Theme: 7, Tint: -0.499984740745262},
  60. ColorNegative: &xlsxTabColor{Theme: 8},
  61. ColorMarkers: &xlsxTabColor{Theme: 7, Tint: -0.499984740745262},
  62. ColorFirst: &xlsxTabColor{Theme: 7, Tint: 0.39997558519241921},
  63. ColorLast: &xlsxTabColor{Theme: 7, Tint: 0.39997558519241921},
  64. ColorHigh: &xlsxTabColor{Theme: 7},
  65. ColorLow: &xlsxTabColor{Theme: 7},
  66. }, // 4
  67. {
  68. ColorSeries: &xlsxTabColor{Theme: 8, Tint: -0.499984740745262},
  69. ColorNegative: &xlsxTabColor{Theme: 9},
  70. ColorMarkers: &xlsxTabColor{Theme: 8, Tint: -0.499984740745262},
  71. ColorFirst: &xlsxTabColor{Theme: 8, Tint: 0.39997558519241921},
  72. ColorLast: &xlsxTabColor{Theme: 8, Tint: 0.39997558519241921},
  73. ColorHigh: &xlsxTabColor{Theme: 8},
  74. ColorLow: &xlsxTabColor{Theme: 8},
  75. }, // 5
  76. {
  77. ColorSeries: &xlsxTabColor{Theme: 9, Tint: -0.499984740745262},
  78. ColorNegative: &xlsxTabColor{Theme: 4},
  79. ColorMarkers: &xlsxTabColor{Theme: 9, Tint: -0.499984740745262},
  80. ColorFirst: &xlsxTabColor{Theme: 9, Tint: 0.39997558519241921},
  81. ColorLast: &xlsxTabColor{Theme: 9, Tint: 0.39997558519241921},
  82. ColorHigh: &xlsxTabColor{Theme: 9},
  83. ColorLow: &xlsxTabColor{Theme: 9},
  84. }, // 6
  85. {
  86. ColorSeries: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  87. ColorNegative: &xlsxTabColor{Theme: 5},
  88. ColorMarkers: &xlsxTabColor{Theme: 5, Tint: -0.249977111117893},
  89. ColorFirst: &xlsxTabColor{Theme: 5, Tint: -0.249977111117893},
  90. ColorLast: &xlsxTabColor{Theme: 5, Tint: -0.249977111117893},
  91. ColorHigh: &xlsxTabColor{Theme: 5},
  92. ColorLow: &xlsxTabColor{Theme: 5},
  93. }, // 7
  94. {
  95. ColorSeries: &xlsxTabColor{Theme: 5, Tint: -0.249977111117893},
  96. ColorNegative: &xlsxTabColor{Theme: 6},
  97. ColorMarkers: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  98. ColorFirst: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  99. ColorLast: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  100. ColorHigh: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  101. ColorLow: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  102. }, // 8
  103. {
  104. ColorSeries: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  105. ColorNegative: &xlsxTabColor{Theme: 7},
  106. ColorMarkers: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  107. ColorFirst: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  108. ColorLast: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  109. ColorHigh: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  110. ColorLow: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  111. }, // 9
  112. {
  113. ColorSeries: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  114. ColorNegative: &xlsxTabColor{Theme: 8},
  115. ColorMarkers: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  116. ColorFirst: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  117. ColorLast: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  118. ColorHigh: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  119. ColorLow: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  120. }, // 10
  121. {
  122. ColorSeries: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  123. ColorNegative: &xlsxTabColor{Theme: 9},
  124. ColorMarkers: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  125. ColorFirst: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  126. ColorLast: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  127. ColorHigh: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  128. ColorLow: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  129. }, // 11
  130. {
  131. ColorSeries: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  132. ColorNegative: &xlsxTabColor{Theme: 4},
  133. ColorMarkers: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  134. ColorFirst: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  135. ColorLast: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  136. ColorHigh: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  137. ColorLow: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  138. }, // 12
  139. {
  140. ColorSeries: &xlsxTabColor{Theme: 4},
  141. ColorNegative: &xlsxTabColor{Theme: 5},
  142. ColorMarkers: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  143. ColorFirst: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  144. ColorLast: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  145. ColorHigh: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  146. ColorLow: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  147. }, // 13
  148. {
  149. ColorSeries: &xlsxTabColor{Theme: 5},
  150. ColorNegative: &xlsxTabColor{Theme: 6},
  151. ColorMarkers: &xlsxTabColor{Theme: 5, Tint: -0.249977111117893},
  152. ColorFirst: &xlsxTabColor{Theme: 5, Tint: -0.249977111117893},
  153. ColorLast: &xlsxTabColor{Theme: 5, Tint: -0.249977111117893},
  154. ColorHigh: &xlsxTabColor{Theme: 5, Tint: -0.249977111117893},
  155. ColorLow: &xlsxTabColor{Theme: 5, Tint: -0.249977111117893},
  156. }, // 14
  157. {
  158. ColorSeries: &xlsxTabColor{Theme: 6},
  159. ColorNegative: &xlsxTabColor{Theme: 7},
  160. ColorMarkers: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  161. ColorFirst: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  162. ColorLast: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  163. ColorHigh: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  164. ColorLow: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  165. }, // 15
  166. {
  167. ColorSeries: &xlsxTabColor{Theme: 7},
  168. ColorNegative: &xlsxTabColor{Theme: 8},
  169. ColorMarkers: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  170. ColorFirst: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  171. ColorLast: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  172. ColorHigh: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  173. ColorLow: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  174. }, // 16
  175. {
  176. ColorSeries: &xlsxTabColor{Theme: 8},
  177. ColorNegative: &xlsxTabColor{Theme: 9},
  178. ColorMarkers: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  179. ColorFirst: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  180. ColorLast: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  181. ColorHigh: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  182. ColorLow: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  183. }, // 17
  184. {
  185. ColorSeries: &xlsxTabColor{Theme: 9},
  186. ColorNegative: &xlsxTabColor{Theme: 4},
  187. ColorMarkers: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  188. ColorFirst: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  189. ColorLast: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  190. ColorHigh: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  191. ColorLow: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  192. }, // 18
  193. {
  194. ColorSeries: &xlsxTabColor{Theme: 4, Tint: 0.39997558519241921},
  195. ColorNegative: &xlsxTabColor{Theme: 0, Tint: -0.499984740745262},
  196. ColorMarkers: &xlsxTabColor{Theme: 4, Tint: 0.79998168889431442},
  197. ColorFirst: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  198. ColorLast: &xlsxTabColor{Theme: 4, Tint: -0.249977111117893},
  199. ColorHigh: &xlsxTabColor{Theme: 4, Tint: -0.499984740745262},
  200. ColorLow: &xlsxTabColor{Theme: 4, Tint: -0.499984740745262},
  201. }, // 19
  202. {
  203. ColorSeries: &xlsxTabColor{Theme: 5, Tint: 0.39997558519241921},
  204. ColorNegative: &xlsxTabColor{Theme: 0, Tint: -0.499984740745262},
  205. ColorMarkers: &xlsxTabColor{Theme: 5, Tint: 0.79998168889431442},
  206. ColorFirst: &xlsxTabColor{Theme: 5, Tint: -0.249977111117893},
  207. ColorLast: &xlsxTabColor{Theme: 5, Tint: -0.249977111117893},
  208. ColorHigh: &xlsxTabColor{Theme: 5, Tint: -0.499984740745262},
  209. ColorLow: &xlsxTabColor{Theme: 5, Tint: -0.499984740745262},
  210. }, // 20
  211. {
  212. ColorSeries: &xlsxTabColor{Theme: 6, Tint: 0.39997558519241921},
  213. ColorNegative: &xlsxTabColor{Theme: 0, Tint: -0.499984740745262},
  214. ColorMarkers: &xlsxTabColor{Theme: 6, Tint: 0.79998168889431442},
  215. ColorFirst: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  216. ColorLast: &xlsxTabColor{Theme: 6, Tint: -0.249977111117893},
  217. ColorHigh: &xlsxTabColor{Theme: 6, Tint: -0.499984740745262},
  218. ColorLow: &xlsxTabColor{Theme: 6, Tint: -0.499984740745262},
  219. }, // 21
  220. {
  221. ColorSeries: &xlsxTabColor{Theme: 7, Tint: 0.39997558519241921},
  222. ColorNegative: &xlsxTabColor{Theme: 0, Tint: -0.499984740745262},
  223. ColorMarkers: &xlsxTabColor{Theme: 7, Tint: 0.79998168889431442},
  224. ColorFirst: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  225. ColorLast: &xlsxTabColor{Theme: 7, Tint: -0.249977111117893},
  226. ColorHigh: &xlsxTabColor{Theme: 7, Tint: -0.499984740745262},
  227. ColorLow: &xlsxTabColor{Theme: 7, Tint: -0.499984740745262},
  228. }, // 22
  229. {
  230. ColorSeries: &xlsxTabColor{Theme: 8, Tint: 0.39997558519241921},
  231. ColorNegative: &xlsxTabColor{Theme: 0, Tint: -0.499984740745262},
  232. ColorMarkers: &xlsxTabColor{Theme: 8, Tint: 0.79998168889431442},
  233. ColorFirst: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  234. ColorLast: &xlsxTabColor{Theme: 8, Tint: -0.249977111117893},
  235. ColorHigh: &xlsxTabColor{Theme: 8, Tint: -0.499984740745262},
  236. ColorLow: &xlsxTabColor{Theme: 8, Tint: -0.499984740745262},
  237. }, // 23
  238. {
  239. ColorSeries: &xlsxTabColor{Theme: 9, Tint: 0.39997558519241921},
  240. ColorNegative: &xlsxTabColor{Theme: 0, Tint: -0.499984740745262},
  241. ColorMarkers: &xlsxTabColor{Theme: 9, Tint: 0.79998168889431442},
  242. ColorFirst: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  243. ColorLast: &xlsxTabColor{Theme: 9, Tint: -0.249977111117893},
  244. ColorHigh: &xlsxTabColor{Theme: 9, Tint: -0.499984740745262},
  245. ColorLow: &xlsxTabColor{Theme: 9, Tint: -0.499984740745262},
  246. }, // 24
  247. {
  248. ColorSeries: &xlsxTabColor{Theme: 1, Tint: 0.499984740745262},
  249. ColorNegative: &xlsxTabColor{Theme: 1, Tint: 0.249977111117893},
  250. ColorMarkers: &xlsxTabColor{Theme: 1, Tint: 0.249977111117893},
  251. ColorFirst: &xlsxTabColor{Theme: 1, Tint: 0.249977111117893},
  252. ColorLast: &xlsxTabColor{Theme: 1, Tint: 0.249977111117893},
  253. ColorHigh: &xlsxTabColor{Theme: 1, Tint: 0.249977111117893},
  254. ColorLow: &xlsxTabColor{Theme: 1, Tint: 0.249977111117893},
  255. }, // 25
  256. {
  257. ColorSeries: &xlsxTabColor{Theme: 1, Tint: 0.34998626667073579},
  258. ColorNegative: &xlsxTabColor{Theme: 0, Tint: 0.249977111117893},
  259. ColorMarkers: &xlsxTabColor{Theme: 0, Tint: 0.249977111117893},
  260. ColorFirst: &xlsxTabColor{Theme: 0, Tint: 0.249977111117893},
  261. ColorLast: &xlsxTabColor{Theme: 0, Tint: 0.249977111117893},
  262. ColorHigh: &xlsxTabColor{Theme: 0, Tint: 0.249977111117893},
  263. ColorLow: &xlsxTabColor{Theme: 0, Tint: 0.249977111117893},
  264. }, // 26
  265. {
  266. ColorSeries: &xlsxTabColor{RGB: "FF323232"},
  267. ColorNegative: &xlsxTabColor{RGB: "FFD00000"},
  268. ColorMarkers: &xlsxTabColor{RGB: "FFD00000"},
  269. ColorFirst: &xlsxTabColor{RGB: "FFD00000"},
  270. ColorLast: &xlsxTabColor{RGB: "FFD00000"},
  271. ColorHigh: &xlsxTabColor{RGB: "FFD00000"},
  272. ColorLow: &xlsxTabColor{RGB: "FFD00000"},
  273. }, // 27
  274. {
  275. ColorSeries: &xlsxTabColor{RGB: "FF000000"},
  276. ColorNegative: &xlsxTabColor{RGB: "FF0070C0"},
  277. ColorMarkers: &xlsxTabColor{RGB: "FF0070C0"},
  278. ColorFirst: &xlsxTabColor{RGB: "FF0070C0"},
  279. ColorLast: &xlsxTabColor{RGB: "FF0070C0"},
  280. ColorHigh: &xlsxTabColor{RGB: "FF0070C0"},
  281. ColorLow: &xlsxTabColor{RGB: "FF0070C0"},
  282. }, // 28
  283. {
  284. ColorSeries: &xlsxTabColor{RGB: "FF376092"},
  285. ColorNegative: &xlsxTabColor{RGB: "FFD00000"},
  286. ColorMarkers: &xlsxTabColor{RGB: "FFD00000"},
  287. ColorFirst: &xlsxTabColor{RGB: "FFD00000"},
  288. ColorLast: &xlsxTabColor{RGB: "FFD00000"},
  289. ColorHigh: &xlsxTabColor{RGB: "FFD00000"},
  290. ColorLow: &xlsxTabColor{RGB: "FFD00000"},
  291. }, // 29
  292. {
  293. ColorSeries: &xlsxTabColor{RGB: "FF0070C0"},
  294. ColorNegative: &xlsxTabColor{RGB: "FF000000"},
  295. ColorMarkers: &xlsxTabColor{RGB: "FF000000"},
  296. ColorFirst: &xlsxTabColor{RGB: "FF000000"},
  297. ColorLast: &xlsxTabColor{RGB: "FF000000"},
  298. ColorHigh: &xlsxTabColor{RGB: "FF000000"},
  299. ColorLow: &xlsxTabColor{RGB: "FF000000"},
  300. }, // 30
  301. {
  302. ColorSeries: &xlsxTabColor{RGB: "FF5F5F5F"},
  303. ColorNegative: &xlsxTabColor{RGB: "FFFFB620"},
  304. ColorMarkers: &xlsxTabColor{RGB: "FFD70077"},
  305. ColorFirst: &xlsxTabColor{RGB: "FF5687C2"},
  306. ColorLast: &xlsxTabColor{RGB: "FF359CEB"},
  307. ColorHigh: &xlsxTabColor{RGB: "FF56BE79"},
  308. ColorLow: &xlsxTabColor{RGB: "FFFF5055"},
  309. }, // 31
  310. {
  311. ColorSeries: &xlsxTabColor{RGB: "FF5687C2"},
  312. ColorNegative: &xlsxTabColor{RGB: "FFFFB620"},
  313. ColorMarkers: &xlsxTabColor{RGB: "FFD70077"},
  314. ColorFirst: &xlsxTabColor{RGB: "FF777777"},
  315. ColorLast: &xlsxTabColor{RGB: "FF359CEB"},
  316. ColorHigh: &xlsxTabColor{RGB: "FF56BE79"},
  317. ColorLow: &xlsxTabColor{RGB: "FFFF5055"},
  318. }, // 32
  319. {
  320. ColorSeries: &xlsxTabColor{RGB: "FFC6EFCE"},
  321. ColorNegative: &xlsxTabColor{RGB: "FFFFC7CE"},
  322. ColorMarkers: &xlsxTabColor{RGB: "FF8CADD6"},
  323. ColorFirst: &xlsxTabColor{RGB: "FFFFDC47"},
  324. ColorLast: &xlsxTabColor{RGB: "FFFFEB9C"},
  325. ColorHigh: &xlsxTabColor{RGB: "FF60D276"},
  326. ColorLow: &xlsxTabColor{RGB: "FFFF5367"},
  327. }, // 33
  328. {
  329. ColorSeries: &xlsxTabColor{RGB: "FF00B050"},
  330. ColorNegative: &xlsxTabColor{RGB: "FFFF0000"},
  331. ColorMarkers: &xlsxTabColor{RGB: "FF0070C0"},
  332. ColorFirst: &xlsxTabColor{RGB: "FFFFC000"},
  333. ColorLast: &xlsxTabColor{RGB: "FFFFC000"},
  334. ColorHigh: &xlsxTabColor{RGB: "FF00B050"},
  335. ColorLow: &xlsxTabColor{RGB: "FFFF0000"},
  336. }, // 34
  337. {
  338. ColorSeries: &xlsxTabColor{Theme: 3},
  339. ColorNegative: &xlsxTabColor{Theme: 9},
  340. ColorMarkers: &xlsxTabColor{Theme: 8},
  341. ColorFirst: &xlsxTabColor{Theme: 4},
  342. ColorLast: &xlsxTabColor{Theme: 5},
  343. ColorHigh: &xlsxTabColor{Theme: 6},
  344. ColorLow: &xlsxTabColor{Theme: 7},
  345. }, // 35
  346. {
  347. ColorSeries: &xlsxTabColor{Theme: 1},
  348. ColorNegative: &xlsxTabColor{Theme: 9},
  349. ColorMarkers: &xlsxTabColor{Theme: 8},
  350. ColorFirst: &xlsxTabColor{Theme: 4},
  351. ColorLast: &xlsxTabColor{Theme: 5},
  352. ColorHigh: &xlsxTabColor{Theme: 6},
  353. ColorLow: &xlsxTabColor{Theme: 7},
  354. }, // 36
  355. }
  356. return groups[ID]
  357. }
  358. // AddSparkline provides a function to add sparklines to the worksheet by
  359. // given formatting options. Sparklines are small charts that fit in a single
  360. // cell and are used to show trends in data. Sparklines are a feature of Excel
  361. // 2010 and later only. You can write them to an XLSX file that can be read by
  362. // Excel 2007 but they won't be displayed. For example, add a grouped
  363. // sparkline. Changes are applied to all three:
  364. //
  365. // err := f.AddSparkline("Sheet1", &excelize.SparklineOption{
  366. // Location: []string{"A1", "A2", "A3"},
  367. // Range: []string{"Sheet2!A1:J1", "Sheet2!A2:J2", "Sheet2!A3:J3"},
  368. // Markers: true,
  369. // })
  370. //
  371. // The following shows the formatting options of sparkline supported by excelize:
  372. //
  373. // Parameter | Description
  374. // -----------+--------------------------------------------
  375. // Location | Required, must have the same number with 'Range' parameter
  376. // Range | Required, must have the same number with 'Location' parameter
  377. // Type | Enumeration value: line, column, win_loss
  378. // Style | Value range: 0 - 35
  379. // Hight | Toggle sparkline high points
  380. // Low | Toggle sparkline low points
  381. // First | Toggle sparkline first points
  382. // Last | Toggle sparkline last points
  383. // Negative | Toggle sparkline negative points
  384. // Markers | Toggle sparkline markers
  385. // ColorAxis | An RGB Color is specified as RRGGBB
  386. // Axis | Show sparkline axis
  387. //
  388. func (f *File) AddSparkline(sheet string, opt *SparklineOption) (err error) {
  389. var (
  390. ws *xlsxWorksheet
  391. sparkType string
  392. sparkTypes map[string]string
  393. specifiedSparkTypes string
  394. ok bool
  395. group *xlsxX14SparklineGroup
  396. groups *xlsxX14SparklineGroups
  397. sparklineGroupsBytes, extBytes []byte
  398. )
  399. // parameter validation
  400. if ws, err = f.parseFormatAddSparklineSet(sheet, opt); err != nil {
  401. return
  402. }
  403. // Handle the sparkline type
  404. sparkType = "line"
  405. sparkTypes = map[string]string{"line": "line", "column": "column", "win_loss": "stacked"}
  406. if opt.Type != "" {
  407. if specifiedSparkTypes, ok = sparkTypes[opt.Type]; !ok {
  408. err = errors.New("parameter 'Type' must be 'line', 'column' or 'win_loss'")
  409. return
  410. }
  411. sparkType = specifiedSparkTypes
  412. }
  413. group = f.addSparklineGroupByStyle(opt.Style)
  414. group.Type = sparkType
  415. group.ColorAxis = &xlsxColor{RGB: "FF000000"}
  416. group.DisplayEmptyCellsAs = "gap"
  417. group.High = opt.High
  418. group.Low = opt.Low
  419. group.First = opt.First
  420. group.Last = opt.Last
  421. group.Negative = opt.Negative
  422. group.DisplayXAxis = opt.Axis
  423. group.Markers = opt.Markers
  424. if opt.SeriesColor != "" {
  425. group.ColorSeries = &xlsxTabColor{
  426. RGB: getPaletteColor(opt.SeriesColor),
  427. }
  428. }
  429. if opt.Reverse {
  430. group.RightToLeft = opt.Reverse
  431. }
  432. f.addSparkline(opt, group)
  433. if ws.ExtLst.Ext != "" { // append mode ext
  434. if err = f.appendSparkline(ws, group, groups); err != nil {
  435. return
  436. }
  437. } else {
  438. groups = &xlsxX14SparklineGroups{
  439. XMLNSXM: NameSpaceSpreadSheetExcel2006Main.Value,
  440. SparklineGroups: []*xlsxX14SparklineGroup{group},
  441. }
  442. if sparklineGroupsBytes, err = xml.Marshal(groups); err != nil {
  443. return
  444. }
  445. if extBytes, err = xml.Marshal(&xlsxWorksheetExt{
  446. URI: ExtURISparklineGroups,
  447. Content: string(sparklineGroupsBytes),
  448. }); err != nil {
  449. return
  450. }
  451. ws.ExtLst.Ext = string(extBytes)
  452. }
  453. f.addSheetNameSpace(sheet, NameSpaceSpreadSheetX14)
  454. return
  455. }
  456. // parseFormatAddSparklineSet provides a function to validate sparkline
  457. // properties.
  458. func (f *File) parseFormatAddSparklineSet(sheet string, opt *SparklineOption) (*xlsxWorksheet, error) {
  459. ws, err := f.workSheetReader(sheet)
  460. if err != nil {
  461. return ws, err
  462. }
  463. if opt == nil {
  464. return ws, ErrParameterRequired
  465. }
  466. if len(opt.Location) < 1 {
  467. return ws, errors.New("parameter 'Location' is required")
  468. }
  469. if len(opt.Range) < 1 {
  470. return ws, errors.New("parameter 'Range' is required")
  471. }
  472. // The ranges and locations must match.\
  473. if len(opt.Location) != len(opt.Range) {
  474. return ws, errors.New(`must have the same number of 'Location' and 'Range' parameters`)
  475. }
  476. if opt.Style < 0 || opt.Style > 35 {
  477. return ws, errors.New("parameter 'Style' must betweent 0-35")
  478. }
  479. if ws.ExtLst == nil {
  480. ws.ExtLst = &xlsxExtLst{}
  481. }
  482. return ws, err
  483. }
  484. // addSparkline provides a function to create a sparkline in a sparkline group
  485. // by given properties.
  486. func (f *File) addSparkline(opt *SparklineOption, group *xlsxX14SparklineGroup) {
  487. for idx, location := range opt.Location {
  488. group.Sparklines.Sparkline = append(group.Sparklines.Sparkline, &xlsxX14Sparkline{
  489. F: opt.Range[idx],
  490. Sqref: location,
  491. })
  492. }
  493. }
  494. // appendSparkline provides a function to append sparkline to sparkline
  495. // groups.
  496. func (f *File) appendSparkline(ws *xlsxWorksheet, group *xlsxX14SparklineGroup, groups *xlsxX14SparklineGroups) (err error) {
  497. var (
  498. idx int
  499. decodeExtLst *decodeWorksheetExt
  500. decodeSparklineGroups *decodeX14SparklineGroups
  501. ext *xlsxWorksheetExt
  502. sparklineGroupsBytes, sparklineGroupBytes, extLstBytes []byte
  503. )
  504. decodeExtLst = new(decodeWorksheetExt)
  505. if err = f.xmlNewDecoder(strings.NewReader("<extLst>" + ws.ExtLst.Ext + "</extLst>")).
  506. Decode(decodeExtLst); err != nil && err != io.EOF {
  507. return
  508. }
  509. for idx, ext = range decodeExtLst.Ext {
  510. if ext.URI == ExtURISparklineGroups {
  511. decodeSparklineGroups = new(decodeX14SparklineGroups)
  512. if err = f.xmlNewDecoder(strings.NewReader(ext.Content)).
  513. Decode(decodeSparklineGroups); err != nil && err != io.EOF {
  514. return
  515. }
  516. if sparklineGroupBytes, err = xml.Marshal(group); err != nil {
  517. return
  518. }
  519. groups = &xlsxX14SparklineGroups{
  520. XMLNSXM: NameSpaceSpreadSheetExcel2006Main.Value,
  521. Content: decodeSparklineGroups.Content + string(sparklineGroupBytes),
  522. }
  523. if sparklineGroupsBytes, err = xml.Marshal(groups); err != nil {
  524. return
  525. }
  526. decodeExtLst.Ext[idx].Content = string(sparklineGroupsBytes)
  527. }
  528. }
  529. if extLstBytes, err = xml.Marshal(decodeExtLst); err != nil {
  530. return
  531. }
  532. ws.ExtLst = &xlsxExtLst{
  533. Ext: strings.TrimSuffix(strings.TrimPrefix(string(extLstBytes), "<extLst>"), "</extLst>"),
  534. }
  535. return
  536. }