/** * @fileOverview 边的 shape * @author dxq613@gmail.com */ var Util = require('../../util'); var Shape = require('./shape'); var ShapeUtil = require('../util/shape'); var Global = require('../../global'); var PathUtil = require('../util/path'); var CORNER_PERCENT = 1 / 3; function getAttrs(cfg) { var defaultCfg = Global.shape.edge; var lineAttrs = Util.mix({}, defaultCfg, cfg.style); ShapeUtil.addStrokeAttrs(lineAttrs, cfg); if (cfg.size) { lineAttrs.lineWidth = cfg.size; } return lineAttrs; } var Edge = Shape.registerFactory('edge', { defaultShapeType: 'line', getDefaultPoints: function getDefaultPoints(pointInfo) { return ShapeUtil.splitPoints(pointInfo); }, getActiveCfg: function getActiveCfg(type, cfg) { var lineWidth = cfg.lineWidth || 0; return { lineWidth: lineWidth + 1 }; } }); function getCPath(from, to) { var points = []; points.push({ x: from.x, y: from.y * (1 - 1 / 2) + to.y * 1 / 2 }); points.push({ y: from.y * (1 - 1 / 2) + to.y * 1 / 2, x: to.x }); points.push(to); var sub = ['C']; Util.each(points, function (point) { sub.push(point.x, point.y); }); return sub; } function getQPath(to, center) { var points = []; points.push({ x: center.x, y: center.y }); points.push(to); var sub = ['Q']; Util.each(points, function (point) { sub.push(point.x, point.y); }); return sub; } function createSmoothPath(from, to) { var sub = getCPath(from, to); var path = [['M', from.x, from.y]]; path.push(sub); return path; } function createArcPath(from, to, center) { var sub = getQPath(to, center); var path = [['M', from.x, from.y]]; path.push(sub); return path; } function createArcWeightPath(points, center) { var arc1 = getQPath(points[1], center); var arc2 = getQPath(points[3], center); var path = [['M', points[0].x, points[0].y]]; path.push(arc2); path.push(['L', points[3].x, points[3].y]); path.push(['L', points[2].x, points[2].y]); path.push(arc1); path.push(['L', points[1].x, points[1].y]); path.push(['L', points[0].x, points[0].y]); path.push(['Z']); return path; } function createRectPath(from, to) { var points = []; points.push({ y: from.y * (1 - CORNER_PERCENT) + to.y * CORNER_PERCENT, x: from.x }); points.push({ y: from.y * (1 - CORNER_PERCENT) + to.y * CORNER_PERCENT, x: to.x }); points.push(to); var path = [['M', from.x, from.y]]; Util.each(points, function (point) { path.push(['L', point.x, point.y]); }); return path; } Shape.registerShape('edge', 'line', { draw: function draw(cfg, container) { var points = this.parsePoints(cfg.points); var attrCfg = getAttrs(cfg); var path = PathUtil.getLinePath(points); var line = container.addShape('path', { attrs: Util.mix(attrCfg, { path: path }) }); return line; }, getMarkerCfg: function getMarkerCfg(cfg) { return Util.mix({ symbol: 'circle', radius: 4.5 }, getAttrs(cfg)); } }); Shape.registerShape('edge', 'vhv', { draw: function draw(cfg, container) { var points = cfg.points; var attrCfg = getAttrs(cfg); var path = createRectPath(points[0], points[1]); path = this.parsePath(path); var line = container.addShape('path', { attrs: Util.mix(attrCfg, { path: path }) }); return line; }, getMarkerCfg: function getMarkerCfg(cfg) { return Util.mix({ symbol: 'circle', radius: 4.5 }, getAttrs(cfg)); } }); Shape.registerShape('edge', 'smooth', { draw: function draw(cfg, container) { var points = cfg.points; var attrCfg = getAttrs(cfg); var path = createSmoothPath(points[0], points[1]); path = this.parsePath(path); var line = container.addShape('path', { attrs: Util.mix(attrCfg, { path: path }) }); return line; }, getMarkerCfg: function getMarkerCfg(cfg) { return Util.mix({ symbol: 'circle', radius: 4.5 }, getAttrs(cfg)); } }); // 弧线包括笛卡尔坐标系下的半圆弧线、极坐标系下以圆心为控制点的二阶曲线、笛卡尔坐标系下带权重的三阶曲线、极坐标系下带权重的以圆心为控制点的二阶曲线 Shape.registerShape('edge', 'arc', { draw: function draw(cfg, container) { var points = cfg.points; var type = points.length > 2 ? 'weight' : 'normal'; var attrCfg = getAttrs(cfg); var line; var path; if (cfg.isInCircle) { var center = { x: 0, y: 1 }; if (type === 'normal') { path = createArcPath(points[0], points[1], center); } else { attrCfg.fill = attrCfg.stroke; path = createArcWeightPath(points, center); } path = this.parsePath(path); line = container.addShape('path', { attrs: Util.mix(attrCfg, { path: path }) }); } else { if (type === 'normal') { points = this.parsePoints(points); line = container.addShape('arc', { attrs: Util.mix(attrCfg, { x: (points[1].x + points[0].x) / 2, y: points[0].y, r: Math.abs(points[1].x - points[0].x) / 2, startAngle: Math.PI, endAngle: Math.PI * 2 }) }); } else { path = [['M', points[0].x, points[0].y], ['L', points[1].x, points[1].y]]; var c1 = getCPath(points[1], points[3]); var c2 = getCPath(points[2], points[0]); path.push(c1); path.push(['L', points[3].x, points[3].y]); path.push(['L', points[2].x, points[2].y]); path.push(c2); path.push(['Z']); path = this.parsePath(path); attrCfg.fill = attrCfg.stroke; line = container.addShape('path', { attrs: Util.mix(attrCfg, { path: path }) }); } } return line; }, getMarkerCfg: function getMarkerCfg(cfg) { return Util.mix({ symbol: 'circle', radius: 4.5 }, getAttrs(cfg)); } }); module.exports = Edge;