diff --git a/packages/datalib/src/chartDefinitions.ts b/packages/datalib/src/chartDefinitions.ts index d335c15cd..b0acf608e 100644 --- a/packages/datalib/src/chartDefinitions.ts +++ b/packages/datalib/src/chartDefinitions.ts @@ -4,6 +4,7 @@ export type ChartXTransformFunction = | 'date:minute' | 'date:hour' | 'date:day' + | 'date:week' | 'date:month' | 'date:year'; export type ChartYAggregateFunction = 'sum' | 'first' | 'last' | 'min' | 'max' | 'count' | 'avg'; @@ -70,6 +71,7 @@ export interface ChartDateParsed { minute?: number; second?: number; fraction?: string; + week?: number; } export interface ChartAvailableColumn { diff --git a/packages/datalib/src/chartTools.ts b/packages/datalib/src/chartTools.ts index 15c2cf469..9856d0a12 100644 --- a/packages/datalib/src/chartTools.ts +++ b/packages/datalib/src/chartTools.ts @@ -9,7 +9,7 @@ import { ChartYFieldDefinition, ProcessedChart, } from './chartDefinitions'; -import { addMinutes, addHours, addDays, addMonths, addYears } from 'date-fns'; +import { addMinutes, addHours, addDays, addMonths, addWeeks, addYears, getWeek } from 'date-fns'; export function getChartDebugPrint(chart: ProcessedChart) { let res = ''; @@ -29,6 +29,7 @@ export function tryParseChartDate(dateInput: any): ChartDateParsed | null { return { year: dateInput.getFullYear(), month: dateInput.getMonth() + 1, + week: getWeek(dateInput), day: dateInput.getDate(), hour: dateInput.getHours(), minute: dateInput.getMinutes(), @@ -42,15 +43,21 @@ export function tryParseChartDate(dateInput: any): ChartDateParsed | null { /^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(Z|[+-]\d{2}:\d{2})?)?$/ ); const monthMatch = dateInput.match(/^(\d{4})-(\d{2})$/); + const weekMatch = dateInput.match(/^(\d{4})\@(\d{2})$/); // const yearMatch = dateInput.match(/^(\d{4})$/); if (dateMatch) { - const [_notUsed, year, month, day, hour, minute, second, fraction] = dateMatch; + const [_notUsed, yearStr, monthStr, dayStr, hour, minute, second, fraction] = dateMatch; + + const year = parseInt(yearStr, 10); + const month = parseInt(monthStr, 10); + const day = parseInt(dayStr, 10); return { - year: parseInt(year, 10), - month: parseInt(month, 10), - day: parseInt(day, 10), + year, + month, + week: getWeek(new Date(year, month - 1, day)), + day, hour: parseInt(hour, 10) || 0, minute: parseInt(minute, 10) || 0, second: parseInt(second, 10) || 0, @@ -71,6 +78,19 @@ export function tryParseChartDate(dateInput: any): ChartDateParsed | null { }; } + if (weekMatch) { + const [_notUsed, year, week] = weekMatch; + return { + year: parseInt(year, 10), + week: parseInt(week, 10), + day: 1, + hour: 0, + minute: 0, + second: 0, + fraction: undefined, + }; + } + // if (yearMatch) { // const [_notUsed, year] = yearMatch; // return { @@ -97,6 +117,8 @@ export function stringifyChartDate(value: ChartDateParsed, transform: ChartXTran return `${value.year}`; case 'date:month': return `${value.year}-${pad2Digits(value.month)}`; + case 'date:week': + return `${value.year}@${pad2Digits(getWeek(new Date(value.year, (value.month ?? 1) - 1, value.day ?? 1)))}`; case 'date:day': return `${value.year}-${pad2Digits(value.month)}-${pad2Digits(value.day)}`; case 'date:hour': @@ -126,6 +148,9 @@ export function incrementChartDate(value: ChartDateParsed, transform: ChartXTran case 'date:month': newDateRepresentation = addMonths(dateRepresentation, 1); break; + case 'date:week': + newDateRepresentation = addWeeks(dateRepresentation, 1); + break; case 'date:day': newDateRepresentation = addDays(dateRepresentation, 1); break; @@ -144,6 +169,11 @@ export function incrementChartDate(value: ChartDateParsed, transform: ChartXTran year: newDateRepresentation.getFullYear(), month: newDateRepresentation.getMonth() + 1, }; + case 'date:week': + return { + year: newDateRepresentation.getFullYear(), + week: getWeek(newDateRepresentation), + }; case 'date:day': return { year: newDateRepresentation.getFullYear(), @@ -175,6 +205,8 @@ export function runTransformFunction(value: string, transformFunction: ChartXTra return dateParsed ? `${dateParsed.year}` : null; case 'date:month': return dateParsed ? `${dateParsed.year}-${pad2Digits(dateParsed.month)}` : null; + case 'date:week': + return dateParsed ? `${dateParsed.year}@${pad2Digits(dateParsed.week)}` : null; case 'date:day': return dateParsed ? `${dateParsed.year}-${pad2Digits(dateParsed.month)}-${pad2Digits(dateParsed.day)}` : null; case 'date:hour': @@ -211,6 +243,14 @@ export function computeChartBucketKey( month: dateParsed.month, }, ]; + case 'date:week': + return [ + dateParsed ? `${dateParsed.year}@${pad2Digits(dateParsed.week)}` : null, + { + year: dateParsed.year, + week: dateParsed.week, + }, + ]; case 'date:day': return [ dateParsed ? `${dateParsed.year}-${pad2Digits(dateParsed.month)}-${pad2Digits(dateParsed.day)}` : null, @@ -265,6 +305,8 @@ export function computeDateBucketDistance( return end.year - begin.year; case 'date:month': return (end.year - begin.year) * 12 + (end.month - begin.month); + case 'date:week': + return (end.year - begin.year) * 52 + (end.week - begin.week); case 'date:day': return ( (end.year - begin.year) * 365 + @@ -302,6 +344,8 @@ export function compareChartDatesParsed( return a.year - b.year; case 'date:month': return a.year === b.year ? a.month - b.month : a.year - b.year; + case 'date:week': + return a.year === b.year ? a.week - b.week : a.year - b.year; case 'date:day': return a.year === b.year && a.month === b.month ? a.day - b.day @@ -356,6 +400,8 @@ function getParentDateBucketKey( return null; // no parent for year case 'date:month': return bucketKey.slice(0, 4); + case 'date:week': + return bucketKey.slice(0, 4); case 'date:day': return bucketKey.slice(0, 7); case 'date:hour': @@ -371,6 +417,8 @@ function getParentDateBucketTransform(transform: ChartXTransformFunction): Chart return null; // no parent for year case 'date:month': return 'date:year'; + case 'date:week': + return 'date:year'; case 'date:day': return 'date:month'; case 'date:hour': @@ -388,6 +436,8 @@ function getParentKeyParsed(date: ChartDateParsed, transform: ChartXTransformFun return null; // no parent for year case 'date:month': return { year: date.year }; + case 'date:week': + return { year: date.week }; case 'date:day': return { year: date.year, month: date.month }; case 'date:hour': diff --git a/yarn.lock b/yarn.lock index 706c4b66c..df07905f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5113,6 +5113,11 @@ bluebird@^3.7.2: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== +blueimp-md5@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.19.0.tgz#b53feea5498dcb53dc6ec4b823adb84b729c4af0" + integrity sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w== + body-parser@1.20.2, body-parser@^1.19.0: version "1.20.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" @@ -6149,11 +6154,6 @@ dbgate-plugin-tools@^1.0.4, dbgate-plugin-tools@^1.0.7, dbgate-plugin-tools@^1.0 pacote "^11.1.13" rimraf "^3.0.2" -dbgate-query-splitter@^4.11.6: - version "4.11.6" - resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.11.6.tgz#8034bd7677e57db09b3ab96d3ff7c0fd3a289a5a" - integrity sha512-QmOOKsaaoZa6OuHjUKRpFiZxfotJ7jebLNzGFhyEjcmjVb9I0QBxPq6mJX7vRleLX5lN0aS6UDwsHwb8B3LNAw== - dbgate-query-splitter@^4.11.7: version "4.11.7" resolved "https://registry.yarnpkg.com/dbgate-query-splitter/-/dbgate-query-splitter-4.11.7.tgz#f9d53b3ceafbd76355152677b87ae453598b4a88"