Skip to content

The ChartFactor Object (CF)

This is the main object of the Toolkit. It represents the entry point and it will be available from the core library as soon as it is loaded.

From this object we obtain all other objects used to build our queries or visuals. These objects have their own section.

Let's take a look at some of the main methods of this object:

setProviders(providers)

Loads a set of providers according to the configuration passed as parameter. It takes an array of objects

1
2
3
4
5
6
7
8
9
    // define providers
    var providers = [{
        name:'Elastic',
        provider:'elasticsearch',
        url:'https://chartfactor.com/elastic/'
    }]

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

registerProvider(provider)

Same as setProviders but it register only one provider at a time. It is specially useful when a provider needs to be updated, in which case, it should be unregistered first, and recreated again.

1
2
3
4
5
    cf.registerProvider({
        name:'Elastic',
        provider:'elasticsearch',
        url:'https://chartfactor.com/elastic/'
    })

unregisterProvider(providerConfig)

Allows to remove an existing provider.

1
cf.unregisterProvider({ name: 'Elastic'})

getProviderByConfig(object)

Returns a provider object that matches the object passed as parameter.

1
    let provider = cf.getProviderByConfig({ name: 'Elastic' })

async getDatasourceMetadata(source, provider)

Returns the metadata of the given datasource.

1
2
3
4
    cf.getDatasourceMetadata("chicago_taxi_trips", "Elasticsearch")
      .then(meta => { 
          console.log(meta.objectFields);
       })

The meta.objectFields will contain an array with the field specification as below:

metaObjectFields

provider(name)

It creates and return a new Aktive instance with the provider passed as parameter set. Is the starting point when creating a new visualization or query.

create(name)

It also creates and return a new Aktive instance. This method is used when we're creating a visualization without a provider that is going to be used only to load injected data or to create a non-query visualizations such as Text Search or the Interaction Manager

It takes as optional parameter a string that is useful when performing Multiple Queries

getAllVisualizations()

It returns an array of all Aktive objects representing all visualizations and queries registered under the instance, including child visualizations such as column statistics and column filter widgets in a Raw Data Table.

getTopLevelVisualizations()

It returns an array of Aktive objects representing the visualizations and queries registered under the instance, excluding child visualizations.

getChildVisualizations(parentElementId)

It returns an array of Aktive objects representing all child visualizations and queries registered under a parent visualization represented by the parentElementId parameter. If no parentElementId is provided, it returns the child visualizations of all available parent visualizations. Examples of child visualizations are column statistics and column filters in the Raw Data Table.

getVisualization(elementId)

Returns the Aktive instance representing the visualization using the elementId passed as parameter.

isAppLoaded(warnSecs, errorSecs)

Returns a promise that will be resolved when the entire application, which translate into all visualizations and/or queries registered under the cf object, has been loaded, which means that they already received the response from the server.

It takes two optional parameters: The first one is the amount of time in seconds that it'll wait before warning the user that the application is taking more than expected to load by default is 7 seconds. The second parameter is the total amount of time in seconds that the application will wait before stopping the time checking. Default to 13.

1
2
3
    cf.isAppLoaded().then(() => {
        console.log('All visualization are ready!')
    })

getIManager()

Returns the Aktive instance representing the Interaction Manager if it exists in the application or dashboard.

getSupportedCharts()

Returns the full list of visualization types that are supported depending on the visualization libraries that are loaded. It is useful to verify if they are loaded correctly before using them.

tooltip

The ChartFactor tooltip utility object. Please refer to the Tooltip object.

clear()

Delete all registered visualizations.

remove(elementId)

Removes the Aktive instance representing the visualization or query, using the elementId passed as parameter.

getDependency(name)

ChartFactor depends on some third-party libraries that can be reused so we don't have to load them from a CDN if we don't need to. We just need to pass the name and assign the object to a variables:

1
2
3
    let moment = cf.getDependency('moment');

    console.log(moment.now())

Here's the list of dependencies that are available from this method:

1
2
3
4
5
6
7
8
const { 
    formatNumericValue,
    BigNumberFormatter,
    isMobileDevice,
    getBoolValue,
    renameKeys,
    mergeData
} = cf.getDependency('utils');

The ChartFactor utils functions are described in the section below.

ChartFactor utils functions

formatNumericValue

This function takes three parameters (value, field, isBigNumber) which only the first one is mandatory.

  • value is the value to be formatted
  • field is an object that will contains three properties: { type: 'NUMBER', currency: '£', displayFormat: '0.0[,]00' }
  • isBigNumber specifies if the given number it is a big number

The type could be MONEY, INTEGER, NUMBER or PERCENT.

