Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VSparkline.js 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
  2. // Mixins
  3. import Colorable from '../../mixins/colorable';
  4. // Utilities
  5. import mixins from '../../util/mixins';
  6. import { genPoints } from './helpers/core';
  7. import { genPath as _genPath } from './helpers/path';
  8. export default mixins(Colorable).extend({
  9. name: 'VSparkline',
  10. props: {
  11. autoDraw: Boolean,
  12. autoDrawDuration: {
  13. type: Number,
  14. default: 2000
  15. },
  16. autoDrawEasing: {
  17. type: String,
  18. default: 'ease'
  19. },
  20. autoLineWidth: {
  21. type: Boolean,
  22. default: false
  23. },
  24. color: {
  25. type: String,
  26. default: 'primary'
  27. },
  28. fill: {
  29. type: Boolean,
  30. default: false
  31. },
  32. gradient: {
  33. type: Array,
  34. default: function _default() {
  35. return [];
  36. }
  37. },
  38. gradientDirection: {
  39. type: String,
  40. validator: function validator(val) {
  41. return ['top', 'bottom', 'left', 'right'].includes(val);
  42. },
  43. default: 'top'
  44. },
  45. height: {
  46. type: [String, Number],
  47. default: 75
  48. },
  49. labels: {
  50. type: Array,
  51. default: function _default() {
  52. return [];
  53. }
  54. },
  55. lineWidth: {
  56. type: [String, Number],
  57. default: 4
  58. },
  59. padding: {
  60. type: [String, Number],
  61. default: 8
  62. },
  63. smooth: {
  64. type: [Boolean, Number, String],
  65. default: false
  66. },
  67. showLabels: Boolean,
  68. type: {
  69. type: String,
  70. default: 'trend',
  71. validator: function validator(val) {
  72. return ['trend', 'bar'].includes(val);
  73. }
  74. },
  75. value: {
  76. type: Array,
  77. default: function _default() {
  78. return [];
  79. }
  80. },
  81. width: {
  82. type: [Number, String],
  83. default: 300
  84. },
  85. labelSize: {
  86. type: [Number, String],
  87. default: 7
  88. }
  89. },
  90. data: function data() {
  91. return {
  92. lastLength: 0
  93. };
  94. },
  95. computed: {
  96. parsedPadding: function parsedPadding() {
  97. return Number(this.padding);
  98. },
  99. parsedWidth: function parsedWidth() {
  100. return Number(this.width);
  101. },
  102. totalBars: function totalBars() {
  103. return this.value.length;
  104. },
  105. _lineWidth: function _lineWidth() {
  106. if (this.autoLineWidth && this.type !== 'trend') {
  107. var totalPadding = this.parsedPadding * (this.totalBars + 1);
  108. return (this.parsedWidth - totalPadding) / this.totalBars;
  109. } else {
  110. return Number(this.lineWidth) || 4;
  111. }
  112. },
  113. boundary: function boundary() {
  114. var height = Number(this.height);
  115. return {
  116. minX: this.parsedPadding,
  117. minY: this.parsedPadding,
  118. maxX: this.parsedWidth - this.parsedPadding,
  119. maxY: height - this.parsedPadding
  120. };
  121. },
  122. hasLabels: function hasLabels() {
  123. return Boolean(this.showLabels || this.labels.length > 0 || this.$scopedSlots.label);
  124. },
  125. parsedLabels: function parsedLabels() {
  126. var labels = [];
  127. var points = this.points;
  128. var len = points.length;
  129. for (var i = 0; labels.length < len; i++) {
  130. var item = points[i];
  131. var value = this.labels[i];
  132. if (!value) {
  133. value = item === Object(item) ? item.value : item;
  134. }
  135. labels.push(_extends({}, item, {
  136. value: String(value)
  137. }));
  138. }
  139. return labels;
  140. },
  141. points: function points() {
  142. return genPoints(this.value.slice(), this.boundary, this.type);
  143. },
  144. textY: function textY() {
  145. return this.boundary.maxY + 6;
  146. }
  147. },
  148. watch: {
  149. value: {
  150. immediate: true,
  151. handler: function handler() {
  152. var _this = this;
  153. this.$nextTick(function () {
  154. if (!_this.autoDraw || _this.type === 'bar') return;
  155. var path = _this.$refs.path;
  156. var length = path.getTotalLength();
  157. if (!_this.fill) {
  158. path.style.transition = 'none';
  159. path.style.strokeDasharray = length + ' ' + length;
  160. path.style.strokeDashoffset = Math.abs(length - (_this.lastLength || 0)).toString();
  161. path.getBoundingClientRect();
  162. path.style.transition = 'stroke-dashoffset ' + _this.autoDrawDuration + 'ms ' + _this.autoDrawEasing;
  163. path.style.strokeDashoffset = '0';
  164. } else {
  165. path.style.transformOrigin = 'bottom center';
  166. path.style.transition = 'none';
  167. path.style.transform = 'scaleY(0)';
  168. path.getBoundingClientRect();
  169. path.style.transition = 'transform ' + _this.autoDrawDuration + 'ms ' + _this.autoDrawEasing;
  170. path.style.transform = 'scaleY(1)';
  171. }
  172. _this.lastLength = length;
  173. });
  174. }
  175. }
  176. },
  177. methods: {
  178. genGradient: function genGradient() {
  179. var _this2 = this;
  180. var gradientDirection = this.gradientDirection;
  181. var gradient = this.gradient.slice();
  182. // Pushes empty string to force
  183. // a fallback to currentColor
  184. if (!gradient.length) gradient.push('');
  185. var len = Math.max(gradient.length - 1, 1);
  186. var stops = gradient.reverse().map(function (color, index) {
  187. return _this2.$createElement('stop', {
  188. attrs: {
  189. offset: index / len,
  190. 'stop-color': color || _this2.color || 'currentColor'
  191. }
  192. });
  193. });
  194. return this.$createElement('defs', [this.$createElement('linearGradient', {
  195. attrs: {
  196. id: this._uid,
  197. x1: +(gradientDirection === 'left'),
  198. y1: +(gradientDirection === 'top'),
  199. x2: +(gradientDirection === 'right'),
  200. y2: +(gradientDirection === 'bottom')
  201. }
  202. }, stops)]);
  203. },
  204. genG: function genG(children) {
  205. return this.$createElement('g', {
  206. style: {
  207. fontSize: '8',
  208. textAnchor: 'middle',
  209. dominantBaseline: 'mathematical',
  210. fill: this.color || 'currentColor'
  211. }
  212. }, children);
  213. },
  214. genLabels: function genLabels() {
  215. if (!this.hasLabels) return undefined;
  216. return this.genG(this.parsedLabels.map(this.genText));
  217. },
  218. genPath: function genPath() {
  219. var radius = this.smooth === true ? 8 : Number(this.smooth);
  220. return this.$createElement('path', {
  221. attrs: {
  222. id: this._uid,
  223. d: _genPath(this.points.slice(), radius, this.fill, Number(this.height)),
  224. fill: this.fill ? 'url(#' + this._uid + ')' : 'none',
  225. stroke: this.fill ? 'none' : 'url(#' + this._uid + ')'
  226. },
  227. ref: 'path'
  228. });
  229. },
  230. genText: function genText(item, index) {
  231. var children = this.$scopedSlots.label ? this.$scopedSlots.label({ index: index, value: item.value }) : item.value;
  232. return this.$createElement('text', {
  233. attrs: {
  234. x: item.x,
  235. y: this.textY
  236. }
  237. }, [children]);
  238. },
  239. genBar: function genBar() {
  240. if (!this.value || this.totalBars < 2) return undefined;
  241. var width = this.width,
  242. height = this.height,
  243. parsedPadding = this.parsedPadding,
  244. _lineWidth = this._lineWidth;
  245. var viewWidth = width || this.totalBars * parsedPadding * 2;
  246. var viewHeight = height || 75;
  247. var boundary = {
  248. minX: parsedPadding,
  249. minY: parsedPadding,
  250. maxX: Number(viewWidth) - parsedPadding,
  251. maxY: Number(viewHeight) - parsedPadding
  252. };
  253. var props = _extends({}, this.$props);
  254. props.points = genPoints(this.value, boundary, this.type);
  255. var totalWidth = boundary.maxX / (props.points.length - 1);
  256. props.boundary = boundary;
  257. props.lineWidth = _lineWidth || totalWidth - Number(parsedPadding || 5);
  258. props.offsetX = 0;
  259. if (!this.autoLineWidth) {
  260. props.offsetX = boundary.maxX / this.totalBars / 2 - boundary.minX;
  261. }
  262. return this.$createElement('svg', {
  263. attrs: {
  264. width: '100%',
  265. height: '25%',
  266. viewBox: '0 0 ' + viewWidth + ' ' + viewHeight
  267. }
  268. }, [this.genGradient(), this.genClipPath(props.offsetX, props.lineWidth, 'sparkline-bar-' + this._uid), this.hasLabels ? this.genBarLabels(props) : undefined, this.$createElement('g', {
  269. attrs: {
  270. transform: 'scale(1,-1) translate(0,-' + boundary.maxY + ')',
  271. 'clip-path': 'url(#sparkline-bar-' + this._uid + '-clip)',
  272. fill: 'url(#' + this._uid + ')'
  273. }
  274. }, [this.$createElement('rect', {
  275. attrs: {
  276. x: 0,
  277. y: 0,
  278. width: viewWidth,
  279. height: viewHeight
  280. }
  281. })])]);
  282. },
  283. genClipPath: function genClipPath(offsetX, lineWidth, id) {
  284. var _this3 = this;
  285. var maxY = this.boundary.maxY;
  286. var rounding = typeof this.smooth === 'number' ? this.smooth : this.smooth ? 2 : 0;
  287. return this.$createElement('clipPath', {
  288. attrs: {
  289. id: id + '-clip'
  290. }
  291. }, this.points.map(function (item) {
  292. return _this3.$createElement('rect', {
  293. attrs: {
  294. x: item.x + offsetX,
  295. y: 0,
  296. width: lineWidth,
  297. height: Math.max(maxY - item.y, 0),
  298. rx: rounding,
  299. ry: rounding
  300. }
  301. }, [_this3.autoDraw ? _this3.$createElement('animate', {
  302. attrs: {
  303. attributeName: 'height',
  304. from: 0,
  305. to: maxY - item.y,
  306. dur: _this3.autoDrawDuration + 'ms',
  307. fill: 'freeze'
  308. }
  309. }) : undefined]);
  310. }));
  311. },
  312. genBarLabels: function genBarLabels(props) {
  313. var _this4 = this;
  314. var offsetX = props.offsetX || 0;
  315. var children = props.points.map(function (item) {
  316. return _this4.$createElement('text', {
  317. attrs: {
  318. x: item.x + offsetX + _this4._lineWidth / 2,
  319. y: props.boundary.maxY + (Number(_this4.labelSize) || 7),
  320. 'font-size': Number(_this4.labelSize) || 7
  321. }
  322. }, item.value.toString());
  323. });
  324. return this.genG(children);
  325. },
  326. genTrend: function genTrend() {
  327. return this.$createElement('svg', this.setTextColor(this.color, {
  328. attrs: {
  329. 'stroke-width': this._lineWidth || 1,
  330. width: '100%',
  331. height: '25%',
  332. viewBox: '0 0 ' + this.width + ' ' + this.height
  333. }
  334. }), [this.genGradient(), this.genLabels(), this.genPath()]);
  335. }
  336. },
  337. render: function render(h) {
  338. if (this.totalBars < 2) return undefined;
  339. return this.type === 'trend' ? this.genTrend() : this.genBar();
  340. }
  341. });
  342. //# sourceMappingURL=VSparkline.js.map