Incubator-echarts: toolTip的formatter属性里,用function自定义时,打印出params.seriesName不能跟配置的系列名对应

Created on 27 Sep 2019  ·  10Comments  ·  Source: apache/incubator-echarts

Version

4.3.0

Steps to reproduce

鼠标悬浮到地图,观察分组名,全都是第一个系列的名称

What is expected?

跟系列名对应起来

What is actually happening?

全部是第一个系列名称

bug missing-demo pending

Most helpful comment

你点下图例试试:

把「分组1」隐藏,是不是都是「分组2」了?

你这两个 series 是罗在一起的两张中国地图啊= =

此外,formatter 的回调函数把 params.data.value 也显示看看,是不是都是「分组1」的数据值—— 30

————
建议只用一个 series,把数据改成这样:
[{ name: "新疆", group: "分组1", value: 30 }, { name: "西藏", group: "分组2", value: 80 }]

自定义图例实现

——————
本来想写个 demo 放 gallery 上,结果服务器更新没法保存……

贴下代码吧(用你的 demo 改的):
脚本引用下「常用脚本>>地图>>china」

// 地图使用的数据
data = [{
    name: '新疆',
    group: '分组1',
    value: 30
}, {
    name: '西藏',
    group: '分组2',
    value: 80
}];

// 一个过滤二维数组的函数,在这凑合用下,过滤下 JSON 数组
function arrFilter(source, hasColumnName, filterCondition) {
    var iBegin = hasColumnName ? 1 : 0;
    var res = hasColumnName ? [source[0]] : [];
    if (typeof(filterCondition) === 'function') {
        for (var i = iBegin; i < source.length; i++) {
            if (filterCondition(source[i])) {
                res.push(source[i]);
            }
        }
    } else if (typeof(filterCondition) === 'string') {
        for (var j = iBegin; j < source.length; j++) {
            var item = source[j];
            if (eval(filterCondition)) {
                res.push(source[j]);
            }
        }
    }
    return res;
}

option = {
    color: ['#469fe3', '#766baa'],
    tooltip: {
        trigger: 'item',
        showDelay: 0,
        transitionDuration: 0.2,

        formatter: function(params) {
            //console.log(params);
            return params.name + '<br />' + params.data.group + ':' + params.data.value;
        }

    },
    visualMap: {
        left: 'right',
        min: 0,
        max: 100,
        inRange: {
            color: ['#469fe3', '#766baa']
        },
        text: ['High', 'Low'],
        calculable: true
    },
    legend: {
        data: ['分组1', '分组2']
    },
    series: [{
        type: 'pie',
        name: '分组1',
        self_Remark: '用于自定义图例'
    }, {
        type: 'pie',
        name: '分组2',
        self_Remark: '用于自定义图例'
    }, {
        name: '地图',
        type: 'map',
        map: 'china',
        data: data
    }]
};
myChart.setOption(option);

myChart.on('legendselectchanged', function(params) {
    //console.log(params)

    filterString1 = params.selected['分组1'] === true ? 'item.group === "分组1"' : 'false';
    filterString2 = params.selected['分组2'] === true ? 'item.group === "分组2"' : 'false';

    filterString = filterString1 + '||' + filterString2;

    myChart.setOption({
        series: {
            name: '地图',
            data: arrFilter(data, false, filterString)
        }
    });
});

效果如图:
image

All 10 comments

Could you provide a reproducible demo?

gallery.echartsjs.com 提交不了,我开了个repo作为demo:http://champyin.com/echarts-issues/

你点下图例试试:

把「分组1」隐藏,是不是都是「分组2」了?

你这两个 series 是罗在一起的两张中国地图啊= =

此外,formatter 的回调函数把 params.data.value 也显示看看,是不是都是「分组1」的数据值—— 30

————
建议只用一个 series,把数据改成这样:
[{ name: "新疆", group: "分组1", value: 30 }, { name: "西藏", group: "分组2", value: 80 }]

自定义图例实现

——————
本来想写个 demo 放 gallery 上,结果服务器更新没法保存……

贴下代码吧(用你的 demo 改的):
脚本引用下「常用脚本>>地图>>china」

// 地图使用的数据
data = [{
    name: '新疆',
    group: '分组1',
    value: 30
}, {
    name: '西藏',
    group: '分组2',
    value: 80
}];

