sparkline.go 23 KB

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