Skip to content

Commit

Permalink
Merge pull request #1424 from evidence-dev/fix/dates-break-barcharts
Browse files Browse the repository at this point in the history
Universal SQL: Pre-release fixes
  • Loading branch information
ItsMeBrianD authored Dec 21, 2023
2 parents a6ae0f4 + 913f591 commit 4252e55
Show file tree
Hide file tree
Showing 8 changed files with 363 additions and 316 deletions.
5 changes: 5 additions & 0 deletions .changeset/sixty-zebras-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@evidence-dev/universal-sql': patch
---

Handle null / undefined values when columns are omitted from result sets
5 changes: 5 additions & 0 deletions .changeset/stupid-seahorses-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@evidence-dev/component-utilities': patch
---

getCompletedData handles dates properly now
43 changes: 17 additions & 26 deletions packages/component-utilities/src/getCompletedData.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
import { tidy, complete, mutate } from '@tidyjs/tidy';
import { tidy, complete } from '@tidyjs/tidy';
import getDistinctValues from './getDistinctValues';
import { findInterval, vectorSeq } from './helpers/getCompletedData.helpers.js';

/**
* This function fills missing data points in the given data array for a specific series.
*
* @param {Record<string, unknown>[]} data - The data as an array of objects.
* @param {Record<string, unknown>[]} _data - The data as an array of objects.
* @param {string} x - The property used as x-axis.
* @param {string} y - The property used as y-axis.
* @param {string} series - The specific series in the data to be filled.
* @param {boolean} [nullsZero=false] - A flag indicating whether nulls should be replaced with zero.
* @param {boolean} [fillX=false] - A flag indicating whether the x-axis values should be filled (based on the found interval distance).
* @return {Record<string, unknown>[]} An array containing the filled data objects.
*/
export default function getCompletedData(data, x, y, series, nullsZero = false, fillX = false) {
export default function getCompletedData(_data, x, y, series, nullsZero = false, fillX = false) {
let xIsDate = false;
const data = _data.map((d) =>
Object.assign({}, d, {
[x]: d[x] instanceof Date ? ((xIsDate = true), d[x].toISOString()) : d[x]
})
);
const groups = Array.from(data).reduce((a, v) => {
if (v[x] instanceof Date) {
v[x] = v[x].toISOString();
xIsDate = true;
}
if (series) {
if (!a[v[series]]) a[v[series]] = [];
a[v[series]].push(v);
if (!a[v[series] ?? 'null']) a[v[series] ?? 'null'] = [];
a[v[series] ?? 'null'].push(v);
} else {
if (!a.default) a.default = [];
a.default.push(v);
Expand All @@ -29,25 +39,13 @@ export default function getCompletedData(data, x, y, series, nullsZero = false,
// e.g. can include series and x values to ensure that all series have all x values
const expandKeys = {};

const xIsDate = data[0]?.[x] instanceof Date;

/** @type {Array<number | string>} */
let xDistinct;
const exampleX = data[0]?.[x];

switch (typeof exampleX) {
case 'object':
// If x is not a date; this shouldn't be hit, abort!
if (!(exampleX instanceof Date)) {
throw new Error('Unexpected object property, expected string, date, or number');
}
// Map dates to numeric values
xDistinct = getDistinctValues(
data.map((d) => ({ [x]: d[x].getTime() })),
x
);
// We don't fillX here because date numbers are very large, so a small interval would create a _massive_ array
break;
throw new Error('Unexpected object property, expected string, date, or number');
case 'number':
// Numbers are the most straightforward
xDistinct = getDistinctValues(data, x);
Expand Down Expand Up @@ -85,16 +83,9 @@ export default function getCompletedData(data, x, y, series, nullsZero = false,
} else {
tidyFuncs.push(complete(expandKeys, nullySpec));
}
if (xIsDate) {
// Ensure that x is actually a date
tidyFuncs.push(
mutate({
[x]: (val) => new Date(val[x])
})
);
}

output.push(tidy(value, ...tidyFuncs));
}
if (xIsDate) return output.flat().map((r) => ({ ...r, [x]: new Date(r[x]) }));
return output.flat();
}
Loading

0 comments on commit 4252e55

Please sign in to comment.