echarts中關(guān)于自定義legend圖例文字

2021-8-16    前端達(dá)人

文章摘自:https://blog.csdn.net/YPJMFC/article/details/78979319,非常感謝大牛分享。

echarts中關(guān)于自定義legend圖例文字
首先看一張echarts餅圖: 
 
這張圖很好做,根本不值得提,但是用過(guò)echarts的可能會(huì)發(fā)現(xiàn)這個(gè)圖例有點(diǎn)不一樣,做這個(gè)圖例花了我好幾個(gè)小時(shí)去查,去試。結(jié)合一下echarts中l(wèi)egend圖例的特質(zhì)我們分析一下一些難點(diǎn):

1.這里的圖例文本包含兩個(gè)變量,而formatter提供的變量模板只有name
2.兩個(gè)變量的樣式各不相同
3.對(duì)齊,換行與居中的應(yīng)用



一個(gè)個(gè)看:

1.兩個(gè)變量
formatter有兩種形式: 
- 模板 
- 回調(diào)函數(shù)

模板

使用字符串模板,模板變量為圖例名稱 {name}
formatter: 'Legend {name}'

這種想要修改name的值,暫時(shí)我做不到,歡迎讀者指正

回調(diào)函數(shù)

使用回調(diào)函數(shù)
formatter: function (name) {
    return 'Legend ' + name;
}

我們?cè)诜祷貢r(shí)可以對(duì)name進(jìn)行修改,從而返回我們需要的值,初步改動(dòng)是這樣:

var data = [
    {value:40, name:'貨幣'},
    {value:20, name:'股票'},
    {value:40, name:'債券'}
]
formatter:  function(name){
    var total = 0;
    var target;
    for (var i = 0, l = data.length; i < l; i++) {
    total += data[i].value;
    if (data[i].name == name) {
        target = data[i].value;
        }
    }
    return name + ' ' + ((target/total)*100).toFixed(2) + '%';
}


2.兩種樣式
想自定義圖例文字樣式,就要用到富文本:rich,但是在官方文檔中看到的只有模板形式的富文本樣式配置,由1知用模板很難實(shí)現(xiàn)自定義name,所以只能用回調(diào)函數(shù)形式,采用富文本的形式對(duì)name進(jìn)行改造:

formatter:  function(name){
    var total = 0;
    var target;
    for (var i = 0, l = data.length; i < l; i++) {
    total += data[i].value;
    if (data[i].name == name) {
        target = data[i].value;
        }
    }
    var arr = [
        '{a|'+((target/total)*100).toFixed(2)+'%}',
        '{b|'+name+'}',
    ]
    return arr.join('\n')
},
textStyle:{
    rich:{
        a:{
            fontSize:20,
            verticalAlign:'top',
            align:'center',
            padding:[0,0,28,0]
        },
        b:{
            fontSize:14,
            align:'center',
            padding:[0,10,0,0],
            lineHeight:25
        }
    }
}

3.對(duì)齊,換行與居中
為了圖例與第一行文字對(duì)齊,需要設(shè)置兩個(gè)樣式的padding,把文字頂?shù)胶线m的位置,然后為了上下行的間隔,設(shè)置了第2行文字的行高,最終呈現(xiàn)了上面圖片的效果。不知道是不是有點(diǎn)地方做煩了,但是能最終實(shí)現(xiàn)自己想要的效果,很有成就感。

4.實(shí)例
這是完整的組件:

class ConfigChart extends Component {

