sparkline.go 21 KB

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