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 Measureoperator 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>;