    constructor(props) {
        super(props);
        this.state = {};
    };
    getOption = () => {
        var data = [
            {value:40, name:'貨幣'},
            {value:20, name:'股票'},
            {value:40, name:'債券'}
        ]
        const option = {
            tooltip : {
                trigger: 'item',
                formatter: "{a} <br/> : {c} (2haydbi%)"
            },
            // formatter:  function(name){

            //     var total = 0;
            //     var target;
            //     for (var i = 0, l = data.length; i < l; i++) {
            //     total += data[i].value;
            //     if (data[i].name == name) {
            //     target = data[i].value;
            //     }
            //     }
            //     return name + ' ' + ((target/total)*100).toFixed(2) + '%';
            // },

            series: [
                {
                    name: '訪問(wèn)來(lái)源',
                    type: 'pie',
                    radius: [50, 80],
                    center: ['50%', '40%'],
                    label: {
                        normal: {
                            show: false
                        },
                        emphasis: {
                            show: false
                        }
                    },
                    data: [
                        {
                            value: 40,
                            name: '貨幣',
                            itemStyle: { normal: { color: "#5877F0" } }
                        },
                        { value: 20, name: '股票', itemStyle: { normal: { color: "#AA9FFD" } } },
                        { value: 40, name: '債券', itemStyle: { normal: { color: "#F96481" } } }
                    ]
                }
            ],
            legend: {
                x: 'center',
                // y: 'bottom',
                bottom:5,
                itemGap:30,
                itemWidth:5,
                textStyle:{
                    fontSize: 12
                },
                align:'left',
                data: [
                    {
                        name:'貨幣',
                        icon:'circle'
                    },
                    {
                        name:'股票',
                        icon:'circle'
                    },{
                        name:'債券',
                        icon:'circle'
                    }
                ],
                // formatter:'{a|{name}}\n{name}',
                formatter:  function(name){
                    var total = 0;
                    var target;
                    for (var i = 0, l = data.length; i < l; i++) {
                    total += data[i].value;
                    if (data[i].name == name) {
                        target = data[i].value;
                        }
                    }
                    var arr = [
                        '{a|'+((target/total)*100).toFixed(2)+'%}',
                        '{b|'+name+'}',
                    ]
                    // return name + ' ' + ((target/total)*100).toFixed(2) + '%';
                    return arr.join('\n')
                },
                textStyle:{
                    rich:{
                        a:{
                            fontSize:20,
                            verticalAlign:'top',
                            align:'center',
                            padding:[0,0,28,0]
                        },
                        b:{
                            fontSize:14,
                            align:'center',
                            padding:[0,10,0,0],
                            lineHeight:25
                        }
                    }
                }
            },
            backgroundColor: "#fff"
        };
        return option;
    };
    render() {
        const _this = this;
        const { isShow } = this.props;
        return isShow ?
            <div className={StyleClass.configChartWrapper}>
                <ReactEcharts
                    option={_this.getOption()}
                    echarts={echarts}
                    style={{ height: '265px', width: $.width() }}
                    className='react_for_echarts' />
            </div> : null;
    }

}
其實(shí)大神上面的數(shù)據(jù)還是有點(diǎn)問(wèn)題,按照大神這樣做的話,餅狀圖的百分比和算出來(lái)的有一點(diǎn)點(diǎn)出入(算出來(lái)的值加起來(lái)不夠百分百),其實(shí)就是最后一項(xiàng)的百分比和餅狀圖的不一樣,其他的都一樣,所以,我自己修改了幾個(gè)小時(shí),終于把它完善了(主要是綠色的代碼),代碼如下:

this.dateEchart.setOption({

color:['#4BC373','#4178E8','#FF5B57'],

             tooltip: {

trigger: 'item',

formatter: "{a} <br/>: {c} (k4cwjoi%)"

},

legend: {

orient: 'vertical',

right:'10%',

top:'40%',

data:['微信支付','支付寶網(wǎng)上支付','銀行支付'],

formatter:(name)=>{

let target,count;

let total=0,num=0;

let l=this.data2.length;

for(var i=0;i<l;i++){

total+=this.data2[i].value;

}

for(i=0;i<l;i++){

if((this.data2[i].name==name)&&(i<l-1)){

target=this.data2[i].value;

count=((target/total)*100).toFixed(2)+'%';

return name+': '+count;

}

if((this.data2[i].name==name)&&(i==l-1)){

for(i=0;i<l-1;i++){

num+=parseFloat((((this.data2[i].value)/total)*100).toFixed(2));

}

let yy=(100-num).toFixed(2);

return name+': '+yy+'%';

}

}

}

},

series: [

{

name:'訪問(wèn)來(lái)源',

type:'pie',

radius: ['40%', '60%'],

center:['40%','50%'],

avoidLabelOverlap: false,

label: {

normal: {

show: false,

position: 'center'

},

emphasis: {

show: true,

textStyle: {

fontSize: '30',

fontWeight: 'bold'

}

},

},

labelLine: {

normal: {

show: false

}

},

data:this.data2

}

]

         });


藍(lán)藍(lán)設(shè)計(jì)建立了UI設(shè)計(jì)分享群,每天會(huì)分享國(guó)內(nèi)外的一些優(yōu)秀設(shè)計(jì),如果有興趣的話,可以進(jìn)入一起成長(zhǎng)學(xué)習(xí),請(qǐng)掃碼ben_lanlan,報(bào)下信息,會(huì)請(qǐng)您入群。歡迎您加入噢~~希望得到建議咨詢、商務(wù)合作,也請(qǐng)與我們聯(lián)系。

文章來(lái)源:csdn

分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責(zé)聲明:藍(lán)藍(lán)設(shè)計(jì)尊重原作者,文章的版權(quán)歸原作者。如涉及版權(quán)問(wèn)題,請(qǐng)及時(shí)與我們?nèi)〉寐?lián)系,我們立即更正或刪除。

藍(lán)藍(lán)設(shè)計(jì)bouu.cn )是一家專注而深入的界面設(shè)計(jì)公司,為期望卓越的國(guó)內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)、BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 、平面設(shè)計(jì)服務(wù)

分享本文至:

日歷

鏈接

個(gè)人資料

存檔