CircleProgress.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. /*!
  2. * Circle Progress - v0.0.0 - 2019-07-13
  3. * https://tigrr.github.io/circle-progress
  4. * Copyright (c) Tigran Sargsyan
  5. * Licensed MIT
  6. */
  7. /**
  8. * 圆形进度条模块
  9. * date:2019-08-08 License By http://easyweb.vip
  10. */
  11. layui.define(function (exports) {
  12. "use strict";
  13. function _classCallCheck(a, b) {
  14. if (!(a instanceof b)) throw new TypeError("Cannot call a class as a function")
  15. }
  16. var _extends = Object.assign || function (a) {
  17. for (var b = 1; b < arguments.length; b++) {
  18. var c = arguments[b];
  19. for (var d in c) Object.prototype.hasOwnProperty.call(c, d) && (a[d] = c[d])
  20. }
  21. return a
  22. }, _createClass = function () {
  23. function a(a, b) {
  24. for (var c = 0; c < b.length; c++) {
  25. var d = b[c];
  26. d.enumerable = d.enumerable || !1, d.configurable = !0, "value" in d && (d.writable = !0), Object.defineProperty(a, d.key, d)
  27. }
  28. }
  29. return function (b, c, d) {
  30. return c && a(b.prototype, c), d && a(b, d), b
  31. }
  32. }(), _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (a) {
  33. return typeof a
  34. } : function (a) {
  35. return a && "function" == typeof Symbol && a.constructor === Symbol && a !== Symbol.prototype ? "symbol" : typeof a
  36. }, CircleProgress = function () {
  37. SVGElement.prototype.hasOwnProperty("innerHTML") || Object.defineProperty(SVGElement.prototype, "innerHTML", {
  38. get: function () {
  39. var a, b, c, d, e, f;
  40. for (c = document.createElement("div"), b = this.cloneNode(!0), f = b.childNodes, d = 0, e = f.length; e > d; d++) a = f[d], c.appendChild(a);
  41. return c.innerHTML
  42. }, set: function (a) {
  43. for (var b, c, d, e, f, g, h; this.firstChild;) this.firstChild.parentNode.removeChild(this.firstChild);
  44. for (a = "<svg id='wrapper' xmlns='http://www.w3.org/2000/svg'>" + a + "</svg>", b = document.createElement("div"), b.innerHTML = a, d = b.querySelector("svg#wrapper"), g = d.childNodes, h = [], e = 0, f = g.length; f > e; e++) c = g[e], h.push(this.appendChild(c));
  45. return h
  46. }, enumerable: !1, configurable: !0
  47. });
  48. var a = function () {
  49. var a, b, c, d;
  50. return a = function (a, c, d, e) {
  51. var f, g;
  52. return e = e || document, g = Object.create(b), "string" == typeof a && (a = e.querySelector(a)), a ? (f = e.createElementNS("http://www.w3.org/2000/svg", "svg"), f.setAttribute("version", "1.1"), c && f.setAttribute("width", c), d && f.setAttribute("height", d), c && d && f.setAttribute("viewBox", "0 0 " + c + " " + d), a.appendChild(f), g.svg = f, g) : void 0
  53. }, b = {
  54. element: function (a, b, d, e) {
  55. var f;
  56. return f = c(this, a, b, e), d && (f.el.innerHTML = d), f
  57. }, _shortcutElement: function (a, b) {
  58. var c, d, e = {};
  59. switch (a) {
  60. case"rect":
  61. c = ["x", "y", "width", "height", "r"];
  62. break;
  63. case"circle":
  64. c = ["cx", "cy", "r"];
  65. break;
  66. case"path":
  67. c = ["d"];
  68. break;
  69. case"text":
  70. c = ["x", "y"], d = b[3]
  71. }
  72. if (c.length !== b.length) throw new Error("Unexpected number of arguments to " + a + ". Expected " + c.length + " arguments, got " + b.length);
  73. return c.forEach(function (a) {
  74. e[a] = b[a]
  75. }), this.element.apply(this, [a, e, d])
  76. }, rect: function () {
  77. return this._shortcutElement("rect", arguments)
  78. }, circle: function () {
  79. return this._shortcutElement("circle", arguments)
  80. }, path: function () {
  81. return this._shortcutElement("path", arguments)
  82. }
  83. }, c = function (a, b, c, e, f) {
  84. var g;
  85. return f = f || document, g = Object.create(d), g.el = f.createElementNS("http://www.w3.org/2000/svg", b), g.attr(c), (e ? e.el || e : a.svg).appendChild(g.el), g
  86. }, d = {
  87. attr: function (a, b) {
  88. if (void 0 === a) return this;
  89. if ("object" === ("undefined" == typeof a ? "undefined" : _typeof(a))) {
  90. for (var c in a) this.attr(c, a[c]);
  91. return this
  92. }
  93. return void 0 === b ? this.el.getAttributeNS(null, a) : (this.el.setAttribute(a, b), this)
  94. }, content: function (a) {
  95. return this.el.innerHTML = a, this
  96. }
  97. }, a
  98. }();
  99. !function () {
  100. for (var a = 0, b = ["ms", "moz", "webkit", "o"], c = 0; c < b.length && !window.requestAnimationFrame; ++c) window.requestAnimationFrame = window[b[c] + "RequestAnimationFrame"], window.cancelAnimationFrame = window[b[c] + "CancelAnimationFrame"] || window[b[c] + "CancelRequestAnimationFrame"];
  101. window.requestAnimationFrame || (window.requestAnimationFrame = function (b, c) {
  102. var d = Date.now(), e = Math.max(0, 16 - (d - a)), f = window.setTimeout(function () {
  103. b(d + e)
  104. }, e);
  105. return a = d + e, f
  106. }), window.cancelAnimationFrame || (window.cancelAnimationFrame = function (a) {
  107. clearTimeout(a)
  108. })
  109. }();
  110. var b = function d(a, b, c, e, f) {
  111. var g = d.easings[a], h = window.performance.now ? window.performance.now() : Date.now(), i = function j() {
  112. var a = (window.performance.now ? window.performance.now() : Date.now()) - h, d = g(a, b, c, e);
  113. f(d), e > a ? requestAnimationFrame(j) : f(b + c)
  114. };
  115. requestAnimationFrame(i)
  116. };
  117. b.easings = {
  118. linear: function (a, b, c, d) {
  119. return c * a / d + b
  120. }, easeInCubic: function (a, b, c, d) {
  121. return a /= d, c * a * a * a + b
  122. }, easeOutCubic: function (a, b, c, d) {
  123. return a /= d, a--, c * (a * a * a + 1) + b
  124. }, easeInOutCubic: function (a, b, c, d) {
  125. return a /= d / 2, 1 > a ? c / 2 * a * a * a + b : (a -= 2, c / 2 * (a * a * a + 2) + b)
  126. }, easeInQuadr: function (a, b, c, d) {
  127. return a /= d, c * a * a * a * a + b
  128. }, easeOutQuadr: function (a, b, c, d) {
  129. return a /= d, a--, -c * (a * a * a * a - 1) + b
  130. }, easeInOutQuadr: function (a, b, c, d) {
  131. return a /= d / 2, 1 > a ? c / 2 * a * a * a * a + b : (a -= 2, -c / 2 * (a * a * a * a - 2) + b)
  132. }
  133. };
  134. var c = function () {
  135. var c = {
  136. math: {
  137. polarToCartesian: function (a, b) {
  138. return {x: a * Math.cos(b * Math.PI / 180), y: a * Math.sin(b * Math.PI / 180)}
  139. }
  140. }
  141. }, d = function () {
  142. function d(b) {
  143. var c = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {},
  144. e = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : document;
  145. _classCallCheck(this, d);
  146. var f = void 0;
  147. if ("string" == typeof b && (b = e.querySelector(b)), !b) throw new Error("CircleProgress: you must pass the container element as the first argument");
  148. return b.circleProgress ? b.circleProgress : (b.circleProgress = this, this.doc = e, b.setAttribute("role", "progressbar"), this.el = b, c = _extends({}, d.defaults, c), Object.defineProperty(this, "_attrs", {
  149. value: {},
  150. enumerable: !1
  151. }), f = "valueOnCircle" === c.textFormat ? 16 : 6, this.graph = {
  152. paper: a(b, 100, 100),
  153. angle: 0
  154. }, this.graph.circle = this.graph.paper.element("circle").attr({
  155. "class": "circle-progress-circle",
  156. cx: 50,
  157. cy: 50,
  158. r: 50 - f / 2,
  159. fill: "none",
  160. stroke: "#eaeef2",
  161. "stroke-width": f
  162. }), this.graph.sector = this.graph.paper.path(d._makeSectorPath(50, 50, 50 - f / 2, 0, 0)).attr({
  163. "class": "circle-progress-value",
  164. fill: "none",
  165. stroke: "#00CC00",
  166. "stroke-width": f,
  167. "stroke-linecap": "round"
  168. }), this.graph.text = this.graph.paper.element("text", {
  169. "class": "circle-progress-text",
  170. x: 50,
  171. y: 50,
  172. font: "22px Arial, sans-serif",
  173. "font-size": "22px",
  174. "text-anchor": "middle",
  175. fill: "#515a6e"
  176. }), this._initText(), void this.attr(["indeterminateText", "textFormat", "startAngle", "clockwise", "animation", "animationDuration", "constrain", "min", "max", "value"].filter(function (a) {
  177. return a in c
  178. }).map(function (a) {
  179. return [a, c[a]]
  180. })))
  181. }
  182. return _createClass(d, [{
  183. key: "value", get: function () {
  184. return this._attrs.value
  185. }, set: function (a) {
  186. this.attr("value", a)
  187. }
  188. }, {
  189. key: "min", get: function () {
  190. return this._attrs.min
  191. }, set: function (a) {
  192. this.attr("min", a)
  193. }
  194. }, {
  195. key: "max", get: function () {
  196. return this._attrs.max
  197. }, set: function (a) {
  198. this.attr("max", a)
  199. }
  200. }, {
  201. key: "startAngle", get: function () {
  202. return this._attrs.startAngle
  203. }, set: function (a) {
  204. this.attr("startAngle", a)
  205. }
  206. }, {
  207. key: "clockwise", get: function () {
  208. return this._attrs.clockwise
  209. }, set: function (a) {
  210. this.attr("clockwise", a)
  211. }
  212. }, {
  213. key: "constrain", get: function () {
  214. return this._attrs.constrain
  215. }, set: function (a) {
  216. this.attr("constrain", a)
  217. }
  218. }, {
  219. key: "indeterminateText", get: function () {
  220. return this._attrs.indeterminateText
  221. }, set: function (a) {
  222. this.attr("indeterminateText", a)
  223. }
  224. }, {
  225. key: "textFormat", get: function () {
  226. return this._attrs.textFormat
  227. }, set: function (a) {
  228. this.attr("textFormat", a)
  229. }
  230. }, {
  231. key: "animation", get: function () {
  232. return this._attrs.animation
  233. }, set: function (a) {
  234. this.attr("animation", a)
  235. }
  236. }, {
  237. key: "animationDuration", get: function () {
  238. return this._attrs.animationDuration
  239. }, set: function (a) {
  240. this.attr("animationDuration", a)
  241. }
  242. }]), _createClass(d, [{
  243. key: "attr", value: function (a) {
  244. var b = this;
  245. if ("string" == typeof a) return 1 === arguments.length ? this._attrs[a] : (this._set(arguments[0], arguments[1]), this._updateGraph(), this);
  246. if ("object" !== ("undefined" == typeof a ? "undefined" : _typeof(a))) throw new TypeError('Wrong argument passed to attr. Expected object, got "' + ("undefined" == typeof a ? "undefined" : _typeof(a)) + '"');
  247. return Array.isArray(a) || (a = Object.keys(a).map(function (b) {
  248. return [b, a[b]]
  249. })), a.forEach(function (a) {
  250. return b._set(a[0], a[1])
  251. }), this._updateGraph(), this
  252. }
  253. }, {
  254. key: "_set", value: function (a, b) {
  255. var c = {value: "aria-valuenow", min: "aria-valuemin", max: "aria-valuemax"}, d = void 0;
  256. if (b = this._formatValue(a, b), void 0 === b) throw new TypeError("Failed to set the " + a + " property on CircleProgress: The provided value is non-finite.");
  257. this._attrs[a] !== b && ("min" === a && b >= this.max || "max" === a && b <= this.min || ("value" === a && void 0 !== b && this.constrain && (null != this.min && b < this.min && (b = this.min), null != this.max && b > this.max && (b = this.max)), this._attrs[a] = b, a in c && (void 0 !== b ? this.el.setAttribute(c[a], b) : this.el.removeAttribute(c[a])), -1 !== ["min", "max", "constrain"].indexOf(a) && (this.value > this.max || this.value < this.min) && (this.value = Math.min(this.max, Math.max(this.min, this.value))), "textFormat" === a && (this._initText(), d = "valueOnCircle" === b ? 16 : 6, this.graph.sector.attr("stroke-width", d), this.graph.circle.attr("stroke-width", d))))
  258. }
  259. }, {
  260. key: "_formatValue", value: function (a, c) {
  261. switch (a) {
  262. case"value":
  263. case"min":
  264. case"max":
  265. c = parseFloat(c), isFinite(c) || (c = void 0);
  266. break;
  267. case"startAngle":
  268. c = parseFloat(c), c = isFinite(c) ? Math.max(0, Math.min(360, c)) : void 0;
  269. break;
  270. case"clockwise":
  271. case"constrain":
  272. c = !!c;
  273. break;
  274. case"indeterminateText":
  275. c = "" + c;
  276. break;
  277. case"textFormat":
  278. if ("function" != typeof c && -1 === ["valueOnCircle", "horizontal", "vertical", "percent", "value", "none"].indexOf(c)) throw new Error('Failed to set the "textFormat" property on CircleProgress: the provided value "' + c + '" is not a legal textFormat identifier.');
  279. break;
  280. case"animation":
  281. if ("string" != typeof c) throw new TypeError('Failed to set "animation" property on CircleProgress: the value must be string, ' + ("undefined" == typeof c ? "undefined" : _typeof(c)) + " passed.");
  282. if ("none" !== c && !b.easings[c]) throw new Error('Failed to set "animation" on CircleProgress: the provided value ' + c + " is not a legal easing function name.")
  283. }
  284. return c
  285. }
  286. }, {
  287. key: "_valToAngle", value: function () {
  288. var a;
  289. return this._isIndeterminate() ? 0 : 0 === this.max ? this.value ? 360 : 0 : (a = (this.value - this.min) / this.max * 360, a = Math.min(360, Math.max(0, a)))
  290. }
  291. }, {
  292. key: "_isIndeterminate", value: function () {
  293. return !("number" == typeof this.value && "number" == typeof this.max && "number" == typeof this.min)
  294. }
  295. }, {
  296. key: "_positionValueText", value: function (a) {
  297. var b = c.math.polarToCartesian(this._getRadius(), a);
  298. this.graph.textVal.attr({x: 50 + b.x, y: 50 + b.y - 4})
  299. }
  300. }, {
  301. key: "_initText", value: function () {
  302. switch (this.graph.text.content(""), this.textFormat) {
  303. case"valueOnCircle":
  304. this.graph.textVal = this.graph.paper.element("tspan", {
  305. x: 0,
  306. y: 0,
  307. "class": "circle-progress-text-value",
  308. "font-size": "12",
  309. fill: "valueOnCircle" === this.textFormat ? "#fff" : "#888"
  310. }, "", this.graph.text), this.graph.textMax = this.graph.paper.element("tspan", {
  311. x: 50,
  312. y: 50,
  313. "class": "circle-progress-text-max",
  314. "font-size": "22"
  315. }, "", this.graph.text), this.graph.text.el.hasAttribute("dominant-baseline") || this.graph.textMax.attr("dy", "0.4em");
  316. break;
  317. case"horizontal":
  318. this.graph.textVal = this.graph.paper.element("tspan", {
  319. "class": "circle-progress-text-value",
  320. "font-size": "20"
  321. }, "", this.graph.text), this.graph.textSeparator = this.graph.paper.element("tspan", {
  322. "class": "circle-progress-text-separator",
  323. "font-size": "20"
  324. }, "/", this.graph.text), this.graph.textMax = this.graph.paper.element("tspan", {
  325. "class": "circle-progress-text-max",
  326. "font-size": "20"
  327. }, "", this.graph.text);
  328. break;
  329. case"vertical":
  330. this.graph.text.el.hasAttribute("dominant-baseline") && this.graph.text.attr("dominant-baseline", "text-after-edge"), this.graph.textVal = this.graph.paper.element("tspan", {
  331. "class": "circle-progress-text-value",
  332. x: 50,
  333. dy: "-0.2em",
  334. "font-size": "20"
  335. }, "", this.graph.text), this.graph.textSeparator = this.graph.paper.element("tspan", {
  336. "class": "circle-progress-text-separator",
  337. x: 50,
  338. dy: "0.1em",
  339. "font-family": "Arial, sans-serif",
  340. "font-size": "20"
  341. }, "___", this.graph.text), this.graph.textMax = this.graph.paper.element("tspan", {
  342. "class": "circle-progress-text-max",
  343. x: 50,
  344. dy: "1.2em",
  345. "font-size": "20"
  346. }, "", this.graph.text)
  347. }
  348. "vertical" !== this.textFormat && (this.graph.text.el.hasAttribute("dominant-baseline") ? this.graph.text.attr("dominant-baseline", "central") : this.graph.text.attr("dy", "0.4em"))
  349. }
  350. }, {
  351. key: "_updateGraph", value: function () {
  352. var a = this, c = this.startAngle - 90, e = void 0, f = void 0, g = void 0;
  353. this._isIndeterminate() ? "valueOnCircle" === this.textFormat && this._positionValueText(c) : (e = this._valToAngle(this.value), f = this._getRadius(), g = this.clockwise, "none" !== this.animation && e !== this.graph.angle ? b(this.animation, this.graph.angle, e - this.graph.angle, this.animationDuration, function (b) {
  354. a.graph.sector.attr("d", d._makeSectorPath(50, 50, f, c, b, g)), a.graph.circle.attr("r", f)
  355. }) : (this.graph.sector.attr("d", d._makeSectorPath(50, 50, f, c, e, g)), this.graph.circle.attr("r", f)), this.graph.angle = e, "valueOnCircle" === this.textFormat && this._positionValueText((2 * c + e) / 2)), "function" == typeof this.textFormat ? this.graph.text.content(this.textFormat(this.value, this.max)) : "value" === this.textFormat ? this.graph.text.el.textContent = void 0 !== this.value ? this.value : this.indeterminateText : "percent" === this.textFormat ? this.graph.text.el.textContent = (void 0 !== this.value && null != this.max ? Math.round(this.value / this.max * 100) : this.indeterminateText) + "%" : "none" === this.textFormat ? this.graph.text.el.textContent = "" : (this.graph.textVal.el.textContent = void 0 !== this.value ? this.value : this.indeterminateText, this.graph.textMax.el.textContent = void 0 !== this.max ? this.max : this.indeterminateText)
  356. }
  357. }, {
  358. key: "_getRadius", value: function () {
  359. return 50 - Math.max(parseFloat(this.doc.defaultView.getComputedStyle(this.graph.circle.el, null)["stroke-width"]), parseFloat(this.doc.defaultView.getComputedStyle(this.graph.sector.el, null)["stroke-width"])) / 2
  360. }
  361. }], [{
  362. key: "_makeSectorPath", value: function (a, b, d, e, f, g) {
  363. g = !!g;
  364. var h = e + (360 === f ? f - .001 : f) * (2 * g - 1), i = c.math.polarToCartesian(d, e),
  365. j = c.math.polarToCartesian(d, h), k = a + i.x, l = a + j.x, m = b + i.y, n = b + j.y;
  366. return ["M", k, m, "A", d, d, 0, +(f > 180), +g, l, n].join(" ")
  367. }
  368. }]), d
  369. }();
  370. return d.defaults = {
  371. startAngle: 0,
  372. min: 0,
  373. max: 1,
  374. constrain: !0,
  375. indeterminateText: "?",
  376. clockwise: !0,
  377. textFormat: "horizontal",
  378. animation: "easeInOutCubic",
  379. animationDuration: 600
  380. }, d
  381. }();
  382. return c
  383. }();
  384. exports('CircleProgress', CircleProgress);
  385. });