Skip to content

Custom Metadata

As mentioned before, metadata is automatically introspected from the provider. However, sometimes this metadata needs to be enhanced for ChartFactor to better render data visualizations. For example we can have a field named pricepaid, which represents a monetary value, but the information coming from the provider says that this field is of type "NUMBER". Since fields with type "MONEY" are formatted with the "$" sign, the value for pricepaid won't be displayed as it should:

CM1

Also note the X Axis label, it could be more expressive. We can enhance almost any field metadata coming from the provider with the following structure:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
var providers = [ {
        name:'Elasticsearch',
        provider:'elasticsearch',
        url:'https://chartfactor.com/elastic/',
        metadata: {
            'ticket_sales': {
                'fields': {
                    'catname': { 'label': 'Category Name' },
                    'pricepaid': { 'label': 'Price Paid', 'type': 'MONEY' }
                }
            }
        }
    }
]

// Set the data provider to chartfactor
cf.setProviders(providers);

myChart = cf.provider('Elasticsearch')....execute();

Note

In the metadata example above, 'ticket_sales' is the source name.

After this, we can see how the tooltip's format has changed as well as the labels for the Y and X axis respectively:

CM2

Metadata structure

As we saw in the previous example, the structure to update field metadata is the following:

1
2
3
4
5
6
7
8
9
var customData = {
    'source_name_1': {
        'fields': {
            'field1': { 'label': 'My Custom Label' },
            'field2': { 'type': 'ATTRIBUTE | INTEGER | NUMBER | MONEY | PERCENT | TIME' }
        }
    },
    'source_name_2': { ... }
})

How to access the data provider's current metadata

We can access the current provider's metadata as follows:

1
2
let provider = cf.getProviderByConfig({ 'name': 'Provider Name' })
let metadata = provider.get('metadata')

Do not modify directly this object since it will be overwritten, so if you need to add more information to it use the custom data.

Timezone support

Something awesome you can do with the custom metadata is time zone handling for your datetimes and timestamp fields. You can convert from one time zone to another and use it to display your data. For more information on how to use time zones with the custom metadata go here.

Using custom metadata to update time granularity

Sometimes the default granularity of a time field in the data source is not what we need. To update it, use the timestampGranularity attribute to pass the new granularity as shown below. Valid values are MINUTE, HOUR, DAY, MONTH, YEAR.

1
2
3
4
5
6
7
var customData = {
    [source]: {
        fields: {
            '@timestamp': { 'label': 'saletime', 'type': 'TIME', 'timestampGranularity': 'MONTH'}
        }
    }
}

Custom date formats for TIME fields

By default, time fields are displayed in EEUU format depending on the granularity. So for example a field with DAY as granularity, will be displayed like: Jan 03, 2008. If we want to change the display format of a given field and granularity, we can do it as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var customData = {
    [source]: {
        fields: {
            '@timestamp': { 
                'displayFormat': {
                    'DAY': "DD MMM YYYY",
                    'MONTH': "MMMM 'YY"
            }}
        }
    }
}

With the configuration above, any visualization using that field will be shown as 03 Jan 2008 if it is DAY or January '08 if it is MONTH.

If we have several time fields and we want them to use the same format we don't need to define the one by one. We just use the source level displayFormats property:

1
2
3
4
5
6
7
8
9
var customData = {
    [source]: {
        displayFormats: {
            'DAY': "DD MMM YYYY",
            'MONTH': "MMMM 'YY"
        }
        fields: {}
    }
}

Field level formats will always have higher priority over source level formats.

ChartFactor uses the momentjs library, which mean that you can use any of these string formats to create your custom.

Custom formats for numeric fields

Similar to date fields' custom formats, numeric fields such as INTEGER, MONEY, NUMBER and PERCENT can be also formatted.

Allowed formats are used according to the library Numeral.js formats, with a very slight modification.

1
2
3
4
5
6
7
8
var customData = {
    [source]: {
        fields: {
            'highPrecisionField': { 
                'displayFormat': '0,0.00000',
        }
    }
}

In the example above, hightPrecisionField will be formatted by delimiting thousands by a comma, and with 5 decimals values.

If we want to apply source level formats, we can accomplish it by using the field type:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var customData = {
    [source]: {
        displayFormats: {
            'INTEGER': "0",
            'NUMBER': "0[.]000",
            'MONEY': '($ 0.00 a)'
        }
        fields: {}
    }
}

Currencies

For fields of type MONEY, ChartFactor formats the value by placing the dollar symbol ($) before the value (ie: $ 100). This can be changed to use any other currency and position:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var customData = {
    [source]: {
        currency: '€',
        fields: {
            'price': { type: 'MONEY' },
            'price_yen': { 
                type: 'MONEY', 
                currency: '¥',
                displayFormat: '0,0.00 $'
            }
        }
    }
}

In the above configuration the euro is defined as global currency, this means that any value of type MONEY will be formatted with that currency, ie: € 22.30, € 100,00.00, etc. On the other hand price_yen has its own currency and format, so for it will have values like: 22.30 ¥, 100,00.00 ¥, etc.

Notice the use of the dollar symbol in the price_yen formatter. This is not a mistake. The $ will tell the position of the currency for the value, and it will be replaced then with the right currency afterwards.

Delimiters

By default, Chartfactor uses the same delimiters provided by numeral.js: comma for thousands, period for decimals. To change this in numeral, some extra steps are required, like having an locale configuration and so on. ChartFactor simplify this step by using just the format:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
var customData = {
    [source]: {
        currency: '€',
        fields: {
            'numeric_value': {
                displayFormat: '0.0i',
            }
            'price_yen': { 
                type: 'MONEY', 
                currency: '¥',
                displayFormat: '0.0,00 $i'
            }
        }
    }
}

Notice that here we're using the period (.) for thousands separator and comma (,) as decimal separator. Also an extra i was added at the end of the format. This i tells the formatter that the current format string has inverted delimiters, so use them as specified.

So the above example will convert 100000000 to 100.000.000 for the case of numeric_values and 200000 to 200.000,00 € for price_yen.

Only commas and periods symbols can be used as delimiters.