UNPKG

chartx

Version:

Data Visualization Chart Library

1,476 lines (1,439 loc) 49.6 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 _canvax = _interopRequireDefault(require("canvax")); var _tools = require("../../../utils/tools"); var _color = require("../../../utils/color"); var _numeral = _interopRequireDefault(require("numeral")); 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 animation = _canvax.default.animation; var BrokenLine = _canvax.default.Shapes.BrokenLine; var Circle = _canvax.default.Shapes.Circle; var Isogon = _canvax.default.Shapes.Isogon; var Rect = _canvax.default.Shapes.Rect; var Path = _canvax.default.Shapes.Path; var LineGraphsGroup = exports.default = /*#__PURE__*/function (_event$Dispatcher) { function LineGraphsGroup(fieldConfig, iGroup, opt, ctx, h, w, _graphs) { var _this; var bottomFieldMap = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : {}; (0, _classCallCheck2.default)(this, LineGraphsGroup); _this = _callSuper(this, LineGraphsGroup); _this._graphs = _graphs; _this._opt = opt; _this.fieldConfig = fieldConfig; _this.field = null; //在extend之后要重新设置 _this.iGroup = iGroup; _this._yAxis = fieldConfig.yAxis; _this.ctx = ctx; _this.w = w; _this.h = h; _this.y = 0; _this.data = []; _this.sprite = null; _this._pointList = []; //brokenline最终的状态 _this._currPointList = []; //brokenline 动画中的当前状态 _this._line = null; _this._bottomPointList = []; // bottomLine的最终状态 _this._currBottomPointList = []; // bottomLine 动画中的当前状态 _this._bottomLine = null; //设置默认的color 为 fieldConfig.color _this.color = fieldConfig.color; _.extend(true, _this, (0, _tools.getDefaultProps)(LineGraphsGroup.defaultProps()), opt); //TODO group中得field不能直接用opt中得field, 必须重新设置, //group中得field只有一个值,代表一条折线, 后面要扩展extend方法,可以控制过滤哪些key值不做extend _this.field = fieldConfig.field; //iGroup 在yAxis.field中对应的值 _this.clipRect = null; _this.__currFocusInd = -1; _this._growed = false; //_bottomField如果有, 那么在画area的时候起点是_bottomField上面的值,而不是从默认的坐标0开始 _this._bottomField = bottomFieldMap[_this.field]; _this.init(opt); return _this; } (0, _inherits2.default)(LineGraphsGroup, _event$Dispatcher); return (0, _createClass2.default)(LineGraphsGroup, [{ key: "init", value: function init() { this.sprite = new _canvax.default.Display.Sprite(); this.graphSprite = new _canvax.default.Display.Sprite(); this.sprite.addChild(this.graphSprite); this.lineSprite = new _canvax.default.Display.Sprite(); this.graphSprite.addChild(this.lineSprite); //hover效果的node被添加到的容器 this._focusNodes = new _canvax.default.Display.Sprite({}); this.sprite.addChild(this._focusNodes); this._nodes = new _canvax.default.Display.Sprite({}); this.sprite.addChild(this._nodes); this._labels = new _canvax.default.Display.Sprite({}); this.sprite.addChild(this._labels); } }, { key: "_clean", value: function _clean() { this.lineSprite.removeAllChildren(); this._focusNodes.removeAllChildren(); this._nodes.removeAllChildren(); this._labels.removeAllChildren(); this._line = null; this._bottomLine = null; this._area = null; } }, { key: "draw", value: function draw(opt, data) { _.extend(true, this, opt); this.data = data; this._widget(opt); } //自我销毁 }, { key: "destroy", value: function destroy() { var me = this; me.sprite.animate({ globalAlpha: 0 }, { duration: 300, onComplete: function onComplete() { me.sprite.remove(); } }); } //styleType , normals , iGroup }, { key: "_getColor", value: function _getColor(s, iNode) { var color = this._getProp(s, iNode); //只有iNode有传数据的时候( 获取node的color 或者 获取 label的color ),才做如下处理 if (arguments.length > 1 && (color === undefined || color === null)) { if (s && s.lineargradient) { color = s.lineargradient[parseInt(s.lineargradient.length / 2)].color; } ; if (!color || !_.isString(color)) { //那么最后,取this.fieldConfig.color color = this.fieldConfig.color; //this._getProp(this.color, iNode) //this.color会被写入到fieldMap.color } } ; return color; } }, { key: "_getProp", value: function _getProp(s, iNode) { if (_.isArray(s)) { return s[this.iGroup]; } if (_.isFunction(s)) { var _nodesInfo = []; if (iNode != undefined) { _nodesInfo.push(this.data[iNode]); } ; return s.apply(this, _nodesInfo); } return s; } //这个是tips需要用到的 }, { key: "getNodeInfoAt", value: function getNodeInfoAt($index, e) { var o = this.data[$index]; if (e && e.eventInfo && e.eventInfo.dimension_1) { var lt = e.eventInfo.dimension_1.layoutType; if (lt == 'proportion') { //$index则代表的xpos,需要计算出来data中和$index最近的值作为 node var xDis; for (var i = 0, l = this.data.length; i < l; i++) { var _node = this.data[i]; var _xDis = Math.abs(_node.x - $index); if (xDis == undefined || _xDis < xDis) { xDis = _xDis; o = _node; continue; } } } } return o; } /** * * @param {object} opt * @param {data} data * * 触发这次reset的触发原因比如{name : 'datazoom', left:-1,right:1}, * dataTrigger 描述了数据变化的原因和变化的过程,比如上面的数据 left少了一个数据,right多了一个数据 * @param {object} dataTrigger */ }, { key: "resetData", value: function resetData(data, dataTrigger, opt) { var me = this; if (data) { this.data = data; } if (!dataTrigger || !dataTrigger.comp) { //如果是系统级别的调用,需要从新执行绘制, 不是内部的触发比如(datazoom) me._growed = false; if (me.clipRect) { me.clipRect.destroy(); me.clipRect = null; } me._widget(this); me._grow(); } else { me._pointList = this._getPointList(this.data); me._bottomPointList = this._getBottomPointList(); var plen = me._pointList.length; var cplen = me._currPointList.length; var params = { left: 0, //默认左边数据没变 right: plen - cplen }; if (dataTrigger && dataTrigger.params) { _.extend(params, dataTrigger.params); } if (params.left) { if (params.left > 0) { this._currPointList = this._pointList.slice(0, params.left).concat(this._currPointList); if (this._bottomField) { this._currBottomPointList = this._bottomPointList.slice(0, params.left).concat(this._currBottomPointList); } } if (params.left < 0) { this._currPointList.splice(0, Math.abs(params.left)); if (this._bottomField) { this._currBottomPointList.splice(0, Math.abs(params.left)); } } } if (params.right) { if (params.right > 0) { this._currPointList = this._currPointList.concat(this._pointList.slice(-params.right)); if (this._bottomField) { this._currBottomPointList = this._currBottomPointList.concat(this._bottomPointList.slice(-params.right)); } } if (params.right < 0) { this._currPointList.splice(this._currPointList.length - Math.abs(params.right)); if (this._bottomField) { this._currBottomPointList.splice(this._currBottomPointList.length - Math.abs(params.right)); } } } me._createNodes(); me._createTexts(); me._transition(); } } //数据变化后的切换动画 }, { key: "_transition", value: function _transition(callback) { var me = this; if (!me.data.length) { //因为在index中有调用 if (me._line.context) { me._line.context.pointList = []; } ; if (me._bottomLine.context) { me._bottomLine.context.pointList = []; } ; if (me._area && me._area.context) { me._area.context.path = ''; } ; callback && callback(me); return; } ; function _update(pointList, bottomPointList) { if (!me._line) { me.sprite._removeTween(me._transitionTween); me._transitionTween = null; return; } var _strokeStyle = me._getLineStrokeStyle(); ; if (me._line.context) { me._line.context.pointList = _.clone(pointList); me._line.context.strokeStyle = _strokeStyle; } if (me._bottomField && me._bottomLine && me._bottomLine.context) { me._bottomLine.context.pointList = _.clone(bottomPointList); me._bottomLine.context.strokeStyle = _strokeStyle; } if (me._area && me._area.context) { me._area.context.path = me._getFillPath(me._line, me._bottomLine); me._area.context.fillStyle = me._getFillStyle(); } var iNode = 0; _.each(pointList, function (point, i) { if (_.isNumber(point[1])) { if (me._nodes) { var _node = me._nodes.getChildAt(iNode); if (_node) { _node.context.x = point[0]; _node.context.y = point[1]; } } if (me._labels) { var _text = me._labels.getChildAt(iNode); if (_text) { _text.context.x = point[0]; _text.context.y = point[1] - 3 - 3; me._checkTextPos(_text, i); } } iNode++; } }); } ; if (!this._growed) { //如果还在入场中 me._currPointList = me._pointList; me._currBottomPointList = me._bottomPointList; _update(me._currPointList, me._currBottomPointList); return; } this._transitionTween = animation.registTween({ from: me._getPointPosStr(me._currPointList, me._currBottomPointList), to: me._getPointPosStr(me._pointList, me._bottomPointList), desc: me.field, onUpdate: function onUpdate(arg) { for (var p in arg) { var currPointerList = p.split("_")[0] == 'p' ? me._currPointList : me._currBottomPointList; var ind = parseInt(p.split("_")[2]); var xory = parseInt(p.split("_")[1]); currPointerList[ind] && (currPointerList[ind][xory] = arg[p]); //p_1_n中间的1代表x or y } ; _update(me._currPointList, me._currBottomPointList); }, onComplete: function onComplete() { me.sprite._removeTween(me._transitionTween); me._transitionTween = null; //在动画结束后强制把目标状态绘制一次。 //解决在onUpdate中可能出现的异常会导致绘制有问题。 //这样的话,至少最后的结果会是对的。 _update(me._pointList, me._bottomPointList); callback && callback(me); } }); this.sprite._tweens.push(this._transitionTween); } //首次加载的进场动画 }, { key: "_grow", value: function _grow(callback) { var _this2 = this; var _coord = this._graphs.app.getCoord(); var width = _coord.width, height = _coord.height; this.clipRect = new Rect({ context: { x: 0, //-100, y: -height - 3, width: 0, height: height + 6, fillStyle: 'green' } }); var growTo = { width: width }; this.lineSprite.clipTo(this.clipRect); this.graphSprite.addChild(this.clipRect); if (this.line.growDriction == 'rightLeft') { this.clipRect.context.x = width; growTo.x = 0; } ; this.clipRect.animate(growTo, { duration: this._graphs.aniDuration, easing: this.aniEasing, onUpdate: function onUpdate() { var clipRectCtx = _this2.clipRect.context; _this2._nodes.children.concat(_this2._labels.children).forEach(function (el) { var _ctx = el.context; if (_ctx.globalAlpha == 0 && _ctx.x >= clipRectCtx.x && _ctx.x <= clipRectCtx.x + clipRectCtx.width) { el.animate({ globalAlpha: 1 }, { duration: 300 }); } }); }, onComplete: function onComplete() { _this2._growed = true; callback && callback(); } }); } }, { key: "_getPointPosStr", value: function _getPointPosStr(pointList, bottomPointList) { var obj = {}; pointList.forEach(function (p, i) { if (!p) { //折线图中这个节点可能没有 return; } ; obj["p_1_" + i] = p[1]; //p_y==p_1 obj["p_0_" + i] = p[0]; //p_x==p_0 }); bottomPointList.forEach(function (p, i) { if (!p) { //折线图中这个节点可能没有 return; } ; obj["bp_1_" + i] = p[1]; //p_y==p_1 obj["bp_0_" + i] = p[0]; //p_x==p_0 }); return obj; } }, { key: "_getPointList", value: function _getPointList(data) { var list = []; for (var a = 0, al = data.length; a < al; a++) { var o = data[a]; list.push([o.x, o.y]); } ; return list; } }, { key: "_widget", value: function _widget(opt) { var me = this; !opt && (opt = {}); if (opt.isResize) { me._growed = true; } ; //绘制之前先自清空 me._clean(); me._pointList = this._getPointList(me.data); if (me._pointList.length == 0) { //filter后,data可能length==0 return; } ; var list = me._pointList; me._currPointList = list; var strokeStyle = me._getLineStrokeStyle(list); //在配置线性渐变的情况下会需要 var blineCtx = { pointList: list, lineWidth: me.line.lineWidth, y: me.y, strokeStyle: strokeStyle, smooth: me.line.smooth, lineType: me._getProp(me.line.lineType), lineDash: me.line.lineDash, //TODO: 不能用_getProp lineJoin: 'bevel', lineCap: "round" }; if (me.line.shadowBlur) { blineCtx.shadowBlur = me._getProp(me.line.shadowBlur); blineCtx.shadowColor = me._getProp(me.line.shadowColor) || strokeStyle; blineCtx.shadowOffsetY = me._getProp(me.line.shadowOffsetY); blineCtx.shadowOffsetX = me._getProp(me.line.shadowOffsetX); } ; var bline = new BrokenLine({ //线条 context: blineCtx }); bline.on(event.types.get(), function (e) { e.eventInfo = { trigger: 'this.line', nodes: [] }; me._graphs.app.fire(e.type, e); }); if (!this.line.enabled) { bline.context.visible = false; } ; me.lineSprite.addChild(bline); me._line = bline; if (me.area.enabled) { if (this._bottomField) { //如果有 _bottomField me._bottomPointList = this._getBottomPointList(); var _list = me._bottomPointList; me._currBottomPointList = _list; var bottomLineCtx = {}; Object.assign(bottomLineCtx, blineCtx); bottomLineCtx.pointList = me._bottomPointList; var bottomLine = new BrokenLine({ //线条 context: bottomLineCtx }); if (!this.area.bottomLine.enabled) { bottomLine.context.visible = false; } ; me.lineSprite.addChild(bottomLine); me._bottomLine = bottomLine; } var area = new Path({ //填充 context: { path: me._getFillPath(me._line, me._bottomLine), fillStyle: me._getFillStyle(), globalAlpha: me.area.alpha } }); area.on(event.types.get(), function (e) { e.eventInfo = { trigger: 'this.area', //me.area, nodes: [] }; me._graphs.app.fire(e.type, e); }); me.lineSprite.addChild(area); me._area = area; } me._createNodes(opt); me._createTexts(opt); } }, { key: "_getBottomPointList", value: function _getBottomPointList() { var _this3 = this; if (!this._bottomField) return []; var _coord = this._graphs.app.getCoord(); var bottomData = this._graphs.dataFrame.getFieldData(this._bottomField); // this._yAxis.addValToSection( bottomData ); //把bottomData的数据也同步到y轴的dataSection, 可能y轴需要更新 var _bottomPointList = []; bottomData.forEach(function (item, i) { var point = _coord.getPoint({ iNode: i, field: _this3.field, value: { //x: y: item } }); _bottomPointList.push([point.pos.x, point.pos.y]); }); return _bottomPointList; } }, { key: "_getFirstNode", value: function _getFirstNode() { var _firstNode = null; for (var i = 0, l = this.data.length; i < l; i++) { var nodeData = this.data[i]; if (_.isNumber(nodeData.y)) { if (_firstNode === null || this.yAxisAlign == "right") { //_yAxis为右轴的话, _firstNode = nodeData; } if (this.yAxisAlign !== "right" && _firstNode !== null) { break; } } ; } return _firstNode; } }, { key: "_getFillStyle", value: function _getFillStyle() { var me = this; var _fillStyle; if (!this._opt.area || !this._opt.area.fillStyle) { //如果用户没有配置area.strokeStyle,那么就用默认的 _fillStyle = this.color; } else { _fillStyle = this._getColor(this._opt.area.fillStyle); } var alpha = me.area.alpha; if ((0, _color.colorIsHex)(_fillStyle) && !_.isArray(alpha)) { alpha = [1, 0]; } if (_.isArray(alpha)) { //alpha如果是数组,那么就是渐变背景,那么就至少要有两个值 //如果拿回来的style已经是个gradient了,那么就不管了 alpha.length = 2; if (alpha[0] == undefined) { alpha[0] = 0; } ; if (alpha[1] == undefined) { alpha[1] = 0; } ; var fill_gradient = { lineargradient: [] }; if ((0, _color.colorIsHex)(_fillStyle)) { //创建一个线性渐变 fill_gradient.lineargradient = [{ position: 0, color: (0, _color.colorRgba)(_fillStyle, alpha[0]) }, { position: 1, color: (0, _color.colorRgba)(_fillStyle, alpha[1]) }]; _fillStyle = fill_gradient; } } ; //也可以传入一个线性渐变 if (_fillStyle && _fillStyle.lineargradient) { var lineargradient = _fillStyle.lineargradient; //如果是右轴的话,渐变色要对应的反转 if (this.yAxisAlign == 'right') { lineargradient = lineargradient.reverse(); } ; //如果用户配置 填充是一个线性渐变 var lps = this._getLinearGradientPoints('area'); if (lps && lps.length) { _fillStyle.points = lps; } ; } //最后,如果是一个十六进制的颜色的话,就变成一个抄底的渐变 return _fillStyle; } }, { key: "_getLineStrokeStyle", value: function _getLineStrokeStyle(pointList, graphType) { var _style; if (!this._opt.line || !this._opt.line.strokeStyle) { //如果用户没有配置line.strokeStyle,那么就用默认的 _style = this.color; } else { _style = this._getColor(this._opt.line.strokeStyle); } if ((0, _color.colorIsHex)(_style) && this.line.hexToLineargradientType != 'none') { var _lineargradient = { lineargradient: [{ position: 0, color: (0, _color.colorRgba)(_style, 0.2) //'rgba(56, 90, 204, 0.2)' }, { position: 0.05, color: (0, _color.colorRgba)(_style, 1) //'rgba(56, 90, 204, 1)' }, { position: 0.95, color: (0, _color.colorRgba)(_style, 1) //'rgba(56, 90, 204, 1)' }, { position: 1, color: (0, _color.colorRgba)(_style, 0.2) //'rgba(56, 90, 204, 0.2)' }] }; if (this.line.hexToLineargradientType == 'left') { _lineargradient = { lineargradient: [{ position: 0, color: (0, _color.colorRgba)(_style, 0.2) //'rgba(56, 90, 204, 0.2)' }, { position: 0.05, color: (0, _color.colorRgba)(_style, 1) //'rgba(56, 90, 204, 1)' }, { position: 1, color: (0, _color.colorRgba)(_style, 1) //'rgba(56, 90, 204, 0.2)' }] }; } if (this.line.hexToLineargradientType == 'right') { _lineargradient = { lineargradient: [{ position: 0, color: (0, _color.colorRgba)(_style, 1) //'rgba(56, 90, 204, 0.2)' }, { position: 0.05, color: (0, _color.colorRgba)(_style, 1) //'rgba(56, 90, 204, 1)' }, { position: 1, color: (0, _color.colorRgba)(_style, 0.2) //'rgba(56, 90, 204, 0.2)' }] }; } _style = _lineargradient; } var lineargradient = _style.lineargradient; if (lineargradient) { //如果是右轴的话,渐变色要对应的反转 if (this.yAxisAlign == 'right') { lineargradient = lineargradient.reverse(); } ; //如果用户配置 填充是一个线性渐变 var lps = this._getLinearGradientPoints('line', pointList); if (!lps) return; _style.points = lps; return _style; } return _style; } }, { key: "_getLinearGradientPoints", value: function _getLinearGradientPoints() { var graphType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'line'; var pointList = arguments.length > 1 ? arguments[1] : undefined; //如果graphType 传入的是area,并且,用户并没有配area.lineargradientDriction,那么就会默认和line.lineargradientDriction对齐 var driction = this[graphType].lineargradientDriction; !pointList && (pointList = this._line.context.pointList); var linearPointStart, linearPointEnd; if (driction == 'topBottom') { //top -> bottom var topX = 0, topY = 0, bottomX = 0, bottomY = 0; for (var i = 0, l = pointList.length; i < l; i++) { var point = pointList[i]; var y = point[1]; if (!isNaN(y)) { topY = Math.min(y, topY); bottomY = Math.max(y, bottomY); } } linearPointStart = { x: topX, y: topY }; linearPointEnd = { x: bottomX, y: bottomY }; if (graphType == 'area') { //面积图的话,默认就需要一致绘制到底的x轴位置去了 linearPointEnd.y = 0; } } else { //left->right var leftX, rightX, leftY = 0, rightY = 0; for (var _i = 0, _l = pointList.length; _i < _l; _i++) { var _point2 = pointList[_i]; var x = _point2[0]; var _y = _point2[1]; if (!isNaN(x) && !isNaN(_y)) { if (leftX == undefined) { leftX = x; } else { leftX = Math.min(x, leftX); } rightX = Math.max(x, leftX); } } ; linearPointStart = { x: leftX, y: leftY }; linearPointEnd = { x: rightX, y: rightY }; } if (linearPointStart.x == undefined || linearPointStart.y == undefined || linearPointEnd.x == undefined || linearPointEnd.y == undefined) { return null; } return [linearPointStart.x, linearPointStart.y, linearPointEnd.x, linearPointEnd.y]; } }, { key: "_createNodes", value: function _createNodes() { var _this4 = this; var opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var me = this; var list = me._currPointList; var iNode = 0; //这里不能和下面的a对等,以为list中有很多无效的节点 var _loop = function _loop() { var node = me.data[a]; var _nodeColor = me._getColor(me.node.strokeStyle || me.color, a); node.color = _nodeColor; //回写回data里,tips的是用的到 var nodeEnabled = me.node.enabled; if (list.length == 1 && !nodeEnabled) { nodeEnabled = true; //只有一个数据的时候, 强制显示node } // if( !nodeEnabled ){ // //不能写return, 是因为每个data的color还是需要计算一遍 // continue; // }; var _point = me._currPointList[a]; if (!_point || !_.isNumber(_point[1])) { //折线图中有可能这个point为undefined return 1; // continue } ; var x = _point[0]; var y = _point[1]; var globalAlpha = 0; if (_this4.clipRect && me._growed) { var clipRectCtx = _this4.clipRect.context; if (x >= clipRectCtx.x && x <= clipRectCtx.x + clipRectCtx.width) { globalAlpha = 1; } } ; var lineWidth = me.node.lineWidth || me.line.lineWidth; var context = { x: x, y: y, r: me._getProp(me.node.radius, a), lineWidth: me._getProp(lineWidth, a) || 2, strokeStyle: _nodeColor, fillStyle: me._getProp(me.node.fillStyle, a) || _nodeColor, visible: nodeEnabled && !!me._getProp(me.node.visible, a), globalAlpha: globalAlpha }; var nodeConstructor = Circle; var _shapeType = me._getProp(me.node.shapeType, a); if (_shapeType == "isogon") { nodeConstructor = Isogon; context.n = me._getProp(me.node.isogonPointNum, a); } ; if (_shapeType == "path") { nodeConstructor = Path; context.path = me._getProp(me.node.path, a); } ; var nodeElement = me._nodes.children[iNode]; //同一个元素,才能直接extend context if (nodeElement) { if (nodeElement.type == _shapeType) { _.extend(nodeElement.context, context); } else { nodeElement.destroy(); //重新创建一个新的元素放到相同位置 nodeElement = new nodeConstructor({ context: context }); var pointerEvent = me.node.pointerEvent; if (typeof me.node.pointerEvent == 'function') { pointerEvent = me.node.pointerEvent.apply(me, [node, nodeElement]); } if (pointerEvent != 'none') { nodeElement.on(event.types.get(), function (e) { e.eventInfo = { trigger: 'this.node', //me.node, nodes: [node] }; me._graphs.app.fire(e.type, e); }); } me._nodes.addChildAt(nodeElement, iNode); } ; } else { nodeElement = new nodeConstructor({ context: context }); var _pointerEvent = me.node.pointerEvent; if (typeof me.node.pointerEvent == 'function') { _pointerEvent = me.node.pointerEvent.apply(me, [node, nodeElement]); } if (_pointerEvent != 'none') { nodeElement.on(event.types.get(), function (e) { e.eventInfo = { trigger: 'this.node', //me.node, nodes: [node] }; me._graphs.app.fire(e.type, e); }); } // nodeElement.on( event.types.get() , function (e) { // e.eventInfo = { // trigger : 'this.node', //me.node, // nodes : [ node ] // }; // me._graphs.app.fire( e.type, e ); // }); me._nodes.addChild(nodeElement); } ; // if ( me.node.corner ) { //拐角才有节点 // let y = me._pointList[a][1]; // let pre = me._pointList[a - 1]; // let next = me._pointList[a + 1]; // if (pre && next) { // if (y == pre[1] && y == next[1]) { // nodeElement.context.visible = false; // } // } // }; node.nodeElement = nodeElement; iNode++; }; for (var a = 0, al = list.length; a < al; a++) { if (_loop()) continue; } ; //把过多的节点删除了 if (me._nodes.children.length > iNode) { for (var i = iNode, l = me._nodes.children.length; i < l; i++) { me._nodes.children[i].destroy(); i--; l--; } } ; } }, { key: "_createTexts", value: function _createTexts() { var opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var me = this; var list = me._currPointList; var _coord = this._graphs.app.getCoord(); if (me.label.enabled) { //节点上面的文本info var iNode = 0; //这里不能和下面的a对等,以为list中有很多无效的节点 for (var a = 0, al = list.length; a < al; a++) { var _point = list[a]; if (!_point || !_.isNumber(_point[1])) { //折线图中有可能这个point为undefined continue; } ; var x = _point[0]; var y = _point[1] - this.node.radius - 2; var globalAlpha = 0; if (this.clipRect && me._growed) { var clipRectCtx = this.clipRect.context; if (x >= clipRectCtx.x && x <= clipRectCtx.x + clipRectCtx.width) { globalAlpha = 1; } } ; var context = { x: x, y: y, fontSize: this.label.fontSize, textAlign: this.label.textAlign, textBaseline: this.label.textBaseline, fillStyle: me._getColor(me.label.fontColor, a), lineWidth: 1, strokeStyle: "#ffffff", globalAlpha: globalAlpha }; var nodeData = me.data[a]; var value = nodeData.value; if (me.label.format) { //如果有单独给label配置format,就用label上面的配置 if (_.isFunction(me.label.format)) { value = me.label.format.apply(me, [value, nodeData]); } if (typeof me.label.format == 'string') { value = (0, _numeral.default)(value).format(me.label.format); } } else { //否则用fieldConfig上面的 var fieldConfig = _coord.getFieldConfig(this.field); if (fieldConfig) { value = fieldConfig.getFormatValue(value); } ; } ; if (value == undefined || value == null) { continue; } ; var _label = this._labels.children[iNode]; if (_label) { _label.resetText(value); _.extend(_label.context, context); } else { _label = new _canvax.default.Display.Text(value, { context: context }); me._labels.addChild(_label); me._checkTextPos(_label, a); } iNode++; } ; //把过多的label节点删除了 if (me._labels.children.length > iNode) { for (var i = iNode, l = me._labels.children.length; i < l; i++) { me._labels.children[i].destroy(); i--; l--; } } ; } ; } }, { key: "_checkTextPos", value: function _checkTextPos(_label, ind) { var me = this; var list = me._currPointList; var pre = list[ind - 1]; var next = list[ind + 1]; if (this.label.arrangementRules == 'auto') { if (pre && next && pre[1] < _label.context.y && next[1] < _label.context.y) { _label.context.y += this.node.radius * 2 + 6; _label.context.textBaseline = "top"; } } if (this.label.arrangementRules == 'oddAndEven') { if (ind % 2) { _label.context.y += this.node.radius * 2 + 6; _label.context.textBaseline = "top"; } } } }, { key: "_getFillPath", value: function _getFillPath(line, bottomLine) { var path = ''; var M = 'M', L = 'L', Z = 'z'; var originPos = -this._yAxis.originPos; var bottomGraphicsData = bottomLine ? bottomLine.graphics.graphicsData : []; line.graphics.graphicsData.forEach(function (graphicsData, gInd) { var points = [].concat(graphicsData.shape.points); if (points.length > 1) { if (bottomGraphicsData.length) { var bottomGraphicsDataGroup = bottomGraphicsData[gInd] || bottomGraphicsData.slice(-1)[0]; var bpoints = bottomGraphicsDataGroup.shape.points; for (var _i2 = 0, l = bpoints.length / 2; _i2 < l; _i2++) { points.push(bpoints[(l - _i2 - 1) * 2]); points.push(bpoints[(l - _i2 - 1) * 2 + 1]); } points = points.concat([points[0], points[1]]); } else { points = points.concat([points[points.length - 2], originPos, points[0], originPos, points[0], points[1]]); } ; var pointLen = points.length / 2; for (var i = 0; i < pointLen; i++) { var x = points[i * 2]; var y = points[i * 2 + 1]; if (!i) { path += M + x + ' ' + y; } else { path += L + x + ' ' + y; if (i == pointLen - 1) { path += Z; } } } } }); return path; } //根据x方向的 val来 获取对应的node, 这个node可能刚好是一个node, 也可能两个node中间的某个位置 }, { key: "getNodeInfoOfX", value: function getNodeInfoOfX(x) { //现在从data中查找 1px 间距内的值,有的话返回 for (var i = 0, l = this.data.length; i < l; i++) { if (this.data[i].value !== null && Math.abs(this.data[i].x - x) <= 1) { //左右相差不到 1px 的,都算 return this.data[i]; } } if (!this.node.showTweenData) { return; } var getPointFromXInLine = function getPointFromXInLine(x, line) { var p = { x: x, y: 0 }; p.y = line[0][1] + (line[1][1] - line[0][1]) / (line[1][0] - line[0][0]) * (x - line[0][0]); return p; }; var point; var _search = function search(points) { //points 是一维的数据,至少一个点有两个数据 if (points.length < 2) return; var pointLen = points.length / 2; if (x < points[0] || x > points[(pointLen - 1) * 2]) { //x<points[0][0] || x>points.slice(-1)[0][0] //x不在该points区间,忽略 return; } ; var midInd = parseInt(pointLen / 2); var midNextInd = midInd + 1; var midPreInd = midInd - 1; var midX = points[midInd * 2]; var midY = points[midInd * 2 + 1]; if (Math.abs(midX - x) <= 1) { //假如中间点的x和查找的x相差1以内,就已该midX为准 point = { x: midX, y: midY }; return; } ; var _pl = []; if (x > midX) { if (x < points[midNextInd * 2]) { //大于midX但是小于下一个点 point = getPointFromXInLine(x, [[midX, midY], [points[midNextInd * 2], points[midNextInd * 2 + 1]]]); return; } else { _pl = points.slice(midNextInd * 2); } } else { if (x > points[midPreInd * 2]) { point = getPointFromXInLine(x, [[points[midPreInd * 2], points[midPreInd * 2 + 1]], [midX, midY]]); return; } else { _pl = points.slice(0, midInd * 2); } } ; _search(_pl); }; if (this._line) { var lineGraphsData = this._line.graphics.graphicsData; lineGraphsData.forEach(function (graphsData) { if (!point) { _search(graphsData.shape.points); } }); } ; if (!point || point.y == undefined) { return null; } ; //和data 中数据的格式保持一致 var node = { type: "line", iGroup: this.iGroup, iNode: -1, //并非data中的数据,而是计算出来的数据 field: this.field, value: this._yAxis.getValOfPos(-point.y), x: point.x, y: point.y, rowData: null, //非data中的数据,没有rowData color: null }; node.color = this._getProp(this.node.strokeStyle, node); return node; } }, { key: "tipsPointerOf", value: function tipsPointerOf(e) { var _this5 = this; if (e.eventInfo) { var iNode = -1; if (e.eventInfo.xAxis.layoutType == "proportion") { var nodeData = this.getNodeInfoOfX(e.eventInfo.xAxis.x); if (nodeData) { iNode = nodeData.iNode; } } else { iNode = e.eventInfo.iNode; } if (iNode != this.__currFocusInd && this.__currFocusInd != -1) { this.unfocusOf(this.__currFocusInd); } ; if (iNode != -1 && e.eventInfo.nodes && e.eventInfo.nodes.length && e.eventInfo.nodes.find(function (node) { return node.field == _this5.field; })) { this.focusOf(iNode); } } } }, { key: "tipsPointerHideOf", value: function tipsPointerHideOf(e) { if (e.eventInfo) { this.unfocusOf(e.eventInfo.iNode); } } }, { key: "focusOf", value: function focusOf(iNode) { var node = this.data[iNode]; if (node) { var _node = node.nodeElement; if (_node && !node.focused && this.__currFocusInd != iNode) { //console.log( 'focusOf' ) _node._fillStyle = _node.context.fillStyle; _node.context.fillStyle = 'white'; _node.context.r += _node.context.lineWidth / 2; _node._visible = _node.context.visible; _node.context.visible = true; var _focusNode = _node.clone(); this._focusNodes.addChild(_focusNode); //_focusNode.context.r += 6; _focusNode.context.visible = true; _focusNode.context.lineWidth = 0; //不需要描边 _focusNode.context.fillStyle = _node.context.strokeStyle; _focusNode.context.globalAlpha = this.node.focus.alpha; _focusNode.animate({ r: _focusNode.context.r + this.node.focus.radiusDiff }, { duration: 300 }); this.__currFocusInd = iNode; } node.focused = true; } } }, { key: "unfocusOf", value: function unfocusOf(iNode) { if (this.__currFocusInd > -1) { iNode = this.__currFocusInd; } ; var node = this.data[iNode]; if (node) { this._focusNodes.removeAllChildren(); var _node = node.nodeElement; if (_node && node.focused) { //console.log('unfocus') _node.context.fillStyle = _node._fillStyle; _node.context.r -= _node.context.lineWidth / 2; _node.context.visible = _node._visible; node.focused = false; this.__currFocusInd = -1; } ; } } }], [{ key: "defaultProps", value: function defaultProps() { return { aniDuration: { //覆盖基类中的设置,line的duration要1000 detail: '动画时长', default: 1000 }, line: { detail: '线配置', propertys: { enabled: { detail: '是否开启', default: true }, growDriction: { detail: '生长动画的方向,默认为从左到右(leftRgiht),可选rightLeft', default: 'leftRight' }, strokeStyle: { detail: '线的颜色', default: undefined //不会覆盖掉constructor中的定义 }, hexToLineargradientType: { detail: 'hex颜色转换成默认的渐隐效果的方案,默认all(左右两边都有渐隐的渐变),可选left right none(不做渐隐渐变)', default: 'all' }, lineargradientDriction: { detail: '线的填充色是渐变对象的话,这里用来描述方向,默认从上到下(topBottom),可选leftRight', default: 'leftRight' //可选 topBottom }, lineWidth: { detail: '线的宽度', default: 2 }, lineType: { detail: '线的样式', default: 'solid' }, lineDash: { detail: '虚线的线段样式,默认[6,3]', default: [2, 5] }, smooth: { detail: '是否平滑处理', default: true }, shadowOffsetX: { detail: '折线的X方向阴影偏移量', default: 0 }, shadowOffsetY: { detail: '折线的Y方向阴影偏移量', default: 2 }, shadowBlur: { detail: '折线的阴影模糊效果', default: 8 }, shadowColor: { detail: '折线的阴影颜色,默认和折线的strokeStyle同步, 如果strokeStyle是一个渐变色,那么shadowColor就会失效,变成默认的黑色,需要手动设置该shadowColor', default: function _default() { var fieldColor = this.color; return (0, _color.colorRgba)(fieldColor, 0.4); } } } }, node: { detail: '单个数据节点配置,对应线上的小icon图形', propertys: { enabled: { detail: '是否开启', default: true }, shapeType: { detail: '节点icon的图形类型,默认circle', documentation: '可选有"isogon"(正多边形),"path"(自定义path路径,待实现)', default: 'circle' }, isogonPointNum: { detail: 'shapeType为"isogon"时有效,描述正多边形的边数', default: 3 }, path: { detail: 'shapeType为path的时候,描述图形的path路径', default: null }, // corner: { // detail: '拐角才有节点', // default: false // }, radius: { detail: '节点半径', default: 3 }, fillStyle: { detail: '节点图形的背景色', default: null }, strokeStyle: { detail: '节点图形的描边色,默认和line.strokeStyle保持一致', default: null }, lineWidth: { detail: '节点图形边宽大小,默认跟随line.lineWidth', default: null }, visible: { detail: '节点是否显示,支持函数', default: true }, focus: { detail: "节点hover态设置", propertys: { radiusDiff: { detail: 'hover后的背景节点半径相差,正数为变大值,默认为4', default: 4 }, alpha: { detail: 'hover后的背景节点透明度,默认为0.5', default: 0.5 } } }, showTweenData: { detail: '是否显示补间数据(数据节点中间补间出来的折线数据,iNode都是-1)', default: false } } }, label: { detail: '文本配置', propertys: { enabled: { detail: '是否开启', default: false }, fontColor: { detail: '文本颜色', default: null }, strokeStyle: { detail: '文本描边色', default: null }, fontSize: { detail: '文本字体大小', default: 12 }, format: { detail: '文本格式化处理函数', default: null }, textAlign: { detail: '水平布局方式', default: 'center' }, textBaseline: { detail: '垂直布局方式', default: 'bottom' }, arrangementRules: { detail: '排列规则', default: 'auto' //可选 单双号(oddAndEven) } } }, area: { detail: '面积区域配置', propertys: { enabled: { detail: '是否开启', default: true }, lineargradientDriction: { detail: '面积的填充色是渐变对象的话,这里用来描述方向,默认null(就会从line中取),从上到下(topBottom),可选leftRight', default: 'topBottom' //默认null(就会和line保持一致),可选 topBottom leftRight }, fillStyle: { detail: '面积背景色', default: null }, alpha: { detail: '面积透明度', default: 0.5 }, bottomLine: { detail: 'area的底部线配置', propertys: { enabled: { detail: '是否开启', default: true } } } } } }; } }]); }(event.Dispatcher);