Incubator-echarts: 饼图中取消勾选个别legend以后,如何让每一项所占的比例,不是以剩下的legend的value和为总数,而是以所有legend的value和为总数(包括未显示的)

Created on 7 May 2016  ·  7Comments  ·  Source: apache/incubator-echarts

问题简述 (One-line summary)

饼图中取消勾选个别legend以后,如何让每一项所占的比例,不是以剩下的legend的value和为总数,而是以所有legend的value和为总数(包括未显示的)

版本及环境 (Version & Environment)

  • ECharts 版本 (ECharts version): 2.2.7
  • 浏览器类型和版本 (Browser version): IE8
  • 操作系统类型和版本 (OS Version): Windows 10 企业版 64位 +CPU: Intel(R) Core(TM) i7-4790K CPU @4.00GHz 4.00GHz +内存: 16GB RAM

    重现步骤 (Steps to reproduce)

  1. image

  2. image
  3. 取消勾选“邀请招标”后,“议标”所占的比例由86.67%变为92.86%

    期望结果 (Expected behaviour)

可能哪里有问题 (What went wrong)

ECharts配置项 (ECharts option)

option = {

}

其他信息 (Other comments)

Most helpful comment

示例:

http://echarts.baidu.com/demo.html#pie-nest

1.建议图例中的数据做排序;
2.只针对series[0]做了相关操作,实际根据你的需求来完成;
3.Legend的勾选无法阻止默认的隐藏图例的操作,所以这里用了pie的勾选来实现;
4.eCharts本身的一些参数提供不完整,所以需要自己判断勾选了第几个序列;

第二种方案是修改formatter,用当前项的值除以所有数据的值,但比例的总和加起来不为100%

image

image

image

以下示例测试通过

var data = [{
    value: 335,
    name: '直达'
}, {
    value: 310,
    name: '邮件营销'
}, {
    value: 234,
    name: '联盟广告'
}, {
    value: 135,
    name: '视频广告'
}, {
    value: 1048,
    name: '百度'
}, {
    value: 251,
    name: '谷歌'
}, {
    value: 147,
    name: '必应'
}, {
    value: 102,
    name: '其他'
}];

option = {
    tooltip: {
        trigger: 'item',
        formatter: "{a} <br/>{b}: {c} ({d}%)"
    },
    legend: {
        orient: 'vertical',
        x: 'left',
        data: ['直达', '邮件营销', '联盟广告', '视频广告', '百度', '谷歌', '必应', '其他']
    },
    series: [{
        name: '访问来源',
        type: 'pie',
        selectedMode: 'single',
        radius: [0, '70%'],

        label: {
            normal: {
                position: 'inner'
            }
        },
        labelLine: {
            normal: {
                show: false
            }
        },
        data: data
    }]
};

function getLegendIdx(str) {
    var isSelected = 0;
    var len = option.legend.data.length;
    for (var i = 0; !isSelected && i < len; i++) {
        if (str == option.legend.data[i]) {
            isSelected = i;
        }
    }
    return isSelected;
}

//记录鼠标点击状态
var clickStatus = [];
data.map(function(elem) {
    clickStatus.push(false);
});

// 图例开关的行为只会触发 legendselectchanged 事件
myChart.on('pieselectchanged', function(params) {

    // 获取点击图例的选中状态
    //var isSelected = params.selected[params.name];
    // 在控制台中打印
    //console.log((isSelected ? '选中了' : '取消选中了') + '图例' + params.name);
    // 打印所有图例的状态
    //console.log(params.selected);
    //console.log(params);

    //获取所选序列的dataID
    var idx = getLegendIdx(params.name);
    var isSelected = clickStatus[idx];
    clickStatus[idx] = !isSelected;
    data[idx].itemStyle = {
        normal: {
            opacity: isSelected ? 1 : 0
        }
    };
    data[idx].label = {
        normal: {
            show: isSelected ? 1 : 0
        }
    };
    option.series[0].data = data;
    myChart.setOption(option);
});

All 7 comments

取消相当于是重计算了,如果不重新算比例那勾选的意义何在?

如果实在要保留的话,可以添加legend事件,把对应的选项的颜色设为透明 opacity:0

@realeve
legend较多时,显示的条目很多,用户想通过勾选来显示自己关心的项,所以才这种需求。
legend事件如何添加呢?

