code: function calculateShownDimensionCombinations(item, dimensions, fullDimensions) {
    // Note we need to suppress the time dimension from the dimension list, if any; it appears as an observation instead.
    // We also need to suppress the regions.
    // Convert the values into all the combinations we'll need to load into columns,
    // eg. [[0], [0], [0, 1, 2], [0, 1]] => [[0, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0], [0, 0, 1, 1], [0, 0, 2, 0], [0, 0, 2, 1]].
    if (!defined(fullDimensions)) {
      fullDimensions = dimensions;
    }
    var valuesArrays = getShownDimensions(item, dimensions, fullDimensions).map(
      function(dimension) {
        return dimension.values;
      }
    );
  
    var idsArrays = valuesArrays.map(function(values) {
      return values.map(function(value) {
        return value.id;
      });
    });
    var namesArrays = valuesArrays.map(function(values) {
      return values.map(function(value) {
        return value.name;
      });
    });
    return {
      ids: arrayProduct(idsArrays),
      names: arrayProduct(namesArrays)
    };
  }
docs: Calculates all the combinations of values that should appear as either:
  - columns in our table (by passing the "loadedDimensions" for a given dataset), or
  - concepts in the Now Viewing panel (by passing the "fullDimensions", ie. those from the dataflow.)
  Does not include suppressed (ie. region or time_period) values.
  Returns an object with properties:
  names: An array, each element of which is an array of the names of each relevant dimension value.
  ids:   An array, each element of which is an array of the ids of each relevant dimension value.
  @private
  @param  {SdmxJsonCatalogItem} item The catalog item.
  @param {Object[]} dimensions The output of buildDimensions, either fullDimensions or loadedDimensions.
  @param {Object[]} fullDimensions The output of buildDimensions on the dataflow result (or data if no dataflow). Defaults to dimensions.
  @return {Object} The values and names of the dimensions to be shown.