UNPKG

vislite

Version:

灵活、快速、简单的数据可视化交互式跨端前端库

677 lines (659 loc) 24.4 kB
/****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; var XLINK_ATTRIBUTE = ["href", "title", "show", "type", "role", "actuate"]; var setLineAttr = function (el, config) { setAttribute(el, "stroke-dasharray", config.lineDash.join(',')); setAttribute(el, "stroke-width", config.lineWidth + ""); setAttribute(el, "stroke-linecap", config.lineCap + ""); setAttribute(el, "stroke-linejoin", config.lineJoin + ""); }; function toNode(tagname) { return document.createElementNS('http://www.w3.org/2000/svg', tagname); } var _setAttribute = function (el, key, value) { if (XLINK_ATTRIBUTE.indexOf(key) > -1) { el.setAttributeNS("http://www.w3.org/1999/xlink", 'xlink:' + key, value + ""); } else { el.setAttribute(key, value + ""); } }; var setAttribute = _setAttribute; function getAttribute(el, key) { if (XLINK_ATTRIBUTE.indexOf(key) > -1) key = 'xlink:' + key; return el.getAttribute(key); } function full(el, config) { setLineAttr(el, config); _setAttribute(el, "stroke", config.strokeStyle); _setAttribute(el, "fill", config.fillStyle); } function fill(el, config) { _setAttribute(el, "fill", config.fillStyle); } function stroke(el, config) { setLineAttr(el, config); _setAttribute(el, "stroke", config.strokeStyle); _setAttribute(el, "fill", "none"); } function setStyle (el, styles) { for (var key in styles) { el.style[key] = styles[key]; } } var rotate$1 = function (cx, cy, deg, x, y) { var cos = Math.cos(deg), sin = Math.sin(deg); return [ +((x - cx) * cos - (y - cy) * sin + cx).toFixed(7), +((x - cx) * sin + (y - cy) * cos + cy).toFixed(7) ]; }; function arc (beginA, rotateA, cx, cy, r1, r2, doback) { if (rotateA < 0) { beginA += rotateA; rotateA *= -1; } var temp = []; var p; p = rotate$1(0, 0, beginA, r1, 0); temp[0] = p[0]; temp[1] = p[1]; p = rotate$1(0, 0, rotateA, p[0], p[1]); temp[2] = p[0]; temp[3] = p[1]; p = rotate$1(0, 0, beginA, r2, 0); temp[4] = p[0]; temp[5] = p[1]; p = rotate$1(0, 0, rotateA, p[0], p[1]); temp[6] = p[0]; temp[7] = p[1]; doback(beginA, beginA + rotateA, temp[0] + cx, temp[1] + cy, temp[4] + cx, temp[5] + cy, temp[2] + cx, temp[3] + cy, temp[6] + cx, temp[7] + cy, (r2 - r1) * 0.5); } var initDefs = function (el) { var defs = el.getElementsByTagName('defs'); if (defs.length <= 0) { var newDefs = toNode("defs"); el.appendChild(newDefs); return newDefs; } else { return defs[0]; } }; var initText = function (el, config, x, y, deg) { if (el.nodeName.toLowerCase() !== "text") throw new Error("Need a <text> !"); setAttribute(el, "dy", { top: config["fontSize"] * 0.5, middle: 0, bottom: -config["fontSize"] * 0.5, }[config.textBaseline]); setStyle(el, { "text-anchor": { left: "start", right: "end", center: "middle", }[config.textAlign], "dominant-baseline": "central", "font-size": config["fontSize"] + "px", "font-family": config["fontFamily"], }); setAttribute(el, "x", x); setAttribute(el, "y", y); if (typeof deg == "number") { deg = deg % 360; setAttribute(el, "transform", "rotate(" + deg + "," + x + "," + y + ")"); } }; var initCircle = function (el, cx, cy, r) { if (el.nodeName.toLowerCase() !== "circle") throw new Error("Need a <circle> !"); setAttribute(el, "cx", cx); setAttribute(el, "cy", cy); setAttribute(el, "r", r); }; var initPath = function (el, path) { if (el.nodeName.toLowerCase() !== "path") throw new Error("Need a <path> !"); setAttribute(el, "d", path); }; var initRect = function (el, config, x, y, width, height) { if (el.nodeName.toLowerCase() !== "path") throw new Error("Need a <path> !"); var rectRadius = []; if (Array.isArray(config.rectRadius) && config.rectRadius.length > 0) { for (var index = 0; index < 4; index++) { rectRadius.push.apply(rectRadius, config.rectRadius); } } if (height < 0) { height *= -1; y -= height; } if (width < 0) { width *= -1; x -= width; } var d = ""; if (rectRadius.length >= 4) { d = "M" + (x + rectRadius[0]) + " " + y; d += "L" + (x + width - rectRadius[1]) + " " + y; d += "A" + rectRadius[1] + " " + rectRadius[1] + " 0 0 1 " + (x + width) + " " + (y + rectRadius[1]); d += "L" + (x + width) + " " + (y + height - rectRadius[2]); d += "A" + rectRadius[2] + " " + rectRadius[2] + " 0 0 1 " + (x + width - rectRadius[2]) + " " + (y + height); d += "L" + (x + rectRadius[3]) + " " + (y + height); d += "A" + rectRadius[3] + " " + rectRadius[3] + " 0 0 1 " + x + " " + (y + height - rectRadius[3]); d += "L" + x + " " + (y + rectRadius[0]); d += "A" + rectRadius[0] + " " + rectRadius[0] + " 0 0 1 " + (x + rectRadius[0]) + " " + y; } else { d = "M" + x + " " + y; d += "L" + (x + width) + " " + y; d += "L" + (x + width) + " " + (y + height); d += "L" + x + " " + (y + height); d += "Z"; } setAttribute(el, "d", d); }; var initArc = function (el, config, cx, cy, r1, r2, beginDeg, deg) { if (el.nodeName.toLowerCase() !== "path") throw new Error("Need a <path> !"); beginDeg = (beginDeg / 180) * Math.PI; deg = (deg / 180) * Math.PI; beginDeg = beginDeg % (Math.PI * 2); if (r1 > r2) { var temp = r1; r1 = r2; r2 = temp; } if (deg >= Math.PI * 1.999999 || deg <= -Math.PI * 1.999999) { deg = Math.PI * 1.999999; } else { deg = deg % (Math.PI * 2); } arc(beginDeg, deg, cx, cy, r1, r2, function (beginA, endA, begInnerX, begInnerY, begOuterX, begOuterY, endInnerX, endInnerY, endOuterX, endOuterY, r) { var f = endA - beginA > Math.PI ? 1 : 0; var d = "M" + begInnerX + " " + begInnerY; if (r < 0) r = -r; d += "A" + r1 + " " + r1 + " 0 " + f + " 1 " + endInnerX + " " + endInnerY; if (config.arcEndCap == "round") d += "A" + r + " " + r + " " + " 0 1 0 " + endOuterX + " " + endOuterY; else if (config.arcEndCap == "-round") d += "A" + r + " " + r + " " + " 0 1 1 " + endOuterX + " " + endOuterY; else d += "L" + endOuterX + " " + endOuterY; d += "A" + r2 + " " + r2 + " 0 " + f + " 0 " + begOuterX + " " + begOuterY; if (config.arcStartCap == "round") d += "A" + r + " " + r + " " + " 0 1 0 " + begInnerX + " " + begInnerY; else if (config.arcStartCap == "-round") d += "A" + r + " " + r + " " + " 0 1 1 " + begInnerX + " " + begInnerY; else d += "L" + begInnerX + " " + begInnerY; if (config.arcStartCap == "butt") d += "Z"; setAttribute(el, "d", d); }); }; function rotate (cx, cy, deg, x, y) { var cos = Math.cos(deg), sin = Math.sin(deg); return [ (x - cx) * cos - (y - cy) * sin + cx, (x - cx) * sin + (y - cy) * cos + cy ]; } var enhanceGradient = function (gradient, gradientId) { var enhanceGradient = { "value": function () { return "url(#" + gradientId + ")"; }, "setColor": function (stop, color) { var stopEl = toNode("stop"); gradient.appendChild(stopEl); setAttribute(stopEl, "offset", (stop * 100) + "%"); setAttribute(stopEl, "style", "stop-color:" + color + ";"); return enhanceGradient; } }; return enhanceGradient; }; var linearGradient = function (el, x0, y0, x1, y1) { var defs = initDefs(el); var gradientId = "visliteLg" + new Date().valueOf() + "" + (Math.random() * 1000000).toFixed(0); var linearGradient = toNode("linearGradient"); defs.appendChild(linearGradient); setAttribute(linearGradient, "id", gradientId); setAttribute(linearGradient, "x1", x0 + "%"); setAttribute(linearGradient, "y1", y0 + "%"); setAttribute(linearGradient, "x2", x1 + "%"); setAttribute(linearGradient, "y2", y1 + "%"); return enhanceGradient(linearGradient, gradientId); }; var radialGradient = function (el, cx, cy, r) { var defs = initDefs(el); var gradientId = "visliteRg" + new Date().valueOf() + "" + (Math.random() * 1000000).toFixed(0); var radialGradient = toNode("radialGradient"); defs.appendChild(radialGradient); setAttribute(radialGradient, "id", gradientId); setAttribute(radialGradient, "cx", cx + "%"); setAttribute(radialGradient, "cy", cy + "%"); setAttribute(radialGradient, "r", r + "%"); return enhanceGradient(radialGradient, gradientId); }; function defaultFactory () { return { fillStyle: "rgb(0,0,0)", strokeStyle: "rgb(0,0,0)", textAlign: "left", textBaseline: "middle", "fontSize": 16, "fontFamily": "sans-serif", "arcStartCap": "butt", "arcEndCap": "butt", lineDash: [], lineWidth: 1, lineCap: "butt", lineJoin: "miter", "rectRadius": [] }; } function initOption(setOption, defaultOption) { for (var key in setOption) { defaultOption[key] = setOption[key]; } return defaultOption; } var SVG$1 = (function () { function SVG(svg) { this.name = "SVG"; this.__config = defaultFactory(); this.__path = ""; this.__currentPosition = []; this.__transform_history = []; this.__transform_current = ""; this.__svg = svg; } SVG.prototype.config = function (params) { if (typeof params !== "object") { return this.__config[params]; } else { for (var key in params) { this.__config[key] = params[key]; } } return this; }; SVG.prototype.reset = function (config) { if (config === void 0) { config = {}; } this.config(initOption(config, defaultFactory())); return this; }; SVG.prototype.useEl = function (el) { this.__useEl = el; return this; }; SVG.prototype.getEl = function () { return this.__useEl; }; SVG.prototype.appendEl = function (el, context) { context = context || this.__svg; if (typeof el == "string") el = toNode(el); context.appendChild(el); this.__useEl = el; return this; }; SVG.prototype.appendBoard = function (el, context) { var _el = el; if (typeof el == "string") _el = { text: "text", path: "path", arc: "path", circle: "circle", rect: "path", }[el] || ""; if (_el == "") throw new Error("Unsupported drawing method:" + el); return this.appendEl(_el, context); }; SVG.prototype.remove = function () { if (!this.__useEl) { throw new Error("Currently, no node can be deleted."); } else { this.__useEl.parentNode.removeChild(this.__useEl); } return this; }; SVG.prototype.attr = function (params) { if (!this.__useEl) throw new Error("Currently, no node can be modified or viewed."); if (typeof params !== "object") { return getAttribute(this.__useEl, params); } else { for (var key in params) { setAttribute(this.__useEl, key, params[key]); } return this; } }; SVG.prototype.fillText = function (text, x, y, deg) { if (deg === void 0) { deg = 0; } initText(this.__useEl, this.__config, x, y, deg); this.attr({ transform: this.__transform_current }); this.__useEl.textContent = text; fill(this.__useEl, this.__config); return this; }; SVG.prototype.strokeText = function (text, x, y, deg) { if (deg === void 0) { deg = 0; } initText(this.__useEl, this.__config, x, y, deg); this.attr({ transform: this.__transform_current }); this.__useEl.textContent = text; stroke(this.__useEl, this.__config); return this; }; SVG.prototype.fullText = function (text, x, y, deg) { if (deg === void 0) { deg = 0; } initText(this.__useEl, this.__config, x, y, deg); this.attr({ transform: this.__transform_current }); this.__useEl.textContent = text; full(this.__useEl, this.__config); return this; }; SVG.prototype.fillArc = function (cx, cy, r1, r2, beginDeg, deg) { initArc(this.__useEl, this.__config, cx, cy, r1, r2, beginDeg, deg); this.attr({ transform: this.__transform_current }); fill(this.__useEl, this.__config); return this; }; SVG.prototype.strokeArc = function (cx, cy, r1, r2, beginDeg, deg) { initArc(this.__useEl, this.__config, cx, cy, r1, r2, beginDeg, deg); this.attr({ transform: this.__transform_current }); stroke(this.__useEl, this.__config); return this; }; SVG.prototype.fullArc = function (cx, cy, r1, r2, beginDeg, deg) { initArc(this.__useEl, this.__config, cx, cy, r1, r2, beginDeg, deg); this.attr({ transform: this.__transform_current }); full(this.__useEl, this.__config); return this; }; SVG.prototype.fillCircle = function (cx, cy, r) { initCircle(this.__useEl, cx, cy, r); this.attr({ transform: this.__transform_current }); fill(this.__useEl, this.__config); return this; }; SVG.prototype.strokeCircle = function (cx, cy, r) { initCircle(this.__useEl, cx, cy, r); this.attr({ transform: this.__transform_current }); stroke(this.__useEl, this.__config); return this; }; SVG.prototype.fullCircle = function (cx, cy, r) { initCircle(this.__useEl, cx, cy, r); this.attr({ transform: this.__transform_current }); full(this.__useEl, this.__config); return this; }; SVG.prototype.fillRect = function (x, y, width, height) { initRect(this.__useEl, this.__config, x, y, width, height); this.attr({ transform: this.__transform_current }); fill(this.__useEl, this.__config); return this; }; SVG.prototype.strokeRect = function (x, y, width, height) { initRect(this.__useEl, this.__config, x, y, width, height); this.attr({ transform: this.__transform_current }); stroke(this.__useEl, this.__config); return this; }; SVG.prototype.fullRect = function (x, y, width, height) { initRect(this.__useEl, this.__config, x, y, width, height); this.attr({ transform: this.__transform_current }); full(this.__useEl, this.__config); return this; }; SVG.prototype.beginPath = function () { this.__currentPosition = []; this.__path = ""; return this; }; SVG.prototype.closePath = function () { this.__path += "Z"; return this; }; SVG.prototype.moveTo = function (x, y) { this.__currentPosition = [x, y]; this.__path += "M" + x + " " + y; return this; }; SVG.prototype.lineTo = function (x, y) { this.__currentPosition = [x, y]; this.__path += (this.__path == "" ? "M" : "L") + x + " " + y; return this; }; SVG.prototype.fill = function () { initPath(this.__useEl, this.__path); this.attr({ transform: this.__transform_current }); fill(this.__useEl, this.__config); return this; }; SVG.prototype.stroke = function () { initPath(this.__useEl, this.__path); this.attr({ transform: this.__transform_current }); stroke(this.__useEl, this.__config); return this; }; SVG.prototype.full = function () { initPath(this.__useEl, this.__path); this.attr({ transform: this.__transform_current }); full(this.__useEl, this.__config); return this; }; SVG.prototype.save = function () { this.__transform_history.push(this.__transform_current); return this; }; SVG.prototype.restore = function () { if (this.__transform_history.length > 0) this.__transform_current = this.__transform_history.pop(); return this; }; SVG.prototype.arc = function (x, y, r, beginDeg, deg) { var begPosition = rotate(x, y, (beginDeg / 180) * Math.PI, x + r, y); var endPosition = rotate(x, y, ((beginDeg + deg) / 180) * Math.PI, x + r, y); if (this.__path == "") { this.__path += "M" + begPosition[0] + "," + begPosition[1]; } else if (begPosition[0] != this.__currentPosition[0] || begPosition[1] != this.__currentPosition[1]) { this.__path += "L" + begPosition[0] + "," + begPosition[1]; } this.__path += "A" + r + "," + r + " 0 " + (deg > 180 || deg < -180 ? 1 : 0) + "," + (deg > 0 ? 1 : 0) + " " + endPosition[0] + "," + endPosition[1]; return this; }; SVG.prototype.quadraticCurveTo = function (cpx, cpy, x, y) { this.__path += "Q" + cpx + " " + cpy + "," + x + " " + y; return this; }; SVG.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) { this.__path += "C" + cp1x + " " + cp1y + "," + cp2x + " " + cp2y + "," + x + " " + y; return this; }; SVG.prototype.bind = function (eventType, callback) { this.__useEl.addEventListener(eventType, function (event) { callback.call(this, event, this); }, false); return this; }; SVG.prototype.createLinearGradient = function (x0, y0, x1, y1) { return linearGradient(this.__svg, x0, y0, x1, y1); }; SVG.prototype.createRadialGradient = function (cx, cy, r) { return radialGradient(this.__svg, cx, cy, r); }; SVG.prototype.translate = function (dx, dy) { this.__transform_current += ' translate(' + dx + ',' + dy + ')'; return this; }; SVG.prototype.rotate = function (deg) { this.__transform_current += ' rotate(' + deg + ')'; return this; }; SVG.prototype.install = function (methods) { var _this = this; var _loop_1 = function (key) { if (key in this_1) { throw new Error("VISLite SVG:Method already exists and cannot be overwritten."); } else { this_1[key] = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var value = methods[key].apply(_this, args); if (value != void 0) return value; return _this; }; } }; var this_1 = this; for (var key in methods) { _loop_1(key); } return this; }; return SVG; }()); var SVG = (function (_super) { __extends(SVG, _super); function SVG(el) { var _this = this; if (!el) { throw new Error("VISLite SVG:The mount point requires an HTMLElement type but encountered null."); } var width = el.clientWidth, height = el.clientHeight; var ViewSVG; var _el = el; if (_el._vislite_svg_) { ViewSVG = _el._vislite_svg_[0]; } else { ViewSVG = document.createElementNS("http://www.w3.org/2000/svg", 'svg'); el.appendChild(ViewSVG); ViewSVG.setAttribute("width", width + ""); ViewSVG.setAttribute("height", height + ""); ViewSVG.setAttribute("viewBox", "0 0 " + width + " " + height); _el._vislite_svg_ = [ViewSVG]; el.setAttribute('vislite', 'SVG'); } _this = _super.call(this, ViewSVG) || this; _this.__el = el; return _this; } SVG.prototype.toDataURL = function () { var _this = this; return new Promise(function (resolve) { var width = _this.__el.clientWidth, height = _this.__el.clientHeight; var img = document.createElement('img'); img.setAttribute('width', width + ""); img.setAttribute('height', height + ""); var base64_svg = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='" + width + "' height='" + height + "'>" + _this.__svg.innerHTML.replace(/"/g, "'") + "</svg>"; img.setAttribute('src', base64_svg); setTimeout(function () { var canvas = document.createElement('canvas'); canvas.setAttribute('width', width + ""); canvas.setAttribute('height', height + ""); var painter = canvas.getContext('2d'); if (painter) painter.drawImage(img, 0, 0, width, height); resolve(canvas.toDataURL()); }, 100); }); }; return SVG; }(SVG$1)); export { SVG as default };