文章摘自: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/>{b} : {c} (oag6v0l%)"
},
// 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/>{b}: {c} (4hwqgmb%)"
},
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ì)( m.paul-jarrel.com )是一家專注而深入的界面設(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ù)