Acrobatic Chart Labels

Acrobatic Chart Labels
Photo by Vultar Bahr / Unsplash

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.