Add underline effect to label in echarts

Effect display

As shown in the figure below, the data on the y-axis are underlined.

Implementation ideas

After seeing this requirement, I immediately went to the echarts official website to check the relevant configuration items, looking for configurations that might be able to achieve this effect, and mainly tried these types.

1. borderType + borderColor + borderWidth

We add the three configuration items borderType, borderColor and borderWidth to axisLabel in yAxis to add a top border to the text label.

 yAxis: {type: 'category',data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World'],axisLabel:{borderType: 'solid',borderColor :'red',borderWidth:1,}
}

The effect is as follows:

From the picture above, we can see that the border has been successfully added to the label, but now we only need the lower border, so I tried many methods and found that the borders on the left, top, and right sides could not be removed well. , so this method failed. Of course, this is just my own attempt and I didn’t find a good method. In fact, there may be a way to remove the extra borders. If anyone knows about it, you can give me some advice. Thank you very much ?♀

2. textBorderColor + textBorderType + textBorderWidth

I also found such a configuration combination related to the border in the configuration items, so I tried it with the mentality of giving it a try, and found that emmmm… something didn’t seem right.

 yAxis: {type: 'category',data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World'],axisLabel:{textBorderType: 'solid',textBorderColor :'red',textBorderWidth:1,}
}

The effect is as follows:

From the picture above, we can see that this effect is not what we want. textBorderType wraps a layer of edges around the edges of the text, so this set of configurations cannot achieve what we need, so We need to keep looking.

3. backgroundColor

Text block background color.

Color values can be used, for example: '#123234', 'red', 'rgba(0,23,11,0.3)'.
You can also use images directly, for example:

backgroundColor: {image: 'xxx/xxx.png'// This can be the URL of the image, // or the dataURI of the image, // or the HTMLImageElement object, // or the HTMLCanvasElement object.
}

When using images, you can use width or height to specify the height and width, or you do not need to specify adaptive.

We can first prepare such a picture

Then convert it to base64

Then set it as the background of the picture

 yAxis: {type: 'category',data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World'],axisLabel:{backgroundColor: {image: 'data :image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAbCAYAAAA + nNxPAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAABPSURBVFhH7dixDQAgCABBoWD/IdhTLRziJX8JgfZbYl9rgHz 7e4bQGEJjCI0hNIbQGEJjCI0hNIbQGEIzJiS6e8Q7KO741yLJqnrnvzJzHUQCCDJBedO2AAAAAElFTkSuQmCC',}}
}

The effect is as follows:

From the picture above, we can see that using the backgroundColor configuration item, we can successfully underline the y-axis label, so I decided to use this solution to achieve the effect.

Requirement changes

After finding a solution that can achieve this effect, I finished typing the code in three strokes, five by two, and after the test, I checked the time. I still have one hour to get off work. Now I can go to the Nuggets to fish, right? When I opened Nuggets and was about to fish, I saw the project manager walking towards me with ill intentions. I felt bad, so I closed the Nuggets page at lightning speed and opened vscode.

The project manager came over and said to me: "The effect style just now seems not very good. Change it to count from top to bottom, with odd numbers underlined and even numbers not underlined.", and then it was cool. walked away

It seems that this fish is out of reach again today. After adding conditional restrictions, it seems that it cannot be realized directly using the backgroundColor attribute. At this time, I remembered that the value of the label can be achieved through formatter function to format, so can we directly format and add underlines to the text?

Use the formatter function

const underLine = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAbCAYAAAA + nNxPAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAABPSURBVFhH7dixDQAgCABBoWD/IdhTLRziJX8 JgfZbYl9rgHz7e4bQGEJjCI0hNIbQGEJjCI0hNIbQGEIzJiS6e8Q7KO741yLJqnrnvzJzHUQCCDJBedO2AAAAAElFTkSuQmCC';yAxis: {type: 'category',data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World'],axisLabel:{formatter:(val,ind)=>{return val + '\
' + underLine;},}
},