See the following examples:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Passing just the value
console.assert(formatNumericValue(10000.34) === '10,000.34');

// Percent
console.assert(formatNumericValue(50, { type: 'PERCENT' }) === '50%');
console.assert(formatNumericValue(0.5, { type: 'PERCENT' }) === '0.50%');

// Should not invert delimiters comma/period if it ends with (i)
let noI = { type: 'NUMBER', displayFormat: '0.0[,]00' };
let withI = { type: 'NUMBER', displayFormat: '0.0[,]00i' };

console.assert(formatNumericValue(10000.34, noI) === '10,000.34');
console.assert(formatNumericValue(10000.34, withI) === '10.000,34');


// Formatting to a custom currency
let f1 = { type: 'MONEY', currency: '¥' };
let f2 = { type: 'MONEY', currency: '£', displayFormat: '(0,0.00) $' };

console.assert(formatNumericValue(3434.35, f1) === '¥ 3,434.35');
console.assert(formatNumericValue(3434.35, f2) === '3,434.35 £');

// With negative values
let f1 = { type: 'MONEY'};
let f2 = { type: 'NUMBER'};
let f3 = { type: 'INTEGER'};

console.assert(formatNumericValue(-3434.35, f1) === '-$ 3,434.35');
console.assert(formatNumericValue(-3434.35, f2) === '-3,434.35');
console.assert(formatNumericValue(-3434.35, f3) === '-3,434');
BigNumberFormatter

This function is a shorcut of the formatNumericValue function, that allows you to format any big number. See the following examples.

1
2
3
4
5
let value = 10000;
let field = { type: 'MONEY'};

console.assert(BigNumberFormatter()(value) === '10k');
console.assert(BigNumberFormatter(field)(value) === '$10k');
isMobileDevice

This function determines if is a mobile device based on the user agent. However this may not work if browser apps modify they user agent. See de developer mozilla for more information.

1
2
3
4
5
if (isMobileDevice()) {
    setTimeout(() => {
        //...
    }, 1000);
}
getBoolValue

This function returns true if the parameter pased is either a boolean with true value or a string with "true" value. It returns false otherwise. See the examples below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
console.assert(getBoolValue('true') === true);
console.assert(getBoolValue('false') === false);
console.assert(getBoolValue(true) === true);
console.assert(getBoolValue(false) === false);
console.assert(getBoolValue('false') === false);
console.assert(getBoolValue('qwed@asd.com') === false);
console.assert(getBoolValue('foo.bar') === false);
console.assert(getBoolValue('1234') === false);
console.assert(getBoolValue({foo: 'bar'}) === false);
console.assert(getBoolValue([]) === false);
renameKeys

This function is useful when you need to rename some keys inside of an object. It takes three mandatory parameters (object, keys, newKeys). See the examples below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const object = {foo: 'value1', bar: 'value2'};

// Rename only one property
const newObj1 = renameKeys(object, 'foo', 'fooNew');

// Rename several properties
const newObj2 = renameKeys(object, ['foo', 'bar'], ['fooNew', 'barNew']);

console.assert(newObj1.hasOwnProperty('fooNew'));

console.assert(newObj2.hasOwnProperty('fooNew'));
console.assert(newObj2.hasOwnProperty('barNew'));
mergeData(...data)

This function is used to merge data from multiple queries using the group in each data object. Therefore, it assumes that each data object contains a single group. The data parameter allows you to pass multiple data objects, eg. mergeData(data1, data2, data3, data4). This function returns an array with the merged data objects.

The example below illustrates how you could query aggregated data from two different sources and then merge the results into a single object using the utils.mergeData function.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
const utils = cf.getDependency('utils');

let metric1 = cf.Metric("test_field_1", "avg").hideFunction();
let group1 = cf.Attribute("Year")
    .limit(200)
    .func("YEAR")
    .sort("asc", "Year");
let metric2 = cf.Metric("test_field_2", "avg");
let group2 = cf.Attribute("DATE")
    .func("YEAR")
    .limit(1000)
    .sort("asc", "DATE");
var eventsHandler = function(result) {
    result.keep = true;
    return result;
};
cf.create("source1")
    .provider("Elasticsearch")
    .source("source_1")
    .groupby(group1)
    .metrics(metric1)
    // Second query starts
    .create("source2") 
    .provider("Elasticsearch")
    .source("source_2")
    .groupby(group2)
    .metrics(metric2)
    .processWith(eventsHandler)
    .on("execute:stop", data => {
        const souceData = data.data;

        // Merge the data using the mergeData(...data) function
        const allData = utils.mergeData(souceData.source2, souceData.source1);

        // Log the merged data
        console.log(allData);
    })
    .element("dummy")
    .execute();