/** * @fileOverview area shape * @author dxq613@gmail.com * @author sima.zhang1990@gmail.com */ var Util = require('../../util'); var Shape = require('./shape'); var PathUtil = require('../util/path'); var ShapeUtil = require('../util/shape'); var Global = require('../../global'); function getLineAttrs(cfg) { var defaultAttrs = Global.shape.hollowArea; var lineAttrs = Util.mix({}, defaultAttrs, cfg.style); ShapeUtil.addStrokeAttrs(lineAttrs, cfg); if (Util.isNumber(cfg.size)) { lineAttrs.lineWidth = cfg.size; } return lineAttrs; } function getFillAttrs(cfg) { var defaultAttrs = Global.shape.area; var areaAttrs = Util.mix({}, defaultAttrs, cfg.style); ShapeUtil.addFillAttrs(areaAttrs, cfg); if (cfg.color) { areaAttrs.stroke = areaAttrs.stroke || cfg.color; } if (Util.isNumber(cfg.size)) { areaAttrs.lineWidth = cfg.size; } return areaAttrs; } function getPath(cfg, smooth, shape) { var path = []; var pointsArr = []; var topLinePoints = []; // area 区域上部分 var bottomLinePoints = []; // area 区域下部分 var isInCircle = cfg.isInCircle; Util.each(cfg.points, function (point) { topLinePoints.push(point[1]); bottomLinePoints.push(point[0]); }); // if (!isInCircle) { bottomLinePoints = bottomLinePoints.reverse(); // } pointsArr.push(topLinePoints, bottomLinePoints); Util.each(pointsArr, function (points, index) { var subPath = []; points = shape.parsePoints(points); var p1 = points[0]; if (isInCircle) { points.push({ x: p1.x, y: p1.y }); } if (smooth) { subPath = PathUtil.getSplinePath(points, false, cfg.constraint); } else { subPath = PathUtil.getLinePath(points, false); } if (index > 0) { subPath[0][0] = 'L'; } path = path.concat(subPath); }); path.push(['Z']); return path; } // get marker cfg function _getMarkerCfg(cfg) { return { symbol: function symbol(x, y, r) { return [['M', x - r, y - 4], ['L', x + r, y - 4], ['L', x + r, y + 4], ['L', x - r, y + 4], ['Z']]; }, radius: 5, fill: cfg.color, fillOpacity: 0.6 }; } // 鼠标悬浮触发active状态 function _getActiveCfg(type, cfg) { if (type === 'line' || type === 'smoothLine') { // 线加粗 var lineWidth = cfg.lineWidth || 0; return { lineWidth: lineWidth + 1 }; } var opacity = cfg.fillOpacity || cfg.opacity || 1; return { fillOpacity: opacity - 0.15, strokeOpacity: opacity - 0.15 }; } // 当只有一个数据时绘制点 function drawPointShape(shapeObj, cfg, container) { var coord = shapeObj._coord; var point = coord.convertPoint(cfg.points[0][1]); return container.addShape('circle', { attrs: Util.mix({ x: point.x, y: point.y, r: 2, fill: cfg.color }, cfg.style) }); } var Area = Shape.registerFactory('area', { defaultShapeType: 'area', /** * @override * @protected * 计算点 如果存在多个点,分割成单个的点, 不考虑多个x对应一个y的情况 * 单点则补上y0点 */ getDefaultPoints: function getDefaultPoints(pointInfo) { var points = []; var x = pointInfo.x; var y = pointInfo.y; var y0 = pointInfo.y0; y = Util.isArray(y) ? y : [y0, y]; Util.each(y, function (yItem) { points.push({ x: x, y: yItem }); }); return points; }, // 获取激活的图形属性 getActiveCfg: function getActiveCfg(type, cfg) { return _getActiveCfg(type, cfg); }, drawShape: function drawShape(type, cfg, container) { var shape = this.getShape(type); var gShape; if (cfg.points.length === 1 && Global.showSinglePoint) { gShape = drawPointShape(this, cfg, container); } else { gShape = shape.draw(cfg, container); } if (gShape) { gShape.set('origin', cfg.origin); gShape._id = cfg.splitedIndex ? cfg._id + cfg.splitedIndex : cfg._id; gShape.name = this.name; } return gShape; }, getSelectedCfg: function getSelectedCfg(type, cfg) { if (cfg && cfg.style) { return cfg.style; } return this.getActiveCfg(type, cfg); } }); // 默认:填充区域图 Shape.registerShape('area', 'area', { draw: function draw(cfg, container) { var attrs = getFillAttrs(cfg); var path = getPath(cfg, false, this); // path = this.parsePath(path, false); return container.addShape('path', { attrs: Util.mix(attrs, { path: path }) }); }, getMarkerCfg: function getMarkerCfg(cfg) { return _getMarkerCfg(cfg); } }); // 填充平滑区域图 Shape.registerShape('area', 'smooth', { draw: function draw(cfg, container) { var attrs = getFillAttrs(cfg); var coord = this._coord; // 曲线的限制 cfg.constraint = [[coord.start.x, coord.end.y], [coord.end.x, coord.start.y]]; var path = getPath(cfg, true, this); // path = this.parsePath(path, false); return container.addShape('path', { attrs: Util.mix(attrs, { path: path }) }); }, getMarkerCfg: function getMarkerCfg(cfg) { return _getMarkerCfg(cfg); } }); // 封闭的折线 Shape.registerShape('area', 'line', { draw: function draw(cfg, container) { var attrs = getLineAttrs(cfg); var path = getPath(cfg, false, this); // path = this.parsePath(path, false); return container.addShape('path', { attrs: Util.mix(attrs, { path: path }) }); }, getMarkerCfg: function getMarkerCfg(cfg) { return _getMarkerCfg(cfg); } }); // 封闭的平滑线 Shape.registerShape('area', 'smoothLine', { draw: function draw(cfg, container) { var attrs = getLineAttrs(cfg); var path = getPath(cfg, true, this); return container.addShape('path', { attrs: Util.mix(attrs, { path: path }) }); }, getMarkerCfg: function getMarkerCfg(cfg) { return _getMarkerCfg(cfg); } }); Area.spline = Area.smooth; module.exports = Area;