\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5\D6?\BD\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2 \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4\E9\F2\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /home/heznutpr/log.heznutprivate.com/dist/assets/node_modules/echarts/util/shape/

Viewing File: MarkLine.js

/**
 * 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;
});