You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
7.7 KiB
248 lines
7.7 KiB
/**
|
|
* zrender
|
|
*
|
|
* @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
|
|
* Yi Shen(https://github.com/pissang)
|
|
*
|
|
* shape类:标线
|
|
*/
|
|
|
|
/**
|
|
* @typedef {Object} IMarkLineStyle
|
|
* @property {number} xStart 起点x坐标
|
|
* @property {number} yStart 起点y坐标
|
|
* @property {number} xEnd 终止点x坐标
|
|
* @property {number} yEnd 终止点y坐标
|
|
* @property {number} cpX1 控制点x坐标,可以使用updatePoints自动根据curveness计算
|
|
* @property {number} cpY1 控制点y坐标,可以使用updatePoints自动根据curveness计算
|
|
* @property {number} curveness 曲度
|
|
* @property {Array.<string>} symbol
|
|
* @property {Array.<number>} symbolRotate
|
|
*/
|
|
define(function (require) {
|
|
var Base = require('zrender/shape/Base');
|
|
var IconShape = require('./Icon');
|
|
var LineShape = require('zrender/shape/Line');
|
|
var lineInstance = new LineShape({});
|
|
var CurveShape = require('zrender/shape/BezierCurve');
|
|
var curveInstance = new CurveShape({});
|
|
|
|
var area = require('zrender/tool/area');
|
|
var dashedLineTo = require('zrender/shape/util/dashedLineTo');
|
|
var zrUtil = require('zrender/tool/util');
|
|
var curveTool = require('zrender/tool/curve');
|
|
|
|
function MarkLine(options) {
|
|
Base.call(this, options);
|
|
|
|
if (this.style.curveness > 0) {
|
|
this.updatePoints(this.style);
|
|
}
|
|
if (this.highlightStyle.curveness > 0) {
|
|
this.updatePoints(this.highlightStyle);
|
|
}
|
|
}
|
|
|
|
MarkLine.prototype = {
|
|
type : 'mark-line',
|
|
/**
|
|
* 画刷
|
|
* @param ctx 画布句柄
|
|
* @param isHighlight 是否为高亮状态
|
|
* @param updateCallback 让painter更新视图,base.brush没用,需要的话重载brush
|
|
*/
|
|
brush : function (ctx, isHighlight) {
|
|
var style = this.style;
|
|
|
|
if (isHighlight) {
|
|
// 根据style扩展默认高亮样式
|
|
style = this.getHighlightStyle(
|
|
style,
|
|
this.highlightStyle || {}
|
|
);
|
|
}
|
|
|
|
ctx.save();
|
|
this.setContext(ctx, style);
|
|
|
|
// 设置transform
|
|
this.setTransform(ctx);
|
|
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
this.buildPath(ctx, style);
|
|
ctx.stroke();
|
|
ctx.restore();
|
|
|
|
this.brushSymbol(ctx, style, 0);
|
|
this.brushSymbol(ctx, style, 1);
|
|
|
|
this.drawText(ctx, style, this.style);
|
|
|
|
ctx.restore();
|
|
},
|
|
|
|
/**
|
|
* 创建线条路径
|
|
* @param {Context2D} ctx Canvas 2D上下文
|
|
* @param {Object} style 样式
|
|
*/
|
|
buildPath : function (ctx, style) {
|
|
var lineType = style.lineType || 'solid';
|
|
|
|
ctx.moveTo(style.xStart, style.yStart);
|
|
if (style.curveness > 0) {
|
|
// FIXME Bezier 在少部分浏览器上暂时不支持虚线
|
|
var lineDash = null;
|
|
switch (lineType) {
|
|
case 'dashed':
|
|
lineDash = [5, 5];
|
|
break;
|
|
case'dotted':
|
|
lineDash = [1, 1];
|
|
break;
|
|
}
|
|
if (lineDash && ctx.setLineDash) {
|
|
ctx.setLineDash(lineDash);
|
|
}
|
|
|
|
ctx.quadraticCurveTo(
|
|
style.cpX1, style.cpY1, style.xEnd, style.yEnd
|
|
);
|
|
}
|
|
else {
|
|
if (lineType == 'solid') {
|
|
ctx.lineTo(style.xEnd, style.yEnd);
|
|
}
|
|
else {
|
|
var dashLength = (style.lineWidth || 1)
|
|
* (style.lineType == 'dashed' ? 5 : 1);
|
|
dashedLineTo(
|
|
ctx, style.xStart, style.yStart,
|
|
style.xEnd, style.yEnd, dashLength
|
|
);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Update cpX1 and cpY1 according to curveniss
|
|
* @param {Object} style
|
|
*/
|
|
updatePoints: function (style) {
|
|
var curveness = style.curveness || 0;
|
|
var inv = 1;
|
|
|
|
var x0 = style.xStart;
|
|
var y0 = style.yStart;
|
|
var x2 = style.xEnd;
|
|
var y2 = style.yEnd;
|
|
var x1 = (x0 + x2) / 2 - inv * (y0 - y2) * curveness;
|
|
var y1 =(y0 + y2) / 2 - inv * (x2 - x0) * curveness;
|
|
|
|
style.cpX1 = x1;
|
|
style.cpY1 = y1;
|
|
},
|
|
|
|
/**
|
|
* 标线始末标注
|
|
*/
|
|
brushSymbol : function (ctx, style, idx) {
|
|
if (style.symbol[idx] == 'none') {
|
|
return;
|
|
}
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
|
|
ctx.lineWidth = style.symbolBorder;
|
|
ctx.strokeStyle = style.symbolBorderColor;
|
|
// symbol
|
|
var symbol = style.symbol[idx].replace('empty', '')
|
|
.toLowerCase();
|
|
if (style.symbol[idx].match('empty')) {
|
|
ctx.fillStyle = '#fff'; //'rgba(0, 0, 0, 0)';
|
|
}
|
|
|
|
// symbolRotate
|
|
var x0 = style.xStart;
|
|
var y0 = style.yStart;
|
|
var x2 = style.xEnd;
|
|
var y2 = style.yEnd;
|
|
var x = idx === 0 ? x0 : x2;
|
|
var y = idx === 0 ? y0 : y2;
|
|
var curveness = style.curveness || 0;
|
|
var rotate = style.symbolRotate[idx] != null ? (style.symbolRotate[idx] - 0) : 0;
|
|
rotate = rotate / 180 * Math.PI;
|
|
|
|
if (symbol == 'arrow' && rotate === 0) {
|
|
if (curveness === 0) {
|
|
var sign = idx === 0 ? -1 : 1;
|
|
rotate = Math.PI / 2 + Math.atan2(
|
|
sign * (y2 - y0), sign * (x2 - x0)
|
|
);
|
|
}
|
|
else {
|
|
var x1 = style.cpX1;
|
|
var y1 = style.cpY1;
|
|
|
|
var quadraticDerivativeAt = curveTool.quadraticDerivativeAt;
|
|
var dx = quadraticDerivativeAt(x0, x1, x2, idx);
|
|
var dy = quadraticDerivativeAt(y0, y1, y2, idx);
|
|
|
|
rotate = Math.PI / 2 + Math.atan2(dy, dx);
|
|
}
|
|
}
|
|
|
|
ctx.translate(x, y);
|
|
|
|
if (rotate !== 0) {
|
|
ctx.rotate(rotate);
|
|
}
|
|
|
|
// symbolSize
|
|
var symbolSize = style.symbolSize[idx];
|
|
IconShape.prototype.buildPath(ctx, {
|
|
x: -symbolSize,
|
|
y: -symbolSize,
|
|
width: symbolSize * 2,
|
|
height: symbolSize * 2,
|
|
iconType: symbol
|
|
});
|
|
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
ctx.stroke();
|
|
ctx.restore();
|
|
},
|
|
|
|
/**
|
|
* 返回矩形区域,用于局部刷新和文字定位
|
|
* @param {Object} style
|
|
*/
|
|
getRect : function (style) {
|
|
style.curveness > 0 ? curveInstance.getRect(style)
|
|
: lineInstance.getRect(style);
|
|
return style.__rect;
|
|
},
|
|
|
|
isCover : function (x, y) {
|
|
var originPos = this.transformCoordToLocal(x, y);
|
|
x = originPos[0];
|
|
y = originPos[1];
|
|
|
|
// 快速预判并保留判断矩形
|
|
if (this.isCoverRect(x, y)) {
|
|
// 矩形内
|
|
return this.style.curveness > 0
|
|
? area.isInside(curveInstance, this.style, x, y)
|
|
: area.isInside(lineInstance, this.style, x, y);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
};
|
|
|
|
zrUtil.inherits(MarkLine, Base);
|
|
|
|
return MarkLine;
|
|
});
|
|
|