Acrobatic Chart Labels
The web designer of a client of mine has been bold enough to design a multiline, multistyle label for the legend of a chart. And, as charts (and legends) are generated using a commodity JS library, the issue has been to enforce such hardy design. Luckily for me, the JS library used in this application is ECharts, which already surprised me with efficency, customizability, speed and completeness of documentation.
This was the required design:
And this is my mostly complete result (of course, here "123 ABC" is a placeholder for actual data):
I've still to fix spacing and fonts style, but the point of this blogpost is the layout: how to dispose the label within two lines, wrapped around the selector, as the whole chart is rendered into a canvas
so it is not targettable with common and easy CSS?
The trick revolves around the "Rich Text" feature of ECharts, which permits to format many type of text (including the labels in the legend) defining different styles for different parts of the same string.
The legend
part of my chart configuration looks like
legend: {
icon: 'path://my-own-svg-path',
itemWidth: 20,
itemHeight: 20,
itemGap: 30,
formatter: function(name) {
let tokens = name.split('|');
if (tokens.length == 2) {
return '{normal|' + tokens[0] + '}\n{big|' + tokens[1] + '}';
}
else {
return name;
}
},
textStyle: {
rich: {
normal: {
padding: [32, 0, 0, 0],
},
big: {
fontSize: 18,
fontWeight: 'bold',
padding: [12, 0, 0, -26],
}
}
}
},
Then, in the series
part with actual data, names of each series is defined as
series: [
{
name: 'Co2 risparmiata|123 ABC',
// data code
},
{
name: 'Alberi risparmiati|123 ABC',
// data code
}
],
The formatter
function in legend
provides to tokenize the series' name, split it in two parts, and put them into a template referring to different rich text definition.
The important part of the formatting options is the padding
array, which permits to place each block of text in the desired position. The motivation of the negative left padding for big
style here is obvious: move the second line below the selector icon. The motivation of the top padding for normal
style may be a bit less obvious, but easily explained: the whole legend's item block is centered vertically (and I've not found any option to define something else), so without some enforcement the icon would appear in the middle of the block instead of being aligned with the first line; specifing a top padding to the first line of text, we move it below in the general layout and we are able to align it as intended with the icon.
Another win for (totally recommended) Echarts.