Skip to content

Crosstab ​

A grid of cube data, read row by row, with several values on each row.

js
const table = cube.crosstab("Sales", {
    rows:    { "Product": [{ set: ["All Products"] }, "expand-all", "remove-all-consolidations"] },
    columns: { "Measures": [{ set: ["Units", "Revenue"] }] },
    context: { "Year": "2026", "Version": "Actual" }
});

for (const row of table) {
    console.log(row.label + ": " + row.values.join(", "));
}

Constructor ​

cube.crosstab cube.crosstab(cubeName, options) Crosstab | null ​

Reads a grid of values from a cube. Returns null when the cube, a dimension or an element can't be found, or the options aren't valid. The reason is written to the process log.

ParameterTypeDescription
cubeNamestringThe cube's name or id.
optionsobjectWhich elements go on the rows and columns; see the table below.
OptionTypeDescription
rowsobjectThe dimensions on the rows. Each key is a dimension's name and each value is an array of set instructions. At least one is required; two give a row for each combination.
columnsobjectThe same, for the columns. At least one is required.
contextobjectOne element for each remaining dimension, keyed by dimension name.
suppressstringOptional. "rows", the default, leaves out rows with no values. "none" keeps every row.
securityboolean | stringOptional. false, the default, reads everything, ignoring security. true reads as the signed-in user, and a user's id or email address reads as that user.
maxRowsnumberOptional. The most rows to read.

Every dimension of the cube must be on the rows, the columns or in context.

Overview ​

  • Set instructions: each dimension on an axis takes an array of instructions, run in order, the same as a Workview set. Use { set: ["All Products"] } to select elements (add hierarchy to take them from a named hierarchy), and plain strings such as "expand-all" and "remove-all-consolidations" for actions.
  • When to use it: use cube.get for one cell and cube.slice for many leaf-level cells. Use cube.crosstab when rows follow a hierarchy, when a row needs several values, or when you need consolidated totals.
  • Rows: each row has a label, its members (one per row dimension, with dimension, name, hierarchy and consolidation), and its values, in the same order as columns().
  • Reading twice: rows are read as you loop, and each loop reads the cube again. Use toArray() or toGrid() if you need the rows more than once.
  • Limits: an axis with more than 100,000 combinations is refused, and reading stops after 250,000 cells, with isTruncated() set.

Methods ​

toArray toArray() array ​

Reads every row and returns them as an array of row objects.

toGrid toGrid() array ​

Reads every row and returns each one as a flat array: the row's element names, then its values, in the order headers() describes.

headers headers() string[] ​

Returns the row dimension names, then the column labels, matching a row from toGrid().

columns columns() array ​

Returns the columns, in the same order as each row's values. Each column has a label, its members, its measure, its elementType ("Numeric" or "String") and whether it's consolidated.

warnings warnings() string[] ​

Returns messages about anything left out of the read, such as calculated elements that were dropped or the cell limit being reached.

rowsProduced rowsProduced() number ​

Returns how many rows have been read so far.

cellsEvaluated cellsEvaluated() number ​

Returns how many cells have been read so far.

isTruncated isTruncated() boolean ​

Returns true when the 250,000-cell limit stopped the read early. Stopping at maxRows doesn't count.

Examples ​

Products with two measures ​

js
const table = cube.crosstab("Sales", {
    rows:    { "Product": [{ set: ["All Products"] }, "expand-all", "remove-all-consolidations"] },
    columns: { "Measures": [{ set: ["Units", "Revenue"] }] },
    context: { "Year": "2026", "Version": "Actual" }
});

for (const row of table) {
    console.log(row.label + ": " + row.values.join(", "));
}
text
Widgets: 120, 1450.5
Gadgets: 85, 980
Gizmos: 40, 512.25

Regions with their totals ​

js
const table = cube.crosstab("Sales", {
    rows:    { "Region": [{ set: ["All Regions"] }, "expand"] },
    columns: { "Measures": [{ set: ["Revenue"] }] },
    context: { "Year": "2026", "Version": "Actual" }
});

for (const row of table) {
    const total = row.members[0].consolidation ? " (total)" : "";
    console.log(row.label + total + " = " + row.values[0]);
}
text
All Regions (total) = 9200
North = 5000
South = 4200

Export to CSV ​

js
const table = cube.crosstab("Sales", {
    rows:    { "Product": [{ set: ["All Products"] }, "expand-all", "remove-all-consolidations"] },
    columns: { "Measures": [{ set: ["Units", "Revenue"] }] },
    context: { "Year": "2026", "Version": "Actual" }
});

const writer = datasource.csv("exports/sales_2026.csv");
writer.write(table.headers());
for (const row of table.toGrid()) {
    writer.write(row);
}
writer.close();
csv
"Product","Units","Revenue"
"Widgets",120,1450.5
"Gadgets",85,980
"Gizmos",40,512.25