UNPKG

chartx

Version:

Data Visualization Chart Library

758 lines (746 loc) 24.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _canvax = _interopRequireDefault(require("canvax")); var _index = _interopRequireDefault(require("../index")); var _tools = require("../../../utils/tools"); var _index2 = _interopRequireDefault(require("../../../layout/pack/index")); var _index3 = _interopRequireDefault(require("../../../layout/hierarchy/index")); var _color = require("../../../utils/color"); function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } var _ = _canvax.default._, event = _canvax.default.event; var Circle = _canvax.default.Shapes.Circle; var BubbleGraphs = /*#__PURE__*/function (_GraphsBase) { function BubbleGraphs(opt, app) { var _this; (0, _classCallCheck2.default)(this, BubbleGraphs); _this = _callSuper(this, BubbleGraphs, [opt, app]); _this.type = "bubble"; _.extend(true, _this, (0, _tools.getDefaultProps)(BubbleGraphs.defaultProps()), opt); _this.init(); return _this; } (0, _inherits2.default)(BubbleGraphs, _GraphsBase); return (0, _createClass2.default)(BubbleGraphs, [{ key: "init", value: function init() { this._shapesp = new _canvax.default.Display.Sprite({ id: "shapesp" }); this._textsp = new _canvax.default.Display.Sprite({ id: "textsp" }); this.sprite.addChild(this._shapesp); this.sprite.addChild(this._textsp); this.sprite.context.x = this.app.padding.left; this.sprite.context.y = this.app.padding.top; } }, { key: "draw", value: function draw(opt) { !opt && (opt = {}); _.extend(true, this, opt); this.data = this._trimGraphs(); this._widget(); var me = this; if (this.animation && !opt.resize && !me.inited) { this.grow(function () { me.fire("complete"); }); } else { this.fire("complete"); } ; //inited 和 complete还不同,complete 是需要等动画结束 this.inited = true; return this; } }, { key: "resetData", value: function resetData(dataFrame) { this.dataFrame = dataFrame; this.data = this._trimGraphs(); this._widget(); this.grow(); } }, { key: "getNodesAt", value: function getNodesAt() { return []; } }, { key: "_trimGraphs", value: function _trimGraphs() { var pack = (0, _index2.default)().size([this.app.width - this.app.padding.left - this.app.padding.right, this.app.height - this.app.padding.top - this.app.padding.bottom]).padding(this.node.margin); var root = (0, _index3.default)({ children: this.dataFrame.jsonOrg }).sum(function (d) { return d.value; }); // 根据你的数据结构可能需要调整 var nodes = pack(root).descendants(); var _coord = this.app.getComponent({ name: 'coord' }); var fieldConfig = _coord.getFieldConfig(this.field); this._alphaData = null; this._alphaMaxValue = null; this._alphaMinValue = null; var tmplData = []; var iNode = -1; for (var i = 0, l = nodes.length; i < l; i++) { var node = nodes[i]; if (!node.depth && !this.node.showRootNode) { continue; } if (node.children && node.children.length && !this.node.showSubGroupNode) { continue; } iNode++; var radius = Math.min(node.r, this.node.maxRadius); var color = this.color || this._getStyle(this.node.fillStyle, node) || fieldConfig.color; var fillStyle = { points: [0, -node.r, 0, node.r], lineargradient: [{ position: 0, color: (0, _color.colorRgba)(color, 1) }, { position: 1, color: (0, _color.colorRgba)(color, 0.6) }] }; var strokeStyle = this._getStyle(this.node.strokeStyle || this.node.fillStyle, node); Object.assign(node, { type: "bubble", rowData: node.data, //为了和其他的的数据结构rowData保存一致 field: this.field, fieldColor: color, iNode: iNode, focused: false, selected: false, //下面的属性都单独设置 radius: radius, fillStyle: fillStyle, color: color, strokeStyle: strokeStyle, lineType: null, lineDash: null, strokeAlpha: 1, lineWidth: 0, label: null, fillAlpha: 1, nodeElement: null //对应的canvax 节点, 在widget之后赋值 }); this._setFillAlpha(node); this._setLineWidth(node); this._setLineType(node); this._setLineDash(node); this._setStrokeAlpha(node); this._setText(node); tmplData.push(node); } return tmplData; } }, { key: "_setText", value: function _setText(nodeLayoutData) { if (this.label.field != null) { if (_.isString(this.label.field) && nodeLayoutData.rowData[this.label.field]) { nodeLayoutData.label = this.label.format(nodeLayoutData.rowData[this.label.field], nodeLayoutData); } } } }, { key: "_setFillAlpha", value: function _setFillAlpha(nodeLayoutData) { // nodeLayoutData.fillAlpha = this._getProp( this.node.fillAlpha, nodeLayoutData ); // return this; var alpha; var _alpha = this.node.fillAlpha; var minAlpha = this.node.minFillAlpha; var maxAlpha = this.node.maxFillAlpha; var rowData = nodeLayoutData.rowData; if (_alpha != null) { if (_.isString(_alpha) && rowData[_alpha]) { //如果配置了某个字段作为r,那么就要自动计算比例 if (!this._alphaData && !this._alphaMaxValue && !this._alphaMinValue) { this._alphaData = this.dataFrame.getFieldData(_alpha); this._alphaData = this._alphaData.filter(function (item) { return item || item == 0; }); this._alphaMaxValue = _.max(this._alphaData); this._alphaMinValue = _.min(this._alphaData); } ; var rVal = rowData[_alpha]; if (this._alphaMaxValue == this._alphaMinValue) { alpha = minAlpha + (maxAlpha - minAlpha) / 2; } else { alpha = minAlpha + (rVal - this._alphaMinValue) / (this._alphaMaxValue - this._alphaMinValue) * (maxAlpha - minAlpha); } ; } else { alpha = this._getProp(this.node.fillAlpha, nodeLayoutData); } } else { alpha = 0; } //console.log(alpha) nodeLayoutData.fillAlpha = alpha; return this; } }, { key: "_setStrokeAlpha", value: function _setStrokeAlpha(nodeLayoutData) { nodeLayoutData.strokeAlpha = this._getProp(this.node.strokeAlpha, nodeLayoutData); return this; } }, { key: "_getProp", value: function _getProp(prop, nodeLayoutData) { var _prop = prop; if (_.isArray(prop)) { _prop = prop[nodeLayoutData.iGroup]; } ; if (_.isFunction(prop)) { _prop = prop.apply(this, [nodeLayoutData]); } ; return _prop; } }, { key: "_getStyle", value: function _getStyle(style, nodeLayoutData) { var _style = style; if (_.isArray(style)) { _style = style[nodeLayoutData.iGroup]; } ; if (_.isFunction(style)) { _style = style.apply(this, [nodeLayoutData]); } ; if (!_style) { _style = nodeLayoutData.fieldColor; } ; return _style; } }, { key: "_setLineWidth", value: function _setLineWidth(nodeLayoutData) { nodeLayoutData.lineWidth = this._getProp(this.node.lineWidth, nodeLayoutData); return this; } }, { key: "_setLineType", value: function _setLineType(nodeLayoutData) { nodeLayoutData.lineType = this._getProp(this.node.lineType, nodeLayoutData); return this; } }, { key: "_setLineDash", value: function _setLineDash(nodeLayoutData) { var _this2 = this; var _getProp = function _getProp(prop, nodeLayoutData) { var _prop = prop; // if( _.isArray( prop ) ){ // _prop = prop[ nodeLayoutData.iGroup ] // }; if (_.isFunction(prop)) { _prop = prop.apply(_this2, [nodeLayoutData]); } ; return _prop; }; nodeLayoutData.lineDash = _getProp(this.node.lineDash, nodeLayoutData); return this; } //根据layoutdata开始绘制 }, { key: "_widget", value: function _widget() { var me = this; _.each(_.flatten([me._shapesp.children, me._textsp.children]), function (el) { el.__used = false; }); _.each(me.data, function (nodeData, iNode) { var _nodeElement = me._getNodeElement(nodeData, iNode); if (!_nodeElement) { nodeData.__isNew = true; } ; var _context = { x: nodeData.x, y: nodeData.y, r: nodeData.radius, fillStyle: nodeData.fillStyle, strokeStyle: nodeData.strokeStyle, strokeAlpha: nodeData.strokeAlpha, lineWidth: nodeData.lineWidth, lineType: nodeData.lineType, lineDash: nodeData.lineDash, fillAlpha: nodeData.fillAlpha, cursor: "pointer" }; if (me.animation && (!me.inited || nodeData.__isNew)) { _context.r = 1; } ; if (!_nodeElement) { _nodeElement = new Circle({ id: "shape_" + iNode, hoverClone: false, context: _context }); me._shapesp.addChild(_nodeElement); _nodeElement.on(event.types.get(), function (e) { e.eventInfo = { title: null, trigger: 'this.node', //me.node, nodes: [this.nodeData] }; if (e.type == 'mouseover') { me.focusAt(this.nodeData); } ; if (e.type == 'mouseout') { !this.nodeData.selected && me.unfocusAt(this.nodeData); } ; //fire到root上面去的是为了让root去处理tips //先触发用户事件,再处理后面的选中事件 me.app.fire(e.type, e); }); } else { //_nodeElement.context = _context; //_.extend( _nodeElement.context, _context ); _nodeElement.animate(_context); } ; _nodeElement.__used = true; //数据和canvax原件相互引用 _nodeElement.nodeData = nodeData; _nodeElement.iNode = iNode; nodeData.nodeElement = _nodeElement; //如果有label if (nodeData.label && me.label.enabled && nodeData.radius > 15) { //20*2就是40 至少要放的下两个字符才有房文本的意义 var _label = _nodeElement.labelElement; if (!_label) { _label = new _canvax.default.Display.Text(nodeData.label, { id: "scat_text_" + iNode, context: {} }); _.extend(_label.context, me._getTextContext(_label, _context, nodeData)); me._textsp.addChild(_label); } else { _label.resetText(nodeData.label); _label.animate(me._getTextContext(_label, _context, nodeData)); } ; _label.__used = true; //图形节点和text文本相互引用 _nodeElement.labelElement = _label; _label.nodeElement = _nodeElement; if (_label.getTextWidth() + 10 > nodeData.radius * 2) { //_label.context.visible = false var newLabels = ['']; for (var i = 0, l = nodeData.label.length; i < l; i++) { var str = nodeData.label[i]; //newLabels[ newLabels.length-1 ] += str _label.resetText(newLabels.join('\n') + str); if (_label.getTextWidth() + 10 > nodeData.radius * 2) { if (newLabels[0].length == 1) { //加入一样只能放一个字符,那么就没有必要显示 多行了, 直接一行就好了 //_label.context.visible = false //也不隐藏 break; } if (newLabels.length < 3) { //最多显示3行label newLabels.push(str); } else { newLabels[newLabels.length - 1] = newLabels[newLabels.length - 1].slice(0, -2); _label.resetText(newLabels.join('\n') + '...'); //调整下垂直高度后居中 var h = _label.getTextHeight(); _label.__offsetY = -(h / 2 - 8); _label.context.y += _label.__offsetY; break; } } else { newLabels[newLabels.length - 1] += str; } if (i == l - 1) { //调整下垂直高度后居中 var _h = _label.getTextHeight(); _label.__offsetY = -(_h / 2 - 8); _label.context.y += _label.__offsetY; } } } } ; }); //多余的元素渐隐后销毁 _.each(_.flatten([me._shapesp.children, me._textsp.children]), function (el) { if (!el.__used) { el.animate({ globalAlpha: 0, r: 0 }, { onComplete: function onComplete() { el.destroy(); } }); } }); } }, { key: "_getNodeElement", value: function _getNodeElement(nodeData, iNode) { var me = this; var nodeEle; var dataKey = me.node.dataKey; if (!dataKey) { nodeEle = me._shapesp.getChildAt(iNode); } else { if (_.isString(dataKey)) { dataKey = dataKey.split(","); } ; for (var i = 0, l = this._shapesp.children.length; i < l; i++) { var _nodeEle = this._shapesp.children[i]; var isThisNodeEle = true; for (var ii = 0, ll = dataKey.length; ii < ll; ii++) { var key = dataKey[ii]; if (_nodeEle.nodeData.rowData[key] != nodeData.rowData[key]) { isThisNodeEle = false; break; } ; } ; if (isThisNodeEle && dataKey.length) { nodeEle = _nodeEle; break; } ; } ; } ; return nodeEle; } }, { key: "_getTextContext", value: function _getTextContext(_label, _context, node) { var fontSize = this.label.fontSize; if (_label.getTextWidth() > _context.r * 2) { fontSize -= 2; } ; var ctx = { x: _context.x, y: _context.y, fillStyle: this._getStyle(this.label.fontColor, node), fontSize: fontSize, textAlign: 'center', textBaseline: 'middle' }; return ctx; } /** * 生长动画 */ }, { key: "grow", value: function grow(callback) { var i = 0; var l = this.data.length - 1; var me = this; _.each(this.data, function (nodeData) { if (nodeData.__isNew) { me._growNode(nodeData, function () { i = i + 1; delete nodeData.__isNew; if (i == l) { callback && callback(); } }); } ; }); } }, { key: "_growNode", value: function _growNode(nodeData, callback) { var me = this; nodeData.nodeElement.animate({ x: nodeData.x, y: nodeData.y, r: nodeData.radius }, { onUpdate: function onUpdate(opt) { if (this.labelElement && this.labelElement.context) { this.labelElement.context.x = opt.x; this.labelElement.context.y = opt.y + (this.labelElement.__offsetY || 0); } }, delay: Math.round(Math.random() * 300), onComplete: function onComplete() { callback && callback(); } }); } }, { key: "focusAt", value: function focusAt(target) { var nodeData; var iNode; if ((0, _typeof2.default)(target) == 'object') { nodeData = target; } else { iNode = target; nodeData = this.data.find(function (item) { return item.iNode == iNode; }); } if (!this.node.focus.enabled || nodeData.focused) return; var nctx = nodeData.nodeElement.context; nctx.lineWidth = this._getProp(this.node.focus.lineWidth, nodeData); nctx.strokeAlpha = this._getProp(this.node.focus.strokeAlpha, nodeData); nctx.fillAlpha = this._getProp(this.node.focus.fillAlpha, nodeData); nodeData.focused = true; } }, { key: "unfocusAt", value: function unfocusAt(target) { var nodeData; var iNode; if ((0, _typeof2.default)(target) == 'object') { nodeData = target; } else { iNode = target; nodeData = this.data.find(function (item) { return item.iNode == iNode; }); } if (!this.node.focus.enabled || !nodeData.focused) return; var nctx = nodeData.nodeElement.context; nctx.lineWidth = this._getProp(nodeData.lineWidth, nodeData); nctx.strokeAlpha = this._getProp(nodeData.strokeAlpha, nodeData); nctx.fillAlpha = this._getProp(nodeData.fillAlpha, nodeData); nctx.strokeStyle = this._getProp(nodeData.strokeStyle, nodeData); nodeData.focused = false; } }, { key: "selectAt", value: function selectAt(target) { //let nodeData = this.data[ ind ]; var nodeData; var iNode; if ((0, _typeof2.default)(target) == 'object') { nodeData = target; } else { iNode = target; nodeData = this.data.find(function (item) { return item.iNode == iNode; }); } if (!this.node.select.enabled || nodeData.selected) return; var nctx = nodeData.nodeElement.context; nctx.lineWidth = this._getProp(this.node.select.lineWidth, nodeData); nctx.strokeAlpha = this._getProp(this.node.select.strokeAlpha, nodeData); nctx.fillAlpha = this._getProp(this.node.select.fillAlpha, nodeData); nodeData.selected = true; } }, { key: "unselectAt", value: function unselectAt(target) { //let nodeData = this.data[ ind ]; var nodeData; var iNode; if ((0, _typeof2.default)(target) == 'object') { nodeData = target; } else { iNode = target; nodeData = this.data.find(function (item) { return item.iNode == iNode; }); } if (!this.node.select.enabled || !nodeData.selected) return; var nctx = nodeData.nodeElement.context; if (nodeData.focused) { //有e 说明这个函数是事件触发的,鼠标肯定还在node上面 nctx.lineWidth = this._getProp(this.node.focus.lineWidth, nodeData); nctx.strokeAlpha = this._getProp(this.node.focus.strokeAlpha, nodeData); nctx.fillAlpha = this._getProp(this.node.focus.fillAlpha, nodeData); } else { nctx.lineWidth = nodeData.lineWidth; nctx.strokeAlpha = nodeData.strokeAlpha; nctx.fillAlpha = nodeData.fillAlpha; } ; nodeData.selected = false; } }, { key: "getNodesOfPos", value: function getNodesOfPos() { //sat的 getNodesOfPos 一定要有两个点 var _nodesInfoList = []; //节点信息集合 return _nodesInfoList; } }], [{ key: "defaultProps", value: function defaultProps() { return { field: { detail: '字段配置', default: null }, node: { detail: '单数据节点图形设置', propertys: { margin: { detail: '圆于圆之间的间隔', default: '10' }, maxRadius: { detail: '圆点最大半径', default: '100' }, showRootNode: { detail: '是否显示根节点的圆', default: false }, showSubGroupNode: { detail: '是否显示子节点的拥有子节点的分组节点', default: true }, fillStyle: { detail: '节点景色', default: null }, fillAlpha: { detail: '节点透明度', default: 0.8 }, maxFillAlpha: { detail: '节点最大透明度', default: 1 }, minFillAlpha: { detail: '节点最小透明度', default: 0.2 }, strokeStyle: { detail: '节点描边颜色', default: null }, lineWidth: { detail: '节点描边线宽', default: 0 }, lineType: { detail: '描边样式', default: 'solid' }, lineDash: { detail: '虚线样式', default: [2, 6] }, strokeAlpha: { detail: '节点描边透明度', default: 1 }, focus: { detail: "节点hover态设置", propertys: { enabled: { detail: '是否开启', default: true }, lineWidth: { detail: 'hover后的边框大小', default: 6 }, strokeAlpha: { detail: 'hover后的边框透明度', default: 0.2 }, fillAlpha: { detail: 'hover后的背景透明度', default: 0.8 } } }, select: { detail: "节点选中态设置", propertys: { enabled: { detail: '是否开启', default: false }, lineWidth: { detail: '选中后的边框大小', default: 8 }, strokeAlpha: { detail: '选中后的边框透明度', default: 0.4 }, fillAlpha: { detail: '选中后的背景透明度', default: 1 } } } } }, label: { detail: '文本设置', propertys: { enabled: { detail: '是否开启', default: true }, field: { detail: '获取label的字段', default: null }, format: { detail: 'label格式化处理函数', default: function _default(txt) { return txt; } }, fontSize: { detail: 'label字体大小', default: 13 }, fontColor: { detail: '字体颜色', default: '#fff' } } } }; } }]); }(_index.default); _index.default.registerComponent(BubbleGraphs, 'graphs', 'bubble'); var _default2 = exports.default = BubbleGraphs;