Report Dataset

The plugin input data is available under the key dataUrl, and can get retrieves with a GET call on that url directly.

An example of the data returned:

{
"context": {
"timeUnit": "day",
"timeBy": "Created at date and time",
"dateRanges": [
"Last 180 days: Nov 14, 2019 - May 11, 2020"
],
"segments": [],
"groupBy": [],
"types": {
"groupBy": [
"Country"
],
"values": [
"number"
]
},
"dataFormat": "timeseries",
"values": [
"Total of User Count"
]
},
"data": [
{
"time": "2020-01-31T00:00:00Z",
"groupBy": ["US"],
"dateRange": 0,
"values": [
111.0
]
},
{
"time": "2020-01-31T00:00:00Z",
"groupBy": ["NL"],
"dateRange": 0,
"values": [
38.0
]
},
{
"time": "2020-02-01T00:00:00Z",
"groupBy": ["US"],
"dateRange": 0,
"values": [
555.0
]
},
{
"time": "2020-02-02T00:00:00Z",
"groupBy": ["NL"],
"dateRange": 0,
"values": [
101.0
]
},
...
]
}

Context

The report data has two main objects, a context which contains metadata such as the timeUnit of the report (hour, day, week, month), and timeBy with a human friendly label that presents what user or event property time is based on. Because a report can have multiple date ranges, segments and group by's, each of those corresponding keys shows the human friendly labels of each. Under types we have groupBy and values, and each has the type of the value and group by — text, number, boolean or date. The dataFormat can be timeseries, users (list of users) or events (list of events). Finally under values we can find the human friendly label of the report value to use a input data. All these correspond by via their array index to values such as valueIndex, but also dateRange and segment under the data object.

Data

The actual data can be found under the data key, where each array item is a data point. First we have time, which is a ISO 8601 timestamp. Next we have values, the array with actual report item values. There are two keys that indicate that date range or segment this data point belongs to, indicated by the dateRange and segment keys — segments is available only if one or more segments are used. Finally groupBy is an array with the value of each group by item, e.g. in the example above the report is grouped by country, so each groupBy consists of array with length 1, and the first item being the country code. In case no group by is used, it's an empty array.

In case many group by's, segments and date ranges are used, and our plugin needs to work on each of those combinations, such as making a forecast per country, for each of the multiple date ranges and segments, we need to re-structure the data first. An easier way is to get the data already prepared in this way, nested by group by's, segments and date-ranges used. To do that add the ?format=nested query parameter to the dataUrl. In addition, you can also specify the number of nested items, by adding group_by_limit=10 as query parameter, which gives precedence to the group by values that occur most often.

The main difference with the non-nested data format is that we now have at the top layer a nested key, which is an array with all nested objects. A nested object is a combination of a group by, date range and segment. Within each nested we have the actual data, just like in the non-nested data format. Note that there, the groupBy, dateRange and segment keys are gone from the data items, and have moved up to the nested item. Each nested item has its own context, where you can get some metadata specific to that nested item. The title directly under the nested item is useful to display to the end-user — like in a tab title — the plugin results for that combination of group by, date range and segment. This will save you some work later on. The top level context is how to context would be in non-nested format, and the context for each nested item with empty groupBy and segments, because those are already rolled at the data level. So usually you will only work with the context at the nested item level.

{
"context": {
"timeUnit": "day",
"timeBy": "Created at date and time",
"dateRanges": [
"Last 14 days: Apr 29, 2020 - May 12, 2020"
],
"segments": [],
"groupBy": [
"Country"
],
"types": {
"groupBy": [
"text"
],
"values": [
"number"
]
},
"dataFormat": "timeseries",
"values": [
"Total of User Count"
]
},
"nested": [
{
"key": "k8bf9c5b7d6af46bbb161cdd57616e333",
"title": "Country is US",
"context": {
"timeUnit": "day",
"timeBy": "Created at date and time",
"dateRanges": [
"Last 14 days: Apr 29, 2020 - May 12, 2020"
],
"segments": [],
"groupBy": [],
"types": {
"groupBy": [
"text"
],
"values": [
"number"
]
},
"dataFormat": "timeseries",
"values": [
"Total of User Count"
]
},
"dateRange": 0,
"groupBy": [
"US"
],
"data": [
{
"time": "2020-04-29T00:00:00Z",
"values": [
45.0
]
},
{
"time": "2020-04-30T00:00:00Z",
"values": [
36.0
]
},
...
]
},
{
"key": "k184be57865524328b314e6c5b4a9db4b",
"title": "Country is NL",
"context": {
"timeUnit": "day",
"timeBy": "Created at date and time",
"dateRanges": [
"Last 14 days: Apr 29, 2020 - May 12, 2020"
],
"segments": [],
"groupBy": [],
"types": {
"groupBy": [
"text"
],
"values": [
"number"
]
},
"dataFormat": "timeseries",
"values": [
"Total of User Count"
]
},
"dateRange": 0,
"groupBy": [
"NL"
],
"data": [
{
"time": "2020-04-29T00:00:00Z",
"values": [
7.0
]
},
{
"time": "2020-04-30T00:00:00Z",
"values": [
11.0
]
},
...
},
...
]

The key can be used to make it easier to store each plugin result for that nested data under its own key in the output data. So for example we want to show the average for each nested item. The plugin output might look like the example below, where we calculate the average based on the values for each nested item, and the key and title coming directly as-is from the nested container object. The average of each nested item is then presented as a separate tab, with a subtitle coming from the nested item context, passed on to the plugin out data object.

{
...,
"data": {
"k8bf9c5b7d6af46bbb161cdd57616e333": {
"average": 40.5,
"title": "Country is US"
},
"k184be57865524328b314e6c5b4a9db4b": {
"average": 9.0,
"title": "Country is NL"
}
},
"jsx": '''
<Insight>
{ results.helpers.renderAll() }
</Insight>
''',
"helper": '''
class {
constructor(results) {
}
resultKeys() {
return Object.keys(this.results.data);
}
renderAll() {
return (
<Tabs>
{
this.resultKeys().map(resultKey => {
const result = this.results.data[resultKey];
return (
<Tab title='Average' subtitle={result.title}>
{ result.average }
</Tab>
);
})
}
</Tabs>
);
}
}
'''
}

Sometimes you want to prevent one or more group-by values from being nested. This can be handy when you e.g. make a funnel report, and group-by on a property that you would always add, in addition to any user specified group-by's. In this case, you can use the request parameter ?format=nested&ignore_group_by_idx=[0]. ignore_group_by_idx is an array, indicating which group-by based on 0 based index, should not be nested. Instead, they will appear within the same data array. All other group-by's not specified hear, will still be nested.