有问题多看官方文档
http://echarts.baidu.com/api.html#events.legendselected

http://echarts.baidu.com/tutorial.html#ECharts%20%E4%B8%AD%E7%9A%84%E4%BA%8B%E4%BB%B6%E5%92%8C%E8%A1%8C%E4%B8%BA

示例:

http://echarts.baidu.com/demo.html#pie-nest

1.建议图例中的数据做排序;
2.只针对series[0]做了相关操作,实际根据你的需求来完成;
3.Legend的勾选无法阻止默认的隐藏图例的操作,所以这里用了pie的勾选来实现;
4.eCharts本身的一些参数提供不完整,所以需要自己判断勾选了第几个序列;

第二种方案是修改formatter,用当前项的值除以所有数据的值,但比例的总和加起来不为100%

image

image

image

以下示例测试通过

var data = [{
    value: 335,
    name: '直达'
}, {
    value: 310,
    name: '邮件营销'
}, {
    value: 234,
    name: '联盟广告'
}, {
    value: 135,
    name: '视频广告'
}, {
    value: 1048,
    name: '百度'
}, {
    value: 251,
    name: '谷歌'
}, {
    value: 147,
    name: '必应'
}, {
    value: 102,
    name: '其他'
}];

option = {
    tooltip: {
        trigger: 'item',
        formatter: "{a} <br/>{b}: {c} ({d}%)"
    },
    legend: {
        orient: 'vertical',
        x: 'left',
        data: ['直达', '邮件营销', '联盟广告', '视频广告', '百度', '谷歌', '必应', '其他']
    },
    series: [{
        name: '访问来源',
        type: 'pie',
        selectedMode: 'single',
        radius: [0, '70%'],

        label: {
            normal: {
                position: 'inner'
            }
        },
        labelLine: {
            normal: {
                show: false
            }
        },
        data: data
    }]
};

function getLegendIdx(str) {
    var isSelected = 0;
    var len = option.legend.data.length;
    for (var i = 0; !isSelected && i < len; i++) {
        if (str == option.legend.data[i]) {
            isSelected = i;
        }
    }
    return isSelected;
}

//记录鼠标点击状态
var clickStatus = [];
data.map(function(elem) {
    clickStatus.push(false);
});

// 图例开关的行为只会触发 legendselectchanged 事件
myChart.on('pieselectchanged', function(params) {

    // 获取点击图例的选中状态
    //var isSelected = params.selected[params.name];
    // 在控制台中打印
    //console.log((isSelected ? '选中了' : '取消选中了') + '图例' + params.name);
    // 打印所有图例的状态
    //console.log(params.selected);
    //console.log(params);

    //获取所选序列的dataID
    var idx = getLegendIdx(params.name);
    var isSelected = clickStatus[idx];
    clickStatus[idx] = !isSelected;
    data[idx].itemStyle = {
        normal: {
            opacity: isSelected ? 1 : 0
        }
    };
    data[idx].label = {
        normal: {
            show: isSelected ? 1 : 0
        }
    };
    option.series[0].data = data;
    myChart.setOption(option);
});

echarts并没有针对legend的CLICK行为,楼上的那个有点乱来,没有人会这样特意去点饼图取消一块东西,好好的legend不点,为啥要特意在一堆五颜六色的饼中去选,这是不符合用户习惯的。
楼主这个问题我建议是改label为“建议”,因为legend目前的所有event都是dispatch action触发的,现阶段来说,你这个需求是无法满足的

更正一下,还是有click事件的,'legendselectchanged',你可以选择用pissang的方法直接用formatter,或者你也可以在这个event里重新算,不过我是不推荐就是了

其实如果只是需要显示的百分比是固定的话可以自己计算一下百分比然后将其作为一个 data 中的自定义参数,这样不管是否有 legend 的筛选,百分比都是固定的。然后就可以通过 formatter 显示自己传入的的百分比

比如:

data: [
  { value: 10, percent: 0.1 },
  { value: 90, percent: 0.9 }
],
label: {
  normal: {
    formatter: function (param) { return param.data.percent; }
  }
}

楼上pissang 给的也是我建议他的另一种方案,因为总和加起来不为100%,比如有三个数据 50 50 50,隐藏一个以后,其余两个各占一半,但是比例只有33%,失去可视化的意义了,不推荐。

Was this page helpful?
0 / 5 - 0 ratings