// 一个过滤二维数组的函数,在这凑合用下,过滤下 JSON 数组
function arrFilter(source, hasColumnName, filterCondition) {
    var iBegin = hasColumnName ? 1 : 0;
    var res = hasColumnName ? [source[0]] : [];
    if (typeof(filterCondition) === 'function') {
        for (var i = iBegin; i < source.length; i++) {
            if (filterCondition(source[i])) {
                res.push(source[i]);
            }
        }
    } else if (typeof(filterCondition) === 'string') {
        for (var j = iBegin; j < source.length; j++) {
            var item = source[j];
            if (eval(filterCondition)) {
                res.push(source[j]);
            }
        }
    }
    return res;
}

option = {
    color: ['#469fe3', '#766baa'],
    tooltip: {
        trigger: 'item',
        showDelay: 0,
        transitionDuration: 0.2,

        formatter: function(params) {
            //console.log(params);
            return params.name + '<br />' + params.data.group + ':' + params.data.value;
        }

    },
    visualMap: {
        left: 'right',
        min: 0,
        max: 100,
        inRange: {
            color: ['#469fe3', '#766baa']
        },
        text: ['High', 'Low'],
        calculable: true
    },
    legend: {
        data: ['分组1', '分组2']
    },
    series: [{
        type: 'pie',
        name: '分组1',
        self_Remark: '用于自定义图例'
    }, {
        type: 'pie',
        name: '分组2',
        self_Remark: '用于自定义图例'
    }, {
        name: '地图',
        type: 'map',
        map: 'china',
        data: data
    }]
};
myChart.setOption(option);

myChart.on('legendselectchanged', function(params) {
    //console.log(params)

    filterString1 = params.selected['分组1'] === true ? 'item.group === "分组1"' : 'false';
    filterString2 = params.selected['分组2'] === true ? 'item.group === "分组2"' : 'false';

    filterString = filterString1 + '||' + filterString2;

    myChart.setOption({
        series: {
            name: '地图',
            data: arrFilter(data, false, filterString)
        }
    });
});

效果如图:
image

嗯,但是不使用formatter自定义的时候,是可以区分「分组1」和 「分组2」的,你可以拉一下我的demo源码,把formatter注释掉看看效果。

所以echarts应该是支持地图罗在一起的时候区分分组的。

我更新了问题复现demo:http://champyin.com/echarts-issues/
加入了效果对比。

额,在原楼层改了好几回……

还有就是,你看没有数据的省,鼠标浮框是不是都是「分组1」

说得有点乱,总结一下,我估计是这么回事:
1、你的两个 map series 是重叠的,最上层的 series 是「分组1」
2、「分组1」显示时,鼠标事件被「分组1」的图形捕获,params 里的 series 是「分组1」,所以自定义的 formatter 只能显示「分组1」的属性
3、 默认的 formatter 似乎会遍历所有 series,把有数据的 series 都显示出来,并把数值相加,如下图:
image
image

formatTooltip: function(dataIndex) {
    // FIXME orignalData and data is a bit confusing
    var data = this.getData();
    var formattedValue = addCommas(this.getRawValue(dataIndex));
    var name = data.getName(dataIndex);

    var seriesGroup = this.seriesGroup;
    var seriesNames = [];
    for (var i = 0; i < seriesGroup.length; i++) {
        var otherIndex = seriesGroup[i].originalData.indexOfName(name);
        var valueDim = data.mapDimension('value');
        if (!isNaN(seriesGroup[i].originalData.get(valueDim, otherIndex))) {
            seriesNames.push(
                encodeHTML(seriesGroup[i].name)
            );
        }
    }

    return seriesNames.join(', ') + '<br />' +
        encodeHTML(name + ' : ' + formattedValue);
},

——————————————————
图例可以自定义,第一个回答里,我后来贴上的那段代码,就是包含自定义图例的

还有一个思路,就是 formatter 的回调函数里,只通过 params.name 确定省份,然后通过省份去原始数据中查询分组信息、数值等;

这样你就可以用多个 series[i]-map 了

@zhouxin860114 分析的很有道理,按照你的方式可以实现我想要的效果,3Q~

@zhouxin860114 分析的很有道理,按照你的方式可以实现我想要的效果,3Q~

不客气 :D

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jarben picture jarben  ·  3Comments

publisherfk picture publisherfk  ·  3Comments

Thinkpad93 picture Thinkpad93  ·  3Comments

hanhui picture hanhui  ·  3Comments

shikelong picture shikelong  ·  3Comments