You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@echarts.apache.org by Ovilia <ov...@gmail.com> on 2020/06/29 09:51:29 UTC

[Discussion] Time axis label formatter improvement

Hi,

I'm working on the time axis label formatter improvement for the next big
release 5.0.

Here are some thoughts on the topic after discussing with Shuang Su and Yi
Shen.
Please feel free to make comments and provide feedback.

Please refer to
https://github.com/apache/incubator-echarts/pull/12859#issue-441014328 for
more details.


1. Default time axis labels don't have nice format and display information
not so importantBefore:

[image: 屏幕快照 2020-06-29 13 50 11]
<https://user-images.githubusercontent.com/779050/85977635-91b42700-ba0f-11ea-9f10-fc926cacac2f.png>

    xAxis: {
        type: 'time',
        interval: DAY / 4,
        axisLabel: {} // default
    },

For example, in the above case
<https://gallery.echartsjs.com/editor.html?c=xkPHcJp2be&v=2>, labels of
each day are all in the format of MM-DD\nYYYY, but the months and years are
all the same so they should not be displayed so many times to distract
users for the real important information: date.
After:

The default result of the above case have the interval of 6 hours, thus
default hour formatter (may be 'hh:mm') should be used to display labels in
hours and day formatter ('YYYY-MM-DD') be used when day changes. This is
the expected result:

[image: 屏幕快照 2020-06-29 13 50 11副本]
<https://user-images.githubusercontent.com/779050/85980069-43555700-ba14-11ea-8021-10605199a98d.png>

And the default style of the primary level (like day in this case) and
secondary level (hour in this case) are different (maybe we can use a
lighter text color for secondary level labels) and can be customized though
axisLabel.rich <https://echarts.apache.org/option.html#xAxis.axisLabel.rich>
.primaryStyle and secondaryStyle.
2. Multiple labels with the same text may be displayed by defaultBefore:

Also with the above example, we can see that there are three 05-12 2012 labels,
which is confusing. Especially, this should not be the default behavior of
labels.
After:

There won't be labels with the same date and hour labels will be displayed
in the above case.
3. Custom style is too complex to write with rich textBefore:

[image: 屏幕快照 2020-06-29 14 05 07]
<https://user-images.githubusercontent.com/779050/85978591-9c6fbb80-ba11-11ea-8b88-59c3accc58dd.png>

To get the above result, the user has to write the following long code of
formatter. Users may not know they could do this, even with clear
documentation.

formatter: function (value) {
    if (value % DAY === 0) {
        var month = echarts.format.formatTime('M月', value)
        var dayOfM = echarts.format.formatTime('d日', value)
        return '{strong|' + dayOfM + '}\n{lite|' + month + '}';
    }
    else {
        var formatted = echarts.format.formatTime('h点', value);
        return formatted;
    }},rich: {
    strong: {
        color: '#2784e8',
        fontSize: 14,
        fontWeight: 700
    },
    lite: {
        color: '#999',
        lineHeight: 15,
        fontSize: 10
    }}

After:

Current callback form of formatter will also be available, but we also
provide a much simpler way to write if the logic is not so complex.

We will support formatters for varied levels like year, month, day, hour,
minute and etc., and each of them supports the formatter in either forms of
{hh}:{mm}:{ss} for simple plain text or {xxx | {hh}:{mm}:ss} for rich text,
whose style can be configured in axisLabel.rich
<https://echarts.apache.org/option.html#xAxis.axisLabel.rich>.
4. Cannot use different formatters for different intervals

Consider the "2020 Feb" and "Feb" in the following example. The user want
to use different formatters ('YYYY-MMM' in case A and 'MMM' in case B.

case A:

    |_____________|_____________|_____________|__ ...
  30th         2020 Feb        2nd            3rd


case B:

    |_____________|_____________|_____________|__ ...
  2020           Feb           Mar           Apr

Before:

It cannot be done.
After:

formatter.month defines formatters when the tick value is a month value (by
checking if it's the first day of a month). And it can be in the form of an
array of formatters like: ['YYYY-MMM', 'MMM'].

This means, if the label is a first-level (also called primary level) as in
case A, where the levels of the labels are day, month, day, day, it uses
the first element in the array for the second tick, which is 'YYYY-MMM' and
gets "2020 Feb". Similarly, in case B, where the levels of the labels are
year, month, month, month, it uses the second element in the array for the
second tick and gets "Feb".
5. Cannot display ticks exactly on the first day of a month or weekBefore:

There are different days in each month, e.g., 28/29 for Feb and 31 for
July. There is no way to make sure the first day is displayed.

[image: 屏幕快照 2020-06-29 16 58 19]
<https://user-images.githubusercontent.com/779050/85994290-2c216400-ba2a-11ea-8804-ef1a6b8c962a.png>

This looks a bit arbitrary when choosing the days to be displayed with
ticks. And it cannot be changed even with configuration.
After:

If the months are different with min and max data (but years are the same),
the primary level will be month and we make sure that the first day of each
month is displayed with ticks. Note that in this case, the space between
each ticks are not the same because days in months are not.
6. i18nBefore:

Using formatter in the callback form like echarts.format.formatTime('M月',
value). It is quite challenging for developers not so familiar with
JavaScript.
After:

We can provide frequently used time formats like YYYY for full year, MM for
month number and so on. Moment.js <https://momentjs.com/docs/#/displaying/> and
can be served as references.

i18n of the time axis should be considered along with other i18n
requirements in ECharts, like toolbox and so on.

We are considering embed with English and Chinese language by default with
ECharts and other languages can be used as extensions. We are still discuss
about the details on this. But the bottom line is, it won't be necessary
for developers to implement by using code as low level as
echarts.format.formatTime.
UsageAre there any API changes?

   -  The API has been changed.

Before:

axisLabel: {
    formatter: string | function    // If it's a string, rich text is
supported. If it's a function, it can return rich text.
    rich: { ... }  // For label rich text if formatter uses rich text.
Default value is null.},interval: number  // The exact interval of
ticks

After:

axisLabel: {
    formatter: string | function | object  // If it's an object, it's
in the type of LevelFormats
    rich: {  // There are two rich styles defined in ECharts by
default, which user may use in formatter
        primaryStyle: {
            color: '#000'  // We use a darker color for primary level text
        },
        secondaryStyle: {
            color: '#666'  // We use a lighter color for secondary level text
        }
    }},
interval: number | string[]  // If it's string[], it should be like
['month', 'day'] meaning the tick intervals may be month or day

LevelFormats is defined as:

type LevelFormats = {
    year?: string | string[],
    month?: string | string[],
    day?: string | string[],
    hour?: string | string[],
    ...}

The string can either be a plain text like '{hh}:{mm}:{ss}' or a rich text
like strong | '{hh}:{mm}' and define the rich style strong in formatter.

Well... I know this sounds a little complex right now. But it's actually
turns easier when you see the real world examples.
Example of Usage1. Default

No formatter is required. Label text will display as what we think work for
general cases.
2. Custom primary and secondary styles

case A:

    |_____________|_____________|_____________|__ ...
  30th         2020 Feb        2nd            3rd


case B:

    |_____________|_____________|_____________|__ ...
  2020           Feb           Mar           Apr

If the user wants to use red color for 2020 Feb in case A and 2020 in case
B, this is what required:

xAxis: {
    // no formatter is required
    rich: {
        primaryStyle: {
            color: 'red'
        }
    }}

3. Display only weeks of year

xAxis: {
    interval: ['week'],
    axisLabel: {
        formatter: {
            week: 'Week w'
        }
    }}


Thanks

*Ovilia*