UNPKG

chartx

Version:

Data Visualization Chart Library

518 lines (503 loc) 16.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; 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 _pie = _interopRequireDefault(require("./pie")); var _index = _interopRequireDefault(require("../index")); var _canvax = require("canvax"); var _tools = require("../../../utils/tools"); 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 PieGraphs = /*#__PURE__*/function (_GraphsBase) { function PieGraphs(opt, app) { var _this; (0, _classCallCheck2.default)(this, PieGraphs); _this = _callSuper(this, PieGraphs, [opt, app]); _this.type = "pie"; _canvax._.extend(true, _this, (0, _tools.getDefaultProps)(PieGraphs.defaultProps()), opt); _this.init(); return _this; } (0, _inherits2.default)(PieGraphs, _GraphsBase); return (0, _createClass2.default)(PieGraphs, [{ key: "init", value: function init() { //初步设置下data,主要legend等需要用到 this.data = this._dataHandle(); } }, { key: "_computerProps", value: function _computerProps() { var w = this.width; var h = this.height; //根据配置情况重新修正 outRadius ,innerRadius ------------ if (!this.node.outRadius) { var outRadius = Math.min(w, h) / 2; if (this.label.enabled) { //要预留moveDis位置来hover sector 的时候外扩 outRadius -= this.node.moveDis; } ; this.node.outRadius = parseInt(outRadius); } ; if (this.node.radius !== null && _canvax._.isNumber(this.node.radius)) { //如果用户有直接配置 radius,那么radius优先,用来计算 this.node.radius = Math.max(this.node.radius, this.node.minRadius); //this.node.outRadius = this.node.innerRadius + this.node.radius; this.node.innerRadius = this.node.outRadius - this.node.radius; } ; //要保证sec具有一个最小的radius if (this.node.outRadius - this.node.innerRadius < this.node.minRadius) { this.node.innerRadius = this.node.outRadius - this.node.minRadius; } ; if (this.node.innerRadius < 0) { this.node.innerRadius = 0; } ; // end -------------------------------------------------- } /** * opt ==> {width,height,origin} */ }, { key: "draw", value: function draw(opt) { !opt && (opt = {}); _canvax._.extend(true, this, opt); this._computerProps(); //这个时候就是真正的计算布局用得layoutdata了 this._pie = new _pie.default(this, this._trimGraphs(this.data)); this._pie.draw(opt); var me = this; if (this.animation && !opt.resize) { this._pie.grow(function () { me.fire("complete"); }); } else { this.fire("complete"); } this.sprite.addChild(this._pie.sprite); } }, { key: "show", value: function show(label) { this._setEnabled(label, true); } }, { key: "hide", value: function hide(label) { this._setEnabled(label, false); } }, { key: "_setEnabled", value: function _setEnabled(label, status) { var me = this; _canvax._.each(this.data, function (item) { if (item.label === label) { item.enabled = status; return false; } }); me._pie.resetData(me._trimGraphs(me.data)); } }, { key: "_dataHandle", value: function _dataHandle() { var me = this; //let _coord = me.app.getComponent({name:'coord'}); var data = []; var dataFrame = me.dataFrame; for (var i = 0, l = dataFrame.length; i < l; i++) { var rowData = dataFrame.getRowDataAt(i); var layoutData = { type: "pie", field: me.field, rowData: rowData, //把这一行数据给到layoutData引用起来 focused: false, //是否获取焦点,外扩 focusEnabled: me.node.focus.enabled, selected: false, //是否选中 selectEnabled: me.node.select.enabled, selectedR: me.node.select.radius, selectedAlpha: me.node.select.alpha, enabled: true, //是否启用,显示在列表中 fillStyle: null, color: null, //加个color属性是为了给tips用 value: rowData[me.field], label: rowData[me.keyField || me.field], labelText: null, //绘制的时候再设置,label format后的数据 iNode: i }; //设置颜色 var color = me._getColor(me.node.fillStyle, layoutData); layoutData.fillStyle = layoutData.color = color; data.push(layoutData); } ; if (data.length && me.sort) { data.sort(function (a, b) { if (me.sort == 'asc') { return a.value - b.value; } else { return b.value - a.value; } }); //重新设定下ind _canvax._.each(data, function (d, i) { d.iNode = i; }); } ; return data; } }, { key: "_trimGraphs", value: function _trimGraphs(data) { var me = this; var total = 0; me.currentAngle = 0 + me.startAngle % 360; //me.allAngle; var limitAngle = me.allAngle + me.startAngle % me.allAngle; var percentFixedNum = 2; //下面连个变量当node.r设置为数据字段的时候用 var maxRval = 0; var minRval = 0; if (data.length) { //先计算出来value的总量 for (var i = 0; i < data.length; i++) { //enabled为false的secData不参与计算 if (!data[i].enabled) continue; total += data[i].value; if (me.node.radius && _canvax._.isString(me.node.radius) && me.node.radius in data[i].rowData) { var _r = Number(data[i].rowData[me.node.radius]); maxRval = Math.max(maxRval, _r); minRval = Math.min(minRval, _r); } } ; if (total > 0) { for (var j = 0; j < data.length; j++) { var percentage = data[j].value / total; //enabled为false的sec,比率就设置为0 if (!data[j].enabled) { percentage = 0; } ; var fixedPercentage = +(percentage * 100).toFixed(percentFixedNum); var angle = me.allAngle * percentage; var endAngle = me.currentAngle + angle > limitAngle ? limitAngle : me.currentAngle + angle; var cosV = Math.cos((me.currentAngle + angle / 2) / 180 * Math.PI); var sinV = Math.sin((me.currentAngle + angle / 2) / 180 * Math.PI); var midAngle = me.currentAngle + angle / 2; //cosV = cosV.toFixed(5); //sinV = sinV.toFixed(5); var quadrant = function (ang) { if (ang >= limitAngle) { ang = limitAngle; } ang = ang % me.allAngle; var angleRatio = parseInt(ang / 90); if (ang >= 0) { switch (angleRatio) { case 0: return 1; case 1: return 2; case 2: return 3; case 3: case 4: return 4; } } else if (ang < 0) { switch (angleRatio) { case 0: return 4; case -1: return 3; case -2: return 2; case -3: case -4: return 1; } } }(midAngle); var outRadius = me.node.outRadius; if (me.node.radius && _canvax._.isString(me.node.radius) && me.node.radius in data[j].rowData) { var _rr = Number(data[j].rowData[me.node.radius]); outRadius = parseInt((me.node.outRadius - me.node.innerRadius) * ((_rr - minRval) / (maxRval - minRval)) + me.node.innerRadius); } ; var moveDis = me.node.moveDis; _canvax._.extend(data[j], { outRadius: outRadius, innerRadius: me.node.innerRadius, startAngle: me.currentAngle, //起始角度 endAngle: endAngle, //结束角度 midAngle: midAngle, //中间角度 moveDis: moveDis, outOffsetx: moveDis * 0.7 * cosV, //focus的事实外扩后圆心的坐标x outOffsety: moveDis * 0.7 * sinV, //focus的事实外扩后圆心的坐标y centerx: outRadius * cosV, centery: outRadius * sinV, outx: (outRadius + moveDis) * cosV, outy: (outRadius + moveDis) * sinV, edgex: (outRadius + moveDis) * cosV, edgey: (outRadius + moveDis) * sinV, orginPercentage: percentage, percentage: fixedPercentage, quadrant: quadrant, //象限 labelDirection: quadrant == 1 || quadrant == 4 ? 1 : 0, iNode: j }); //这个时候可以计算下label,因为很多时候外部label如果是配置的 data[j].labelText = me._getLabelText(data[j]); data[j].subValue = fixedPercentage + "%"; me.currentAngle += angle; if (me.currentAngle > limitAngle) { me.currentAngle = limitAngle; } } ; } } return { list: data, total: total }; } }, { key: "_getColor", value: function _getColor(prop, layoutData) { var me = this; var iNode = layoutData.iNode; var color = prop; if (_canvax._.isArray(prop)) { color = prop[iNode]; } ; if (_canvax._.isFunction(prop)) { color = prop.apply(this, [layoutData]); } ; if (!color) { color = me.app.getTheme(iNode); } ; return color; } }, { key: "_getLabelText", value: function _getLabelText(itemData) { var str; if (this.label.enabled) { if (this.label.format) { if (_canvax._.isFunction(this.label.format)) { str = this.label.format(itemData.label, itemData); } } else { var _field = this.keyField; if (_field) { str = itemData.rowData[_field] + ":" + itemData.percentage + "%"; } else { str = itemData.percentage + "%"; } } } return str; } }, { key: "getList", value: function getList() { return this.data; } }, { key: "getLegendData", value: function getLegendData() { //return this.data; var legendData = []; _canvax._.each(this.data, function (item) { legendData.push({ name: item.label, color: item.fillStyle, enabled: item.enabled }); }); return legendData; } }, { key: "tipsPointerOf", value: function tipsPointerOf() {} }, { key: "tipsPointerHideOf", value: function tipsPointerHideOf() {} }, { key: "focusAt", value: function focusAt(ind) { var nodeData = this._pie.data.list[ind]; if (!this.node.focus.enabled) return; this._pie.focusOf(nodeData); } }, { key: "unfocusAt", value: function unfocusAt(ind) { var nodeData = this._pie.data.list[ind]; if (!this.node.focus.enabled) return; this._pie.unfocusOf(nodeData); } }, { key: "selectAt", value: function selectAt(ind) { var nodeData = this._pie.data.list[ind]; if (!this.node.select.enabled) return; this._pie.selectOf(nodeData); } }, { key: "unselectAt", value: function unselectAt(ind) { var nodeData = this._pie.data.list[ind]; if (!this.node.select.enabled) return; this._pie.unselectOf(nodeData); } }], [{ key: "defaultProps", value: function defaultProps() { return { field: { detail: '字段配置', default: null }, keyField: { detail: '分组字段', default: null, documentation: 'keyField主要是给legend用的, 所有在legend中需要显示的分组数据,都用keyField' }, sort: { detail: '排序,默认不排序,可以配置为asc,desc', default: null }, startAngle: { detail: '起始角度', default: -90 }, allAngle: { detail: '全部角度', default: 360 }, node: { detail: '单个节点(扇形)配置', propertys: { radius: { detail: '半径', default: null, documentation: '每个扇形单元的半径,也可以配置一个字段,就成了丁格尔玫瑰图' }, innerRadius: { detail: '内径', default: 0 }, outRadius: { detail: '外径', default: null }, minRadius: { detail: '最小的半径厚度', default: 10, documentation: 'outRadius - innerRadius , 也就是radius的最小值' }, moveDis: { detail: 'hover偏移量', default: 8, documentation: '要预留moveDis位置来hover sector 的时候外扩' }, fillStyle: { detail: '单个图形背景色', default: null }, focus: { detail: '图形的hover设置', propertys: { enabled: { detail: '是否开启', default: true } } }, select: { detail: '图形的选中效果', propertys: { enabled: { detail: '是否开启', default: true }, radius: { detail: '选中效果图形的半径厚度', default: 5 }, alpha: { detail: '选中效果图形的透明度', default: 0.7 } } } } }, label: { detail: 'label', propertys: { field: { detail: '获取label的字段', default: null }, enabled: { detail: '是否开启', default: false }, format: { detail: 'label的格式化函数,支持html', default: null } } } }; } }, { key: "polyfill", value: function polyfill(opt) { if (opt.groupField) { //20220304 keyField 统一为keyField opt.keyField = opt.groupField; delete opt.groupField; } if (opt.label && opt.label.field) { //已经移除,开始使用keyField opt.keyField = opt.label.field; delete opt.label.field; } return opt; } }]); }(_index.default); _index.default.registerComponent(PieGraphs, 'graphs', 'pie'); var _default = exports.default = PieGraphs;