echarts自訂tooltip繪製軌跡

來源:互聯網
上載者:User

之前用過一陣子echarts做APP上的趨勢圖,修改過源碼實現一些自訂效果。以及設定一些echarts-m.js的隱藏setting,在此Mark一下,防止忘記。

1. 自訂tooltip繪製軌跡。

    echarts提供的tooltip,在繪製直線時,只提供了實線,虛線,陰影線。如果要在直線的基礎上,增加一些功能,比如線要超出圖的邊界(如果用formatter事件注入,會有延遲效果),就需要修改一下源碼,指導內部的繪製路徑,因為echarts本身就是用canvas畫tootip的。廢話不多說。

    A. 新增Config屬性。

在'echarts/component/tooltip'模組下,ecConfig.tooltip的定義中,擴充下axisPointer,新增selfDefine屬性,預設為String,不啟用。傳入function可以覆蓋使用。

axisPointer: {            type: 'line',            lineStyle: {                color: '#48b',                width: 2,                type: 'solid',                selfDefine : 'self defined function to help draw tip panel'   //modify, new add            },            crossStyle: {                color: '#1e90ff',                width: 1,                type: 'dashed',                selfDefine : 'self defined function to help draw tip panel'   //modify, new add            },            shadowStyle: {                color: 'rgba(150,150,150,0.3)',                width: 'auto',                type: 'default',                selfDefine : 'self defined function to help draw tip panel'   //modify, new add            }        },
  B. 在Tooltip.prototype = {}的定義中,修改_styleAxisPointer方法,注意//new add 註解部分為selfDefine方法的注入。

_styleAxisPointer: function (seriesArray, xStart, yStart, xEnd, yEnd, gap, x, y) {            if (seriesArray.length > 0) {                var queryTarget;                var curType;                var axisPointer = this.option.tooltip.axisPointer;                var pointType = axisPointer.type;                var appendStyle = this.option.tooltip.appendStyle;                 var style = {                    line: {},                    cross: {},                    shadow: {}                };                for (var pType in style) {                    style[pType].color = axisPointer[pType + 'Style'].color;                    style[pType].width = axisPointer[pType + 'Style'].width;                    style[pType].type = axisPointer[pType + 'Style'].type;                    style[pType].selfDefine = axisPointer[pType + 'Style'].selfDefine;   // new add                }                for (var i = 0, l = seriesArray.length; i < l; i++) {                    queryTarget = seriesArray[i];                    curType = this.query(queryTarget, 'tooltip.axisPointer.type');                    pointType = curType || pointType;                    if (curType) {                        style[curType].color = this.query(queryTarget, 'tooltip.axisPointer.' + curType + 'Style.color') || style[curType].color;                        style[curType].width = this.query(queryTarget, 'tooltip.axisPointer.' + curType + 'Style.width') || style[curType].width;                        style[curType].type = this.query(queryTarget, 'tooltip.axisPointer.' + curType + 'Style.type') || style[curType].type;                        style[curType].selfDefine = style[curType].selfDefine;  //new add                    }                }                if (pointType === 'line') {                    var lineWidth = style.line.width;                    var isVertical = xStart == xEnd;                    this._axisLineShape.style = {                        xStart: isVertical ? this.subPixelOptimize(xStart, lineWidth) : xStart,                        yStart: isVertical ? yStart : this.subPixelOptimize(yStart, lineWidth),                        xEnd: isVertical ? this.subPixelOptimize(xEnd, lineWidth) : xEnd,                        yEnd: isVertical ? yEnd : this.subPixelOptimize(yEnd, lineWidth),                        strokeColor: style.line.color,                        lineWidth: lineWidth,                        lineType: style.line.type,                        selfDefine : style.line.selfDefine   //new add                     };                    this._axisLineShape.invisible = false;                    this.zr.modShape(this._axisLineShape.id);                } else if (pointType === 'cross') {                    var crossWidth = style.cross.width;                    this._axisCrossShape.style = {                        brushType: 'stroke',                        rect: this.component.grid.getArea(),                        x: this.subPixelOptimize(x, crossWidth),                        y: this.subPixelOptimize(y, crossWidth),                        text: ('( ' + this.component.xAxis.getAxis(0).getValueFromCoord(x) + ' , ' + this.component.yAxis.getAxis(0).getValueFromCoord(y) + ' )').replace('  , ', ' ').replace(' ,  ', ' '),                        textPosition: 'specific',                        strokeColor: style.cross.color,                        lineWidth: crossWidth,                        lineType: style.cross.type                    };                    if (this.component.grid.getXend() - x > 100) {                        this._axisCrossShape.style.textAlign = 'left';                        this._axisCrossShape.style.textX = x + 10;                    } else {                        this._axisCrossShape.style.textAlign = 'right';                        this._axisCrossShape.style.textX = x - 10;                    }                    if (y - this.component.grid.getY() > 50) {                        this._axisCrossShape.style.textBaseline = 'bottom';                        this._axisCrossShape.style.textY = y - 10;                    } else {                        this._axisCrossShape.style.textBaseline = 'top';                        this._axisCrossShape.style.textY = y + 10;                    }                    this._axisCrossShape.invisible = false;                    this.zr.modShape(this._axisCrossShape.id);                } else if (pointType === 'shadow') {                    if (style.shadow.width == null || style.shadow.width === 'auto' || isNaN(style.shadow.width)) {                        style.shadow.width = gap;                    }                    if (xStart === xEnd) {                        if (Math.abs(this.component.grid.getX() - xStart) < 2) {                            style.shadow.width /= 2;                            xStart = xEnd = xEnd + style.shadow.width / 2;                        } else if (Math.abs(this.component.grid.getXend() - xStart) < 2) {                            style.shadow.width /= 2;                            xStart = xEnd = xEnd - style.shadow.width / 2;                        }                    } else if (yStart === yEnd) {                        if (Math.abs(this.component.grid.getY() - yStart) < 2) {                            style.shadow.width /= 2;                            yStart = yEnd = yEnd + style.shadow.width / 2;                        } else if (Math.abs(this.component.grid.getYend() - yStart) < 2) {                            style.shadow.width /= 2;                            yStart = yEnd = yEnd - style.shadow.width / 2;                        }                    }                    this._axisShadowShape.style = {                        xStart: xStart,                        yStart: yStart,                        xEnd: xEnd,                        yEnd: yEnd,                        strokeColor: style.shadow.color,                        lineWidth: style.shadow.width                    };                    this._axisShadowShape.invisible = false;                    this.zr.modShape(this._axisShadowShape.id);                }                               this.zr.refreshNextFrame();                if(appendStyle && (typeof appendStyle === 'function')){  //new add                appendStyle.call(this, x, y);                }            }        },
   C.  修改模組'zrender/shape/Line', Line.prototype = {} 的定義處,指導buildPath繪製。如果有傳入selfDefine函數,使用selfDefine的畫圖路徑,通過這種方式,可以繪製各種樣式,不一定要按照echarts提供的幾種tooltip.

Line.prototype = {        type: 'line',        buildPath: function (ctx, style) {        if(style.selfDefine && (typeof style.selfDefine === 'function')){//      console.log(style.xStart+" "+style.yStart+" "+style.xEnd+" "+style.yEnd);        var selfDefine = style.selfDefine;        selfDefine.call(this,ctx,style.xStart,style.yStart,style.xEnd,style.yEnd);                return;        }else if (!style.lineType || style.lineType == 'solid') {//          console.log('solid line');                ctx.moveTo(style.xStart, style.yStart);                ctx.lineTo(style.xEnd, style.yEnd);            } else if (style.lineType == 'dashed' || style.lineType == 'dotted') {//          console.log('dash line');                var dashLength = (style.lineWidth || 1) * (style.lineType == 'dashed' ? 5 : 1);                dashedLineTo(ctx, style.xStart, style.yStart, style.xEnd, style.yEnd, dashLength);            }        },        getRect: function (style) {            if (style.__rect) {                return style.__rect;            }            var lineWidth = style.lineWidth || 1;            style.__rect = {                x: Math.min(style.xStart, style.xEnd) - lineWidth,                y: Math.min(style.yStart, style.yEnd) - lineWidth,                width: Math.abs(style.xStart - style.xEnd) + lineWidth,                height: Math.abs(style.yStart - style.yEnd) + lineWidth            };            return style.__rect;        }    };
  D. 使用。

   修改完成後,使用配置如下。通過設定yStart-26後,可以使tooltip線超出echarts的網格地區。

tooltip: {showDelay:0,transitionDuration:0,backgroundColor: "#a6afb6",borderColor: "yellow",borderWidth: 2,padding: 0,showContent: false,trigger: 'axis', //item,axisposition: function() {return [0, 0];},formatter: function(params) {}, axisPointer: {type: 'line',lineStyle: {width: 2,color :"#a6afb6",selfDefine: function(ctx,xStart,yStart,xEnd,yEnd){ctx.moveTo(xStart, yStart-26);ctx.lineTo(xEnd, yEnd);}}}},
2. echarts-m.

    echarts提供了一個m版本,刪除了很多PC事件,適用於APP, 但是API和PC版有一些不一致,尤其是Y軸座標值預設在右側,太蛋疼。通過查看原始碼,找到了這些預設設定。記錄如下:

    1. Y軸座標值水平位置

     yAxis > axisLabel > margin ,設定為35,可以調整。

yAxis: [{type: 'value',lineStyle: {color: '#a6afb6',width: 1,type: 'solid'},axisLine: {lineStyle: {  color: '#a6afb6',  width: 1,  type: 'solid'}      },   axisLabel: {textStyle: {   color: '#a6afb6'},margin: 35,  //modify for ehcarts-malign: 'right',formatter: function(value){if(value >= 10000000){value = value/1000000;value = value+"M";}else if(value >= 10000){value = value/1000;value = value+"K";}else{value = value+"";}for(var i = value.length ; i < 5;i++){value = " "+value;}return value;}}}],
  B. max3顯示重複趨勢線段。

設定animation:false

最後,有問題,歡迎交流。








聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.