diff --git a/docs/pages/reference/frontend/cubejs-client-core.mdx b/docs/pages/reference/frontend/cubejs-client-core.mdx index 4e871b09f9358..86b1ed068e191 100644 --- a/docs/pages/reference/frontend/cubejs-client-core.mdx +++ b/docs/pages/reference/frontend/cubejs-client-core.mdx @@ -838,7 +838,8 @@ resultSet.tablePivot({ Name | Type | Description | ------ | ------ | ------ | aliasSeries? | string[] | Give each series a prefix alias. Should have one entry for each query:measure. See [chartPivot](#result-set-chart-pivot) | -fillMissingDates? | boolean | null | **`true` by default.** If set to `true`, missing dates on the time dimensions will be filled with `0` for all measures. Note: setting this option to `true` will override any `order` applied to the query. | +fillMissingDates? | boolean | null | **`true` by default.** If set to `true`, missing dates on the time dimensions will be filled with `fillWithValue` or `0` by default for all measures. Note: setting this option to `true` will override any `order` applied to the query. | +fillWithValue? | string | null | Value to autofill all the missing date's measure. | x? | string[] | Dimensions to put on **x** or **rows** axis. | y? | string[] | Dimensions to put on **y** or **columns** axis. | @@ -1055,4 +1056,4 @@ values? | never | [link-mdn-max-safe-integer]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER [ref-query-format]: /product/apis-integrations/rest-api/query-format -[ref-security]: /product/auth \ No newline at end of file +[ref-security]: /product/auth diff --git a/packages/cubejs-client-core/index.d.ts b/packages/cubejs-client-core/index.d.ts index beb0b97d168a7..bd9222a49c709 100644 --- a/packages/cubejs-client-core/index.d.ts +++ b/packages/cubejs-client-core/index.d.ts @@ -252,9 +252,13 @@ declare module '@cubejs-client/core' { */ y?: string[]; /** - * If `true` missing dates on the time dimensions will be filled with `0` for all measures.Note: the `fillMissingDates` option set to `true` will override any **order** applied to the query + * If `true` missing dates on the time dimensions will be filled with fillWithValue or `0` by default for all measures.Note: the `fillMissingDates` option set to `true` will override any **order** applied to the query */ fillMissingDates?: boolean | null; + /** + * Value to autofill all the missing date's measure. + */ + fillWithValue?: string | number | null; /** * Give each series a prefix alias. Should have one entry for each query:measure. See [chartPivot](#result-set-chart-pivot) */ diff --git a/packages/cubejs-client-core/src/ResultSet.js b/packages/cubejs-client-core/src/ResultSet.js index 3ec2e184ae40d..02777216fa126 100644 --- a/packages/cubejs-client-core/src/ResultSet.js +++ b/packages/cubejs-client-core/src/ResultSet.js @@ -341,7 +341,7 @@ class ResultSet { const pivotImpl = (resultIndex = 0) => { let groupByXAxis = groupByToPairs(({ xValues }) => this.axisValuesString(xValues)); - const measureValue = (row, measure) => row[measure] || 0; + const measureValue = (row, measure) => row[measure] || pivotConfig.fillWithValue || 0; if ( pivotConfig.fillMissingDates && diff --git a/packages/cubejs-client-core/src/tests/ResultSet.test.js b/packages/cubejs-client-core/src/tests/ResultSet.test.js index 229acf0c82fc0..f1c997eb68119 100644 --- a/packages/cubejs-client-core/src/tests/ResultSet.test.js +++ b/packages/cubejs-client-core/src/tests/ResultSet.test.js @@ -1418,6 +1418,126 @@ describe('ResultSet', () => { ]); }); + test('fill missing dates with custom value', () => { + const resultSet = new ResultSet({ + query: { + measures: ['Orders.total'], + timeDimensions: [ + { + dimension: 'Orders.createdAt', + granularity: 'day', + dateRange: ['2020-01-08T00:00:00.000', '2020-01-11T23:59:59.999'] + } + ], + filters: [], + timezone: 'UTC' + }, + data: [ + { + 'Orders.createdAt': '2020-01-08T00:00:00.000', + 'Orders.total': 1 + }, + { + 'Orders.createdAt': '2020-01-10T00:00:00.000', + 'Orders.total': 10 + } + ], + annotation: { + measures: {}, + dimensions: {}, + segments: {}, + timeDimensions: { + 'Orders.createdAt': { + title: 'Orders Created at', + shortTitle: 'Created at', + type: 'time' + } + } + } + }); + + expect(resultSet.tablePivot({ + 'fillWithValue': 5 + })).toEqual([ + { + 'Orders.createdAt.day': '2020-01-08T00:00:00.000', + 'Orders.total': 1 + }, + { + 'Orders.createdAt.day': '2020-01-09T00:00:00.000', + 'Orders.total': 5 + }, + { + 'Orders.createdAt.day': '2020-01-10T00:00:00.000', + 'Orders.total': 10 + }, + { + 'Orders.createdAt.day': '2020-01-11T00:00:00.000', + 'Orders.total': 5 + } + ]); + }); + + test('fill missing dates with custom string', () => { + const resultSet = new ResultSet({ + query: { + measures: ['Orders.total'], + timeDimensions: [ + { + dimension: 'Orders.createdAt', + granularity: 'day', + dateRange: ['2020-01-08T00:00:00.000', '2020-01-11T23:59:59.999'] + } + ], + filters: [], + timezone: 'UTC' + }, + data: [ + { + 'Orders.createdAt': '2020-01-08T00:00:00.000', + 'Orders.total': 1 + }, + { + 'Orders.createdAt': '2020-01-10T00:00:00.000', + 'Orders.total': 10 + } + ], + annotation: { + measures: {}, + dimensions: {}, + segments: {}, + timeDimensions: { + 'Orders.createdAt': { + title: 'Orders Created at', + shortTitle: 'Created at', + type: 'time' + } + } + } + }); + + expect(resultSet.tablePivot({ + 'fillWithValue': 'N/A' + })).toEqual([ + { + 'Orders.createdAt.day': '2020-01-08T00:00:00.000', + 'Orders.total': 1 + }, + { + 'Orders.createdAt.day': '2020-01-09T00:00:00.000', + 'Orders.total': "N/A" + }, + { + 'Orders.createdAt.day': '2020-01-10T00:00:00.000', + 'Orders.total': 10 + }, + { + 'Orders.createdAt.day': '2020-01-11T00:00:00.000', + 'Orders.total': "N/A" + } + ]); + }); + test('same dimension and time dimension without granularity', () => { const resultSet = new ResultSet({ query: {