The loadData
function is one of the most powerful functions in the Embeddable SDK. It enables component builders (that’s you) to easily load data to populate your components (charts and controls, etc.), while giving your team, using the no-code builder, the freedom to freely choose exactly which data to show in your component.
This is the key to building powerful, re-usable components in Embeddable.
The loadData
function takes the following parameters:
Param | Type | Required | Default value |
---|---|---|---|
from | Dataset |
Yes | |
dimensions | array of Dimension |
No, but at least one measure or dimension must be specified | [] |
measures | array of Measure |
No, but at least one measure or dimension must be specified | [] |
timeDimensions | array of TimeDimension |
No | [] |
orderBy | array of OrderBy |
No | none |
limit | number |
No | 100 |
offset | number |
No | 0 |
filters | array of QueryFilter |
No | [] |
You can effectively think of loadData
like performing an SQL statement (as that’s literally what it will do behind the scenes):
SELECT <timeDimensions>, <dimensions>, <measures>
FROM <dataset>
WHERE <filters on dimensions>
GROUP BY <timeDimensions>, <dimensions>
HAVING <filters on measures>
ORDER BY <orderBy>
LIMIT <limit>
OFFSET <offset>
The types expected by the loadData(…)
function are:
Dataset
is nothing more than a chosen data model with filters applied (learn more here)
To ask for a dataset in your component, define an input like so:
{
name: "ds",
type: "dataset",
label: "Dataset to display", // shown in the UI in the no-code builder
}
Dimension
is a virtual column in your data model (learn more here)
To ask for a dimension in your component**,** define an input like so:
{
name: "ds",
type: "dataset",
label: "Dataset to display"
},
{
name: "myDimension",
type: "dimension",
label: "X-Axis", // shown in the UI in the no-code builder
config: {
dataset: "ds", // tells no-code builder where to get the list of dimensions from
},
},
Measure
is an aggregated calculation like the sum, count or average of a value (learn more here)
To ask for a measure in your component**,** define an input like so:
{
name: "ds",
type: "dataset",
label: "Dataset to display"
},
{
name: "myMeasure",
type: "measure",
label: "Y-axis", // shown in the UI in the no-code builder
config: {
dataset: "ds", // tells no-code builder where to get the list of measures from
},
},
TimeDimension
is a dimension of type time, aggregated by, for example, day, week, month or year, etc.
Very useful for populating time-series charts (usually with time along the x-axis)
To ask for a time dimension in your component**,** define inputs like so:
{
name: "ds",
type: "dataset",
label: "Dataset to display"
},
{
name: 'xAxis',
type: 'dimension',
label: 'X-axis',
config: {
dataset: 'ds',
supportedTypes: ['time'] //only include dimensions of type 'time'
}
},
{
name: 'xAxisGranularity',
type: 'granularity', // asks user to specify one of day, week, month, etc.
label: 'Granularity'
}
And then use those inputs with loadData
like so:
export default defineComponent(Component, meta, {
props: (inputs) => {
return {
...inputs,
results: loadData({
from: inputs.ds,
timeDimensions: [
{
dimension: props.xAxis?.name,
granularity: props.xAxisGranularity
}
]
})
};
}
});
OrderBy
is a dimension or measure that you want to have the returned results sorted by (asc
or desc
).
To ask for a dimension or measure in your component**,** you could define inputs like so:
{
name: "ds",
type: "dataset",
label: "Dataset to display"
},
{
name: "columnsToShow",
type: "dimensionOrMeasure",
array: true,
label: "Columns to show",
config: {
dataset: "ds",
},
},
{
name: "columnToSortBy",
type: "dimensionOrMeasure",
label: "Column to sort by",
config: {
dataset: "ds",
},
},
And then you can sort your results by this column like so:
import { loadData, isMeasure, isDimension } from '@embeddable.com/core';
...
export default defineComponent(Component, meta, {
props: (inputs) => {
return {
...inputs,
results: loadData({
from: inputs.ds,
dimensions: inputs.columnsToShow.filter((c) => isDimension(c)),
measures: inputs.columnsToShow.filter((c) => isMeasure(c)),
orderBy: [{ property: inputs.columnToSortBy, direction: 'desc' }]
})
};
}
});
limit
and offset
are your standard way of performing paging in SQL.
limit
tells your DB how many results to return (max). Defaults to 100.
offset
tells your DB to skip the first offset
rows before returning rows. Defaults to 0.
This means you could, for example, ask your user for a page number and page size:
{
name: "ds",
type: "dataset",
label: "Dataset to display"
},
{
name: "columnsToShow",
type: "dimensionOrMeasure",
array: true,
label: "Columns to show",
config: {
dataset: "ds",
},
},
{
name: "pageNumber",
type: "number",
label: "Page number",
},
{
name: "pageSize",
type: "number",
label: "Page size",
},
And then retrieve that page like so:
import { loadData, isMeasure, isDimension } from '@embeddable.com/core';
...
export default defineComponent(Component, meta, {
props: (inputs) => {
return {
...inputs,
results: loadData({
from: inputs.ds,
dimensions: inputs.columnsToShow.filter((c) => isDimension(c)),
measures: inputs.columnsToShow.filter((c) => isMeasure(c)),
limit: inputs.pageSize,
offset: inputs.pageNumber * inputs.pageSize
})
};
}
});
QueryFilter
is a filter applied to the results (note that any filters applied here will be applied additionally to any filters applied on the Dataset itself, not instead of). Filters are applied to the database query (using WHERE
for dimension filters and HAVING
for measure filters), as opposed to being applied using javascript after the results have come back.
QueryFilter
is defined as { property, operator, value }
property
is either a Dimension
or Measure
operator
is a string and must be one of the Cube built-in operators (listed here) or Embeddable’s custom isNull
or notNull
operators which replace Cube’s set
and notSet
operators, respectively, for clarity purposes.value
is currently defined as string | boolean | number | Date | Time | TimeRange | Array<string | boolean | number | Date>;