The effect is as follows:

emmm… There seems to be a problem, so let’s generate an image tag from the image in base64 format and try it:

const underLine = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAbCAYAAAA + nNxPAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAABPSURBVFhH7dixDQAgCABBoWD/IdhTLRziJX8 JgfZbYl9rgHz7e4bQGEJjCI0hNIbQGEJjCI0hNIbQGEIzJiS6e8Q7KO741yLJqnrnvzJzHUQCCDJBedO2AAAAAElFTkSuQmCC';
const hr = new Image();
hr.src = underLine;yAxis: {type: 'category',data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World'],axisLabel:{formatter:(val ,ind)=>{return val + '\
' + hr;},}
},

The effect is as follows:

It seems that the picture still cannot be displayed normally. This is another imaginative configuration item I saw.

yAxis.axisLabel.rich

In rich, you can customize rich text styles. Using rich text styles, you can create very rich effects in labels.

For example:

label: {// In the text, you can apply the style defined in rich to part of the text. // Here you need to use markup symbols in the text: // `{styleName|text content text content}` mark style name. // Note that '\
' is still used for newlines. formatter: ['{a|This text adopts style a}','{b|This text adopts style b}This paragraph uses the default style {x|This paragraph uses style x}'].join('\
' ),rich: {a: {color: 'red',lineHeight: 10},b: {backgroundColor: {image: 'xxx/xxx.jpg'},height: 40},x: {fontSize: 18,fontFamily: 'Microsoft YaHei',borderColor: '#449933',borderRadius: 4},...}
}

See tutorial for details: Rich text tags

All attributes

{ color , fontStyle , fontWeight , fontFamily , fontSize , align , verticalAlign , lineHeight , backgroundColor , borderColor , borderWidth , borderType , borderDashOffset , borderRadius , padding , shadowColor , shadowBlur , shadowOffsetX , shadowOffsetY , width , height , textBorderColor , textBorderWid th , textBorderType , textBorderDashOffset , textShadowColor , textShadowBlur , textShadowOffsetX , textShadowOffsetY }

Use

After reading the usage of this tag, it seems that it can meet our needs, so let’s try it:

const underLine = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAbCAYAAAA + nNxPAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAABPSURBVFhH7dixDQAgCABBoWD/IdhTLRziJX8 JgfZbYl9rgHz7e4bQGEJjCI0hNIbQGEJjCI0hNIbQGEIzJiS6e8Q7KO741yLJqnrnvzJzHUQCCDJBedO2AAAAAElFTkSuQmCC';yAxis: {type: 'category',data: ['Brazil', 'Indonesia', 'USA', 'India', 'China', 'World'],axisLabel:{formatter:(val,ind)=>{return val + '\
' + '{hr|}';},interval:0,rich: {hr: {width : '100%',backgroundColor: { image: underLine}//text block background image}},}
},

The effect is as shown below

Through this method, the picture was successfully added, but the picture here is spliced as another element on the next line of the label text, so the height of the original picture will also occupy the space, so we can set a height for the background picture. Make restrictions.




Through the above set of pictures, we can find that the height attribute of the background picture will affect the display of pixels. This setting makes the display of underlined pictures unstable, so we can change the picture and directly use a completely black picture. Just use it as an underline picture.

Convert to base64

Use the new image to replace the original image:

const underLine = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAbCAYAAAA + nNxPAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAABBSURBVFhH7c/BCQAwDMNAp/vvnPTRIZSiA + O3KknfrXfer2cIjSE0htAYQmMIjSE0htAYQmMIjSE0htAYQvNJSDJsvgE1zcTjegAAAABJRU5ErkJggg==';yAxis: {type: 'category',data: ['Brazil', 'Indonesia', 'USA ', 'India', 'China', 'World'],axisLabel:{formatter:(val,ind)=>{return val + '\
' + '{hr|}';},interval:0,rich : {hr: {width: '100%',height: 1,backgroundColor: { image: underLine}//Text block background image}},}
},

