echarts bar內tooltip的formatter回調參數params.seriesId中的’\0’問題以及stack的獲取

對菜鳥來說,這真的是一個深坑……

 

先說結局:

    1、params對象的成員在echarts的“配置項”說明(http://echarts.baidu.com/option.html#series-bar.tooltip.formatter)裏進行了介紹,但並沒有出現seriesId成員;

    2、以3.5.0版本爲例,seriesId最終是由3865行的keyInfo.id ='\0' + keyInfo.name + '\0' + idNum++; 生成的,因此,你總會發現seriesId明明是個字符串,長度seriesId.length卻總是不對;

    3、本文意在bar series tooltip的formatter中獲取bar的stack值(http://echarts.baidu.com/option.html#series-bar.stack),echarts3.5.0、3.6.1中均未在params對象中提供。本文最終對echarts-3.5.0.js文件的getDataParams方法進行了修改,以便獲取到stack參數,以3.5.0版本爲例,第3618行開始,整個方法最終如下(其實就增加了一行):

getDataParams: function (dataIndex, dataType) {
    var data = this.getData(dataType);
    var rawValue = this.getRawValue(dataIndex, dataType);
    var rawDataIndex = data.getRawIndex(dataIndex);
    var name = data.getName(dataIndex, true);
    var itemOpt = data.getRawDataItem(dataIndex);

    return {
        componentType: this.mainType,
        componentSubType: this.subType,
        seriesType: this.mainType === 'series' ? this.subType : null,
        seriesIndex: this.seriesIndex,
        seriesId: this.id,
        seriesName: this.name,
        name: name,
        dataIndex: rawDataIndex,
        data: itemOpt,
        dataType: dataType,
        value: rawValue,
        color: data.getItemVisual(dataIndex, 'color'),
        stack: this.get(‘stack’),    //增加此行,修改之處
        // Param name list for mapping `a`, `b`, `c`, `d`, `e`
        $vars: ['seriesName', 'name', 'value']
    };
},


 

羅索的正文:

 

本文針對的echarts版本爲:3.5.0;3.6.1;


使用echarts,作者期望初步得到下面的結果圖:


 

        並且,在上圖中,能實現這樣的效果:舉例來說,當鼠標hover到“產品1”的“口徑1”最上面的棕色區域時,在彈出的tooltip中應該顯示中關鍵字“口徑1”、“產品1”、“8類買家”等。

        但是,從上圖的tooltip中,能夠看到,並沒有“口徑1”的字眼……

        如何獲取?

        從echarts的文檔http://echarts.baidu.com/option.html#series-bar.stack處,我們能夠看到stack的介紹,它主要起數據堆疊的作用。但尷尬的是,我通過你堆疊之後,卻不能知道我的堆疊的組是誰。

        所以,作者仔細觀察tooltip的顯示,發現seriesId的值“8類買家0”(如上圖tooltip內),與seriesName的值“8類買家”就差一個0,而且,當移動到“口徑2”時,這個“8類買家0”會變爲“8類買家1”。想當然的,作者以爲這個0、1至少能夠代表stack的索引吧。

        然後就開始瞭如下的代碼:

tooltip : {
        formatter: function(params) {
            var iStackIndex = parseInt(params.seriesId.replace(params.seriesName, ''));
            return aryStack[iStackIndex];
        }
    },

        然後發現,iStackIndex總是爲NaN,百思不得其解,各種查看文檔各種找資料,玩兒命懷疑智商……

        然而,茫然堅守的調試仍舊沒有解決問題。

        然後使用console.log(params.seriesId.length)發現其長度總是不對,而同樣的console.log(params.seriesName.length)卻是對的。

        經過#%.^&^@的折騰,最後,終於跟同事一起構造出了seriesId裏面莫名出現的’\0’。作爲前端小白,真心覺得WTF……

        後面的事兒就簡單了,搜索echarts的源碼,發現真有’\0’出現,然後再一點點回溯,終於發現了本文開頭結局中的第2點。

        並且發現了上面的0、1與stack的索引僅是巧合,根本不能用其代表自己構造的stack數組下標。

 

        最後,附上上文echarts圖的源碼,以便讓你知道我在說什麼:

        (注意,你需要在http://echarts.baidu.com/demo.html#bar-stack運行下面的代碼)

app.title = '堆疊柱狀圖';

// 生成n個和爲sum的隨機整數
function randGenerator(n, sum) {
	  var aryRet = [];
  var fSumTmp = sum;
  var iAcc = 0;
  for (var i = 0; i < (n -1); i++) {
  	var iTmp = Math.ceil(Math.random() * (fSumTmp / 2));
    aryRet.push(iTmp);
    fSumTmp -= iTmp;
    iAcc += iTmp;
  }
  aryRet.push(sum-iAcc);
  return aryRet;
}


var aryDataXAxis = ['產品A','產品B','產品C','產品D','產品E'];
var aryDataLegend = ['1類買家','2類買家','3類買家','4類買家','5類買家','6類買家','8類買家'];

// map的格式
// mapData = ['口徑1', '口徑2']['產品A','產品B','產品C','產品D','產品E']['1類買家','2類買家','3類買家','4類買家','5類買家','6類買家','8類買家']
var mapData = [];
mapData['口徑1'] = [];
mapData['口徑2'] = [];
var aryStack = [];

// 最外層標明“口徑1”、“口徑2”
for (var itemMap in mapData) {
    aryStack.push(itemMap);
    // x軸
    for (var itemXAxis in aryDataXAxis) {
        mapData[itemMap][itemXAxis] = [];
        // y軸
        // for (var itemLegend in aryDataLegend) {
        //     mapData[itemMap][itemXAxis].push((Math.random() * 100).toFixed(1));
        // }
        mapData[itemMap][itemXAxis] = randGenerator(aryDataLegend.length, 100);
    }   
}

var arySeries = [];

// 最外層標明“口徑1”、“口徑2”
for (var itemMap in mapData) {
    
    // y軸
    for (var itemLegend in aryDataLegend) {
        //console.log(aryDataLegend[itemLegend]);
        var objTmp = new Object();
        objTmp.name = aryDataLegend[itemLegend];
        objTmp.type = 'bar';
        objTmp.stack = itemMap;
        objTmp.data = [];
        // x軸
        for (var itemXAxis in aryDataXAxis) {
            objTmp.data.push(mapData[itemMap][itemXAxis][itemLegend]);
        }
        objTmp.tooltip = {
            formatter: function (params) {

                return funcTooltip(params);
            }
        };
        if (itemLegend == aryDataLegend.length - 1) {
            objTmp.label = {
                normal: {
                    show: true,
                    position: 'top',
                    textStyle: {
                        color: '#666'  
                    },
                    formatter: itemMap
                } 
            };
        }
        arySeries.push(objTmp);
    }
}


function funcTooltip(params) {
    var aryHtml = [];
    aryHtml.push('<div style="text-align:left;">');
    for (var item in params) {
        aryHtml.push('<br />');
        aryHtml.push(item + ':' + params[item]);
    }
    aryHtml.push('</div>');
    return aryHtml.join('');
}

option = {
    tooltip : {
        formatter: function(params) {
            var iStackIndex = parseInt(params.seriesId.replace(params.seriesName, ''));
            return aryStack[iStackIndex];
        }
    },
    legend: {
        data: aryDataLegend
    },
    grid: {
        left: '3%',
        right: '4%',
        height: '280',
        containLabel: true
    },
    xAxis : [
        {
            type : 'category',
            data : aryDataXAxis
        }
    ],
    yAxis : [
        {
            type : 'value'
        }
    ],
    series : arySeries
};




發佈了40 篇原創文章 · 獲贊 9 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章