"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _color = _interopRequireDefault(require("@jiaminghi/color")); var _bezierCurve = _interopRequireDefault(require("@jiaminghi/bezier-curve")); var _util = require("../plugin/util"); var _graphs = _interopRequireDefault(require("../config/graphs")); var _graph = _interopRequireDefault(require("./graph.class")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * @description Class of CRender * @param {Object} canvas Canvas DOM * @return {CRender} Instance of CRender */ var CRender = function CRender(canvas) { (0, _classCallCheck2["default"])(this, CRender); if (!canvas) { console.error('CRender Missing parameters!'); return; } var ctx = canvas.getContext('2d'); var clientWidth = canvas.clientWidth, clientHeight = canvas.clientHeight; var area = [clientWidth, clientHeight]; canvas.setAttribute('width', clientWidth); canvas.setAttribute('height', clientHeight); /** * @description Context of the canvas * @type {Object} * @example ctx = canvas.getContext('2d') */ this.ctx = ctx; /** * @description Width and height of the canvas * @type {Array} * @example area = [300,100] */ this.area = area; /** * @description Whether render is in animation rendering * @type {Boolean} * @example animationStatus = true|false */ this.animationStatus = false; /** * @description Added graph * @type {[Graph]} * @example graphs = [Graph, Graph, ...] */ this.graphs = []; /** * @description Color plugin * @type {Object} * @link https://github.com/jiaming743/color */ this.color = _color["default"]; /** * @description Bezier Curve plugin * @type {Object} * @link https://github.com/jiaming743/BezierCurve */ this.bezierCurve = _bezierCurve["default"]; // bind event handler canvas.addEventListener('mousedown', mouseDown.bind(this)); canvas.addEventListener('mousemove', mouseMove.bind(this)); canvas.addEventListener('mouseup', mouseUp.bind(this)); }; /** * @description Clear canvas drawing area * @return {Undefined} Void */ exports["default"] = CRender; CRender.prototype.clearArea = function () { var _this$ctx; var area = this.area; (_this$ctx = this.ctx).clearRect.apply(_this$ctx, [0, 0].concat((0, _toConsumableArray2["default"])(area))); }; /** * @description Add graph to render * @param {Object} config Graph configuration * @return {Graph} Graph instance */ CRender.prototype.add = function () { var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var name = config.name; if (!name) { console.error('add Missing parameters!'); return; } var graphConfig = _graphs["default"].get(name); if (!graphConfig) { console.warn('No corresponding graph configuration found!'); return; } var graph = new _graph["default"](graphConfig, config); if (!graph.validator(graph)) return; graph.render = this; this.graphs.push(graph); this.sortGraphsByIndex(); this.drawAllGraph(); return graph; }; /** * @description Sort the graph by index * @return {Undefined} Void */ CRender.prototype.sortGraphsByIndex = function () { var graphs = this.graphs; graphs.sort(function (a, b) { if (a.index > b.index) return 1; if (a.index === b.index) return 0; if (a.index < b.index) return -1; }); }; /** * @description Delete graph in render * @param {Graph} graph The graph to be deleted * @return {Undefined} Void */ CRender.prototype.delGraph = function (graph) { if (typeof graph.delProcessor !== 'function') return; graph.delProcessor(this); this.graphs = this.graphs.filter(function (graph) { return graph; }); this.drawAllGraph(); }; /** * @description Delete all graph in render * @return {Undefined} Void */ CRender.prototype.delAllGraph = function () { var _this = this; this.graphs.forEach(function (graph) { return graph.delProcessor(_this); }); this.graphs = this.graphs.filter(function (graph) { return graph; }); this.drawAllGraph(); }; /** * @description Draw all the graphs in the render * @return {Undefined} Void */ CRender.prototype.drawAllGraph = function () { var _this2 = this; this.clearArea(); this.graphs.filter(function (graph) { return graph && graph.visible; }).forEach(function (graph) { return graph.drawProcessor(_this2, graph); }); }; /** * @description Animate the graph whose animation queue is not empty * and the animationPause is equal to false * @return {Promise} Animation Promise */ CRender.prototype.launchAnimation = function () { var _this3 = this; var animationStatus = this.animationStatus; if (animationStatus) return; this.animationStatus = true; return new Promise(function (resolve) { animation.call(_this3, function () { _this3.animationStatus = false; resolve(); }, Date.now()); }); }; /** * @description Try to animate every graph * @param {Function} callback Callback in animation end * @param {Number} timeStamp Time stamp of animation start * @return {Undefined} Void */ function animation(callback, timeStamp) { var graphs = this.graphs; if (!animationAble(graphs)) { callback(); return; } graphs.forEach(function (graph) { return graph.turnNextAnimationFrame(timeStamp); }); this.drawAllGraph(); requestAnimationFrame(animation.bind(this, callback, timeStamp)); } /** * @description Find if there are graph that can be animated * @param {[Graph]} graphs * @return {Boolean} */ function animationAble(graphs) { return graphs.find(function (graph) { return !graph.animationPause && graph.animationFrameState.length; }); } /** * @description Handler of CRender mousedown event * @return {Undefined} Void */ function mouseDown(e) { var graphs = this.graphs; var hoverGraph = graphs.find(function (graph) { return graph.status === 'hover'; }); if (!hoverGraph) return; hoverGraph.status = 'active'; } /** * @description Handler of CRender mousemove event * @return {Undefined} Void */ function mouseMove(e) { var offsetX = e.offsetX, offsetY = e.offsetY; var position = [offsetX, offsetY]; var graphs = this.graphs; var activeGraph = graphs.find(function (graph) { return graph.status === 'active' || graph.status === 'drag'; }); if (activeGraph) { if (!activeGraph.drag) return; if (typeof activeGraph.move !== 'function') { console.error('No move method is provided, cannot be dragged!'); return; } activeGraph.moveProcessor(e); activeGraph.status = 'drag'; return; } var hoverGraph = graphs.find(function (graph) { return graph.status === 'hover'; }); var hoverAbleGraphs = graphs.filter(function (graph) { return graph.hover && (typeof graph.hoverCheck === 'function' || graph.hoverRect); }); var hoveredGraph = hoverAbleGraphs.find(function (graph) { return graph.hoverCheckProcessor(position, graph); }); if (hoveredGraph) { document.body.style.cursor = hoveredGraph.style.hoverCursor; } else { document.body.style.cursor = 'default'; } var hoverGraphMouseOuterIsFun = false, hoveredGraphMouseEnterIsFun = false; if (hoverGraph) hoverGraphMouseOuterIsFun = typeof hoverGraph.mouseOuter === 'function'; if (hoveredGraph) hoveredGraphMouseEnterIsFun = typeof hoveredGraph.mouseEnter === 'function'; if (!hoveredGraph && !hoverGraph) return; if (!hoveredGraph && hoverGraph) { if (hoverGraphMouseOuterIsFun) hoverGraph.mouseOuter(e, hoverGraph); hoverGraph.status = 'static'; return; } if (hoveredGraph && hoveredGraph === hoverGraph) return; if (hoveredGraph && !hoverGraph) { if (hoveredGraphMouseEnterIsFun) hoveredGraph.mouseEnter(e, hoveredGraph); hoveredGraph.status = 'hover'; return; } if (hoveredGraph && hoverGraph && hoveredGraph !== hoverGraph) { if (hoverGraphMouseOuterIsFun) hoverGraph.mouseOuter(e, hoverGraph); hoverGraph.status = 'static'; if (hoveredGraphMouseEnterIsFun) hoveredGraph.mouseEnter(e, hoveredGraph); hoveredGraph.status = 'hover'; } } /** * @description Handler of CRender mouseup event * @return {Undefined} Void */ function mouseUp(e) { var graphs = this.graphs; var activeGraph = graphs.find(function (graph) { return graph.status === 'active'; }); var dragGraph = graphs.find(function (graph) { return graph.status === 'drag'; }); if (activeGraph && typeof activeGraph.click === 'function') activeGraph.click(e, activeGraph); graphs.forEach(function (graph) { return graph && (graph.status = 'static'); }); if (activeGraph) activeGraph.status = 'hover'; if (dragGraph) dragGraph.status = 'hover'; } /** * @description Clone Graph * @param {Graph} graph The target to be cloned * @return {Graph} Cloned graph */ CRender.prototype.clone = function (graph) { var style = graph.style.getStyle(); var clonedGraph = _objectSpread({}, graph, { style: style }); delete clonedGraph.render; clonedGraph = (0, _util.deepClone)(clonedGraph, true); return this.add(clonedGraph); };