The effect is as follows:

Dynamicly add underline

const underLine = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAbCAYAAAA + nNxPAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAABBSURBVFhH7c/BCQAwDMNAp/vvnPTRIZSiA + O3KknfrXfer2cIjSE0htAYQmMIjSE0htAYQmMIjSE0htAYQvNJSDJsvgE1zcTjegAAAABJRU5ErkJggg==';yAxis: {type: 'category',data: ['Brazil', 'Indonesia', 'USA ', 'India', 'China', 'World'],axisLabel:{formatter:(val,ind)=>{return val + '\
' + (ind % 2 == 1 ? '{hr|}' : '');},interval:0,rich: {hr: {width: '100%',height: 1,backgroundColor: { image: underLine}//Text block background image}},}
},

The effect is as follows:

At this time, we found that the label text that was not underlined seemed to move up a little, which was definitely not possible, so we also added a background to the text labels that were not underlined.

const underLine = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAbCAYAAAA + nNxPAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAABBSURBVFhH7c/BCQAwDMNAp/vvnPTRIZSiA + O3KknfrXfer2cIjSE0htAYQmMIjSE0htAYQmMIjSE0htAYQvNJSDJsvgE1zcTjegAAAABJRU5ErkJggg==';yAxis: {type: 'category',data: ['Brazil', 'Indonesia', 'USA ', 'India', 'China','Japan', 'World'],axisLabel:{formatter:(val,ind)=>{//The 6 in (6 + ind) here is the length of data minus 1 , because n - 1 + n - 1 = (2 - 1) * n, so the top item is always an even number. Return val + '\
' + ((6 + ind) % 2 == 1 ? '{ hr|}' : '{none|}');},interval:0,rich: {hr: {width: '100%',height: 1,backgroundColor: { image: underLine}//text block background image} ,none: {width: '100%',height: 1,backgroundColor: { image: 'none'}//text block background image}},}
},

The effect is as follows:

Judging from the picture above, the effect is perfect, so I showed the rendering to the project manager. As a result, the project manager said that I can’t count. Didn’t he say that should be counted from top to bottom, with odd numbers underlined? Don't you add even numbers? , then I said yes, and then after some battle, I found that our counting methods were different.

Then I made some minor modifications and got off work on time

Complete code

const underLine = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAbCAYAAAA + nNxPAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAABBSURBVFhH7c/BCQAwDMNAp/vvnPTRIZSiA + O3KknfrXfer2cIjSE0htAYQmMIjSE0htAYQmMIjSE0htAYQvNJSDJsvgE1zcTjegAAAABJRU5ErkJggg==';
option = {title: {text: 'World Population'},tooltip: {trigger: 'axis',axisPointer: {type: 'shadow'}},legend: {},grid: {left: '3%',right : '4%',bottom: '3%',containLabel: true},xAxis: {type: 'value',boundaryGap: [0, 0.01]},yAxis: {type: 'category',data: ['Brazil ', 'Indonesia', 'USA', 'India', 'China','Japan', 'World'],axisLabel:{formatter:(val,ind)=>{//Here (7 + ind) 7 is the length of data, because n + n - 1 = 2 * n - 1, so the top item is always an odd number. Return val + '\
' + ((7 + ind) % 2 == 1 ? '{hr|}' : '{none|}');},interval:0,rich: {hr: {width: '100%',height: 1,backgroundColor: { image: underLine}//Text block background Image},none: {width: '100%',height: 1,backgroundColor: { image: 'none'}//Text block background image}},}},series: [{name: '2011',type: 'bar',data: [18203, 23489, 29034, 104970, 131744,111111, 741341]},{name: '2012',type: 'bar',data: [19325, 23438, 31000, 121594, 134141, 111111 ,792918]}]
};