sparkline.go 23 KB

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